维护程序集版本号的最佳实践/指南


154

我正在寻找有关如何管理.NET程序集的三个不同程序集版本号的指针,建议甚至指令。产品版本是最简单的,因为这通常是由业务决定的。然后,文件版本似乎用于部署之间的版本控制,其中仅在出厂时才使用实际的程序集版本。

现在,我只是在寻找一种简单的方法来标记程序集的测试和维护版本,而这些都不依赖于该程序集,因此我正在寻找文件版本上的自动递增版本号和修订版号,对于最终版本,请复制当前版本。文件版本到程序集版本。该产品已投入生产,但仍处于开发阶段-您知道-这些小型公司之一,没有变更控制基础架构的情况。


Answers:


211

我非常热衷于版本控制,并花了很长时间尝试提出一种易于使用的版本控制系统。从您在问题中已经说过的内容很明显,您已经了解了一个重要的观点,程序集版本号不是产品版本的同义词。一个是技术驱动的,另一个是业务驱动的。

以下假设您使用某种形式的源代码管理和构建服务器。对于上下文,我们使用TeamCity和Subversion / Git。对于少数(10)个项目,TeamCity是免费的,并且是一个非常好的构建服务器,但还有其他项目,其中有些是完全免费的。

版本号是什么意思

一个版本对一个人意味着什么可能意味着与另一个人不同的东西,总体结构是主要,次要,宏观,微观。我查看版本号的方式是将其分为两部分。上半部分描述了主要版本(主要)和所有主要更新(次要)。后半部分指示何时构建它以及源代码的版本。根据上下文的不同,版本号的含义也有所不同,例如API,Web App等。

MajorMinorBuildRevision

  • Revision 这是从源代码管理中识别实际构建内容的编号。
  • Build这是一个越来越多的数字,可用于在构建服务器上查找特定的构建。这个数字很重要,因为构建服务器可能使用不同的参数集两次构建相同的源。将内部版本号与源代码结合使用,可以确定构建了什么以及如何构建。
  • Minor仅当公共接口发生重大更改时,才应更改。例如,如果它是一个API,那么消费代码是否仍然可以编译?当主要编号更改时,该编号应重置为零。
  • Major指示您所使用产品的版本。例如,所有VisualStudio 2008程序集的Major均为9,VisualStudio 2010的Major为10。

规则的例外

规则总是有例外,遇到这些规则时,您必须适应。我最初的方法是基于使用subversion的,但是最近我转到了Git。使用中央存储库的源控制(例如,颠覆和源安全)具有一个编号,可用于在给定时间内标识一组特定的源。对于分布式源控件(如Git),情况并非如此。由于Git使用的是每台开发机器上的分布式存储库,因此没有可以使用的自动递增编号,因此有一种利用签入数量的黑客程序,但是这样做很丑陋。因此,我不得不发展自己的方法。

MajorMinorMacroBuild

现在,修订版本号已消失,构建版本已移至该修订版本所在的位置,并且已插入Macro。您可以按照自己的喜好使用宏,但在大多数情况下,我不理会它。因为我们使用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任务,可以设置版本号。只需将其设置为任意数字并进行测试即可。
  • 添加一个属性组,其中包含内部版本号每个段的属性。在这里设置主要和次要。内部版本号和修订号应作为参数传递。

随着颠覆:

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

希望我已经清楚了,但是涉及到很多。请问任何问题。我将使用任何反馈将更简洁的博客文章放在一起。


您是否考虑过使用GitHub中的版本标签?我很好奇这将如何解决这个难题。
raRaRa

1
@raRaRa-这是一个很老的帖子。尽管大多数情况下我仍然支持,但有些事情我会有所不同。NuGet版本控制已经改变了我的操作方式,并且我确实使用Git标签进行成功构建,但最终,程序集上的版本号应与构建服务器上的构建版本以及源代码管理中的标签版本相关联。
Bronumski '17

57

[AssemblyVersion]在.NET中非常重要。Microsoft鼓励的一种理念是,让它自动递增,从而强制重新编译依赖程序集的所有项目。如果使用构建服务器,则工作正常。这是从来没有的错误的事情,但背着剑的人要小心了。

另一个与其实际含义更紧密相关的是,该数字代表程序集公共接口的版本控制。换句话说,只有在更改公共接口或类时才可以更改它。因为只有这样的更改才需要重新编译程序集的客户。尽管构建系统不够智能,无法自动检测到此类更改,但这需要手动完成。

您可以通过仅在程序集部署在您无法访问的计算机上时增加版本来进一步扩展此方法。这是Microsoft使用的方法,其.NET程序集版本号很少更改。主要是因为它给客户带来了极大的痛苦。

因此,Microsoft鼓吹的不是实践。但是,它的构建过程和版本控制是无与伦比的,他们甚至拥有专门的软件工程师来监视过程。效果不是很好,尤其是WaitHandle.WaitOne(int)重载引起了相当多的痛苦。在.NET 4.0中以一种非常不同的方法进行了修复,但这超出了范围。

这取决于您和您对如何控制构建过程和发布周期以做出自己的选择的信心。除此之外,自动增加[AssemblyFileVersion]非常合适。然而,不便之处在于支持这种做法。


11

您可以使用版本号的Build部分进行自动递增。

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

在您的环境中,测试版本是具有构建版本!= 0的版本。发布时,您增加次要部分并将构建部分设置为0,这就是识别发布的程序集的方式。

如果将组件安装在GAC中,随着时间的流逝,GAC会充斥着许多不同的版本,因此请记住这一点。但是,如果您仅在本地使用dll,我认为这是一个好习惯。


我喜欢发行版本的0内部版本号。
ProfK

1
当然,这意味着无论您希望与否,程序集的强名都会随每次构建而改变。
理查德

9

除了Bronumskis答案外,我想指出的是,在semver.org的Semantic Versioning 2.0标准之后Major.Minor.Build.Revision由于规则的增加,即必须将右边的所有常规值都重置为零,因此将是非法的。

遵循该标准的更好方法是使用Major.Minor+Build.Revision。显然,这不适用于AssemblyVersionAttribute,但是可以改用自定义属性或静态类。

使用Meta-runner Power Pack应该可以使用TeamCity中的Semver。对于具有git-flow的git(尤其是在.NET世界中),我发现GitVersion会有所帮助。


2
有趣的是,我会检查一下。您提到的版本号格式可以在AssemblyInformationalVersion属性中使用。
Bronumski

1

版本程序集没有硬性规定,因此可以随意尝试哪种方法最适合您,但是我建议您使用4部分方法,因为如果您要进行一些更改,可以灵活使用在将来。

...例如:1.0.0。*

保留-如果您将来要进行任何更改,则可以增加灵活性。但默认情况下,请将其保持为0。

另外,请考虑使用强键对程序集进行签名。如果您在GAC中注册了多个版本的程序集,这将解决程序集冲突问题。 MSDN链接

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.