产品流水线¶
产品流水线 回答了一个更具挑战性的问题:我的“产品”是否能用新版本的包正确构建?以及它们的依赖项呢?这才是真正的“持续集成”部分,其中不同包的变化真正地针对组织的重要产品进行测试,以检查集成是否干净或是否中断。
让我们继续上面的例子,如果我们现在有一个新的 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 级别表示给定包的依赖方或消费者。在我们的例子中,如果我们在 CI 系统中为构建 ai
包配置了一个作业,我们可以为 engine
包配置另一个作业,它在 ai
作业之后触发,从而在 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
新二进制文件。在以下部分中,我们将以增量方式介绍产品流水线,就像包流水线一样。