获取作为Git子模块的C#共享项目版本信息及版本号管理优化方案
我来分享几个针对你场景的实用方案,既解决直观版本信息展示的问题,又能避免手动更新版本号的麻烦:
获取共享项目的直观版本/修改日期
如果你不想让用户看到晦涩的Commit ID,可以通过构建脚本自动提取Git信息,转换成用户易懂的内容:
1. 提取最后提交日期并注入代码
你可以在主项目的.csproj文件中添加MSBuild任务,在编译前执行Git命令获取子模块的最后提交日期,然后将其作为编译常量注入代码:
<Target Name="FetchSubmoduleLastModified" BeforeTargets="CoreCompile"> <!-- 执行Git命令获取子模块最后提交的日期时间 --> <Exec Command="git log -1 --format=%ci $(SolutionDir)你的子模块路径/ --output $(IntermediateOutputPath)SubmoduleDate.txt" /> <ReadLinesFromFile File="$(IntermediateOutputPath)SubmoduleDate.txt"> <Output TaskParameter="Lines" ItemName="SubmoduleModifiedDate" /> </ReadLinesFromFile> <!-- 将日期转换为编译常量 --> <PropertyGroup> <DefineConstants>$(DefineConstants);SUBMODULE_LAST_MODIFIED="@(SubmoduleModifiedDate)"</DefineConstants> </PropertyGroup> </Target>
之后在主项目代码里就能直接使用这个常量:
public string GetSharedModuleInfo() { #if SUBMODULE_LAST_MODIFIED return $"共享模块最后更新:{SUBMODULE_LAST_MODIFIED}"; #else return "共享模块信息未获取"; #endif }
2. 生成「短哈希+提交日期」的友好标识
如果想兼顾可追溯性和可读性,可以用git log -1 --format="%h %ci"命令获取短哈希(7位)+提交日期,格式类似a1b2c3d 2024-05-20 14:30:00 +0800。同样通过MSBuild任务注入代码,用户既能直观看到更新时间,也能通过短哈希在Git中定位具体版本。
自动版本号的实现方案
完全不用手动维护Version类的话,可以试试以下几种自动化方式:
1. 用GitVersion自动生成语义化版本号
GitVersion是一个基于Git历史自动生成语义化版本的工具,它会根据提交记录、标签、分支名等信息自动计算版本号(比如1.2.3、1.3.0-beta.1)。
- 在共享项目仓库中添加
GitVersion.yml配置文件,定义版本规则; - 在主项目的构建脚本中,进入子模块目录执行
gitversion /showvariable FullSemVer,获取自动生成的版本号; - 将这个版本号注入到主项目或共享项目的代码中,或者直接作为程序集版本使用。
这种方式完全自动化,只要在共享项目中打正式版本标签(比如v1.2.3),GitVersion就能自动识别并生成对应的版本号。
2. 构建时自动生成版本信息类
在共享项目的.csproj中添加MSBuild任务,每次构建时自动生成包含版本、Commit ID、最后修改日期的静态类,无需手动修改:
<Target Name="AutoGenerateVersionInfo" BeforeTargets="CoreCompile"> <!-- 获取共享项目的Git信息 --> <Exec Command="git log -1 --format=%H" WorkingDirectory="$(MSBuildProjectDirectory)" Outputs="CommitHash" /> <Exec Command="git log -1 --format=%ci" WorkingDirectory="$(MSBuildProjectDirectory)" Outputs="LastModified" /> <!-- 生成VersionInfo.cs文件 --> <WriteLinesToFile File="$(IntermediateOutputPath)VersionInfo.cs" Overwrite="true"> <Lines>namespace SharedProject;</Lines> <Lines>public static class VersionInfo</Lines> <Lines>{</Lines> <Lines> public const string CommitHash = "$(CommitHash)";</Lines> <Lines> public const string LastModifiedDate = "$(LastModified)";</Lines> <Lines> public static readonly System.DateTime LastModified = System.DateTime.Parse("$([System.Text.RegularExpressions.Regex]::Replace('$(LastModified)', ' \+.*$', ''))");</Lines> <Lines>}</Lines> </WriteLinesToFile> <!-- 将生成的文件纳入编译 --> <ItemGroup> <Compile Include="$(IntermediateOutputPath)VersionInfo.cs" /> </ItemGroup> </Target>
主项目引用共享项目后,就能直接通过SharedProject.VersionInfo.LastModified获取更新时间,或者基于CommitHash结合Git标签生成更友好的版本标识。
3. 标签驱动的版本展示
在共享项目的Git仓库中,每次发布重要更新时打版本标签(比如v1.0.0、v1.1.0),然后在主项目中执行git describe --tags命令获取子模块的最近标签信息,格式类似v1.1.0-5-gabc123——表示距离v1.1.0版本有5次提交,当前Commit短哈希是abc123。这个信息对用户来说非常直观,既能知道基于哪个正式版本,也能了解更新的次数。
内容的提问来源于stack exchange,提问作者Jonas Rapp

