GitVer.MSBuild 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package GitVer.MSBuild --version 1.0.0
                    
NuGet\Install-Package GitVer.MSBuild -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GitVer.MSBuild" Version="1.0.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GitVer.MSBuild" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="GitVer.MSBuild">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GitVer.MSBuild --version 1.0.0
                    
#r "nuget: GitVer.MSBuild, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GitVer.MSBuild@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GitVer.MSBuild&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=GitVer.MSBuild&version=1.0.0
                    
Install as a Cake Tool

GitVer - Git 版本自動化工具

基於 Git 的 .NET 版本自動化系統,在編譯時自動生成包含 Git 標籤、提交哈希和建置時間的版本字串。

功能特色

  • 完全自動化 - 無需手動修改版本號
  • Git 原生整合 - 基於 tag、commit hash、建置時間戳
  • 編譯時生成 - 每次 build 自動更新版本信息
  • 多重後備策略 - 確保在各種 Git 狀態下都能生成有效版本
  • 台灣時區 - 使用 +08:00 時區顯示建置時間

版本格式

版本字串會根據 Git 狀態自動選擇最適合的格式:

  • 標準格式v1.0.0-db3ebe00 @ 2025-10-08T15:32:34+08:00
  • 僅有標籤v1.0.0 @ 2025-10-08T15:32:34+08:00
  • 僅有提交db3ebe00 @ 2025-10-08T15:32:34+08:00
  • 無 Git 信息2025-10-08T15:32:34+08:00

快速開始

建置和執行

dotnet build
dotnet run

輸出範例:

Application Version: v1.0.0-db3ebe00 @ 2025-10-08T15:32:34+08:00

發布新版本

# 創建新版本標籤
git tag v1.1.0

# 重新建置即可獲得新版本
dotnet build && dotnet run

如何整合到其他專案

方法一:複製核心程式碼

  1. 複製版本解析邏輯到目標專案的 .csproj 檔案:



<Target Name="ResolveVersion" BeforeTargets="GenerateVersionSource">
  <PropertyGroup>
    <DefineConstantsOriginal>$(DefineConstants)</DefineConstantsOriginal>
    <VersionEffective Condition="'$(VersionEffective)' == '' and '$(Version)' != '' and '$(Version)' != '1.0.0'">$(Version)</VersionEffective>
    <VersionFromConstants Condition="'$(VersionFromConstants)' == '' and '$(DefineConstantsOriginal)' != ''">$([System.Text.RegularExpressions.Regex]::Match('$(DefineConstantsOriginal)', 'VERSION=(?:&quot;(?&lt;value&gt;[^"]+)&quot;|(?&lt;value&gt;[^;]+))').Groups['value'].Value)</VersionFromConstants>
    <VersionEffective Condition="'$(VersionEffective)' == '' and '$(VersionFromConstants)' != ''">$(VersionFromConstants)</VersionEffective>
  </PropertyGroup>

  
  <Exec
    Command="git -C &quot;$(MSBuildProjectDirectory)&quot; describe --tags --always"
    ConsoleToMSBuild="true"
    IgnoreExitCode="true"
    StandardOutputImportance="Low">
    <Output TaskParameter="ConsoleOutput" PropertyName="GitDescribeOutputRaw" />
  </Exec>

  <Exec
    Command="git -C &quot;$(MSBuildProjectDirectory)&quot; describe --tags --abbrev=0"
    ConsoleToMSBuild="true"
    IgnoreExitCode="true"
    StandardOutputImportance="Low">
    <Output TaskParameter="ConsoleOutput" PropertyName="GitTagRaw" />
  </Exec>

  <Exec
    Command="git -C &quot;$(MSBuildProjectDirectory)&quot; rev-parse --short=8 HEAD"
    ConsoleToMSBuild="true"
    IgnoreExitCode="true"
    StandardOutputImportance="Low">
    <Output TaskParameter="ConsoleOutput" PropertyName="GitCommitRaw" />
  </Exec>

  
  <PropertyGroup>
    <GitDescribeOutput>$([System.String]::Copy('$(GitDescribeOutputRaw)').Trim())</GitDescribeOutput>
    <GitTag>$([System.String]::Copy('$(GitTagRaw)').Trim())</GitTag>
    <GitTag Condition="'$(GitTag)' != '' and $([System.String]::Copy('$(GitTag)').StartsWith('fatal:'))"></GitTag>
    <GitCommit>$([System.String]::Copy('$(GitCommitRaw)').Trim())</GitCommit>
    <BuildTimestamp>$([System.DateTime]::UtcNow.AddHours(8).ToString(&quot;yyyy-MM-ddTHH:mm:ss+08:00&quot;))</BuildTimestamp>
    <AutoVersion Condition="'$(VersionEffective)' == '' and '$(GitTag)' != '' and '$(GitCommit)' != ''">$(GitTag)-$(GitCommit) @ $(BuildTimestamp)</AutoVersion>
    <AutoVersion Condition="'$(VersionEffective)' == '' and '$(AutoVersion)' == '' and '$(GitTag)' != ''">$(GitTag) @ $(BuildTimestamp)</AutoVersion>
    <AutoVersion Condition="'$(VersionEffective)' == '' and '$(AutoVersion)' == '' and '$(GitCommit)' != ''">$(GitCommit) @ $(BuildTimestamp)</AutoVersion>
    <AutoVersion Condition="'$(VersionEffective)' == '' and '$(AutoVersion)' == '' and '$(GitDescribeOutput)' != ''">$(GitDescribeOutput) @ $(BuildTimestamp)</AutoVersion>
    <AutoVersion Condition="'$(VersionEffective)' == '' and '$(AutoVersion)' == ''">$(BuildTimestamp)</AutoVersion>
    <VersionEffective Condition="'$(VersionEffective)' == ''">$(AutoVersion)</VersionEffective>
    <DefineConstantsSanitized Condition="'$(DefineConstantsOriginal)' != ''">$([System.Text.RegularExpressions.Regex]::Replace('$(DefineConstantsOriginal)', '(^|;)VERSION=(?:&quot;[^"]+&quot;|(?&lt;value&gt;[^;]+)', '$1'))</DefineConstantsSanitized>
    <DefineConstantsSanitized Condition="'$(DefineConstantsSanitized)' != ''">$([System.Text.RegularExpressions.Regex]::Replace('$(DefineConstantsSanitized)', ';;+', ';'))</DefineConstantsSanitized>
    <DefineConstantsSanitized Condition="'$(DefineConstantsSanitized)' != ''">$([System.Text.RegularExpressions.Regex]::Replace('$(DefineConstantsSanitized)', '^;|;$', ''))</DefineConstantsSanitized>
    <DefineConstants Condition="'$(DefineConstantsSanitized)' != ''">$(DefineConstantsSanitized)</DefineConstants>
    <DefineConstants Condition="'$(DefineConstantsSanitized)' == '' and '$(DefineConstantsOriginal)' != ''"></DefineConstants>
  </PropertyGroup>
</Target>


<Target Name="GenerateVersionSource" BeforeTargets="BeforeBuild">
  <PropertyGroup>
    <GeneratedVersionPath>$(IntermediateOutputPath)GeneratedVersion.g.cs</GeneratedVersionPath>
    <VersionLiteral>$([MSBuild]::Escape('$(VersionEffective)'))</VersionLiteral>
  </PropertyGroup>

  <ItemGroup>
    <VersionSourceLine Include="namespace YourNamespace%3b" />
    <VersionSourceLine Include="internal static partial class Program" />
    <VersionSourceLine Include="{" />
    <VersionSourceLine Include="    static partial void ApplyVersionOverride(ref string version)" />
    <VersionSourceLine Include="    {" />
    <VersionSourceLine Include="        version = &quot;$(VersionLiteral)&quot;%3b" />
    <VersionSourceLine Include="    }" />
    <VersionSourceLine Include="}" />
    <Compile Include="$(GeneratedVersionPath)" />
  </ItemGroup>

  <WriteLinesToFile
    File="$(GeneratedVersionPath)"
    Lines="@(VersionSourceLine)"
    Overwrite="true"
    Encoding="UTF-8" />
</Target>
  1. 修改目標類別(如 Program.cs):
namespace YourNamespace;

internal static partial class Program
{
    // 預設版本字串,若編譯時帶入參數會被覆寫
    internal static string Version = "dev";

    // 由編譯時生成的部分方法
    static partial void ApplyVersionOverride(ref string version);

    private static void Main()
    {
        // 套用自動生成的版本
        ApplyVersionOverride(ref Version);

        Console.WriteLine($"Application Version: {Version}");
    }
}

方法二:NuGet 套件(推薦)

注意:這個專案目前是概念驗證版本,建議包裝成 NuGet 套件以便重複使用。

方法三:Git Submodule

如果你有多個專案需要相同的版本控制邏輯:

# 在目標專案中加入 submodule
git submodule add https://github.com/youruser/gitver.git tools/gitver

# 參考 tools/gitver/gitver.csproj 的實作

自訂配置

修改時區

預設使用台灣時區 (+08:00),如需修改:

<BuildTimestamp>$([System.DateTime]::UtcNow.AddHours(YOUR_OFFSET).ToString(&quot;yyyy-MM-ddTHH:mm:ssZZ&quot;))</BuildTimestamp>

修改版本格式

可以自訂 AutoVersion 的格式:


<AutoVersion Condition="'$(VersionEffective)' == '' and '$(GitTag)' != ''">$(GitTag) ($(BuildTimestamp))</AutoVersion>

修改命名空間

將生成目標中的 YourNamespace 替換為你的專案命名空間:

<VersionSourceLine Include="namespace YourProject.Core%3b" />

故障排除

Git 命令失敗

如果 Git 命令執行失敗,系統會自動降級到時間戳版本:

2025-10-08T15:32:34+08:00

編譯錯誤

確保:

  1. 目標類別宣告為 partial
  2. 包含正確的 ApplyVersionOverride 部分方法宣告
  3. 命名空間與生成的程式碼一致

授權

MIT License

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 577 10/8/2025
1.0.1 354 10/8/2025
1.0.0 420 10/8/2025

v1.0.0:
• 初始版本
• 支援 Git tag + commit hash + 建置時間
• 台灣時區支援 (+08:00)
• 強型別 GitVersionInfo 類別生成
• 多重後備策略