簡體   English   中英

維護程序集版本號的最佳實踐/指南

[英]Best practices/guidance for maintaining assembly version numbers

我正在尋找有關如何管理 .NET 程序集的三個不同程序集版本號的指針、建議甚至口述。 產品版本是最簡單的,因為這似乎通常由業務決定。 然后,文件版本似乎用於部署之間的版本控制,其中實際的程序集版本僅在發布時使用。

現在我只是在尋找一種簡單的方法來標記一個不依賴的程序集的測試和維護版本,所以我正在查看文件版本上自動遞增的構建和修訂號,對於最終版本,復制當前文件版本到程序集版本。 該產品在生產中使用,但仍在開發中 - 你知道 - 那些小公司之一,沒有變更控制基礎設施的情況。

版本控制是我非常熱衷的事情,並且花了很長時間試圖想出一個易於使用的版本控制系統。 根據您在問題中已經說過的內容,很明顯您已經理解了一個重要的觀點,即匯編版本號與產品版本不同。 一個是技術驅動,另一個是業務驅動。

以下假定您使用某種形式的源代碼控制和構建服務器。 對於上下文,我們使用TeamCity和Subversion / Git。 TeamCity對於少數(10)個項目是免費的,並且是一個非常好的構建服務器,但還有其他一些,其中一些是完全免費的。

版本號的含義

一個版本對一個人意味着什么可能意味着另一個人不同,一般結構是主要的,次要的,宏觀的,微觀的。 我查看版本號的方法是將其分為兩部分。 上半部分描述了主要版本(Major)和任何關鍵更新(Minor)。 下半部分表示它何時構建以及源代碼版本是什么。 根據上下文,版本號也意味着不同的東西,它是API,Web App等。

Major Minor Build Revision

  • Revision這是從源代碼管理中獲取的數字,用於標識實際構建的內容。
  • Build這是一個不斷增加的數字,可用於在構建服務器上查找特定的構建。 這是一個重要的數字,因為構建服務器可能使用不同的參數集兩次構建相同的源。 將構建號與源號一起使用可以識別構建的內容和方式。
  • Minor只有在公共接口發生重大變化時才會更改。 例如,如果它是一個API,消費代碼仍然可以編譯? 當主要號碼改變時,該號碼應重置為零。
  • Major表示您所使用的產品版本。 例如,所有VisualStudio 2008程序集的主要部分為9,VisualStudio 2010為10。

規則的例外

規則總是存在例外情況,您必須在遇到它們時進行調整。 我最初的方法是基於使用顛覆,但最近我已經轉移到Git。 使用中央存儲庫的源控件(如subversion和source safe)具有一個可用於標識給定時間內特定源集的數字。 對於諸如Git的分布式源控件,情況並非如此。 因為Git使用每個開發機器上的分布式存儲庫,所以沒有可以使用的自動遞增數字,有一個hack使用了簽到的數量,但它很難看。 因此,我必須改進我的方法。

Major Minor Macro Build

修訂號現在已經消失,構建已經轉移到以前修改的位置和宏已插入。 你可以使用你看起來合適的宏,但大部分時間我都不管它。 因為我們使用TeamCity,從版本號中丟失的信息可以在構建中找到,它確實意味着有兩個步驟但我們沒有丟失任何東西,並且是可接受的妥協。

要設置什么

首先要了解的是,程序集版本,文件版本和產品版本不必匹配。 我並不主張使用不同的數字集,但是當對程序集進行小的更改而不會影響任何公共接口時,它會使生活變得容易得多,而不會強制您重新編譯依賴程序集。 我處理這個問題的方法是只在程序集版本中設置主要和次要數字,而是設置文件版本中的所有值。 例如:

  • 1.2.0.0(AssemblyVersion)
  • 1.2.3.4(FileVersion)

這使您能夠推出不會破壞現有代碼的熱修復,因為程序集版本不匹配,但允許您通過查看其文件版本號來查看程序集的修訂版本/版本。 這是一種常見的方法,當您查看程序集詳細信息時,可以在某些開源程序集中看到它。

作為團隊負責人,您需要負責在需要進行重大更改時遞增次要編號。 向接口推出所需更改但不破壞先前代碼的一種解決方案是將當前代碼標記為過時並創建新接口。 這意味着現有代碼被警告該方法已過時,可以隨時刪除,但不要求您立即中斷所有內容。 然后,您可以在遷移所有內容時刪除過時的方法。

如何將它們連接在一起

您可以手動完成上述所有操作,但這將非常耗時,以下是我們如何自動化該過程。 每個步驟都是可運行的。

  • 從所有項目AssemblyInfo.cs文件中刪除AssemblyVersionAssemblyFileVersion屬性。
  • 創建一個公共程序集信息文件(稱之為VersionInfo.cs)並將其作為鏈接項添加到所有項目中。
  • AssemblyVersionAssemblyFileVersion屬性添加到值為“0.0.0.0”的版本。
  • 創建一個構建解決方案文件的MsBuild項目。
  • 在構建之前添加一個更新VersionInfo.cs的任務。 有許多開源的MsBuild庫包含可以設置版本號的AssemblyInfo任務。 只需將其設置為任意數字並進行測試即可。
  • 為構建號的每個段添加包含屬性的屬性組。 這是您設置主要和次要的地方。 構建和修訂號應作為參數傳遞。

用subversion:

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

希望我很清楚,但涉及很多。 請問任何問題。 我將使用任何反饋將更簡潔的博客文章放在一起。

[AssemblyVersion]在.NET中是一個非常大的問題。 Microsoft鼓勵的一個理念是讓它自動增加,強制重新編譯依賴於程序集的所有項目。 如果您使用構建服務器,則可以正常工作。 這絕不是錯誤的事情,但要小心攜帶劍的人。

另一個與其實際含義更密切相關的是該數字代表了程序集公共接口的版本控制。 換句話說,只有在更改公共接口或類時才更改它。 由於只有這樣的更改才需要重新編譯程序集的客戶端。 這需要手動完成,但構建系統不夠智能,無法自動檢測此類更改。

您可以進一步擴展此方法,只需在將程序集部署到您無法訪問的計算機上時增加版本。 這是Microsoft使用的方法,它們的.NET程序集版本號很少更改。 主要是因為它給客戶帶來了相當大的痛苦。

所以微軟所宣揚的不是它的實踐。 然而,它的構建過程和版本控制是無與倫比的,甚至還有一個專門的軟件工程師來監控這個過程。 沒有那么好用,WaitHandle.WaitOne(int)重載特別引起了相當大的痛苦 在.NET 4.0中使用一種非常不同的方法修復,但這有點超出了范圍。

這取決於您和您對控制構建過程和發布周期的能力的信心,以便您自己做出選擇。 除此之外,自動遞增[AssemblyFileVersion]是非常合適的。 然而,不方便的是,這是支持的。

您可以使用版本號的Build部分進行自動增量。

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

在您的環境中,測試版本是具有構建版本的版本!= 0.在發布時,您將增加次要部分並將構建部分設置為0,這是您識別已發布程序集的方式。

如果您在GAC中安裝程序集,您的GAC會隨着時間的推移而充斥着許多不同的版本,因此請記住這一點。 但是如果你只在本地使用dll,我認為這是一個很好的做法。

添加到Bronumskis的答案 ,我想指出,在semver.org的Semantic Versioning 2.0標准之后Major.Minor.Build.Revision將是非法的,因為規則在增加數字之后,右邊的所有常規值都會有被重置為零。

遵循標准的更好方法是使用Major.Minor+Build.Revision 這顯然不適用於AssemblyVersionAttribute ,但可以使用自定義屬性或靜態類。

TeamCity中的Semver應該可以使用Meta-runner Power Pack。 對於使用git-flow的git(特別是在.NET世界中),我發現GitVersion很有幫助。

在版本化程序集方面沒有嚴格的規則,所以請隨意嘗試哪些適用於你,但我建議你使用4部分方法,因為你有靈活性,你想做一些改變在將來。

...例如:1.0.0。*

保留 - 這增加了額外的靈活性,因為您希望將來進行任何更改。 但作為默認值,將其保持為0。

另外,請考慮使用強密鑰簽署程序集。 如果您在GAC中注冊了多個版本的程序集,這將解決程序集沖突問題。 MSDN鏈接

是一個用於自動生成程序集信息的 T4 模板示例。 每次執行轉換時,程序集版本都會遞增。 您應該只填寫您的項目數據:

// Names.
string projectName = "MyProjectName"; // Project (short name for COM).
string productName = "My Project Name"; // Full title.
string developerName = "Developer Name"; // Developer.
string assemblyType = "Application"; // Application, Library, etc.

// Version.
int majorVersion = 1;
int minorVersion = 0;

// Year of the start of work on the project.
string since = "2021";

轉換模板后,您將獲得如下輸出:

#if COMVISIBLE
using System.EnterpriseServices;
#endif
using System.Reflection;
using System.Runtime.InteropServices;

// General information about this assembly is provided by the following set
// attributes. Change the values of these attributes to change the information,
// related to the assembly.
[assembly: AssemblyTitle ("My Project Name Application 1.0")] // Assembly name.
[assembly: AssemblyDescription ("My Project Name Application 1.0")] // Assembly description.
[assembly: AssemblyCompany ("Developer Name")] // Developer.
[assembly: AssemblyProduct ("Developer Name My Project Name Application")] // Product name.
[assembly: AssemblyCopyright ("© Developer Name 2021")] // Copyright.
//[assembly: AssemblyTrademark ("Developer Name ® My Project Name Application®")] // Trademark.
[assembly: AssemblyCulture ("")]
[assembly: AssemblyVersion ("1.0.2110.0047")]
[assembly: AssemblyFileVersion ("1.0.2110.0047")]
#if DEBUG
[assembly: AssemblyConfiguration ("Debug")]
#else
[assembly: AssemblyConfiguration ("Release")]
#endif

// Setting ComVisible to False makes the types in this assembly invisible
// for COM components. If you need to refer to the type in this assembly via COM,
// set the ComVisible attribute to TRUE for this type.
#if COMVISIBLE
[assembly: ComVisible (true)]
[assembly: ApplicationName ("MyProjectName")] // The name of the COM application.
[assembly: ApplicationID ("fc24620a-239d-4e40-b756-7ed38e82ef69")]
#else
[assembly: ComVisible (false)]
#endif
// The following GUID is used to identify the type library if this project will be visible to COM
[assembly: Guid ("e60d1ecf-6c7b-4c9b-925f-4bf07615da87")]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM