首頁

目前文章總數:157 篇

  

最後更新:2024年 12月 07日

0065. Asp.net Core 專案,自動遞增版本號的方法

日期:2024年 03月 31日

標籤: C# Asp.net Core Web MVC Software Version

摘要:C# 學習筆記


應用所需:1. 範例專案需 Visual Studio 2022 以上、.net Core 7 以上
解決問題:如何使用Visual Studio 的內建版本號,並在建置時觸發自動化遞增版本號,便於發布的時候不用手動輸入
內文說明用範例:範例
基本介紹:本篇分為三大部分,已經熟悉微軟版本號 PropertyGroup 配置屬性,可跳到第三部分參考
第一部分:.net core 版本號說明
第二部分:版本號 - 手動輸入
第三部分:版本號 - 啟用建置自動遞增






第一部分:.net core 版本號說明

Step 1:MSDN版本號說明 - 屬性

版本號說明來源於MSDN,可以參考:
MSDN 英文說明
MSDN 中文說明


這邊整理幾個主要設定值 (於專案檔 .csproj 中的 PropertyGroup 內的屬性值)

版本屬性 名稱 說明
AssemblyVersion 組件版本 程式組件時的版本號,可在屬性中檢閱
FileVersion 檔案版本 產生 .dll 檔案的版本號,或者特定檔案
PackageVersion 套件版本 Nuget的版本號,若程式要上架 Nuget 必須設定此值
Version 軟體版本 程式整體的版本號,預設使用此值,不可與 PackageVersion 共存
VersionPrefix 版本增量,前綴部分 用於版本迭代,只包含 Major、Minor、Build
VersionSuffix 版本增量,後綴部分 用於版本迭代,附加標示用,只有 Revision



Step 2:MSDN版本號說明 - 格式組成

版本號標準約定由 4 個部分組成
這標準主要目的:1.易讀性 2.語意化 3.遵循標準
4 個部分組成對應如下:

Major.Minor.Build.Revision    
版本屬性 名稱 說明
Major 主要版本 “不”向後兼容,程式重大改變時會遞增
Minor 次要版本 “可”向後兼容,程式有新功能、改進、調整時會遞增
Build 生成版本 標示建構版本,無論有無調整,發布時都應遞增
Revision 修訂版本 任何微調,都應遞增



Step 3:手動版本號位置 - 1

Visual Studio IDE 中,版號位置如圖
鍵盤 Alt + Enter -> 套件 -> 一般 -> 套件版本


Step 4:手動版本號位置 - 2

鍵盤 Alt + Enter -> 套件 -> 一般 -> 檔案版本、組件版本


Step 5:自動版本位置 - 1

開啟專案的 .csproj 檔案,如圖
對自己的專案滑鼠右鍵 -> 編輯專案檔案


Step 6:自動版本位置 - 2

自動版本的版本號要自己添加
※手動版本號亦可從 .csproj 中自行添加




第二部分:版本號 - 手動輸入

Step 1:開啟 IDE 調整

如第一部分 Step 3. 、 Step 4. 顯示,可以手動調整此值



Step 2:顯示範例

以下是取得 AssemblyVersion 、 FileVersion 、Version 的方法
此篇是 Web 範例,因此捨棄 PackageVersion 用通常的 Version

/// <summary>
/// 手動自定義版號
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
    // 取得 Assembly Version
    var assembly = Assembly.GetExecutingAssembly();
    var assemblyName = assembly.GetName();
    ViewBag.AssemblyVersion = assemblyName.Version;

    // 取得 File Version
    var fileVersionInfo = FileVersionInfo.GetVersionInfo(typeof(Program).Assembly.Location);
    ViewBag.FileVersion = fileVersionInfo.FileVersion;
    
    // 取得 取得軟體版本資訊 / 取得 Nuget (套件版本) ※只能存在一種屬性
    // 此專案非 Nuget 套件,因此使用 Version 
    var version = typeof(Program).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
    ViewBag.Version = version;           
    return View();
}



Step 3:Demo 結果 - 顯示結果

執行範例的代碼,可以看到能正確取配置版本號的結果


Step 4:Demo 結果 - 檔案內容 - 1

對建置產生的 .dll 開啟 -> 內容


Step 5:Demo 結果 - 檔案內容 - 2

也可以確認產生的 .dll FileVersion 是設定的 2.0.0.1
整體的 Version 為 1.0.0.0




第三部分:版本號 - 啟用建置自動遞增

Step 1:新增自動化腳本檔案

本篇目的是在建置時自動增加修訂版本號,讓最終整體版號 Version 會自動變化,不用透過人工
因此需要新增腳本檔案,在專案下新增一個檔案 UpdateVersionNumber.targets




Step 2:自動化腳本內容

自動化腳本內容如下,主要分成五個部分
關鍵的點是 BeforeTargets=”BeforeBuild” ,當專案建置前會觸發這個腳本

<Target Name="UpdateVersionNumber" BeforeTargets="BeforeBuild">


完整內容:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <!-- 獲取 csproj 檔案的路徑 -->
    <ProjectFile>$(MSBuildProjectFile)</ProjectFile>
  </PropertyGroup>

  <Target Name="UpdateVersionNumber" BeforeTargets="BeforeBuild">
    <!-- 讀取專案文件中的版本號屬性 -->
    <XmlPeek XmlInputPath="$(ProjectFile)" Query="/Project/PropertyGroup/VersionPrefix/text()">
      <Output TaskParameter="Result" PropertyName="VersionPrefix" />
    </XmlPeek>
    <XmlPeek XmlInputPath="$(ProjectFile)" Query="/Project/PropertyGroup/VersionSuffix/text()">
      <Output TaskParameter="Result" PropertyName="VersionSuffix" />
    </XmlPeek>

    <!-- 解析版本號屬性的值,僅支持前Major.Minor.Build的版本號(不包含Revision) -->
    <PropertyGroup>
      <Major>$([System.Version]::Parse($(VersionPrefix)).Major)</Major>
      <Minor>$([System.Version]::Parse($(VersionPrefix)).Minor)</Minor>
      <Build>$([System.Version]::Parse($(VersionPrefix)).Build)</Build>
    </PropertyGroup>

    <!-- 對 Revision 值加 1 -->
    <PropertyGroup>
      <Revision>$([MSBuild]::Add($(VersionSuffix), 1))</Revision>
    </PropertyGroup>

    <!-- 更新 Revision 值 -->
    <XmlPoke XmlInputPath="$(ProjectFile)" Query="/Project/PropertyGroup/VersionSuffix" Value="$(Revision)" />

	<!-- 更新 版本號 內容 -->
	<XmlPoke XmlInputPath="$(ProjectFile)" Query="/Project/PropertyGroup/Version" Value="$(Major).$(Minor).$(Build).$(Revision)" />
  </Target>
</Project>



Step 3:專案檔編輯

然後開啟專案檔 .csproj ,將新建的檔案 UpdateVersionNumber.targets 做引入
關鍵點1. 新增兩個增量參數,用於組成版本號

<!--用於遞增 -->
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>1</VersionSuffix>


關鍵點2. 引入 UpdateVersionNumber.targets 檔案

<!-- 引入 UpdateVersionNumber.targets 文件 -->
<Import Project="UpdateVersionNumber.targets" />


完整內容:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <TypeScriptRemoveComments>False</TypeScriptRemoveComments>
    <TypeScriptNoEmitOnError>True</TypeScriptNoEmitOnError>
    <TypeScriptCompileOnSaveEnabled>True</TypeScriptCompileOnSaveEnabled>
    <TypeScriptSourceMap>True</TypeScriptSourceMap>
  </PropertyGroup>
  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <TypeScriptRemoveComments>False</TypeScriptRemoveComments>
    <TypeScriptNoEmitOnError>True</TypeScriptNoEmitOnError>
    <TypeScriptCompileOnSaveEnabled>True</TypeScriptCompileOnSaveEnabled>
    <TypeScriptSourceMap>True</TypeScriptSourceMap>
  </PropertyGroup>
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AssemblyVersion>3.0.0.1</AssemblyVersion>
    <FileVersion>2.0.0.1</FileVersion>
    <Version>1.0.0.1</Version>
    <!--用於遞增 -->
    <VersionPrefix>1.0.0</VersionPrefix>
    <VersionSuffix>1</VersionSuffix>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.0" />
  </ItemGroup>
  <!-- 引入 UpdateVersionNumber.targets 文件 -->
  <Import Project="UpdateVersionNumber.targets" />
</Project>



Step 4:顯示範例

以下是取得 PrefixVersion 、 Version 、 SuffixVersion 的方法
其中 SuffixVersion 要從 Version 中取出第四部份 Revision

/// <summary>
/// 自動遞增版號
/// </summary>
/// <returns></returns>
public IActionResult AutoIncretmentVersion()
{
    // 取得 Prefix Version
    string prefixVersion = typeof(Program).Assembly.GetCustomAttribute<System.Reflection.AssemblyInformationalVersionAttribute>().InformationalVersion;
    ViewBag.PrefixVersion = prefixVersion;
    
	// 此時合併版號應存在於 Version 中
    var version = typeof(Program).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
    ViewBag.Version = version;
    
	// 取得 Suffix Version ※為動態寫入值,通常不可直接取得
    string suffixVersion = version.Split('.').Length >= 4 
                           ? version.Split('.')[3] 
                           : "0";
    ViewBag.SuffixVersion = suffixVersion;
    return View();
}



Step 5:Demo 結果 - 顯示結果

執行範例的代碼,每次重新建置後,都能看到版本號第四部份自動遞增