Praktik terbaik dengan Nuget: Debug atau Rilis?

92

Saat ini, saya mengemas rilis build dengan Nuget untuk build resmi ke nuget.org, tetapi saya mengemas build debug dengan Nuget untuk push source simbol ke symbolource.org.

EDIT: (Jon Skeet, dengan beberapa bias dari pengembangan Noda Time)

NuGet sekarang mendukung pengiriman ke galeri NuGet dan symbolource.org (atau server serupa), seperti yang didokumentasikan . Sayangnya, ada dua persyaratan yang kontradiktif di sini:

  • Saat hanya menggunakan perpustakaan tanpa perlu debugging, Anda benar-benar menginginkan rilis build. Itulah gunanya rilis build.
  • Saat men-debug ke pustaka untuk tujuan diagnostik, Anda benar-benar menginginkan build debug dengan semua pengoptimalan yang sesuai dinonaktifkan. Itulah gunanya build debug.

Itu akan baik-baik saja, tetapi NuGet tidak (sejauh yang saya tahu) mengizinkan rilis dan debug build untuk dipublikasikan dengan cara yang berguna, dalam paket yang sama.

Jadi, pilihannya adalah:

  • Distribusikan build debug kepada semua orang (seperti yang ditunjukkan dalam contoh di dokumen) dan aktifkan dengan ukuran dan kinerja apa pun yang muncul.
  • Distribusikan rilis build untuk semua orang dan hidup dengan pengalaman debug yang sedikit terganggu.
  • Gunakan kebijakan distribusi yang sangat rumit, berpotensi menyediakan rilis terpisah dan paket debug.

Dua yang pertama benar-benar bermuara pada efek perbedaan antara debug dan rilis build ... meskipun perlu dicatat bahwa ada juga perbedaan besar antara ingin masuk ke dalam kode perpustakaan karena Anda ingin memeriksa beberapa perilaku, dan menginginkan untuk men-debug kode perpustakaan karena Anda yakin telah menemukan bug. Dalam kasus kedua, mungkin lebih baik untuk mendapatkan kode perpustakaan sebagai solusi Visual Studio dan debug seperti itu, jadi saya tidak terlalu memperhatikan situasi itu.

Godaan saya adalah tetap menggunakan build rilis, dengan harapan bahwa relatif sedikit orang yang perlu melakukan debug, dan orang yang melakukannya tidak akan banyak terpengaruh oleh pengoptimalan dalam build rilis. (Kompiler JIT melakukan sebagian besar pengoptimalan.)

Jadi, apakah ada opsi lain yang belum kami pertimbangkan? Apakah ada pertimbangan lain yang memberi keseimbangan? Apakah mendorong paket NuGet ke SymbolSource cukup baru sehingga "praktik terbaik" benar-benar belum dibuat?

gzak
sumber
2
Saya akan mengajukan pertanyaan yang sama - meskipun saat ini saya mendorong konfigurasi Rilis ke sumber simbol juga, mengingat bahwa saya hanya menggunakan nuget pack ... -Symboldan mendorong paket yang dihasilkan ...
Jon Skeet
1
Saya merasa saya harus mengirimkan sesi Tanya Jawab ini kepada orang-orang di balik NuGet dan melihat apakah mereka dapat mempertimbangkannya.
gzak
Panggang login ke paket Anda dan kemudian publikasikan hanya rilis build. Anda dapat mengizinkan injeksi logger yang akan menyediakan konsumen untuk mengatur logging sesuai dengan preferensinya.
CShark

Jawaban:

31

Berbicara untuk SymbolSource, saya yakin praktik terbaiknya adalah:

  1. Dorong rilis paket konten + biner ke nuget.org saja (atau umpan produksi lainnya)
  2. Dorong paket konten + biner debug ke feed pengembangan:
    • di tempat
    • di myget.org
    • di nuget.org sebagai paket pra-rilis.
  3. Dorong rilis dan debug paket simbol + biner ke symbolource.org atau penyimpanan simbol lainnya.

Sementara kita melakukannya, itu adalah kesalahpahaman umum bahwa rilis dan debug yang dibangun di .NET sangat berbeda, tetapi saya berasumsi bahwa perbedaannya ada di sini karena berbagai kode yang mungkin atau mungkin tidak disertakan dalam salah satu build, seperti Debug .Menyatakan.

Meskipun demikian, sangatlah berharga untuk mendorong kedua konfigurasi ke SymbolSource, karena Anda tidak pernah tahu kapan Anda perlu men-debug kode produksi. Jauh di produksi untuk membuatnya lebih sulit. Anda akan membutuhkan bantuan yang dapat Anda peroleh dari perkakas Anda saat itu terjadi. Yang jelas tidak saya inginkan pada siapa pun.

Masih ada masalah yang perlu dipertimbangkan terkait pembuatan versi: apakah benar memiliki 2 paket berbeda (build dalam debug dan dalam rilis) yang berbagi 1 nomor versi? SymbolSource akan menerimanya, karena mengekstrak paket dan menyimpan biner dalam cabang mode build terpisah, JIKA HANYA NuGet diizinkan untuk menandai paket yang sesuai. Tidak ada cara saat ini untuk menentukan apakah sebuah paket adalah debug atau mode rilis.

TripleEmcoder
sumber
Bagian "menerbitkan dua versi ke NuGet" adalah bagian yang sedikit rumit. Saya selalu menerbitkan rilis rilis Waktu Noda, dengan alasan bahwa saya harus memilih di antara keduanya. (Saya punya file nuspec, daripada melakukannya hanya dari proyek C #.) Anda menyebutkan men-debug kode produksi seolah-olah itu jauh lebih sulit dengan hanya rilis build - meskipun sebelumnya bagian "mereka tidak berbeda jauh". Saya mengetahui NOP dalam build debug, dan tentu saja Debug.Assertdll - tetapi dapatkah Anda memperluas (dalam jawaban Anda) tentang implikasi saat debugging? Seberapa buruk menggunakan build Rilis?
Jon Skeet
Yang saya maksud hanyalah Anda ingin memiliki simbol yang tersedia untuk semua binari yang digunakan: jika ada build debug dan rilis di alam liar, Anda akan ingin memberikan simbol untuk keduanya. Mereka tidak perlu banyak berbeda dalam hal kode, tetapi mereka akan berbeda dalam checksum, yang membuat simbol pemuatan tidak mungkin tanpa beberapa peretasan.
TripleEmcoder
1
Baik. Solusi saya yang mungkin adalah hanya merilis binari Rilis, tetapi saya khawatir tentang seberapa banyak yang akan merugikan dalam hal debugging. Misalnya, apakah kurangnya NOP berarti Anda tidak dapat menambahkan breakpoint?
Jon Skeet
Masalahnya lebih pada pengoptimalan JIT daripada pengoptimalan waktu build. Jadi, jika Anda mendorong paket mode rilis dan merekomendasikan penggunaan COMPLUS_ZapDisable = 1 saat debugging diperlukan, itu sudah cukup bagi saya. NuGet tetap harus mengizinkan debug dan rilis bersama-sama dalam beberapa cara.
TripleEmcoder
Saya tidak tahu symbolssource.org ada. Karena gatal saya berkali-kali harus menggaruk, saya menyambutnya.
Remus Rusanu
4

Saya sepenuhnya setuju dengan kesimpulan Anda. Paket NuGet dengan RELEASE dan SymbolSource dengan debug. Tampaknya sangat jarang untuk masuk langsung ke paket dan kesalahan langkah debug sesekali dengan pengoptimalan diaktifkan mungkin dapat diterima.

Jika benar-benar ada masalah, saya pikir solusi yang ideal adalah meminta NuGet mendukungnya. Misalnya, bayangkan jika saat men-debug, itu bisa menggantikan rilis DLL dengan yang disertakan dalam paket SymbolSource.

Idealnya, yang akan terjadi selanjutnya adalah bahwa nuget pack SomePackage -Symbolsversi rilis akan membuat paket nuget rilis, tetapi paket simbol debug. Dan plugin VS akan diperbarui agar cukup pintar untuk melihat pengaitan dan menarik rakitan Debug saat berjalan di debugger dan memuatnya sebagai gantinya. Agak gila, tapi akan menarik.

Namun, saya hanya tidak melihat cukup banyak orang yang mengeluh tentang hal ini sehingga layak dilakukan saat ini.

Tim NuGet menerima permintaan penarikan. :)

Haacked
sumber
Saya tidak yakin saya mengerti kalimat kedua Anda - Saya menduga OP (sebelum saya mengedit) melakukan dorongan manual ke SymbolSource untuk membangun debug. Apakah Anda membayangkan masalah yang signifikan jika PDB versi rilis berakhir di SymbolSource, bukan di versi debug? Ataukah itu yang Anda dukung, dan saya hanya salah paham?
Jon Skeet
3
"Namun, saya tidak melihat cukup banyak orang yang mengeluh tentang hal ini sehingga hal ini layak dilakukan saat ini." Mungkin mereka tidak mengeluh, tetapi jika Anda bertanya kepada sampel pengguna apa pendapat mereka tentang hal ini, saya yakin Anda akan menemukan bahwa kebanyakan orang akan mengakui sedikit kebingungan pada langkah khusus ini (apa yang harus dipublikasikan ke NuGet.org dan SymbolSource .org). Jika Anda bertanya apa yang akhirnya mereka pilih, Anda mungkin akan menemukan bahwa tidak ada satu pun latihan yang disepakati, semua orang hanya melakukan hal mereka sendiri.
gzak
7
Saya ingin mengeluh tentang ini, di mana saya harus mendaftar?
Alex
Setelah Anda memiliki NuGets internal dan Anda mulai menerapkannya ke server simbol ... Anda pasti ingin men-debugnya .... dan meskipun Anda dapat melangkah melalui kode, Anda akan berakhir dengan "Tidak dapat memperoleh nilai dari variabel atau argumen lokal ... itu telah dioptimalkan ". Seperti yang dikatakan Phil ... JIKA nuget memiliki cara untuk memuat dll debug dalam mode debug dan melepaskan dll dalam mode rilis (dari paket nuget), ini akan menjadi yang terakhir. Sampai saat itu kami terjebak dengan pengalih paket
Nuget
1
Saya setuju, ini akan menjadi peningkatan produk yang bagus.
htm11h
2

Sudah 8 tahun sejak posting OP, jadi saya akan memberikan celah dengan apa yang digunakan saat ini.

Ada 2 cara untuk " melangkah ke " paket NuGet:

1. Distribusi PDB

.symbols.nupkgpaket simbol dianggap sebagai warisan dan telah diganti dengan .snupkgpaket yang dipublikasikan ke Server Simbol . Ini didukung oleh sebagian besar vendor dengan Azure DevOps sebagai pihak luar terbesar di mana permintaan fitur masih "dalam peninjauan" (terima kasih @alv untuk tautannya).

Berikut adalah instruksi resminya . Cukup tambahkan dua baris ini ke file csproj:

<PropertyGroup>
  <IncludeSymbols>true</IncludeSymbols>
  <SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

Di sisi konsumen, pastikan bahwa IDE Anda dikonfigurasi untuk Server Simbol NuGet.org (atau Azure, dll.) Untuk memungkinkan masuk ke kode paket saat debugging.

2. Source Link. Menghubungkan kode sebenarnya

Dalam beberapa kasus, PDB mungkin menyembunyikan beberapa spesifikasi kode sumber karena pengoptimalan MSIL / JIT. Jadi ada cara untuk " Melangkah ke " sumber sebenarnya dari NuGet Anda saat melakukan debug. Ini disebut Source Link dari .NET Foundation - " sistem agnostik kontrol bahasa dan sumber untuk menyediakan pengalaman debugging sumber untuk binari ".

Ini didukung oleh Visual Studio 15.3+ dan semua vendor utama (juga mendukung repo pribadi).

Sangat mudah untuk menyiapkan ( dokumen resmi ) - cukup tambahkan dependensi pengembangan ke file proyek (tergantung pada jenis repo Anda) bersama dengan beberapa flag:

<PropertyGroup>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    <EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

Lihat lebih lanjut tentang subjek ini di " 5 langkah untuk paket NuGet yang lebih baik ".

Alex Klaus
sumber
1
snupkg tidak didukung oleh Azure DevOps, lihat developercommunity.visualstudio.com/idea/657354/…
alv
Terima kasih! Saya mengoreksi jawabannya
Alex Klaus
1

Contoh dalam Membuat dan Menerbitkan Paket Simbol mereferensikan file di direktori Debug sebagai sumber untuk file dll dan pdb.

Menentukan Isi Paket Simbol

Paket simbol dapat dibangun berdasarkan konvensi, dari folder yang terstruktur dengan cara yang dijelaskan di bagian sebelumnya, atau isinya dapat ditentukan menggunakan bagian file. Jika Anda ingin membuat paket contoh yang dijelaskan sebelumnya, Anda dapat memasukkan ini ke dalam file nuspec Anda:

<files>
  <file src="Full\bin\Debug\*.dll" target="lib\net40" /> 
  <file src="Full\bin\Debug\*.pdb" target="lib\net40" /> 
  <file src="Silverlight\bin\Debug\*.dll" target="lib\sl40" /> 
  <file src="Silverlight\bin\Debug\*.pdb" target="lib\sl40" /> 
  <file src="**\*.cs" target="src" />
</files>

Karena tujuan penerbitan simbol adalah untuk memungkinkan orang lain melewati kode Anda saat men-debug, tampaknya paling bijaksana untuk menerbitkan versi kode yang dimaksudkan untuk debugging tanpa pengoptimalan yang mungkin memengaruhi langkah kode.

tvanfosson.dll
sumber
Ya, itulah yang dilakukan contoh - tetapi saya lebih suka tidak berakhir dengan kemampuan untuk men-debug yang mengesampingkan keinginan sebagian besar pengembang untuk hanya menjalankan versi rilis. Masalahnya adalah NuGet tidak memiliki cara untuk menerbitkan rilis dan versi debug, sejauh yang saya tahu. (Ini juga akan sedikit merepotkan bagi saya untuk mempublikasikan keduanya, karena itu berarti membuat satu set konfigurasi lain, untuk pembuatan debug yang ditandatangani ...)
Jon Skeet
Di sini kita membahas sedikit subjektivitas. Biasanya, pilihan saya untuk "praktik terbaik" adalah yang penulis rekomendasikan, baik secara eksplisit maupun implisit, karena saya menganggap mereka memiliki lebih banyak wawasan (atau pengawasan, dalam kasus asumsi yang berakhir dalam contoh) daripada I. Berbicara secara pribadi, Saya pikir simbol harus sesuai dengan versi yang saya gunakan. Saya biasanya tidak akan menggunakan paket yang menurut saya mungkin harus saya debug, kecuali sumbernya bersifat publik dan saya dapat mengkompilasi dari awal jika diperlukan, jadi kurangnya paket build debug tidak terlalu penting.
tvanfosson
Dalam kasus saya, jika ada yang perlu men-debug Noda Time karena mereka yakin ada bug di Noda Time, lebih baik mereka mengunduh sumbernya (yang dapat mereka lakukan, tentu saja). Namun, masih berguna untuk dapat masuk ke kode sumber Waktu Noda hanya untuk melihat apa yang terjadi. Pada dasarnya saya pikir ada (setidaknya) dua skenario berbeda untuk debugging, dengan solusi berbeda ...
Jon Skeet
Satu hal yang ingin saya pikirkan adalah .NET itu sendiri: Menurut saya aman untuk mengatakan Microsoft menerbitkan rilis rilis dan bukan men-debug build dari .NET. Versi rilis menyiratkan tingkat kualitas dan stabilitas tertentu, jadi idenya adalah Anda jarang perlu masuk ke dalam kode untuk mendiagnosis berbagai hal.
gzak
2
Namun, itu juga mentalitas yang agak "sumber tertutup". Saya telah menemukan bahwa di dunia open source, lebih diharapkan untuk dapat masuk ke kode "rilis stabil" dari berbagai pustaka bukan karena ada yang rusak, tetapi karena terkadang dokumentasi terbaik adalah hanya melihat apa pustaka itu perbuatan.
gzak