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

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

现在我只是寻找一个简单的方法来标记一个组件的testing和维护版本,而不依赖于这个版本,所以我正在考虑在文件版本上自动递增构build版本和修订版本号,并且为了最终版本,复制当前版本文件版本到程序集版本。 该产品在生产中使用,但仍在开发 – 你知道 – 这些小公司之一,没有改变控制基础设施的情况。

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

以下假定您使用某种forms的源代码pipe理和生成服务器。 对于上下文,我们使用TeamCity和Subversion / Git。 TeamCity是免费的一小部分(10)项目,是一个非常好的构build服务器,但也有其他人,其中一些是完全免费的。

什么是版本号的意思

一个版本对一个人意味着什么可能意味着与另一个不同的东西,一般结构是重大的,微小的,macros观的,微观的。 我看一个版本号的方法是把它分解成两部分。 上半部分描述了主要版本(Major)和任何关键更新(Minor)。 下半部分显示了它的构build时间和源代码版本。 版本号根据上下文也有不同的意思,是API,Web App等

Major MinorBuildRevision

  • Revision这是从源代码pipe理中获取的数字,用于确定实际构build的内容。
  • Build这是一个越来越多的数字,可以用来在构build服务器上查找特定的构build。 这是一个重要的数字,因为构build服务器可能已经使用不同的参数集build立了两次相同的源。 将内部版本号与源代码结合使用,可以确定构build的内容和方式。
  • Minor这应该只会改变公共界面的重大变化。 比如说,如果是一个API,那么消费代码还是可以编译的? 主号码发生变化时,此号码应重置为零。
  • Major表示您所在产品的版本。 例如,所有VisualStudio 2008程序集中的Major都是9,而VisualStudio 2010是10。

规则的例外

总是有例外的规则,你将不得不适应,因为你遇到他们。 我原来的做法是基于使用颠覆,但最近我已经转移到Git。 使用中央存储库的源代码控制(如subversion和source safe)具有一个可以用于从给定时间标识特定源的编号。 分布式源代码控制(如Git)并不是这种情况。 因为Git使用的是每个开发机器上的分布式存储库,所以没有可以使用的自动递增数字,有一种使用检入数量的黑客攻击,但是它很丑陋。 正因为如此,我不得不改进我的方法。

Major MinorMacroBuild

版本号现在已经消失了,版本已经转移到修订版本以及Macro已经插入的地方。 你可以使用macros如何看待健康,但大部分时间我都不愿意。 因为我们使用了TeamCity,修改版本中丢失的信息可以在构build中find,这确实意味着有两个步骤的过程,但是我们没有丢失任何东西,并且是可接受的折衷scheme。

要设置什么

首先要了解的是,组件版本,文件版本和产品版本不必匹配。 我并不主张拥有不同的数字集合,但是在对组件进行小的更改时不会影响任何公用接口,因此您不必强制重新编译依赖程序集。 我处理这个问题的方法是仅在组件版本中设置主要和次要数字,而在文件版本中设置所有的值。 例如:

  • 1.2.0.0(AssemblyVersion)
  • 1.2.3.4(FileVersion)

这使您能够推出不会破坏现有代码的修补程序,因为程序集版本不匹配,但可以通过查看其文件版本号来查看程序集的修订版/构build版。 这是一种常见的方法,当您查看程序集细节时,可以在一些开源程序集中看到。

作为团队负责人,如果需要进行重大更改,则需要负责增加次要人数。 一个解决scheme是对接口进行必要的更改,但不能破坏以前的代码,就是将当前的代码标记为过时并创build一个新的接口。 这意味着现有的代码被警告,该方法已经过时,可以在任何时候被删除,但不要求你立即破坏一切。 当所有东西都被迁移的时候,你可以删除过时的方法。

如何将它连接在一起

您可以手动完成以上所有操作,但这将非常耗时,以下是我们如何自动执行此过程。 每一步都可以运行。

  • 从所有的项目AssemblyInfo.cs文件中删除AssemblyVersionAssemblyFileVersion属性。
  • 创build一个常用的组件信息文件(称为VersionInfo.cs),并将其作为链接项添加到所有项目中。
  • AssemblyVersionAssemblyFileVersion属性添加到值为“0.0.0.0”的版本。
  • 创build一个构build解决scheme文件的MsBuild项目。
  • 添加更新VersionInfo.cs的构build之前的任务。 有许多开源的MsBuild库,包括一个可以设置版本号的AssemblyInfo任务。 只需将其设置为任意数字并进行testing。
  • 为内部版本号的每个段添加一个包含属性的属性组。 这是你设置主要和次要的地方。 构build版本号和修订版号应作为参数传入。

随着颠覆:

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

希望我已经清楚,但涉及很多。 请提出任何问题。 我会用任何反馈把一个更简洁的博客文章放在一起。

  • 编译程序集中的版本号
  • MSBuild扩展包
  • TeamCity的

.NET中的[AssemblyVersion]是一个非常重要的部分。 微软鼓励的一个理念是让它自动递增,强制依赖于程序集的所有项目都被重新编译。 如果您使用构build服务器,则可以工作。 做永远不是错误的事情,但要提防拿着剑的人。

另一个与其实际意义更密切相关的是,这个数字代表了程序集公共接口版本的代表性。 换句话说,当你改变公共接口或类时,你只能改变它。 由于只有这样的改变需要重新编译程序集的客户端。 这需要手动完成,但构build系统不够智能,无法自动检测到这种变化。

您可以进一步扩展此方法,只需将程序集部署在不在您的机器之外的机器上即可。 这是微软使用的方法,他们的.NET程序集版本号很less改变。 主要是因为他们的顾客造成了相当大的痛苦。

那么微软宣扬的不是它的做法。 它的构build过程和版本控制是无与伦比的,他们甚至有一个专门的软件工程师来监视过程。 如果没有这么好的工作,WaitHandle.WaitOne(int)过载尤其会造成相当大的痛苦 。 在.NET 4.0中修复了一个非常不同的方法,但是这已经超出了范围。

这是相当于你和你的信心,你可以控制的build设过程和释放周期,使自己的select。 除此之外,自动递增[AssemblyFileVersion]是非常合适的。 然而,这不受支持的不便。

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

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

在您的环境中,testing版本是具有版本版本!= 0的版本。在发行版中,增加次要部分并将生成部分设置为0,这是如何识别发布的程序集。

如果您在GAC中安装程序集,您的GAC会随着时间的推移而被大量不同版本充斥,因此请记住这一点。 但是如果你只在本地使用dll,我认为这是一个很好的做法。

再加上Bronumskis的回答 ,我想指出的是,在semver.org的Semantic Versioning 2.0标准之后 , Major.Minor.Build.Revision是非法的,因为在增加一个数字之后,右边的所有正则值都会有重置为零。

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

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

在版本化组件方面没有硬性的规定,所以随时可以尝试哪种方法适合你,但是我build议你使用4个部分的方法,因为你可以灵活地进行一些更改在将来。

…例如:1.0.0。*

保留 – 这增加了额外的灵活性,因此您想在将来进行任何更改。 但作为默认值,保持为0。

另外,请考虑用强大的密钥签署大会。 这将解决assembly冲突问题,因为您有在GAC中注册的多个版本的程序集。 MSDN链接