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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3768261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:45:21  来源:igfitidea点击:

Best practices/guidance for maintaining assembly version numbers

.netversion-controlversioning.net-assemblyassemblyversions

提问by ProfK

I'm looking for pointers, suggestions, and even dictation on how to manage the three different assembly version numbers for a .NET assembly. The Product version is the simplest, as this seems would normally be dictated by business. Then, the file version seems to be for versioning between deployments, where the actual assembly version is only used when shipping.

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

Right now I'm just looking for a simple means of labeling test and maintenance releases of an assembly on which none depend, so I am looking at auto-incrementing build and revision numbers on the file version, and for final release, copying the current file version to the assembly version. The product is in production use, but still under development - you know - one of those small company, no change control infrastructure situations.

现在我只是在寻找一种简单的方法来标记一个不依赖的程序集的测试和维护版本,所以我正在查看文件版本上的自动递增构建和修订号,对于最终版本,复制当前文件版本到程序集版本。该产品正在生产中使用,但仍在开发中 - 你知道 - 那些没有变更控制基础设施情况的小公司之一。

回答by Bronumski

Versioning is something that I am very passionate about and have spent a long time trying to come up with an easy to use versioning system. From what you have already said in your question it is clear that you have understood one important point, the assembly version numbers are not synonymous with the product version. One is technically driven, and the other is driven by the business.

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

The following assumes that you use some form of source control and a build server. For context we use TeamCityand Subversion/Git. TeamCity is free for a small (10) number of projects and is a very good build server but there are others, some of which are completely free.

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

What a version number means

版本号是什么意思

What a version means to one person may mean something different to another, the general structure is major, minor, macro, micro. The way I look at a version number is to break it down into two parts. The first half describes the main version (Major) and any key updates (Minor). The second half indicates when it was built and what the source code version was. Version numbers also mean different things depending on the context, is it an API, Web App, etc.

一个版本对一个人意味着什么,对另一个人意味着什么,一般结构是主要的、次要的、宏观的、微观的。我查看版本号的方式是将其分解为两部分。前半部分描述了主要版本(Major)和任何关键更新(Minor)。后半部分表示它的构建时间和源代码版本。版本号也意味着不同的东西,具体取决于上下文,它是 API、Web 应用程序等。

Major.Minor.Build.Revision

Major. Minor. Build.Revision

  • RevisionThis is the number taken from source control to identify what was actually built.
  • BuildThis is an ever increasing number that can be used to find a particular build on the build server. It is an important number because the build server may have built the same source twice with a different set of parameters. Using the build number in conjunction with the source number allows you to identify what was built and how.
  • MinorThis should only change when there is a significant change to the public interface. For instance, if it is an API, would consuming code still be able to compile? This number should be reset to zero when the Major number changes.
  • Majorindicates what version of the product you are on. For example the Major of all the VisualStudio 2008 assemblies is 9 and VisualStudio 2010 is 10.
  • Revision这是从源代码控制中获取的数字,用于识别实际构建的内容。
  • Build这是一个不断增加的数字,可用于在构建服务器上查找特定构建。这是一个重要的数字,因为构建服务器可能使用不同的参数集构建了相同的源两次。将内部版本号与源代码号结合使用可以让您确定构建的内容和方式。
  • Minor这应该只在公共接口发生重大变化时才会改变。比如,如果是API,消费代码还能编译吗?当主编号更改时,此编号应重置为零。
  • Major指示您使用的产品版本。例如,所有 VisualStudio 2008 程序集的 Major 是 9,VisualStudio 2010 是 10。

The exception to the rule

规则的例外

There are always exceptions to the rule and you will have to adapt as you come across them. My original approach was based on using subversion but recently I have moved to Git. Source control like subversion and source safe that use a central repository have a number that can be used to identify a particular set of sources from a given time. This is not the case for a distributed source control such as Git. Because Git uses distributed repositories that are on each development machine there is no auto incrementing number that you can use, there is a hack which uses the number of check-ins but it is ugly. Because of this I have had to evolve my approach.

规则总是有例外的,您必须在遇到它们时进行调整。我最初的方法是基于使用 subversion,但最近我转向了 Git。使用中央存储库的像 subversion 和 source safe 这样的源代码控制有一个数字,可用于从给定时间识别一组特定的源。对于诸如 Git 之类的分布式源代码控制而言,情况并非如此。因为 Git 使用位于每台开发机器上的分布式存储库,所以没有您可以使用的自动递增数字,所以有一个使用签入数量的 hack,但它很丑陋。因此,我不得不改进我的方法。

Major.Minor.Macro.Build

Major. Minor. Macro.Build

The revision number has now gone, build has shifted to where the revision used to be and Macro has been inserted. You can use the macro how you see fit but most of the time I leave it alone. Because we use TeamCity the information lost from the revision number can be found in the build, it does mean there is a two step process but we have not lost anything and is an acceptable compromise.

修订号现已消失,构建已转移到以前修订的位置,并且已插入宏。您可以使用您认为合适的宏,但大多数时候我不理会它。因为我们使用 TeamCity,可以在构建中找到从修订号丢失的信息,这确实意味着有一个两步过程,但我们没有丢失任何东西,这是一个可以接受的妥协。

What to set

设置什么

The first thing to understand is that the Assembly Version, File Version and Product Version do not have to match. I am not advocating having different sets of numbers but it makes life a lot easier when making small changes to an assembly that doesn't affect any public interfaces that you are not forced to recompile dependent assemblies. The way I deal with this is to only set the Major and Minor numbers in the Assembly Version but to set all the values in the File Version. For example:

首先要了解的是,程序集版本、文件版本和产品版本不必匹配。我不提倡使用不同的数字集,但是当对不影响任何公共接口的程序集进行小的更改时,它会让生活变得更轻松,您不必重新编译依赖程序集。我处理这个问题的方法是只在程序集版本中设置主要和次要编号,而在文件版本中设置所有值。例如:

  • 1.2.0.0 (AssemblyVersion)
  • 1.2.3.4 (FileVersion)
  • 1.2.0.0(汇编版本)
  • 1.2.3.4(文件版本)

This gives you the ability to roll out hot fixes which will not break existing code because the assembly versions do not match but allow you to see the revision/build of an assembly by looking at its file version number. This is a common approach and can be seen on some open source assemblies when you look at the assembly details.

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

You as the Team lead would need to be responsible for incrementing the minor number when ever a breaking change is required. One solution to rolling out a required change to an interface but not breaking previous code is to mark the current one as obsolete and creating a new interface. It means that existing code is warned that the method is obsolete and could be removed at any time but doesn't require you to break everything immediately. You can then remove the obsolete method when everything has been migrated.

当需要进行重大更改时,您作为团队负责人需要负责增加次要编号。对接口进行所需更改但不破坏先前代码的一种解决方案是将当前代码标记为过时并创建新接口。这意味着现有代码会被警告该方法已过时并且可以随时删除,但不需要您立即破坏所有内容。然后,您可以在迁移完所有内容后删除过时的方法。

How to wire it together

如何将它连接在一起

You could do all the above manually but it would be very time consuming, the following is how we automate the process. Each step is runnable.

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

  • Remove the AssemblyVersionand AssemblyFileVersionattributes from all the project AssemblyInfo.cs files.
  • Create a common assembly info file (call it VersionInfo.cs) and add it as a linked item to all your projects.
  • Add AssemblyVersionand AssemblyFileVersionattributes to the version with values of "0.0.0.0".
  • Create an MsBuild project that builds your solution file.
  • Add in a task prior to the build that updates the VersionInfo.cs. There are a number of open source MsBuild libraries that include an AssemblyInfo task which can set the version number. Just set it to an arbitrary number and test.
  • Add a property group containing a property for each of the segments of the build number. This is where you set the major and minor. The build and revision number should be passed in as arguments.
  • 从所有项目 AssemblyInfo.cs 文件中删除AssemblyVersionAssemblyFileVersion属性。
  • 创建一个通用程序集信息文件(称为 VersionInfo.cs)并将其作为链接项添加到所有项目中。
  • AssemblyVersionAssemblyFileVersion属性添加到值为“0.0.0.0”的版本。
  • 创建一个构建解决方案文件的 MsBuild 项目。
  • 在更新 VersionInfo.cs 的构建之前添加一个任务。有许多开源 MsBuild 库包含可以设置版本号的 AssemblyInfo 任务。只需将其设置为任意数字并进行测试。
  • 添加一个属性组,其中包含内部版本号的每个段的属性。这是您设置大调和小调的地方。版本号和修订号应作为参数传入。

With subversion:

与颠覆:

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

Hopefully I have been clear but there is a lot involved. Please ask any questions. I will use any feedback to put a more concise blog post together.

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

回答by Hans Passant

The [AssemblyVersion] is a very big deal in .NET. One philosophy, encouraged by Microsoft is that you let it auto-increment, forcing allprojects that depend on the assembly to be recompiled. Works okayish if you use a build server. It is never the wrongthing to do but beware of people carrying swords.

[AssemblyVersion] 在 .NET 中非常重要。Microsoft 鼓励的一种理念是让它自动递增,从而强制重新编译依赖于程序集的所有项目。如果您使用构建服务器,则可以正常工作。这样做永远不会错,但要小心携带剑的人。

The other one, more closely associated with its actual meaning is that the number is representative for the versioning of the public interface of the assembly. In other words, you only change it when you alter a public interface or class. Since only such a change requires clients of the assembly to be recompiled. This needs to be done manually though, the build system isn't smart enough to auto-detect such a change.

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

You can further extend this approach by only incrementing the version when the assembly was deployed on machines outside of your reach. This is the approach that Microsoft uses, their .NET assemblies version numbers very rarely change. Mostly because of the very considerable pain it causes on their customers.

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

So what Microsoft preaches is not what it practices. Its build process and versioning control is however unparalleled, they even have a dedicated software engineer that monitors the process. Didn't quite work out so well, the WaitHandle.WaitOne(int) overload in particular caused a fair amount of pain. Fixed in .NET 4.0 with a very different approach, but that's getting a bit beyond the scope.

所以微软所宣扬的并不是它所实践的。然而,它的构建过程和版本控制是无与伦比的,他们甚至有一个专门的软件工程师来监控这个过程。效果不太好,WaitHandle.WaitOne(int) 重载尤其引起了相当多的痛苦。在 .NET 4.0 中修复了一个非常不同的方法,但这有点超出了范围。

It is rather up to you and your confidence in how well you can control the build process and the release cycles to make your own choice. Other than that, auto-incrementing the [AssemblyFileVersion] automatically is very appropriate. With however the inconvenience that this is notsupported.

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

回答by testalino

You could use the Build part of the version number for auto-increment.

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

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

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

In your environment a test version is a version that has a build version != 0. On release you increment the minor part and set the build part to 0, this is how you would identify released assemblies.

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

If you install your assemblies in the GAC your GAC gets flooded with lots of diffent versions over time, so keep that in mind. But if you use the dlls only locally, I think this is a good practice.

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

回答by sunside

Adding to Bronumskis answer, I want to point out that after the Semantic Versioning 2.0 standard at semver.org, Major.Minor.Build.Revisionwould be illegal due to the rule that after increasing a number, all regular values to the right would have to be reset to zero.

添加到Bronumskis 的回答中,我想指出,在semver.org的语义版本控制 2.0 标准之后Major.Minor.Build.Revision由于增加一个数字后,右侧的所有常规值必须重置为零的规则,这将是非法的。

A better way following the standard would be to use Major.Minor+Build.Revision. This is obivously not for use in AssemblyVersionAttribute, but a custom attribute or static class could be used instead.

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

Semver in TeamCity should be available using the Meta-runner Power Pack. For git with git-flow (especially in the .NET world), I found GitVersionto be helpful.

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

回答by Karthik Mahalingam

There is no hard and fast rule when it comes to versioning assemblies, so feel free to try which ever would work for you, but I would suggest you make use of 4 parts approach as you will have the flexiblity incase you want to make some changes in the future.

在版本控制程序集方面没有硬性规定,所以请随意尝试哪种适合您,但我建议您使用 4 部分方法,因为您将拥有灵活性,以防您想进行一些更改在将来。

... for ex : 1.0.0.*

...例如:1.0.0.*

Reserved - This adds additional flexiblity, incase you want to make any change in future. But as a default, keep it as 0.

保留 - 这增加了额外的灵活性,以防您将来想要进行任何更改。但作为默认值,将其保留为 0。

Also, consider signing the assembly with strong key. This will solve the assembly conflict issue incase you have multiple version of assembly registered in the GAC. MSDN Link

此外,请考虑使用强密钥签署程序集。如果您在 GAC 中注册了多个版本的程序集,这将解决程序集冲突问题。 MSDN链接