对项目版本自动控制——利用gitversion

对项目版本自动控制——利用gitversion

1 为什么需要自动版本控制

笔者很多年以前是从事fpga芯片设计工作的,那时需要将fpga的固件下载进fpga芯片,而某个文件夹下会放历史的固件,那时笔者就在编译时将编译时刻的时刻写进了fpga的某个寄存器,方便测试人员跟开发人员查看区分。同时将此时刻命名在了固件的名字上以作区分。这样新生成的版本很好区分。那会代码仓库用的是SVN。

总结起来,对某项目进行自动化版本信息命名的好处:

  • 方便测试人员产品经理识别版本变化;
  • 方便客户带版本信息反馈问题,使得开发人员更有效的定位问题;
  • 自动化生成版本信息,对开发人员则不需要有意识地去管理版本;

2 如何使项目版本一目了然

作者比较喜欢以如下格式来命名版本
{主版本}.{子版本}.{提交仓库时间}.{仓库短编码}

比如
1-H.1.2021-02-02T05-45-05.3beaf10
表示主版本为1,H项目,子版本为1,代码提交时间为2021-02-02T05-45-05,代码仓库短编码为3beaf10

1-N.1.2021-02-02T05-45-05.3beaf10
含义同上。

3 Dot Net Core,程序集中的版本概念及作用

本文所探讨的是dot Net Core里程序集的版本。
一张表看懂dll版本号的值和设定版本号方式

Assembly Version File Version Product Version
作用 net core runtime找dll的适合看这个值 区别build出来的dll和上一个版本的差异,一般此处会新增 从产品的角度解释这个版本,同时也是nuget版本号
确认dll的版本号 [System.Reflection.Assembly]::LoadFrom(“I:\IBMS.webapi.dll”).GetName().Version 右键属性Details页File Version 右键属性Details页Product Version
设定Attribute名称 [assembly: AssemblyVersion(“1.0.0.0”)] [assembly: AssemblyFileVersion(“1.0.0.0”)] [assembly: AssemblyInformationalVersion(“1.0.0.0”)]

3.1 AssemblyVersion查询方式

3.2 AssemblyFileVersion与AssemblyInformationalVersion查询方式

3.3 三个版本号的差异

3.3.1 程序集版本,Assembly Version

这是net Core 运行时用的版本号,当有reference某个dll,会包含此dll的版本号。这个版本号就是Assembly Version。当你在你的项目中引用了指定的程序集,其版本号将会嵌入到你的项目中。在运行时,CLR通过该版本号加载指定程序集。

3.3.2 文件版本,Assembly File Version

这是在文件系统中给文件的版本号,会在Windows资源管理器中显示。但是,在.NET Framework引用类库时从来不会用到这个版本。原则上这个是用来区分不通build的次数,递增。

建议:如果您在为一个应用程序构建一个很多开发者都在引用的基础程序集,并且这个程序集更新速度非常快,比如一天一次之类的,而且这个程序集还是强命名的,那么您每次更新完程序集后所有的开发者都需要重新更新引用。这样做非常繁琐并且还容易引用出错。所以对于这种情况更好的办法是,固定好Assembly Version,而只修改Assembly File Version,即使用后者来表示最新的版本号。在这种情况下,开发者们不需要更新引用,而仅仅只需要把新的程序集文件覆盖到引用目录下就可以了。在中间或最后发布的版本中,为了更有意义,可以更新Assembly Version,使Assembly File Version与Assembly Version近似。

3.3.3 产品版本,AssemblyInformationalVersion

这个主要用来表示,从一个产品的角度之间的差异,可以自己在AssemblyInfo.cs文件中添加,那就是AssemblyInformationalVersion,从名字就可以看出来,这个版本号更大的意义是版本的信息,而不仅仅是数字的描述,比如可以设置为如下的版本信息之类的。

AssemblyInformationalVersion与AssemblyFileVersion一样,都是可以在Windows资源管理器中显示的,换言之,其都是存储在Win32版本资源中的。所以如果不设置AssemblyInformationalVersion的话,默认在文件属性里显示的“产品版本”就是AssemblyFileVersion,而设置了AssemblyInformationalVersion以后,才会显示AssemblyInformationalVersion设置的内容。如下图,左边为未设置AssemblyInformationalVersion,右边为设置了AssemblyInformationalVersion。

如果用nuget建立出nuget的package,那么nuget预设使用Product Version作为版本号。

3.4 Build与Revision

对于.NET的项目,版本号是由Major.Minor.Build.Revision构成的,通常被称作主要版本、次要版本、内部版本以及修订号。在MSDN上有专门对版本号说明的内容,比较重要的摘抄如下:

Major:名称相同但主要版本号不同的程序集不可互换。 更高版本号可能表明大幅重写无法假定向后兼容的产品。
Minor:如果两个程序集的名称和主要版本号相同,而次要版本号不同,这指示显著增强,但照顾到了向后兼容性。 该较高的次要版本号可指示产品的修正版或完全向后兼容的新版本。
Build:生成号的不同表示对相同源所作的重新编译。 处理器、 平台或编译器更改时,可能使用不同的生成号。
Revision:名称、主要版本号和次要版本号都相同但修订号不同的程序集应是完全可互换的。 更高修订号可能在修复以前发布的程序集安全漏洞的版本中使用。

程序集的只有Build或Revision不同的后续版本被认为是先前版本的修补程序 (Hotfix) 更新。

4 gitVersion介绍

gitVersion开源项目github地址
使用Git时的版本控制已解决。 GitVersion查看您的git历史记录,并计算出正在构建的提交的语义版本。

GetVersion兼容windows,linux,Mac。

官方文档介绍

这个官方文档虽然写得很详细,但是晦涩难懂,吐槽下。

5 如何在dot Net Core, visual studio项目里使用

关键讲下如何利用gitversion工具设定项目dll的版本,这主要是指product version。因为这个信息支持字符串写入,包含得更全面。

5.1 下载getversion命令行工具

通过此链接下载Win64编译好版本
如下图:

5.2 将此exe工具放到需要运行的startup项目中


该工具主要可以从git仓库中获取版本的提交时间,版本号等信息。

5.3 添加gitVersion工具的yml配置文件

在startup路径下添加GitVersion.yml配置文件

配置文件内容如下:

next-version: 1.1
assembly-versioning-scheme: MajorMinorPatch
assembly-file-versioning-scheme: MajorMinorPatchTag
assembly-informational-format: '{Major}.{Minor}.{CommitDate}.{ShortSha}'
mode: ContinuousDelivery
increment: Inherit
continuous-delivery-fallback-tag: ci
tag-prefix: '[vV]'
major-version-bump-message: '\+semver:\s?(breaking|major)'
minor-version-bump-message: '\+semver:\s?(feature|minor)'
patch-version-bump-message: '\+semver:\s?(fix|patch)'
no-bump-message: '\+semver:\s?(none|skip)'
legacy-semver-padding: 4
build-metadata-padding: 4
commits-since-version-source-padding: 4
commit-message-incrementing: Enabled
commit-date-format: 'yyyy-MM-ddTHH:mm:ss'

ignore:
  sha: []
  commits-before: 2015-10-23T12:23:15
merge-message-formats: {}

配置介绍参照官网此篇

这里主要介绍如下几个参数:

  • next-version: 1.1
    表示主版本与子版本;

  • assembly-informational-format
    设置产品版本格式,'{Major}.{Minor}.{CommitDate}.{ShortSha}’表示,{主版本}.{子版本}.{提交仓库时间}.{仓库短编码}

  • 提交日期格式
    commit-date-format: ‘yyyy-MM-ddTHH:mm:ss’

5.4 往VS项目添加项目的生成前事件

$(ProjectDir)gitversion-win-x64-5.6.4\GitVersion.exe /updateassemblyinfo $(ProjectDir)Properties\AssemblyInfo.cs /ensureassemblyinfo

大概含义是从git中取出版本信息,更新到Properties文件夹的AssemblyInfo.cs文件中。
AssemblyInfo.cs文件如下:

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by GitVersion.
//
// You can modify this code as we will not overwrite it when re-executing GitVersion
// </auto-generated>
//------------------------------------------------------------------------------

using System.Reflection;

[assembly: AssemblyFileVersion("1.1.0.127")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.2021-02-02T06-11-12.b311391")]

5.5 点击重新生成解决方案

Net Core中 VS会自动去项目里找 AssemblyFileVersion,AssemblyVersion,AssemblyInformationalVersion关键属性,匹配到会自动写入到程序集中。

VS输出窗口会输出gitVersion工具产生的变量如下图:

这些变量很有用是gitVersion产生输出的,可以通过配置文件的格式将变量自动写入到版本信息中去。

5.6 写入成功

5.7 asp net core中获取产品版本号

   private string GetInformationalVersion()
   {

       return FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
   }

5.8 时区加8小时

不知道什么原因,git仓库时间是对的,gitVersion取出来的时间就是少8小时,所以我自己手动给他加了8小时,再返回给前端。

    private string GMTAdd8(string productVersioName)
    {
        var versionArray = productVersioName.Split(".");
        DateTime dt = DateTime.ParseExact(versionArray[2], "yyyy-MM-ddTHH-mm-ss", System.Globalization.CultureInfo.CurrentCulture).AddHours(8);
        versionArray[2] = dt.ToString("yyyy-MM-ddTHH:mm:ss");
        productVersioName = string.Join(".", versionArray);

        return productVersioName;
    }

6 最终Web效果

CI/DI传到gitLab上也能跑。

当然在gitlab上通过他的yml文件去调gitversion.exe可能会更方便,因为当有多个项目时可以共用同一个gitVersion工具,而且,项目生成不会依赖gitVersion。大家感兴趣可自行研究。


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接://www.cnblogs.com/JerryMouseLi/p/14366880.html