产品流水线¶
产品流水线 回答了一个更具挑战性的问题:我的“产品”是否能使用软件包的新版本正确构建?是否能与软件包及其依赖项正确构建?这是真正的“持续集成”部分,其中针对组织的重要产品真正测试不同软件包中的更改,以检查事物是否干净地集成或是否发生中断。
让我们继续上面的例子,如果我们现在有一个新的 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 二进制模型,我们将拥有 2 个不同的 engine/1.0
二进制文件,具有 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
新二进制文件。在接下来的章节中,我们将以增量方式介绍产品流水线,与软件包流水线相同。