如何避免在源代码中保留版本号?

18

目前我们在setup.py文件中保留了Python源代码的版本号。

每次CI运行成功后,这个版本号都会增加。

这意味着中央库的版本号每天都会增加多次。

由于版本号存储在git repo文件中,每次增加版本号都是一次新的提交。

这意味着大约50%的提交不是由人类而是由CI完成的。

我有一种感觉,我们走错了路。也许在CI中保留版本号并不是一个好的解决方案。

我们如何避免那些'无用'的CI提交只是为了增加版本号呢?

如何避免在源代码中保留版本号?

更新

几年来,我们没有手动发布过更新。我们没有像MAJOR.MINOR这样的版本号计划。我们过去没有错过它。我知道这并不适用于所有环境。但它适用于我的当前环境。

我们有一个版本号看起来像这样:YEAR.MONTH.X

这意味着每次经过CI验证的提交都是一个新的发布。

阅读回答后,我意识到:我需要问自己:我是否真的有一个版本号?我觉得没有。我只有一个构建号。在这种情况下,不需要更多。

(感谢点赞。在提出这个问题之前,我确信这个问题会被关闭,因为人们认为它是“不清楚”或“太广泛”)


2
你确定需要在代码库中保留版本号吗?每个通过CI的提交都可以打上一个(递增的)版本号标签,这样就不需要通过版本升级来改变代码库的内容了。 - chepner
如果CI通过进行新提交来增加版本号,为什么不让CI使用git commit --amend将版本号的修改附加到上一个提交中呢? - Roll
3
这不是一个好的做法,因为会导致提交版本哈希值的更改,提交的原始作者会发现每次 CI 运行后他的本地 git 仓库与远程仓库不同步。他不能简单地使用 git-pull 命令进行更新,因为会产生冲突。 - hackape
1
你也可以使用像 https://pypi.org/project/setuptools-scm/ 这样的工具,它可以从 git 的提交和标签中设置版本。如果你正在使用 poetry,那么有一个 hack 可以实现相同的功能: https://github.com/mtkennerly/poetry-dynamic-versioning - gabuzo
6个回答

5

在源代码中保留版本号是一种常见的做法,这并没有什么问题。

你需要将CI过程分为常规构建、发布发布和发布部署。

常规构建:每天运行甚至每次提交后运行,可以包括静态代码分析和自动测试,检查代码是否可以构建。常规构建不应更改版本号。

发布发布:只能由发布经理的显式手动操作触发。
触发操作可以是使用新版本号标记提交,合并到发布分支进行新合并或仅更改特殊文件中保留的版本号(例如pom.xml)。请参阅Git Flow示例。
发布发布分配一个新版本号(自动或手动),如果必要,则将其提交到源代码中,使用新版本构建二进制包并将其上传到二进制包存储库(例如Nexus、devpi、本地APT存储库、Docker注册表等)。

发布部署:另一个手动触发的操作,从软件包存储库中获取准备好的二进制包,并将其安装到目标环境(开发、QA/UAT/分段、金丝雀部署或整个生产环境)。


我更新了问题:我们已经好几年没有手动发布了。我们没有像 MAJOR.MINOR 这样的版本控制方案。过去我们也没有错过这个。我知道这并不适用于所有环境。但是它适用于我的当前环境。这意味着每次通过 CI 的提交都是一个新的发布。 - guettli
3
看起来您实际上正在使用构建编号,通常人们不会将它们存储在版本库中。但是需要识别特定安装版本并将其映射到提交记录。在这种情况下,您可以尝试使用版本库修订作为构建编号。考虑使用Git提交哈希或参考此SO答案:https://dev59.com/qm855IYBdhLWcg3w1oA8#18834279。 - void

4

前提条件:

我认为这些是讨论解决方案的前提条件。

  1. 当前版本号存储在git跟踪的源文件中,但您可以放心地摆脱它。
  2. 没有人手动管理版本号,也没有触发发布过程,其中包括:(a)增加版本号,(b)从源代码构建,以及(c)将构建结果存储在某个位置。这些由CI负责处理,并且应该保持不变。

解决方案:

  1. CI仅对通过CI检查的特定提交打上标签,而不是写入源文件并创建新的提交。
  2. 构建脚本应读取当前HEAD提交的标记,并将其用作发布版本的版本号。
  3. 可选地,您可能希望使用git filter-branch来重写现有的git存储库历史记录,标记先前的发布提交以确保一致性,删除并停止跟踪版本号源文件,然后摆脱这些CI提交。

请问您建议使用哪个工具来确定新版本号?我找不到一个适当的带有CLI界面的工具,它可以读取最后一个标签并根据特定需求(major、minor、patch、prerelease等)进行增加。最接近的是setuptools_scm,但它缺少CLI :( - Hodossy Szabolcs
@HodossySzabolcs 我建议使用定制脚本而不是任何现成的工具。在 OP 的情况下,他们只是将日期字符串用作版本号。我知道很多人也使用递增整数作为版本号。所以这真的取决于你的需求。 - hackape

4
如果项目在git存储库中用于生产,则只需使用您喜欢的任何git describe变体即可,无需将其存储在已跟踪的文件中,因为结果标识了特定的历史记录,并且您已经拥有该历史记录。
如果源代码是单独发布的,则可以使用git archiveexport-subst属性来嵌入几乎任何您想要的内容。

4

注意:作为新用户无法添加评论。

扩展并支持@VibrantVivek的this答案。

对于持续集成而言,回溯存储库非常重要,无论您是将其保存在代码中还是使用任何其他git方法,在每次成功的CI之后都必须有相应的标签/版本。

如果您拥有针对提交的CI标签/版本,则可能存在某些问题。

+1 Martin Fowler,这里提供另一篇更详细的文章(与同一个人有关)https://www.thoughtworks.com/continuous-integration(请建议阅读)。


4

我认为你应该使用Git Flow,并创建一个主分支和一个开发分支。每次CI检查开发分支时,版本号保持不变。每次你创建一个发布版本,例如将开发分支合并到主分支中,你可以通过CI增加版本号。

或者我漏掉了什么,但在我的意见中,没有理由每次CI运行时都增加版本号。

总之,你最好考虑何时对新版本进行更改和“发布”!


我更新了问题:我们已经好几年没有手动发布了。我们没有像 MAJOR.MINOR 这样的版本控制方案。而且我们过去也没有错过这个。我知道这对于所有环境都不适用。但是它适用于我的当前环境。这意味着每次通过 CI 的提交都是一个新的发布。 - guettli

3

在你的第一个问题中:

我们如何避免“无用”的CI提交,这些提交只是增加了版本号?

请注意:持续集成(CI)是一种开发实践,通过自动化构建验证每个check-in,使团队能够及早发现问题。

话虽如此,在这里想表达的是:

  • 从实践中得知:每个提交都应该在一个集成机器上构建

  • 关于如何做到这一点: CI服务器监视存储库,并在发生更改时检查它们

简单来说,只有在有新提交时,CI服务器才应该增强版本以确保每个代码提交都可以发布。

看起来像是OP所说的,在你的区域里有更多(正如你所说)来自CI服务器“无用”commits

基于您的CI机制,我希望您应该/必须能够控制它,几乎每个我们使用的工具都有处理方式(例如:Bitbucket中的Webhooks、版本插件等)。

因此,确保只有在新提交后我们才有一个新版本。

现在,如果您正在考虑那些定期夜间集成构建,则请阅读以下内容:

许多组织会按时间表定期进行构建,例如每晚。 这不同于持续构建,并且对于持续集成来说不足够。持续集成的整个重点是尽早发现问题。每晚构建意味着错误在被发现之前会被忽略一整天。一旦它们在系统中存在那么长时间,就需要很长时间才能找到并删除它们。

此外,您已经提到:通过CI的每个提交都是一个新版本,因此在某种程度上您已经实现了真正的CI。

尽管如此,如果您仍然不知道如何避免版本号的“无用”提交,那么我建议您添加另一个问题,详细说明您的CI机制是如何工作的以及为什么在给定条件下很难。我敢打赌一定有解决方案。还可以查看GithubFlowVsGitFlow
来源:Martin fowler's white paper on CI

如何避免在源代码中保留版本号?

关于这个问题,我想扩展一下@void的答案,因为他说了这样一句话:
It is a common practice to keep a version number in the source code, there is nothing wrong in that.

有些项目必须知道已部署的确切版本(由于某些重要原因),在这种情况下,它们会在源代码中保留版本,并使用HTTP GET API从部署的代码中获取(一种方法)以了解当前在X服务器上部署的版本。
然而,这更多地取决于需求,假设对于另一个项目不存在这种情况,则建议保持版本的方法是使用每个成功的CI构建的提交哈希/标记。
您可以在此处获得更多详细信息here
希望这可以帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接