Products pipeline¶
产品流水线 回答了一个更具挑战性的问题:我的“产品”是否能使用软件包的新版本正确构建?针对软件包及其依赖项?这是真正的“持续集成”部分,其中不同软件包的更改会真正针对组织重要的产品进行测试,以检查集成是否顺利或出现故障。
让我们继续使用上面的例子,如果现在有一个新的 ai/1.1.0 软件包,它是否会破坏现有的 game/1.0 和/或 mapviewer/1.0 应用程序?是否需要从源代码重新构建一些直接或间接依赖于 ai 软件包的现有软件包?在本教程中,我们将使用 game/1.0 和 mapviewer/1.0 作为我们的“产品”,但这个概念将在稍后进一步解释,特别是为什么重要的是以“产品”为单位进行思考,而不是试图在 CI 中明确建模自上而下的依赖关系。
在这个例子中,这个 产品流水线 的本质是,上传到 products 仓库的新 ai/1.1.0 版本会自动落入有效的版本范围内,并且我们的版本控制方法意味着这种小版本增量将需要构建其消费者(在本例中为 engine/1.0 和 game/1.0)的源代码,并且按照特定的顺序进行,而所有其他软件包将保持不变。了解哪些软件包需要从源代码构建以及构建顺序,并执行该构建以检查主要组织产品是否能继续与新的依赖项版本正常工作,是产品流水线的责任。
什么是 产品¶
产品 是一个组织(公司、团队、项目)交付的最终软件制品,并为这些制品的用户提供价值。 在这个例子中,我们将 game/1.0 和 mapviewer/1.0 视为“产品”。 请注意,可以定义相同软件包的不同版本作为产品,例如,如果我们需要为不同的客户维护 game 的不同版本,我们可以拥有 game/1.0 和 game/2.3 以及 mapviewer 的不同版本作为产品。
“产品”方法除了关注业务价值的优势外,还有另一个非常重要的优势:它避免了在 CI 层建模依赖图。 试图建模反向依赖关系是一种常见的尝试,即在 CI 级别表示给定软件包的依赖项或消费者。 在我们的例子中,如果我们为构建 ai 软件包配置了一个作业,我们可以为 engine 软件包配置另一个作业,该作业在 ai 作业之后触发,以某种方式在 CI 系统中配置这种拓扑结构。
但是这种方法根本无法扩展,并且存在非常重要的限制
上面的例子相对简单,但在实践中,依赖图可能包含更多的软件包,甚至数百个软件包,这使得在 CI 中定义所有软件包之间的依赖关系变得非常繁琐且容易出错。
依赖关系会随着时间的推移而演变,并使用新版本,一些依赖关系会被删除,并添加新的依赖关系。 在 CI 级别建模的仓库之间的简单关系可能会导致非常低效、缓慢且耗时的 CI,甚至是一个不断崩溃的 CI,因为某些依赖关系发生了变化。
依赖图下游发生的组合性质,其中一个相对稳定的顶级依赖项,比如
mathlib/1.0可能会被多个消费者使用,比如ai/1.0、ai/1.1、ai/1.2,而这些又每个都可能被多个engine不同版本使用,依此类推。 在许多情况下,仅构建消费者的最新版本是不够的,而构建所有版本则成本极高。“反向”依赖模型,即询问给定软件包的“依赖项”是什么,在实践中极具挑战性,尤其是在像 Conan 这样的去中心化方法中,软件包可以存储在不同的仓库中,包括不同的服务器,并且没有所有软件包及其关系的中央数据库。 此外,“反向”依赖模型与直接依赖模型类似,也是有条件的。 由于依赖关系可以依赖于任何配置(设置、选项),因此反向依赖关系也受到相同逻辑的约束,并且这种逻辑也会随着每次新的修订和版本而演变和变化。
在 C 和 C++ 项目中,“产品”流水线比其他语言更必要和关键,这归因于带有文本包含的头文件成为消费者二进制工件的一部分的编译模型,以及本机工件链接模型。
构建中间软件包的新二进制文件¶
一个经常被问到的问题是,当它构建针对新依赖项版本时,消费者软件包的版本会是什么。 明确地说明我们的例子,我们已经定义了我们需要重新构建 engine/1.0 软件包,因为它现在依赖于 ai/1.1.0 新版本
我们应该创建一个新的
engine/1.1版本来构建针对新的ai/1.1.0吗?或者我们应该保留
engine/1.0版本?
答案在于 二进制模型以及依赖项如何影响 package_id。 Conan 具有一个二进制模型,该模型考虑了依赖项的版本、修订版和 package_id,以及不同的软件包类型(package_type 属性)。
建议保持软件包版本与源代码一致。 如果 engine/1.0 是从其源代码仓库的特定提交/标签构建的,并且该源代码没有发生任何变化,那么拥有与源代码版本不同的变化的软件包版本会非常令人困惑。 使用 Conan 二进制模型,我们将为 engine/1.0 拥有 2 个不同的二进制文件,具有 2 个不同的 package_id。 一个二进制文件将构建针对 ai/1.0 版本,另一个二进制文件将构建针对 ai/1.1.0,类似于
$ conan list engine:* -r=develop
engine/1.0
revisions
fba6659c9dd04a4bbdc7a375f22143cb (2024-08-22 09:46:24 UTC)
packages
2c5842e5aa3ed21b74ed7d8a0a637eb89068916e
info
settings
...
requires
ai/1.0.Z
graphics/1.0.Z
mathlib/1.0.Z
de738ff5d09f0359b81da17c58256c619814a765
info
settings
...
requires
ai/1.1.Z
graphics/1.0.Z
mathlib/1.0.Z
让我们看看产品流水线如何使用新的依赖项版本构建这些 engine/1.0 和 game/1.0 新二进制文件。 在接下来的章节中,我们将以增量方式呈现一个产品流水线,就像软件包流水线一样。