แนวทางปฏิบัติที่ดีที่สุด / คำแนะนำสำหรับการบำรุงรักษาหมายเลขรุ่นแอสเซมบลี


154

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

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


คำตอบ:


211

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

ต่อไปนี้อนุมานว่าคุณใช้การควบคุมแหล่งที่มาบางรูปแบบและสร้างเซิร์ฟเวอร์ สำหรับบริบทเราใช้TeamCityและ Subversion / Git TeamCity ให้บริการฟรีสำหรับโครงการขนาดเล็กจำนวน 10 โครงการและเป็นเซิร์ฟเวอร์สำหรับสร้างที่ดีมาก แต่มีหลายโครงการซึ่งบางโครงการให้บริการฟรี

หมายเลขเวอร์ชันหมายถึงอะไร

สิ่งที่รุ่นหมายถึงคนคนหนึ่งอาจหมายถึงสิ่งที่แตกต่างจากที่อื่นโครงสร้างทั่วไปเป็นหลักรองมาโครไมโคร วิธีที่ฉันดูหมายเลขเวอร์ชันคือการแบ่งมันออกเป็นสองส่วน ครึ่งแรกจะอธิบายรุ่นหลัก (หลัก) และการอัปเดตที่สำคัญใด ๆ (เล็กน้อย) ครึ่งหลังบ่งบอกว่ามันถูกสร้างขึ้นเมื่อใดและรุ่นของซอร์สโค้ดคืออะไร หมายเลขเวอร์ชันยังหมายถึงสิ่งต่าง ๆ โดยขึ้นอยู่กับบริบทคือ API, Web App และอื่น ๆ

Major. Minor. Build.Revision

  • Revision นี่คือตัวเลขที่นำมาจากการควบคุมแหล่งที่มาเพื่อระบุสิ่งที่สร้างขึ้นจริง
  • Buildนี่เป็นตัวเลขที่เพิ่มมากขึ้นซึ่งสามารถใช้เพื่อค้นหาบิลด์เฉพาะบนบิลด์เซิร์ฟเวอร์ เป็นหมายเลขที่สำคัญเนื่องจากบิลด์เซิร์ฟเวอร์อาจสร้างซอร์สเดียวกันสองครั้งด้วยชุดพารามิเตอร์ที่แตกต่างกัน การใช้หมายเลขบิลด์ประกอบกับหมายเลขแหล่งที่มาช่วยให้คุณระบุสิ่งที่สร้างและวิธีการ
  • Minorสิ่งนี้ควรเปลี่ยนเมื่อมีการเปลี่ยนแปลงที่สำคัญในส่วนต่อประสานสาธารณะ ตัวอย่างเช่นหากเป็น API รหัสการบริโภคจะยังคงสามารถรวบรวมได้หรือไม่ หมายเลขนี้ควรถูกรีเซ็ตเป็นศูนย์เมื่อหมายเลขหลักเปลี่ยนไป
  • Majorระบุรุ่นของผลิตภัณฑ์ที่คุณใช้ ตัวอย่างเช่น Major ของชุดประกอบ VisualStudio 2008 ทั้งหมดคือ 9 และ VisualStudio 2010 คือ 10

ข้อยกเว้นกฎ

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

Major. Minor. Macro.Build

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

สิ่งที่จะตั้ง

สิ่งแรกที่ต้องทำความเข้าใจคือแอสเซมบลี, เวอร์ชันไฟล์และเวอร์ชันผลิตภัณฑ์ไม่จำเป็นต้องตรงกัน ฉันไม่ได้เรียกร้องให้มีชุดตัวเลขที่แตกต่างกัน แต่มันทำให้ชีวิตง่ายขึ้นมากเมื่อทำการเปลี่ยนแปลงเล็กน้อยในแอสเซมบลีที่ไม่ส่งผลกระทบต่อส่วนต่อประสานสาธารณะใด ๆ ที่คุณไม่ได้บังคับให้คอมไพล์ที่ขึ้นต่อกัน วิธีที่ฉันจัดการกับสิ่งนี้คือการตั้งค่าเฉพาะหมายเลข Major และ Minor ใน Assembly Version แต่เพื่อตั้งค่าทั้งหมดใน File Version ตัวอย่างเช่น:

  • 1.2.0.0 (AssemblyVersion)
  • 1.2.3.4 (FileVersion)

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

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

วิธีต่อสายเข้าด้วยกัน

คุณสามารถทำทุกอย่างได้ด้วยตนเอง แต่มันใช้เวลานานมากต่อไปนี้เป็นวิธีที่เราดำเนินการโดยอัตโนมัติ แต่ละขั้นตอนสามารถรันได้

  • ลบAssemblyVersionและAssemblyFileVersionคุณลักษณะจากไฟล์ AssemblyInfo.cs โครงการทั้งหมด
  • สร้างไฟล์ข้อมูลประกอบทั่วไป (เรียกว่า VersionInfo.cs) และเพิ่มเป็นรายการที่เชื่อมโยงกับโครงการทั้งหมดของคุณ
  • เพิ่มAssemblyVersionและAssemblyFileVersionแอตทริบิวต์ให้กับเวอร์ชันด้วยค่า "0.0.0.0"
  • สร้างโครงการ MsBuild ที่สร้างไฟล์โซลูชันของคุณ
  • เพิ่มในงานก่อนบิลด์ที่อัพเดต VersionInfo.cs มีจำนวนไลบรารี MsBuild โอเพนซอร์สที่มีงาน AssemblyInfo ซึ่งสามารถตั้งค่าหมายเลขรุ่นได้ เพียงแค่ตั้งค่าเป็นหมายเลขโดยพลการและทดสอบ
  • เพิ่มกลุ่มคุณสมบัติที่มีคุณสมบัติสำหรับแต่ละเซ็กเมนต์ของหมายเลขบิลด์ ที่นี่คุณตั้งหลักและรอง หมายเลขบิลด์และการแก้ไขควรถูกส่งผ่านเป็นอาร์กิวเมนต์

ด้วยการโค่นล้ม:

<PropertyGroup>
    <Version-Major>0</Version-Major>
    <Version-Minor>0</Version-Minor>
    <Version-Build Condition=" '$(build_number)' == '' ">0</Version-Build>
    <Version-Build Condition=" '$(build_number)' != '' ">$(build_number)</Version-Build>
    <Version-Revision Condition=" '$(revision_number)' == '' ">0</Version-Revision>
    <Version-Revision Condition=" '$(revision_number)' != '' ">$(revision_number)</Version-Revision>
</PropertyGroup>

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


คุณได้พิจารณาใช้แท็กเวอร์ชันจาก GitHub หรือไม่ ฉันสงสัยมากว่ามันจะเข้ากับปริศนาได้อย่างไร
raRaRa

1
@raRaRa - นี่เป็นโพสต์ที่ค่อนข้างเก่า ในขณะที่ส่วนใหญ่ฉันยังคงยืนหยัดมีบางสิ่งที่ฉันจะทำแตกต่างกัน การกำหนดเวอร์ชันของ NuGet เปลี่ยนวิธีการทำสิ่งต่าง ๆ และฉันใช้แท็ก Git สำหรับการสร้างที่ประสบความสำเร็จ แต่ในตอนท้ายของวันหมายเลขรุ่นในชุดประกอบควรผูกกลับไปเป็นรุ่นบิลด์บนบิลด์เซิร์ฟเวอร์และรุ่นแท็กในแหล่งควบคุม
Bronumski

57

[AssemblyVersion] เป็นข้อตกลงที่ใหญ่มากใน. NET ปรัชญาหนึ่งที่ Microsoft ได้รับการสนับสนุนคือให้คุณเพิ่มจำนวนอัตโนมัติบังคับให้ทุกโครงการที่ขึ้นอยู่กับแอสเซมบลีที่จะคอมไพล์ใหม่ ทำงานได้โอเคถ้าคุณใช้เซิร์ฟเวอร์บิลด์ มันไม่เคยผิดที่ต้องทำ แต่ระวังคนถือดาบ

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

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

ดังนั้นสิ่งที่ Microsoft เทศนาไม่ใช่สิ่งที่ปฏิบัติ กระบวนการสร้างและการควบคุมเวอร์ชันนั้นไม่มีใครเทียบได้พวกเขายังมีวิศวกรซอฟต์แวร์เฉพาะที่คอยตรวจสอบกระบวนการ ไม่ได้ผลค่อนข้างดี WaitHandle.WaitOne (int) เกินพิกัดโดยเฉพาะทำให้เกิดความเจ็บปวดพอสมควร แก้ไขใน. NET 4.0 ด้วยวิธีที่แตกต่างกันมาก แต่มันก็เกินขอบเขต

ขึ้นอยู่กับคุณและความมั่นใจของคุณว่าคุณสามารถควบคุมกระบวนการสร้างและรอบการเปิดตัวได้ดีเพียงใดเพื่อให้คุณเลือกได้เอง นอกเหนือจากนั้นการเพิ่ม [AssemblyFileVersion] การเพิ่มอัตโนมัติโดยอัตโนมัติมีความเหมาะสมมาก อย่างไรก็ตามในความไม่สะดวกที่ไม่ได้รับการสนับสนุน


11

คุณสามารถใช้ส่วน Build ของหมายเลขรุ่นสำหรับการเพิ่มอัตโนมัติ

[assembly: AssemblyVersion("1.0.*")]

ในสภาพแวดล้อมของคุณเวอร์ชันทดสอบคือเวอร์ชันที่มีรุ่นบิลด์! = 0 ในรุ่นที่คุณเพิ่มส่วนย่อยและตั้งส่วนสร้างเป็น 0 นี่คือวิธีที่คุณจะระบุชุดประกอบที่นำออกใช้

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


ฉันชอบหมายเลขบิลด์ 0 สำหรับรุ่นที่วางจำหน่าย
ProfK

1
แน่นอนนี่หมายถึงชื่อที่รัดกุมของแอสเซมบลีของคุณจะเปลี่ยนไปในแต่ละบิลด์ไม่ว่าคุณต้องการหรือไม่
Richard

9

การเพิ่มคำตอบ Bronumskisผมอยากจะชี้ให้เห็นว่าหลังจากที่ 2.0 มาตรฐานความหมายของรุ่นที่semver.org , Major.Minor.Build.Revisionจะผิดกฎหมายเนื่องจากกฎว่าหลังจากที่การเพิ่มจำนวนเป็นค่าปกติไปทางขวาจะต้องมีการตั้งค่าให้เป็นศูนย์

Major.Minor+Build.Revisionวิธีที่ดีกว่าต่อไปมาตรฐานที่จะใช้ สิ่งนี้ไม่ได้เป็นการใช้อย่างหลีกเลี่ยงไม่ได้AssemblyVersionAttributeแต่สามารถใช้แอตทริบิวต์ที่กำหนดเองหรือคลาสสแตติกแทน

ควรใช้ Semver ใน TeamCity โดยใช้ Power-Runner Power Pack สำหรับ git กับ git-flow (โดยเฉพาะในโลก. NET) ฉันพบว่าGitVersionมีประโยชน์


2
ที่น่าสนใจฉันจะตรวจสอบนี้ รูปแบบหมายเลขเวอร์ชันที่คุณกล่าวถึงสามารถใช้ในแอตทริบิวต์ AssemblyInformationalVersion
Bronumski

1

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

... สำหรับอดีต: 1.0.0. *

สงวนไว้ - สิ่งนี้จะเพิ่มความยืดหยุ่นเพิ่มเติมในกรณีที่คุณต้องการเปลี่ยนแปลงในอนาคต แต่โดยค่าเริ่มต้นให้เป็น 0

นอกจากนี้ให้พิจารณาการเซ็นชื่อชุดประกอบด้วยคีย์ที่แข็งแกร่ง วิธีนี้จะช่วยแก้ปัญหาความขัดแย้งของแอสเซมบลีในกรณีที่คุณมีแอสเซมบลีหลายรุ่นที่ลงทะเบียนใน GAC ลิงก์ MSDN

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