แนวทางปฏิบัติที่ดีที่สุดกับ Nuget: Debug or Release?


92

ตอนนี้ฉันจัดแพ็คเกจบิวด์รีลีสด้วย Nuget สำหรับบิวด์อย่างเป็นทางการไปยัง nuget.org แต่ฉันแพ็กเกจการดีบักบิวด์ด้วย Nuget สำหรับซอร์สสัญลักษณ์ที่ส่งไปยัง Symbolource.org

แก้ไข: (Jon Skeet มีอคติจากการพัฒนา Noda Time)

ตอนนี้ NuGet รองรับการส่งไปยังทั้งแกลเลอรีNuGet และ Symbolource.org (หรือเซิร์ฟเวอร์ที่คล้ายกัน) ตามที่บันทึกไว้ น่าเสียดายที่มีข้อกำหนดที่ขัดแย้งกันสองประการที่นี่:

  • เมื่อใช้ไลบรารีโดยไม่จำเป็นต้องมีการดีบักใด ๆ คุณต้องการสร้างรุ่น นั่นคือสิ่งที่รุ่นสร้างมีไว้สำหรับหลังจากทั้งหมด
  • เมื่อทำการดีบักลงในไลบรารีเพื่อวัตถุประสงค์ในการวินิจฉัยคุณต้องการสร้างดีบักโดยปิดใช้งานการเพิ่มประสิทธิภาพที่เหมาะสมทั้งหมด นั่นคือสิ่งที่สร้างดีบักมีไว้สำหรับหลังจากทั้งหมด

นั่นจะดี แต่ NuGet ไม่ (เท่าที่ฉันบอกได้) อนุญาตให้เผยแพร่ทั้งรุ่นและรุ่นแก้ไขข้อบกพร่องในรูปแบบที่เป็นประโยชน์ในแพ็คเกจเดียวกัน

ดังนั้นตัวเลือกคือ:

  • แจกจ่ายบิวด์การแก้ไขข้อบกพร่องให้ทุกคน (ดังที่แสดงในตัวอย่างในเอกสาร) และใช้งานกับ Hit ขนาดและประสิทธิภาพใด ๆ
  • แจกจ่ายรุ่นสร้างให้กับทุกคนและใช้ชีวิตด้วยประสบการณ์การดีบักที่บกพร่องเล็กน้อย
  • ใช้นโยบายการแจกจ่ายที่ซับซ้อนมากโดยอาจให้แพ็คเกจรีลีสและดีบักแยกต่างหาก

สองคนแรกเดือดลงไปถึงผลของความแตกต่างระหว่างการดีบักและการสร้างรุ่น ... แม้ว่าจะเป็นที่น่าสังเกตว่ายังมีความแตกต่างอย่างมากระหว่างการต้องการก้าวเข้าสู่รหัสของไลบรารีเพราะคุณต้องการตรวจสอบพฤติกรรมบางอย่างและต้องการ เพื่อดีบักโค้ดของไลบรารีเพราะคุณเชื่อว่าคุณพบข้อบกพร่อง ในกรณีที่สองอาจเป็นการดีกว่าที่จะรับโค้ดของไลบรารีเป็นโซลูชัน Visual Studioและดีบักด้วยวิธีนี้ดังนั้นฉันจึงไม่ต้องใส่ใจกับสถานการณ์นั้นมากเกินไป

สิ่งล่อใจของฉันคือการเพียงให้กับการเปิดตัวสร้างที่มีการคาดการณ์ว่าค่อนข้างไม่กี่คนที่จะต้องแก้ปัญหาและเป็นคนที่ทำจะไม่ได้รับผลกระทบมากจากการเพิ่มประสิทธิภาพในการปล่อยสร้าง (คอมไพลเลอร์ JIT จะทำการปรับให้เหมาะสมเป็นส่วนใหญ่)

มีทางเลือกอื่นที่เราไม่ได้พิจารณาหรือไม่? มีข้อควรพิจารณาอื่น ๆ ที่ช่วยให้สมดุลหรือไม่? การผลักดันแพ็คเกจ NuGet ไปยัง SymbolSource ใหม่เพียงพอที่ "แนวทางปฏิบัติที่ดีที่สุด" ยังไม่ได้ถูกกำหนดขึ้นจริงหรือ?


2
ฉันกำลังจะถามคำถามเดียวกัน - แม้ว่าตอนนี้ฉันกำลังผลักดันการกำหนดค่าการเผยแพร่ไปยังแหล่งสัญลักษณ์ด้วยเนื่องจากฉันเพิ่งใช้nuget pack ... -Symbolและผลักดันแพ็คเกจที่สร้างขึ้น ...
Jon Skeet

1
ฉันรู้สึกว่าควรส่งเซสชันถาม / ตอบนี้ให้กับคนที่อยู่เบื้องหลัง NuGet และดูว่าพวกเขาสามารถชั่งใจได้หรือไม่
gzak

เข้าสู่ระบบในแพ็คเกจของคุณแล้วเผยแพร่เฉพาะรุ่นที่วางจำหน่าย คุณสามารถอนุญาตให้มีการฉีดคนตัดไม้ซึ่งจะช่วยให้ผู้บริโภคสามารถตั้งค่าการบันทึกได้ตามความต้องการของตน
CShark

คำตอบ:


31

เมื่อพูดถึง SymbolSource ฉันเชื่อว่าแนวทางปฏิบัติที่ดีที่สุดคือ:

  1. ผลักดันชุดเนื้อหาไบนารี + ไปยัง nuget.org เท่านั้น (หรือฟีดการผลิตอื่น ๆ )
  2. พุชแพ็กเกจเนื้อหา binary + debug ไปยังฟีดการพัฒนา
    • บนสมมติฐาน
    • บน myget.org
    • บน nuget.org เป็นแพ็คเกจก่อนวางจำหน่าย
  3. พุชทั้งรีลีสและดีบักแพ็คเกจสัญลักษณ์ไบนารี + ไปยัง Symbolsource.org หรือที่เก็บสัญลักษณ์อื่น ๆ

ในขณะที่เรากำลังทำอยู่มันเป็นความเข้าใจผิดทั่วไปที่การสร้างและการดีบักใน. NET แตกต่างกันมาก แต่ฉันคิดว่าความแตกต่างอยู่ที่นี่เนื่องจากรหัสต่างๆที่อาจรวมหรือไม่รวมอยู่ในบิลด์เช่น Debug .Asserts.

ที่กล่าวว่ามันคุ้มค่ามากที่จะผลักดันการกำหนดค่าทั้งสองไปยัง SymbolSource เพราะคุณไม่มีทางรู้เลยว่าคุณจะต้องดีบักโค้ดการผลิตเมื่อใด ในการผลิตจากระยะไกลเพื่อให้ยากขึ้น คุณจะต้องได้รับความช่วยเหลือจากเครื่องมือของคุณเมื่อเกิดเหตุการณ์นั้นขึ้น ซึ่งเห็นได้ชัดว่าฉันไม่ปรารถนาต่อใคร

ยังมีเรื่องที่ต้องพิจารณาเกี่ยวกับการกำหนดเวอร์ชัน: การมีแพ็กเกจ 2 แพ็กเกจที่แตกต่างกัน (build in debug and in release) แชร์ 1 หมายเลขเวอร์ชันถูกต้องหรือไม่ SymbolSource ยอมรับสิ่งนั้นเนื่องจากแยกแพ็กเกจและจัดเก็บไบนารีในสาขาโหมดบิลด์ที่แยกจากกันหาก NuGet อนุญาตให้แท็กแพ็กเกจตามนั้นเท่านั้น ในปัจจุบันไม่มีวิธีใดที่จะตรวจสอบได้ว่าแพ็กเกจเป็น debug หรือ release-mode


ส่วน "การเผยแพร่สองบิลด์ไปยัง NuGet" เป็นส่วนที่ยุ่งยาก ฉันได้เผยแพร่รุ่นของ Noda Time อยู่เสมอโดยมีเหตุผลว่าฉันต้องเลือกระหว่างทั้งสอง (ฉันมีไฟล์ nuspec แทนที่จะทำเพียงแค่จากโปรเจ็กต์ C #) คุณพูดถึงการดีบักโค้ดการผลิตราวกับว่ามันยากกว่าอย่างมากโดยมีเพียงบิลด์รีลีส - แม้ว่าส่วนก่อนหน้าจะ "ไม่แตกต่างกันมาก" ก็ตาม ฉันทราบถึง NOP ในการสร้างการแก้ไขข้อบกพร่องและเห็นได้ชัดว่าDebug.Assertฯลฯ แต่คุณสามารถขยาย (ในคำตอบของคุณ) เกี่ยวกับผลกระทบเมื่อทำการดีบักได้หรือไม่ การใช้รุ่น Release แย่แค่ไหน?
Jon Skeet

สิ่งที่ฉันหมายถึงคือคุณต้องการให้มีสัญลักษณ์สำหรับไบนารีทั้งหมดที่ใช้งานอยู่: หากมีทั้งการดีบักและการปล่อยบิวด์ในไวลด์คุณจะต้องระบุสัญลักษณ์สำหรับทั้งสองอย่าง พวกเขาไม่จำเป็นต้องแตกต่างกันมากในแง่ของรหัส แต่จะแตกต่างกันในการตรวจสอบซึ่งทำให้ไม่สามารถโหลดสัญลักษณ์ได้หากไม่มีการแฮ็ก
TripleEmcoder

1
ขวา. วิธีการแก้ปัญหาที่เป็นไปได้ของฉันคือการเท่านั้นที่เคยปล่อยไบนารีปล่อย แต่ฉันกังวลเกี่ยวกับวิธีการมากว่าจะไปทำร้ายในแง่ของการแก้จุดบกพร่อง ตัวอย่างเช่นการขาด NOP หมายความว่าคุณไม่สามารถเพิ่มเบรกพอยท์ได้หรือไม่?
Jon Skeet

ปัญหาเกิดจากการเพิ่มประสิทธิภาพ JIT มากกว่าการเพิ่มประสิทธิภาพในเวลาสร้าง ดังนั้นหากคุณดันแพ็กเกจโหมดรีลีสและแนะนำให้ใช้ COMPLUS_ZapDisable = 1 เมื่อจำเป็นต้องมีการดีบักนั่นก็จะดีพอสำหรับฉัน NuGet ยังควรอนุญาตให้แก้จุดบกพร่องและปล่อยร่วมกันไม่ทางใดก็ทางหนึ่ง
TripleEmcoder

ฉันไม่มีความคิด symbolssource.org อยู่ เนื่องจากอาการคันฉันต้องเกาหลายครั้งฉันยินดีต้อนรับ
Remus Rusanu

4

ฉันเห็นด้วยอย่างยิ่งกับข้อสรุปของคุณ แพ็คเกจ NuGet พร้อม RELEASE และ SymbolSource พร้อม debug ดูเหมือนจะเป็นเรื่องยากที่จะก้าวเข้าสู่แพ็กเกจโดยตรงและการแก้ไขข้อผิดพลาดในบางครั้งเมื่อเปิดใช้การเพิ่มประสิทธิภาพอาจเป็นที่ยอมรับ

หากมีปัญหาจริงๆฉันคิดว่าทางออกที่ดีที่สุดคือให้ NuGet สนับสนุน ตัวอย่างเช่นสมมติว่าเมื่อทำการดีบักมันสามารถแทนที่ DLL รีลีสด้วย DLL ที่รวมอยู่ในแพ็คเกจ SymbolSource

ตามหลักการแล้วสิ่งที่จะเกิดขึ้นก็คือnuget pack SomePackage -Symbolsเมื่อเทียบกับเวอร์ชันรีลีสจะสร้างแพ็กเกจนูเก็ตรีลีส แต่แพ็กเกจสัญลักษณ์ดีบัก และปลั๊กอิน VS จะได้รับการอัปเดตให้ฉลาดพอที่จะดูการเชื่อมโยงและดึงชุดประกอบการดีบักเมื่อทำงานในดีบักเกอร์และโหลดสิ่งเหล่านั้นแทน ชนิดบ้า แต่น่าสนใจ

อย่างไรก็ตามฉันไม่เห็นคนบ่นเกี่ยวกับเรื่องนี้มากพอที่จะคุ้มค่าในตอนนี้

ทีม NuGet ยอมรับคำขอดึง :)


ฉันไม่แน่ใจว่าฉันเข้าใจประโยคที่สองของคุณ - ฉันสงสัยว่า OP (ก่อนที่ฉันจะแก้ไข) กำลังทำการส่งด้วยตนเองไปที่ SymbolSource สำหรับการสร้างการแก้ปัญหา คุณมองเห็นปัญหาที่สำคัญหรือไม่หากPDB ของเวอร์ชันรีลีสลงเอยด้วย SymbolSource แทนที่จะเป็นเวอร์ชันดีบัก หรือนั่นคือสิ่งที่คุณสนับสนุนและฉันเข้าใจผิด?
Jon Skeet

3
"อย่างไรก็ตามฉันไม่เห็นคนบ่นมากพอเกี่ยวกับเรื่องนี้ว่ามันจะคุ้มค่าในตอนนี้" บางทีพวกเขาอาจจะไม่บ่น แต่ถ้าคุณถามตัวอย่างผู้ใช้ว่าพวกเขาคิดอย่างไรกับสิ่งนี้ฉันพนันได้เลยว่าคุณจะพบว่าคนส่วนใหญ่ยอมรับความสับสนเล็กน้อยในขั้นตอนนี้ (สิ่งที่จะเผยแพร่ไปยัง NuGet.org และ SymbolSource .org). หากคุณถามว่าพวกเขาเลือกอะไรคุณอาจจะพบว่าไม่มีการปฏิบัติตามที่ตกลงกันไว้เพียงอย่างเดียวทุกคนก็ทำในสิ่งที่ตัวเองชอบ
gzak

7
ฉันต้องการร้องเรียนเกี่ยวกับเรื่องนี้ฉันจะสมัครได้ที่ไหน?
Alex

เมื่อคุณมี NuGets ภายในและคุณเริ่มปรับใช้กับเซิร์ฟเวอร์สัญลักษณ์ ... คุณจะต้องการแก้ไขข้อบกพร่องอย่างหลีกเลี่ยงไม่ได้ .... และแม้ว่าคุณจะสามารถก้าวผ่านรหัสคุณจะลงเอยด้วย "ไม่สามารถรับค่าของ ตัวแปรท้องถิ่นหรืออาร์กิวเมนต์ ... ได้รับการปรับให้เหมาะสมแล้ว ". ตามที่ฟิลกล่าวถึง ... หากนักเก็ตมีวิธีโหลด dlls debug ในโหมด debug และปล่อย dll ในโหมด release (จากแพ็คเกจ nuget) นี่จะเป็นขั้นสูงสุด ก่อนหน้านี้เราติดอยู่กับตัวสลับแพ็คเกจ
Nuget

1
ฉันเห็นด้วยนี่จะเป็นการปรับปรุงผลิตภัณฑ์ที่ดี
htm11h

2

เป็นเวลา 8 ปีแล้วที่ OP ของโพสต์ดังนั้นฉันจะให้มันแตกกับสิ่งที่ใช้ในปัจจุบัน

การ " เข้าสู่ " แพ็กเกจ NuGet มี 2 ​​วิธีดังนี้

1. การกระจาย PDB

.symbols.nupkgแพคเกจสัญลักษณ์จะถือเป็นมรดกและได้รับการแทนที่ด้วย.snupkgแพคเกจที่ได้รับการเผยแพร่ไปยังเซิร์ฟเวอร์สัญลักษณ์ ได้รับการสนับสนุนจากผู้ขายส่วนใหญ่โดยAzure DevOpsเป็นบุคคลภายนอกที่ใหญ่ที่สุดโดยที่คำขอคุณลักษณะยัง "อยู่ระหว่างการตรวจสอบ" (ขอบคุณ @alv สำหรับลิงก์)

ที่นี่มีคำแนะนำอย่างเป็นทางการ เพียงเพิ่มสองบรรทัดนี้ลงในไฟล์ csproj:

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

ในฝั่งผู้บริโภคตรวจสอบให้แน่ใจว่า IDE ของคุณได้รับการกำหนดค่าสำหรับ NuGet.org (หรือ Azure เป็นต้น) Symbol Server เพื่ออนุญาตให้เข้าสู่รหัสแพ็คเกจเมื่อทำการดีบัก

2. ลิงก์แหล่งที่มาการเชื่อมโยงรหัสจริง

ในบางกรณี PDB อาจซ่อนเฉพาะบางส่วนของซอร์สโค้ดเนื่องจากการเพิ่มประสิทธิภาพ MSIL / JIT ดังนั้นจึงมีวิธี " ก้าวเข้าสู่ " แหล่งที่มาที่แท้จริงของ NuGet ของคุณในขณะที่แก้ไขจุดบกพร่อง เรียกว่าSource Linkจาก. NET Foundation - " ระบบไม่เชื่อเรื่องพระเจ้าควบคุมภาษาและแหล่งที่มาสำหรับมอบประสบการณ์การดีบักแหล่งที่มาสำหรับไบนารี "

ได้รับการสนับสนุนโดย Visual Studio 15.3+ และผู้ขายรายใหญ่ทั้งหมด (รองรับ repos ส่วนตัวด้วย)

การตั้งค่า ( เอกสารอย่างเป็นทางการ ) เป็นเรื่องเล็กน้อย- เพียงแค่เพิ่มการพึ่งพาการพัฒนาลงในไฟล์โครงการ (ขึ้นอยู่กับประเภทของ repo ของคุณ) พร้อมกับแฟล็กบางส่วน:

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ใน " 5 ขั้นตอนสู่แพ็คเกจ NuGet ที่ดีกว่า "


1
Azure DevOps ไม่รองรับ snupkg โปรดดูที่developercommunity.visualstudio.com/idea/657354/…
alv

ขอบคุณ! ฉันแก้ไขคำตอบ
Alex Klaus

1

ตัวอย่างในการสร้างและการเผยแพร่แพ็คเกจสัญลักษณ์อ้างอิงไฟล์ในไดเร็กทอรีการดีบักเป็นซอร์สสำหรับไฟล์ dll และ pdb

การระบุสัญลักษณ์บรรจุภัณฑ์

แพ็กเกจสัญลักษณ์สามารถสร้างขึ้นตามแบบแผนจากโฟลเดอร์ที่มีโครงสร้างตามที่อธิบายไว้ในส่วนก่อนหน้านี้หรือสามารถระบุเนื้อหาโดยใช้ส่วนไฟล์ หากคุณต้องการสร้างแพ็คเกจตัวอย่างที่อธิบายไว้ก่อนหน้านี้คุณสามารถใส่สิ่งนี้ลงในไฟล์ nuspec ของคุณ:

<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>

เนื่องจากจุดประสงค์ของการเผยแพร่สัญลักษณ์คือการอนุญาตให้ผู้อื่นก้าวผ่านโค้ดของคุณเมื่อทำการดีบักดูเหมือนว่าควรระมัดระวังมากที่สุดในการเผยแพร่เวอร์ชันของโค้ดที่มีไว้สำหรับการดีบักโดยไม่มีการปรับให้เหมาะสมซึ่งอาจส่งผลต่อโค้ดที่ผ่าน


ใช่นั่นคือสิ่งที่ตัวอย่าง - แต่ฉันไม่อยากลงเอยด้วยความสามารถในการดีบักที่แทนที่ความปรารถนาของนักพัฒนาส่วนใหญ่ในการเรียกใช้เวอร์ชันที่วางจำหน่าย ปัญหาคือ NuGet ไม่มีวิธีการเผยแพร่ทั้งรุ่นที่วางจำหน่ายและรุ่นแก้จุดบกพร่องเท่าที่ฉันสามารถบอกได้ (มันจะเป็นความเจ็บปวดเล็กน้อยสำหรับฉันที่จะเผยแพร่ทั้งสองอย่างเนื่องจากมันหมายถึงการสร้างชุดของการกำหนดค่าอีกชุดสำหรับการสร้างการแก้ปัญหาที่ลงชื่อ ... )
Jon Skeet

ที่นี่เราจะเข้าสู่ความเป็นส่วนตัวเล็กน้อย โดยปกติแล้วตัวเลือก "แนวทางปฏิบัติที่ดีที่สุด" ของฉันจะเป็นสิ่งที่ผู้เขียนแนะนำไม่ว่าจะโดยชัดแจ้งหรือโดยปริยายเพราะฉันคิดว่าพวกเขามีความเข้าใจ (หรือการกำกับดูแลในกรณีของสมมติฐานที่ลงท้ายด้วยตัวอย่าง) มากกว่าฉันพูดเป็นการส่วนตัว ฉันคิดว่าสัญลักษณ์ควรตรงกับเวอร์ชันที่ฉันใช้ โดยทั่วไปฉันจะไม่ใช้แพ็คเกจที่ฉันคิดว่าฉันน่าจะต้องดีบักเว้นแต่ว่าแหล่งที่มานั้นเป็นแบบสาธารณะและฉันสามารถคอมไพล์ตั้งแต่เริ่มต้นได้หากจำเป็นดังนั้นการขาดการสร้างดีบักแบบแพ็กเกจจึงไม่สำคัญอย่างยิ่ง
tvanfosson

ในกรณีของฉันถ้าใครต้องการดีบัก Noda Time เพราะพวกเขาเชื่อว่ามีข้อผิดพลาดใน Noda Time พวกเขาจะดีกว่าถ้าดาวน์โหลดซอร์ส (ซึ่งพวกเขาทำได้แน่นอน) อย่างไรก็ตามยังคงมีประโยชน์ที่จะสามารถเข้าสู่ซอร์สโค้ด Noda Time เพื่อดูว่าเกิดอะไรขึ้น โดยทั่วไปฉันคิดว่ามี (อย่างน้อย) สองสถานการณ์ที่แตกต่างกันสำหรับการดีบักโดยมีวิธีแก้ปัญหาที่แตกต่างกัน ...
Jon Skeet

สิ่งหนึ่งที่ฉันชอบคิดคือ. NET เอง: ฉันคิดว่าปลอดภัยที่จะบอกว่า Microsoft เผยแพร่รุ่นที่วางจำหน่ายและไม่ได้แก้ไขข้อบกพร่องของ. NET การสร้างรุ่นแสดงถึงคุณภาพและความเสถียรในระดับหนึ่งดังนั้นแนวคิดก็คือคุณแทบไม่จำเป็นต้องก้าวเข้าไปในโค้ดเพื่อวินิจฉัยสิ่งต่างๆ
gzak

2
อย่างไรก็ตามนั่นเป็นความคิดที่ค่อนข้าง "ปิดแหล่งที่มา" ฉันพบว่าในโลกโอเพนซอร์สคาดว่าจะสามารถก้าวเข้าสู่รหัส "การเผยแพร่ที่เสถียร" ของไลบรารีต่างๆได้มากขึ้นไม่ใช่เพราะของเสีย แต่เป็นเพราะบางครั้งเอกสารที่ดีที่สุดคือการดูว่าไลบรารีคืออะไร ทำ.
gzak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.