首页 > 解决方案 > CI 如何影响语义版本控制?

问题描述

Countinous Delivery 书中,建议将所有内容(包括 CI 脚本)保留在版本控制中。实际上,像gitlab CI这样的当前 CI 系统已经遵循这个经验法则,在同一个代码库中搜索 CI 脚本。
另一方面,只要代码库发生变化,我们就会对其进行版本控制(它是构建的工件)。我们为此遵循语义版本控制;为错误修复增加补丁字段,为非破坏性功能增加补丁字段,等等......
我们通过在 CI 中检查它来确保版本在提交之间增加。
但是,有些提交只会更改 CI 脚本;即添加分析作业、优化另一个作业等。
在这个冗长无聊的序言之后,我的问题是,对 CI 的此类更改进行版本控制的最佳实践是什么?因为它可能会影响最终构建的工件(例如,更改 CI 作业中的构建标志以进行优化或...)。
在这种情况下可以增加版本吗?

标签: continuous-integrationsemantic-versioning

解决方案


Git 是一个版本控制系统。每次您向 git repo 提交内容时,它都会使用表示该版本的 repo 的内容哈希值标记 repo 的内容。git repo 内容的语义版本控制是多余且毫无意义的。SemVer 的重点是为生产者提供一种向消费者传达风险的方法。换句话说,语义版本控制旨在用于构建产品标签,而不是用于生成构建的位。

如果您尝试将SemVer语义应用于 repo,则您标记的是产品输入,而不是产品本身。在执行所有单元/回归/验收测试之前,您不应应用 SemVer 字符串。你怎么能确定代码/构建脚本更改是否破坏了任何东西?


预构建标签不起作用。能够连续两次复制完全相同的输出的构建过程是极其罕见的,如果有的话。在世界上拥有多个 API/包并附加相同的 SemVer 字符串是违反最佳实践的。如果您标记 repo 内容,然后将该标签转发到构建输出,则每次运行构建时,都会生成具有不同内容的包。总会有一些风险,即不止一种产出会被释放到野外。许多有安全意识的消费者密切关注他们消费的包裹的内容哈希。检测到特定的生产者已经发布了多个包哈希值而没有增加版本号,将引发危险信号并导致对该生产者内部流程的不信任。


这是一个非常深奥的话题,在这里无法完全涵盖。其他需要考虑的问题是操作系统/编译器/工具链更新。您还会将整个构建工具链提交到同一个仓库吗?这是一种站不住脚的方法,充满了我无法完全列举的危险,如果不花几个月的时间来记录它们。

最佳实践:

  • 使用明确说明开发人员意图的语义提交消息。
  • 在包装/贴标签之前验证构建输出。
  • 对于非预发布出版物,始终让人类参与其中。

为清楚起见,让我补充一点,在存储库中维护构建脚本和工具清单被认为是最佳实践。它将您的脚本和工具的版本与您正在构建的代码的版本联系起来。Git 通过创建包含整个 repo 状态的提交哈希(如果我没记错的话,减去标签)确实很好地完成了这项工作。但最终会出现问题,旧版本的工具会从文件共享/提要中退出,特别是当它们被发现会造成安全漏洞时。

有时会出现这样的情况,即您的产品的较旧版本无法使用较早的构建过程进行复制。签入二进制文件通常被宣传为解决此问题,但我认为这是一种反模式。您将来可能永远不会想要或需要的二进制文件不应存储在您的存储库中。它只会堵塞一切。

考虑使用备用存档系统。维护旧工具的单独存档并不是一个坏主意,但您经常会发现,如果不对构建机器进行重大重新配置并重新引入众所周知的安全风险,您就无法在当前硬件和操作系统上运行它们. 您应该经常根据最新的已知风险和权衡必须做一些额外工作的成本来修剪这样的档案,如果/当那一天到来时,您需要从一个非常旧的提交哈希构建。

最好维护一个最新的构建系统,它可以构建你所有的代码库,回到它历史上的某个合理点。这一点通常是您愿意通过错误修复积极支持的最古老的部分。


推荐阅读