在VCS中存储软件版本号是一种好习惯吗?


22

产品版本(例如)v1.0.0.100不仅代表软件的唯一生产版本,而且还有助于识别该产品的功能集和修补程序阶段。现在,我看到两种方法来维护产品的最终程序包/内部版本/二进制版本:

  1. 版本控制。一个文件存储着版本号。持续集成(CI)构建服务器将具有脚本来构建软件,该脚本使用此签入的版本号将其应用于所需的软件的所有区域(二进制文件,安装程序包,帮助页面,文档等)。

  2. 环境和/或构建参数。这些在版本控制之外进行维护(即,它们不依赖于快照/标签/分支)。构建脚本以相同的方式分配和使用数字,但是它们只是以不同的方式获取值(将其提供给构建脚本,而不是让脚本知道相对于源树在何处获取该值)。

第一种方法的问题在于,它会使跨主线分支的合并变得复杂。如果您仍然维护同一软件的2个并行发行版,并且自上次合并以来两个主版本的版本均已更改,则将在合并两个主干之间时解决冲突。

第二种方法的问题是和解。回到1年前的发行版时,您将仅依靠标签信息来标识其发行版号。

在这两种情况下,版本号的某些方面可能在CI生成之前是未知的。例如,CI构建可能会以编程方式放入第4个组件,该组件实际上是自动构建编号(例如,分支上的第140个构建)。它也可能是VCS中的修订号。

跟上软件版本号的最佳方法是什么?是否应始终在VCS中维护“已知”部分?如果是这样,主线分支之间的冲突是否成为问题?

现在,我们通过CI构建计划(Atlassian Bamboo)中指定和维护的参数来维护版本号。在合并到我们的master分支机构之前,我们必须小心一点,即在开始构建CI之前正确设置了版本号。关于Gitflow工作流程,我认为,如果在源代码管理中跟踪了版本号,我们可以保证在创建release分支以准备发布时正确设置了版本号。质量检查人员将在该分支机构上执行最终的集成/烟熏/回归测试,并在签收后进行合并,master这表示发布承诺。


3
文件的两个版本之间是否存在合并冲突,version.txt其中一个版本包含单行1.0.7,而另一个版本1.2.0确实很难解决?如果这是合并两个分开的分支的唯一冲突,那么我认为自己很幸运。它多久发生一次?如果确实发生了,那么您被迫考虑合并版本应具有的版本号是一件好事吗?(很抱歉使用“版本”一词。)
5gon12eder

1
@ 5gon12eder关于合并本身的困难或感受是无关紧要的。这只是整体解决方案的负面影响。
void.pointer 2015年

Answers:


28

我个人选择选项3:将版本控制信息保留在VCS 元数据(特别是标签)中。

Git非常容易做到这一点,因为这里有一个command git describe,它可以根据标签唯一地描述提交。运作方式如下:

  • 如果当前提交已被标记,则输出标记的名称。
  • 否则,请向后浏览历史记录,直到找到标签,然后以以下格式输出描述:<tag>-<number of commits since the tag>-g<abbreviated commit hash>
  • 如果工作树中有未提交的更改,请追加-dirty

因此,如果您正在执行发行版构建,并标记了提交1.2.3,它将输出1.2.3。如果您当前正在使用1.2.4,并且自1.2.3开始进行了4次提交,并且树中未提交更改,则将输出1.2.3-4-gdeadbee-dirty

这保证是唯一且单调的,并且是人类可读的,因此可以直接用作版本字符串。您唯一需要确保的是标签的正确命名约定。


我真的很喜欢这个主意,但是使用JIRA + Bamboo似乎很难解决。Bamboo仅在分支上起作用,而不在标签上起作用,因此您必须确保在生成内部版本之前已按下标签。这容易出错。
void.pointer 2015年

1
git describe也可以与分支一起使用:“ --all –使用refs/命名空间中找到的所有引用,而不是仅使用带注释的标签。此选项可匹配任何已知的分支,远程跟踪分支或轻量级标签。” 但是,不确定如何与Bamboo一起使用。(这当然需要仔细命名分支,就像普通模式使用标签一样。)
JörgW Mittag

1
我知道有些人会从Git完全自动发布。版本字符串是由构建的git describe,ChangeLog是从生成的git shortlog(实际上是从解析的输出的脚本git log --pretty=tformat:<some custom format string>生成的),发行说明是从标记描述生成的,并git notes附加在重要的里程碑提交上。
约尔格W¯¯米塔格

我的观点是,必须在发布之前创建标签,以便在使用基数对版本进行正确版本化后提交。这违反了发布期间或发布时进行标记的原则。竹拿起建立自动根据提交给master(从develop,记住我使用gitflow)。如果有人将master不带标签的合并推送到该怎么办?它不会使用正确的版本(事实上,它会使用的版本,最后的版本)
void.pointer

如果您使用这样的方案,则标记将释放。嗯,我想我明白了。因此,当前,您的CI服务器是发布驱动程序,并且通过此更改,SCM是发布驱动程序,但是您希望它保持这种状态吗?
约尔格W¯¯米塔格

8

是。最好将大多数版本号保留在vcs中。如果考虑使用语义版本控制semver.org,则在其中具有major.minor.patch.build,则前三个必须存在于vcs中。最后一个可以是构建服务器中的递增编号,用于回溯生成二进制文件的特定提交。

为了在.NET中简化此操作,我们制作了一个用于git的小cmd行exe。通过预构建事件,它将获取在构建过程中teamcity标记的构建号。此cmd行工具会自动生成一个类,该类具有一个包含内部版本号的常量。版本号的其余部分:major.minor.patch只是另一个文件中的普通常量。这两个共享文件作为链接(alt + shift-drag)包含在解决方案的每个程序集中。

这种方法功能强大,足以使我们拥有团队协作能力来构建和测试代码。推送至天蓝色并让kudu重新构建它,但将teamcity内部版本号作为dll的版本。

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.