【问题标题】:How to manage release versions across different build tools?如何跨不同的构建工具管理发布版本?
【发布时间】:2018-01-15 21:23:19
【问题描述】:

我正在研究如何改进发布版本控制在我的项目中的工作方式。发布的结果由多个工件组成,涉及多个工具及其对应的控制文件,具体取决于它们的域:

  • C/C++ 的 CMake (CMakeFiles.txt)
  • 用于 Java 的 Maven (pom.xml)
  • Node.js 的 NPM (package.js)
  • Sphinx (conf.py) 用于 ReadTheDocs 上托管的文档
  • 任何其他工具(例如,我认为我们很快就会为每个版本生成 Docker 映像,因此请在此处添加 Dockerfile

每一个通常都包含一个 Project Version 字段,其中编写了发布的版本,并且发布工件从那里获取其版本号。我想将分散在多个文件中的那些重复的版本号统一到一个单一的事实来源中。我已经搜索但没有找到令人满意的解决方案,所以我在这里问:

在跨多种语言/构建工具的项目中,对于版本号的健壮和轻松管理,有哪些最佳实践或标准?特别是至少对于前 4 种类型的 avobe,尽管通用解决方案将是首选。

一个重要的必要条件是我宁愿避免包装脚本(例如,使用sed 进行字段替换),以保持工具独立于更多外部工具(即我希望构建命令保持“cmake" 而不是 "cmake_prepare_and_run.sh")。

更新:我认为将 CI 限制为代码存储库上的只读操作是一种普遍的良好做法,这是我在项目中强制执行的策略。我真的不需要,也不希望 CI 太聪明,决定在没有任何监督的情况下自动发布新版本。

【问题讨论】:

  • 我已经包含了 2 个想法来回答这个问题,现在已经转移到他们自己的答案中
  • maven 版本在每个工件的 pom.xml 中都是硬编码的。 maven-release-plugin 旨在指导版本控制和发布版本控制。我正在努力应对构建 C/C++ 和 maven 的类似挑战。之前,我们让 maven 控制一切,并使用 maven-native-plugin 来构建 C/C++。但是那个插件已经死了(不支持 VS 2010+ 64 位)并且 cmake 似乎是最流行的 C/C++ 工具。我也在试图弄清楚如何跨构建工具进行版本控制。类似q:stackoverflow.com/questions/44639122/…

标签: git maven npm cmake versioning


【解决方案1】:

通常,解决方案 A 是最常实施的解决方案。

  • 版本控制系统不会经常更改(如果有的话)
  • 大多数构建过程已经有一个插件调用正确的 git 命令并生成一个包含版本信息的属性文件。

例如,对于 maven,应该是 ktoso/maven-git-commit-id-plugin

【讨论】:

  • 只是补充一点,拥有VERSION 文件可能是版本控制的噩梦——因为您通常希望将此文件作为发布的一部分提交,但这样做会修改 VC 历史记录,这意味着文件的内容不反映它所属的提交 SHA/标签!
  • @match 真。然而,这一代是在构建步骤中完成的,并导致一个额外的提交,它只包括一个修改后的 VERSION 文件(或者在 git maven 插件的情况下,一个属性文件)。让 VERSION 文件引用上一个提交而不是当前提交是可以接受的。
  • 我更新了问题以澄清这一点:我认为让 CI 自动提交并推送到 repo 是一种不好的做法,所以我宁愿避免这种做法。一个 repo 应该像 CI 的只读文件系统,并且 CI 脚本应该(或者几乎应该,除了一些非常具体的细节,例如读取 git 标签)被编写成同样可以正常工作,如果给定例如包含项目源代码的 .tar.gz 文件。 VERSION 文件可以通过首先在 repo 中更改它,然后创建并推送一个 git 标签来工作。 CI 将在标签被推送时触发。
  • @j1elo 好的。我很想知道还有谁会为此提出答案。
【解决方案2】:

我自己对这个问题的解决方案 - 到目前为止,这是我想到的两个想法:

A.从 Git 标签获取发布版本。在构建任何模块时,构建工具必须在git describe --tags 行中执行某些操作(可能使用--always 和/或--abbrev=0)并将结果提取到包含版本的变量中。我将在 Git 中有一个“release”分支,该分支仅用于发布,并且新的发布工件将仅针对该分支中标有某个版本号的提交发布。这有一个问题,即要求每个单独的构建工具能够轻松地运行带有命令的子 shell 并获得命令的结果。这也意味着版本号与版本控制系统相关联。

B.在存储库的根目录中创建一个名为 VERSION 的文本文件,其中包含版本号。然后,将每个构建工具配置为首先读取该文件并从中加载版本号,然后再执行正常的构建步骤。它仍然依赖于编辑一个文件,但至少这将集中到一个文件上,而且它总是一样的,坐在同一个地方。

两种解决方案都要求构建工具允许执行这些操作;对于像 CMake 和 Python 这样的人来说,这很容易,但我对 Maven、NPM 甚至任何解析 Dockerfile 的工具都不太熟悉,所以我不确定这些是否是通用解决方案。

【讨论】:

  • 通用解决方案,可能不是。不过,请为此反馈 +1。
  • 你好,我宁愿多等一会儿,有机会得到更多答案;毕竟,这些都是我自己的想法,我写这个问题是因为我想得到新的。您认为我应该在其他 StackExchange 社区中要求它提高知名度吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
相关资源
最近更新 更多