ฉันจะเพิ่มเวอร์ชันแอสเซมบลี C # โดยอัตโนมัติผ่านแพลตฟอร์ม CI (ฮัดสัน) ได้อย่างไร


112

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

เราเริ่มดีขึ้นมากกับแนวทางปฏิบัติของเราผ่านแพลตฟอร์มCIของเราและฉันต้องการตั้งค่าให้เพิ่มค่าภายในassemblyinfo.csไฟล์โดยอัตโนมัติเพื่อให้เวอร์ชันของแอสเซมบลีของเราได้รับการอัปเดตโดยอัตโนมัติเมื่อมีการเปลี่ยนแปลงโค้ดในแอสเซมบลีนั้น

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

การเพิ่มหมายเลขเวอร์ชันของฮัดสันเป็นความคิดที่ไม่ดีหรือไม่? จะมีทางเลือกอื่นให้ทำอย่างไร?

ตามหลักการแล้วเกณฑ์ของฉันสำหรับการแก้ปัญหาคือ:

  • เพิ่มหมายเลขบิวด์assemblyinfo.csก่อนสร้าง
  • เพิ่มเฉพาะหมายเลขบิลด์ในแอสเซมบลีที่มีการเปลี่ยนแปลง สิ่งนี้อาจเป็นไปไม่ได้เนื่องจากฮัดสันจะล้างโฟลเดอร์โครงการทุกครั้งที่สร้าง
  • ยอมรับ assemblyinfo.cs ที่เปลี่ยนแปลงลงในที่เก็บโค้ด (ปัจจุบันคือVisualSVN )
  • ไม่ทำให้ฮัดสันทริกเกอร์บิวด์ใหม่ในครั้งถัดไปที่สแกนหาการเปลี่ยนแปลง

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

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

คำตอบ:


63

ทางเลือกง่ายๆคือให้สภาพแวดล้อม C # เพิ่มเวอร์ชันแอสเซมบลีสำหรับคุณโดยตั้งค่าแอตทริบิวต์เวอร์ชันเป็นmajor.minor.*(ตามที่อธิบายไว้ในเทมเพลตไฟล์ AssemblyInfo)

คุณอาจกำลังมองหาวิธีแก้ปัญหาที่ครอบคลุมมากขึ้น

แก้ไข (ตอบคำถามในความคิดเห็น):

จากAssemblyInfo.cs:

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]

ฉันไม่เคยเจอแบบนี้มาก่อนคุณช่วยลงรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่ทำ มันทำงานได้ภายใน IDE เดียวหรือทำงานร่วมกับทีมนักพัฒนาทั้งหมดที่มีแพลตฟอร์ม CI?
Allen Rice

อ่าฉันเคยเห็นมาก่อนนั่นอาจเป็นวิธีแก้ปัญหาที่ยอมรับได้ แต่ # built ไม่ได้ถูกเก็บไว้ในการโค่นล้ม ฯลฯ ฉันมีการตั้งค่า Hudson เพื่อเก็บไฟล์และด้วยวิธีนั้นจะถูกจัดเก็บเพื่อที่อาจเป็นที่ยอมรับ ฉันจะต้องทำการวิจัยเพิ่มเติมว่ากลไกนั้นทำงานอย่างไรขอบคุณ! คุณจะไม่รู้ว่ามันกำหนดสิ่งที่จะใส่เป็นค่าได้อย่างไร?
Allen Rice

1
ดูคำตอบของฉันด้านล่างสำหรับคำตอบสำหรับคำถามของคุณ ค่าต่างๆจะถูกกำหนดตามเวลาในการสร้าง
Kyle Trauberman

ว้าวฉันคิดว่ามันจะได้ผล ไม่แน่ใจว่าเรามองข้ามวิธีง่ายๆเช่นนี้ไปอย่างไร
Allen Rice

หวังว่าจะเป็นเช่นนั้นฉันดีใจที่ช่วยได้ ทำไมต้องทำอะไรบางอย่างที่ยากในเมื่อวิธีที่ง่ายและรวดเร็วก็เป็นวิธีที่ถูกต้องเช่นกัน :)
Greg D

65

นี่คือสิ่งที่ฉันทำเพื่อปั๊มแอตทริบิวต์ AssemblyFileVersion

ลบ AssemblyFileVersion จาก AssemblyInfo.cs

เพิ่มไฟล์ใหม่ว่างเปล่าชื่อ AssemblyFileInfo.cs ลงในโปรเจ็กต์

ติดตั้งชุดเครื่องมืองานชุมชน MSBuildบนเครื่องสร้างฮัดสันหรือเป็นการพึ่งพา NuGetในโครงการของคุณ

แก้ไขไฟล์โครงการ (csproj) เป็นเพียงไฟล์ msbuild และเพิ่มสิ่งต่อไปนี้

บางแห่งจะมีการ<PropertyGroup>ระบุเวอร์ชัน เปลี่ยนให้มันอ่านเช่น

 <Major>1</Major>
 <Minor>0</Minor>
 <!--Hudson sets BUILD_NUMBER and SVN_REVISION -->
 <Build>$(BUILD_NUMBER)</Build>
 <Revision>$(SVN_REVISION)</Revision>

ฮัดสันจัดเตรียมตัวแปร env ที่คุณเห็นเมื่อโครงการสร้างขึ้นบนฮัดสัน (สมมติว่าดึงมาจากการโค่นล้ม)

ที่ด้านล่างของไฟล์โครงการให้เพิ่ม

 <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')" />
  <Target Name="BeforeBuild" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')">
    <Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)" />
    <AssemblyInfo CodeLanguage="CS" OutputFile="AssemblyFileInfo.cs" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" AssemblyConfiguration="$(Configuration)" Condition="$(Revision) != '' " />
  </Target>

สิ่งนี้ใช้ MSBuildCommunityTasks เพื่อสร้าง AssemblyFileVersion.cs เพื่อรวมแอ็ตทริบิวต์ AssemblyFileVersion ก่อนสร้างโปรเจ็กต์ คุณสามารถทำสิ่งนี้กับแอตทริบิวต์เวอร์ชันใดก็ได้ / ทั้งหมดหากต้องการ

ผลลัพธ์คือเมื่อใดก็ตามที่คุณสร้างฮัดสันบิลด์แอสเซมบลีผลลัพธ์จะได้ AssemblyFileVersion เป็น 1.0.HUDSON_BUILD_NR.SVN_REVISION เช่น 1.0.6.2632 ซึ่งหมายถึงบิลด์ที่ 6 # ในฮัดสันสร้างจากการโค่นล้มการแก้ไข 2632


1
เพื่ออัปเดตสิ่งนี้: วิธีนี้ใช้ได้กับ C # ฉันใช้มันมาบ้างแล้ว แต่การประกอบ C ++ (เช่น C ++ / CLI) ยังคงเป็นปัญหา เท่าที่ฉันบอกได้งาน AssemblyInfo ไม่ได้สร้าง C ++ ที่ถูกต้อง นอกจากนี้ฉันคิดว่าวิธีนี้มีข้อเสียเล็กน้อยตรงที่นักพัฒนาคนอื่น ๆ เข้าใจว่าเกิดอะไรขึ้นบ้าง น่าเสียดายที่คุณไม่สามารถส่งหมายเลขเวอร์ชันลงใน MSBuild โดยตรงเป็นทรัพย์สินได้ ...
CJBrew

@CJBrew คุณสามารถสร้างไฟล์. bat ขนาดเล็กที่สร้างรหัส C ++ สำหรับ AssemblyInfo และให้ msbuild เริ่มต้น scipt นั้น ฉันไม่แน่ใจว่าคุณหมายถึงอะไรโดยการผลักดันให้เป็นคุณสมบัติคุณสามารถยัดสตริงเวอร์ชันในคุณสมบัติที่คุณต้องการได้อย่างแน่นอน - คุณไม่จำเป็นต้องใช้ major / minor / build / revision ที่ฉันใช้ที่นี่
เลขที่

มีอะไรที่ได้รับจากการใช้เส้นทางนี้เทียบกับเพียงแค่แสดงความคิดเห็นออก AssemblyFileVersion และปล่อยให้มันถูกตั้งค่าให้ตรงกับ [แอสเซมบลี: AssemblyVersion ("1.0. *")] โดยอัตโนมัติ
cchamberlain

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

42

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

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

ขั้นตอน:

  1. เพิ่มคลาสให้กับไฟล์โซลูชัน * .cs ของคุณฉันตั้งชื่อว่า min SharedAssemblyProperties.cs
  2. ลบข้อมูล cs ทั้งหมดออกจากไฟล์ใหม่นั้น
  3. ตัดข้อมูลการประกอบออกจากไฟล์ AssemblyInfo: [แอสเซมบลี: AssemblyVersion ("1.0.0.0")] [แอสเซมบลี: AssemblyFileVersion ("1.0.0.0")]
  4. เพิ่มคำสั่ง "using System.Reflection;" ไปยังไฟล์แล้ววางข้อมูลลงในไฟล์ cs ใหม่ของคุณ (เช่น SharedAssemblyProperties.cs)
  5. เพิ่มรายการที่มีอยู่ให้กับโปรเจ็กต์ของคุณ (รอ ... อ่านต่อก่อนเพิ่มไฟล์)
  6. เลือกไฟล์และก่อนที่คุณจะคลิกเพิ่มให้คลิกรายการแบบเลื่อนลงถัดจากปุ่มเพิ่มแล้วเลือก "เพิ่มเป็นลิงก์"
  7. ทำซ้ำขั้นตอนที่ 5 และ 6 สำหรับโครงการที่มีอยู่และโครงการใหม่ทั้งหมดในโซลูชัน

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

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


ขอบคุณมาร์ค ขออภัยสำหรับลิงก์ที่ตายแล้วปรากฎว่าเซิร์ฟเวอร์ชุมชนไม่สะดวกในการย้าย ฉันควรค้นหาความช่วยเหลือในหัวข้อนั้น ...
sondlerd

11

ฮัดสันสามารถกำหนดค่าให้ละเว้นการเปลี่ยนแปลงบางเส้นทางและไฟล์เพื่อไม่ให้สร้างใหม่

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

ตัวอย่างเช่นการละเว้นการเปลี่ยนแปลงไฟล์version.properties ที่คุณสามารถใช้ได้:

/MyProject/trunk/version.properties

สิ่งนี้จะใช้ได้กับภาษาอื่นที่ไม่ใช่ C # และช่วยให้คุณจัดเก็บข้อมูลเวอร์ชันของคุณภายในการโค่นล้ม


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

9

.NET ทำเพื่อคุณ ในไฟล์ AssemblyInfo.cs ของคุณตั้งค่าเวอร์ชันแอสเซมบลีของคุณเป็น major.minor. * (ตัวอย่างเช่น 1.0. *)

เมื่อคุณสร้างโครงการของคุณเวอร์ชันจะถูกสร้างขึ้นโดยอัตโนมัติ

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


21
<แหวนแหวน> "สวัสดีฉันจะช่วยสนับสนุนผลิตภัณฑ์ได้อย่างไร" <customer> "ฉันมีข้อผิดพลาด" <support> "ตกลงคุณกำลังใช้งานเวอร์ชันใด" <customer> "เวอร์ชันหนึ่งจุดสองการแก้ไขแปดห้าสองห้าสามเจ็ดสี่บิลด์เจ็ดสี่หกสามห้าสองเก้า ... " <support> "เดี๋ยวก่อนพิมพ์ว่า ... อืมม ... โปรดทำซ้ำเวอร์ชัน ตัวเลขดูเหมือนว่าเราจะไม่มีการสร้างและการแก้ไขในรายการนั้น ... "- GRRR!
Jimbo

ความคิดเห็นที่ดี ฉันไม่ใช่แฟนของระบบที่เพิ่มขึ้นเช่นกัน: p
Joshua Hayes

3
การสร้างภาพอัตโนมัติในสตูดิโอภาพแย่มาก
Kugel

8
@ Jimbo: แม้ว่าเราทุกคนยอมรับว่าความคิดเห็นของคุณเป็นเรื่องตลก แต่ในทางปฏิบัติก็ไม่สำคัญ เมื่อคุณพูดเกี่ยวกับการติดตั้ง VS คุณมี Visual Studio 2008 SP1 หรือ VS2008 9.0.30729.1 SP หรือไม่? การใช้หมายเลขการสร้างการเพิ่มอัตโนมัติเป็นรูปแบบที่ใช้กันทั่วไปและสามารถ "แก้ไข" ได้อย่างง่ายดายโดยการเพิ่มหมายเลขเวอร์ชันหลัก / รองเมื่อบิลด์รุ่นออกมา
Marek

สูงสุดที่เราได้ไปด้วยหมายเลขบิวด์คือ 678 ก่อนที่จะรีเซ็ตกลับเป็น 0 เพื่อเพิ่มการแก้ไขเล็กน้อย (แน่นอนว่า cruisecontrol มันดูเหมือนจะรีเซ็ตได้ง่ายกว่าฮัดสันเช่นเดียวกับใน cruisecontrol คุณเพิ่งเข้าไปและบันทึกกลับเป็น 0 ในโครงการ แต่อย่างอื่นในฮัดสันดีกว่า)
Dean Hiller

8

ฉันไม่เคยเห็นว่าฟีเจอร์ 1.0. * ทำงานได้จริงใน VS2005 หรือ VS2008 มีสิ่งที่ต้องทำเพื่อตั้งค่า VS เพื่อเพิ่มค่าหรือไม่?

ถ้า AssemblyInfo.cs เป็นฮาร์ดโค้ด 1.0. * แล้ว build / revision จริงจะเก็บไว้ที่ไหน?

หลังจากใส่ 1.0. * ใน AssemblyInfo เราไม่สามารถใช้คำสั่งต่อไปนี้ได้เนื่องจากตอนนี้ ProductVersion มีค่าที่ไม่ถูกต้อง - ใช้ 1.0. * ไม่ใช่ค่าที่ VS กำหนด:

Version version = new Version(Application.ProductVersion);

เฮ้อ - นี่ดูเหมือนจะเป็นหนึ่งในสิ่งที่ทุกคนถามถึง แต่ก็ไม่มีคำตอบที่ชัดเจน หลายปีก่อนฉันเห็นโซลูชันสำหรับการสร้างหมายเลขการแก้ไขและบันทึกลงใน AssemblyInfo ซึ่งเป็นส่วนหนึ่งของกระบวนการหลังการสร้าง ฉันหวังว่าการเต้นแบบนี้จะไม่จำเป็นสำหรับ VS2008 อาจจะ VS2010?


10
คุณต้องลบ AssemblyFileVersion นอกเหนือจากนั้นผลงานที่ยอดเยี่ยมสำหรับเราคำตอบที่ได้รับการยอมรับก็คือ
Allen Rice

1
ใช่การลบ AssemblyFileVersion ทำให้สามารถอัปเดตเวอร์ชันได้และไม่มีข้อผิดพลาดอีกต่อไปกับเวอร์ชัน ดี หมายเหตุ: การดำเนินการสร้างสองครั้งจะเพิ่มการแก้ไขเพียงครั้งเดียว แต่ถ้าคุณสร้างใหม่การแก้ไขจะได้รับการอัปเดต ดังที่ ktrauberman กล่าวไว้ดูเหมือนว่า build.revision = date.time ซึ่งอธิบายว่าเหตุใดข้อมูลจึงไม่ถูกจัดเก็บที่ใดก็ได้ยกเว้นในแอสเซมบลี ตอนนี้ฉันต้องได้รับการตั้งค่า MSI มาตรฐานเพื่อสร้างรหัสผลิตภัณฑ์ใหม่เมื่อโปรเจ็กต์เอาต์พุตหลักอัปเดต การตั้งค่าไม่อนุญาตให้แก้ไขสร้างเท่านั้น ฉันต้องการติดตั้งทับการติดตั้งที่มีอยู่เพื่อทำการอัปเดต ต้องค้นคว้า.
TonyG

5

ฉันคิดว่าอาจมีคนทำเช่นนี้กับเทมเพลตข้อความที่คุณสร้างแอตทริบิวต์แอสเซมบลีที่เป็นปัญหาได้ทันทีจากสภาพแวดล้อมเช่น AssemblyVersion.tt ด้านล่าง

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var build = Environment.GetEnvironmentVariable("BUILD_NUMBER");
build = build == null ? "0" : int.Parse(build).ToString();
var revision = Environment.GetEnvironmentVariable("SVN_REVISION");
revision = revision == null ? "0" : int.Parse(revision).ToString();    
#>
using System.Reflection;
[assembly: AssemblyVersion("1.0.<#=build#>.<#=revision#>")]
[assembly: AssemblyFileVersion("1.0.<#=build#>.<#=revision#>")]

3

จากคำตอบของ MikeS ฉันต้องการเพิ่มว่าต้องติดตั้ง VS + Visual Studio Visualization และ Modeling SDK เพื่อให้ใช้งานได้และคุณต้องแก้ไขไฟล์โครงการด้วย ควรกล่าวถึงฉันใช้ Jenkins เป็นเซิร์ฟเวอร์สร้างที่ทำงานบนกล่องเซิร์ฟเวอร์ windows 2008 R2 พร้อมโมดูลเวอร์ชันซึ่งฉันได้รับ BUILD_NUMBER

ไฟล์แม่แบบข้อความของฉัน version.tt มีลักษณะเช่นนี้

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var build = Environment.GetEnvironmentVariable("BUILD_NUMBER");
build = build == null ? "0" : int.Parse(build).ToString();
var revision = Environment.GetEnvironmentVariable("_BuildVersion");
revision = revision == null ? "5.0.0.0" : revision;    
#>
using System.Reflection;
[assembly: AssemblyVersion("<#=revision#>")]
[assembly: AssemblyFileVersion("<#=revision#>")]

ฉันมีสิ่งต่อไปนี้ในกลุ่มอสังหาริมทรัพย์

<PropertyGroup>
    <TransformOnBuild>true</TransformOnBuild>
    <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

หลังจากนำเข้า Microsoft.CSharp.targets ฉันมีสิ่งนี้ (ขึ้นอยู่กับตำแหน่งที่คุณติดตั้ง VS.

<Import Project="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />

บนเซิร์ฟเวอร์การสร้างของฉันฉันมีสคริปต์ต่อไปนี้เพื่อเรียกใช้การแปลงข้อความก่อนสร้างจริงเพื่อรับหมายเลขชุดการเปลี่ยนแปลงล่าสุดบน TFS

set _Path="C:\Build_Source\foo"

pushd %_Path% 
"%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe" history . /r /noprompt /stopafter:1 /Version:W > bar
FOR /f "tokens=1" %%foo in ('findstr /R "^[0-9][0-9]*" bar') do set _BuildVersion=5.0.%BUILD_NUMBER%.%%foo
del bar
popd

echo %BUILD_NUMBER%
echo %_BuildVersion%
cd C:\Program Files (x86)\Jenkins\jobs\MyJob\workspace\MyProject
MSBuild MyProject.csproj /t:TransformAll 
...
<rest of bld script>

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

ฉันแน่ใจว่าคุณสามารถทำอะไรบางอย่างที่น่าสนใจและโทรหา TFS ได้โดยตรงจากภายในเทมเพลต tt แต่สิ่งนี้ใช้ได้กับฉัน

จากนั้นฉันจะได้เวอร์ชันของฉันที่รันไทม์เช่นนี้

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
return fvi.FileVersion;

1

โซลูชันของฉันไม่ต้องการการเพิ่มเครื่องมือภายนอกหรือภาษาสคริปต์ซึ่งรับประกันได้ว่าจะทำงานบนเครื่องสร้างของคุณได้ ฉันแก้ปัญหานี้ในหลายส่วน ก่อนอื่นฉันได้สร้างไฟล์ BUILD.BAT ที่แปลงพารามิเตอร์ Jenkins BUILD_NUMBER เป็นตัวแปรสภาพแวดล้อม ฉันใช้ฟังก์ชัน "Execute Windows batch command" ของ Jenkins เพื่อเรียกใช้ไฟล์ batch build โดยป้อนข้อมูลต่อไปนี้สำหรับบิลด์ Jenkins:

     ./build.bat --build_id %BUILD_ID% -build_number %BUILD_NUMBER%

ในสภาพแวดล้อมการสร้างฉันมีไฟล์ build.bat ที่เริ่มต้นดังนี้:

     rem build.bat
     set BUILD_ID=Unknown
     set BUILD_NUMBER=0
     :parse_command_line
     IF NOT "%1"=="" (
         IF "%1"=="-build_id" (
             SET BUILD_ID=%2
             SHIFT
             )
         IF "%1"=="-build_number" (
             SET BUILD_NUMBER=%2
             SHIFT
         )
         SHIFT
         GOTO :parse_command_line
     )
     REM your build continues with the environmental variables set
     MSBUILD.EXE YourProject.sln

เมื่อฉันทำเช่นนั้นฉันคลิกขวาที่โปรเจ็กต์ที่จะสร้างในบานหน้าต่าง Solution Explorer ของ Visual Studio และเลือก Properties เลือก Build Events และป้อนข้อมูลต่อไปนี้เป็น Pre-Build Event Command Line ซึ่งจะสร้างไฟล์. cs โดยอัตโนมัติ มีข้อมูลหมายเลขบิลด์ตามการตั้งค่าตัวแปรสภาพแวดล้อมปัจจุบัน:

     set VERSION_FILE=$(ProjectDir)\Properties\VersionInfo.cs
     if !%BUILD_NUMBER%==! goto no_buildnumber_set
     goto buildnumber_set
     :no_buildnumber_set
     set BUILD_NUMBER=0
     :buildnumber_set
     if not exist %VERSION_FILE% goto no_version_file
     del /q %VERSION_FILE%
     :no_version_file
     echo using System.Reflection; >> %VERSION_FILE%
     echo using System.Runtime.CompilerServices; >> %VERSION_FILE%
     echo using System.Runtime.InteropServices; >> %VERSION_FILE%
     echo [assembly: AssemblyVersion("0.0.%BUILD_NUMBER%.1")] >> %VERSION_FILE%
     echo [assembly: AssemblyFileVersion("0.0.%BUILD_NUMBER%.1")] >> %VERSION_FILE%

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


1

ดังนั้นเราจึงมีโครงการที่มีโซลูชันเดียวซึ่งมีหลายโครงการที่มีชุดประกอบที่มีหมายเลขเวอร์ชันต่างกัน

หลังจากตรวจสอบหลายวิธีข้างต้นฉันเพิ่งใช้ขั้นตอนการสร้างเพื่อเรียกใช้สคริปต์ Powershell ที่ค้นหาและแทนที่บนไฟล์ AssemblyInfo.cs ฉันยังคงใช้หมายเลขเวอร์ชัน 1.0. * ในการควบคุมแหล่งที่มาและเจนกินส์เพิ่งอัปเดตหมายเลขเวอร์ชันด้วยตนเองก่อนที่ msbuild จะทำงาน

dir **/Properties/AssemblyInfo.cs | %{ (cat $_) | %{$_ -replace '^(\s*)\[assembly: AssemblyVersion\("(.*)\.\*"\)', "`$1[assembly: AssemblyVersion(`"`$2.$build`")"} | Out-File $_ -Encoding "UTF8" }
dir **/Properties/AssemblyInfo.cs | %{ (cat $_) | %{$_ -replace '^(\s*)\[assembly: AssemblyFileVersion\("(.*)\.\*"\)', "`$1[assembly: AssemblyFileVersion(`"`$2.$build`")"} | Out-File $_ -Encoding "UTF8" }

ฉันเพิ่มอ็อพชัน -Encoding "UTF8" เนื่องจาก git เริ่มปฏิบัติกับไฟล์. cs เป็นไฟล์ไบนารีถ้าฉันไม่ทำ จริงอยู่สิ่งนี้ไม่สำคัญเพราะฉันไม่เคยทำผลลัพธ์เลย มันเพิ่งเกิดขึ้นขณะที่ฉันกำลังทดสอบ

สภาพแวดล้อม CI ของเรามีสิ่งอำนวยความสะดวกในการเชื่อมโยงเจนกินส์บิลด์กับคอมมิตเฉพาะ (ขอบคุณปลั๊กอิน Stash!) ดังนั้นฉันไม่ต้องกังวลว่าจะไม่มีคอมมิตคอมมิตกับหมายเลขเวอร์ชันที่แนบมา


0

นี่เป็นกลไกที่ง่ายกว่า มันเกี่ยวข้องกับการเพิ่มขั้นตอนการสร้างงานคำสั่ง Windows Batch ก่อนขั้นตอน MSBuild และการใช้โปรแกรมค้นหาและแทนที่อย่างง่าย (FART)

ขั้นตอนแบทช์

fart --svn -r AssemblyInfo.cs "[assembly: AssemblyVersion(\"1.0.0.0\")]" "[assembly: AssemblyVersion(\"1.0.%BUILD_NUMBER%.%SVN_REVISION%\")]"
if %ERRORLEVEL%==0 exit /b 1
fart --svn -r AssemblyInfo.cs "[assembly: AssemblyFileVersion(\"1.0.0.0\")]" "[assembly: AssemblyFileVersion(\"1.0.%BUILD_NUMBER%.%SVN_REVISION%\")]"
if %ERRORLEVEL%==0 exit /b 1
exit /b 0

หากคุณใช้ซอร์สคอนโทรลนอกเหนือจาก svn ให้เปลี่ยนอ็อพชัน --svn สำหรับอ็อพชันที่เหมาะสมสำหรับสภาวะแวดล้อม scm ของคุณ

ดาวน์โหลด Fart


0

ฉันตัดสินใจใช้สองวิธีโดยใช้สคริปต์ Powershell ที่สร้างไว้ล่วงหน้า ( https://gist.github.com/bradjolicoeur/e77c508089aea6614af3 ) เพื่อเพิ่มการสร้างที่ประสบความสำเร็จแต่ละครั้งใน Global.asax ฉันจะทำสิ่งนี้:

  // We are using debug configuration, so increment our builds.
  if (System.Diagnostics.Debugger.IsAttached)
  {
      string version = System.Reflection.Assembly.GetExecutingAssembly()
                                                       .GetName()
                                                       .Version
                                                       .ToString();

      var psi = new ProcessStartInfo(@"svn", "commit -m \"Version: " + version + "\n \"");
      psi.WorkingDirectory = @"C:\CI\Projects\myproject";
      Process.Start(psi); 
  }

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

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