为什么build.number是语义版本控制的“滥用”?


35

我解释提出了构建系统(摇篮/ Artifactory的/詹金斯/厨师),以我们的高级建筑师之一,他所提出的意见,我认为我的那种不同意,但我没有足够的经验,真正权衡上。

该项目构建了一个Java库(JAR)作为工件,供其他团队重用。对于版本控制,我想使用以下语义方法:

<major>.<minor>.<patch>

其中patch指示错误/紧急修复,minor指示向后兼容的发行版,并major指示API的大规模重构和/或向后不兼容的更改。

就交付而言,这就是我想要的:开发人员提交一些代码;这将触发构建到QA / TEST环境。一些测试已经运行(一些自动化,一些手动)。如果所有测试均通过,则生产版本会将JAR发布到我们的内部仓库中。至此,应该正确地对JAR进行版本控制,我的想法是使用build.numberCI工具自动生成并提供的JAR 作为补丁号。

因此,版本控制实际上是:

<major>.<minor>.<build.number>

同样,build.numberCI工具在哪里提供。

架构师对此表示否认,称使用CI版本号是语义版本控制的“滥用”。

我的问题是:这是正确的吗?如果正确,为什么?如果没有,为什么不呢?

Answers:


45

您的内部版本号不会重置为0,当次要和主要版本增加时,这会违反规范的第7和8节:

如果将新的向后兼容功能引入了公共API,则必须增加次要版本Y(xYz | x> 0)。如果任何公共API功能标记为已弃用,则必须递增。如果在私有代码中引入了实质性的新功能或改进,则可以增加它。它可能包括补丁级别的改变。当次要版本增加时,补丁版本必须重置为0。

如果向公共API引入了任何向后不兼容的更改,则必须增加主要版本X(Xyz | X> 0)。它可能包括次要级别和补丁级别更改。当主要版本增加时,补丁和次要版本必须重置为0。

因此,必须手动提供版本号(主要,次要,补丁),因为它们用于告诉您的用户某个地方的更改,而无需他们查看变更日志或其他文档。

如果要包括内部版本号,则可以在+第10节之后附加它们:

可以通过在补丁或预发行版本之后立即添加加号和一系列由点分隔的标识符来表示构建元数据。标识符只能包含ASCII字母数字和连字符[0-9A-Za-z-]。标识符不得为空。确定版本优先级时,应忽略构建元数据。因此,只有版本元数据不同的两个版本具有相同的优先级。例如:1.0.0-alpha + 001、1.0.0 + 20130313144700、1.0.0-beta + exp.sha.5114f85。


快速跟进@Residuum(答案是BTW +1):那么版本号应该总是手动获得吗?如果不是,可以使用哪些工具代替CI /内部版本号?
herpylderp 2014年

1
@herpylderp一点也不,Tom Preston-Werner的“规范”只是他的意见,其他公司的负载有不同的(通常彼此非常相似)标准。在大多数此类文件中,自动生成的数字是该版本的一部分。使用CI内部版本号是明智的选择。
gbjbaanb 2014年

如果CI工具允许您对内部版本号进行算术运算,则仍然可以使用CI工具。无论您发布的版本是主要版本还是次要版本升级,都应将该版本号插入版本字符串的表达式中,该表达式将从当前CI版本号中减去。瞧,您只是将新版本的内部版本号重置为零,而没有实际重置内部版本号。
KeithS 2014年

2
对于我来说,我只使用[major]。[minor]。[revision]。[SVN-Version]用于DLL,而[major]。[minor]。[SVN-Version]用于安装程序。CI内部版本号仅供内部使用,以显示失败的内部版本在更改CI环境(安装密钥证书,向GAC添加通用库等)后可能已针对完全相同的代码库重新运行。
KeithS 2014年

1
@gbjbaanb等:在我参与的每次有关“语义版本控制”的讨论中,semver.org的定义都是主题。在网络上搜索“语义版本控制”,至少第一页显示来自semver.org的有关定义的优点/缺点。您可以自由使用自己的版本控制方案,但不要将其称为语义版本控制,因为该术语已明确定义。
Residuum

2

一个原因是该修补程序可能需要多个构建,因此,如果您具有版本5.7,并且想要将其修补到5.7.1,但是当您将前2个错误修复提交给CI系统后无法构建,那么您将在发布第一个补丁之前,请按照5.7.3进行操作!

答案是简单地使用4位数字(这是Microsoft系统倾向于使用的)。第四位是内部版本号,“仅供参考”。通常,人们将存储库的版本号放在那里(如果他们使用SVN或TFS或类似的东西),这真的很好,因为您可以验证用于构建二进制文件的确切提交。如果您没有这样的东西,那么CI内部版本号是一个合理的近似值(因为您希望您的CI系统可以记住内部版本号并将其与回购历史记录相关联,但是您并不依赖于CI系统会记住它们-您永远无法删除旧版本)。

需要注意的一件事是,用于版本控制的Microsoft架构使用内部编号作为内部版本号。Chrome仅使用1个数字。Ubuntu使用日期。没有“标准”可使用,只是所有数字必须递增。


5
尽管没有普遍使用或强制执行的标准,但问题似乎专门针对确实具有规范的语义版本控制
2014年

即使在该领域中也是如此,例如,Microsoft的NuGet版本控制以某种方式使用semver(使用内部版本号的预发行版本),而Ruby使用major.minor.teeny.patch。无论如何,因为内部版本号可能是服务器的一部分,所以架构师在胡说八道(尽管应该承认,它应该是+内部版本,而不是第三位置)。
gbjbaanb 2014年

2
据我所知,SemVer 2.0规范来自2013年,而1.0规范则来自2012年。在规范出现之前,NuGet和Ruby可能正在做自己的事情。SemVer规范并不新颖。它只是使人们已经在做的事情正式化,因此我们都可以最终以一种方式达成共识,而不用一variations而就。
2014年

“您的版本为5.7,并且想要将其修补为5.7.1,但是当您将前2个错误修正提交给CI系统后,它们将无法构建,那么在发布第一个补丁之前,您将处于5.7.3 !” 好的,那又如何呢?我在回忆中什么都没有说数字不能跳过。
安迪
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.