持续集成 (CI) 教程¶
注意
这是一个高级主题,需要事先了解 Conan 的知识。请先阅读并实践用户教程。
本节旨在为正在设计和实施涉及 Conan 软件包的 CI 流水线的 DevOps 和构建工程师而编写。如果不是这种情况,您可以跳过本节。
对于不同的用户和组织,持续集成具有不同的含义。在本教程中,我们将涵盖用户更改其软件包的源代码并希望自动为这些软件包构建新二进制文件,并计算这些新的软件包更改是否能干净地集成或破坏组织的主要产品的场景。
在本教程中,我们将使用这个小型项目,该项目使用多个软件包(默认情况下为静态库)来构建几个应用程序,一个视频游戏和一个地图查看器实用程序。game
和 mapviewer
是我们最终的“产品”,即我们分发给用户的内容
依赖关系图中的所有软件包都使用版本范围对其直接依赖项具有 requires
,例如,game
包含 requires("engine/[>=1.0 <2]")
,因此将自动使用依赖项的新补丁和次要版本,而无需修改配方。
注意
重要提示
本节编写为动手教程。旨在通过在您的机器上复制命令来重现。
本教程介绍了一些工具、良好实践和解决 CI 问题的常用方法。但没有万能的方法。本教程不是完成事情的唯一方法。不同的组织可能有不同的需求和优先级、不同的构建服务能力和预算、不同的规模等等。本教程中介绍的原则和实践可能需要进行调整。
如果您有任何问题或反馈,请在 https://github.com/conan-io/conan/issues 中提交新 issue
然而,一些原则和最佳实践对于所有方法都是通用的。诸如软件包不可变性、在仓库之间使用晋升以及不为此目的使用
channel
等都是应该遵循的良好实践。
软件包和产品流水线¶
当开发人员对软件包源代码进行一些更改时,我们将考虑整个系统 CI 的 2 个不同部分或流水线:软件包流水线和产品流水线
软件包流水线负责在单个软件包的代码更改时构建该软件包。如有必要,它将针对不同的配置进行构建。
产品流水线负责构建组织的主要“产品”(实现最终应用程序或交付物的软件包),并确保依赖项中的更改和新版本正确集成,并在必要时重建图中任何中间软件包。
想法是,如果某些开发人员更改了 ai
软件包,生成了新的 ai/1.1.0
版本,则软件包流水线将首先构建此新版本。但是,此新版本可能会意外破坏或需要重建某些使用者软件包。如果我们组织的主要产品是 game/1.0
和 mapviewer/1.0
,则可以触发产品流水线,在这种情况下,它将重建 engine/1.0
和 game/1.0
,因为它们受到更改的影响。
仓库和晋升¶
多个服务器端仓库的概念对于 CI 非常重要。在本教程中,我们将使用 3 个仓库
develop
:此仓库是开发人员在其机器中配置的主要仓库,以便能够conan install
依赖项并进行工作。因此,它有望非常稳定,类似于 git 中的共享“develop”分支,并且该仓库应包含组织预定义平台的预编译二进制文件,因此开发人员和 CI 不需要执行--build=missing
并一遍又一遍地从源代码构建。packages
:此仓库将用于临时上传由“软件包流水线”构建的软件包,而不是直接将它们上传到develop
仓库,并避免在这些软件包完全验证之前造成中断。products
:此仓库将用于临时上传由“产品流水线”构建的软件包,同时构建和测试新的依赖项更改不会破坏主要“产品”。
晋升是用于使软件包从一个流水线到另一个流水线可用的机制。将上述软件包和产品流水线与仓库连接起来,将有 2 个晋升
当使用
packages pipeline
为单个软件包构建了不同配置的所有不同二进制文件,并上传到packages
仓库后,软件包的新版本和更改可以被认为是“正确的”,并晋升(复制)到products
仓库。当
products pipeline
从源代码构建了由于products
仓库中新的软件包版本而需要重新构建的所有必要软件包,并检查了组织“产品”(例如game/1.0
和mapviewer/1.0
)没有损坏时,则可以将软件包从products
仓库晋升(复制)到develop
仓库,以使其可供所有其他开发人员和 CI 使用。
注意
不可变性的概念在软件包管理和 DevOps 中非常重要。强烈建议不要修改
channel
,请参阅 软件包晋升。版本控制方法非常重要。本教程将遵循默认的 Conan 版本控制方法,请在此处查看详细信息
本教程仅对开发流程进行建模。在生产系统中,将有其他仓库和晋升,例如 QA 团队的 testing
仓库和最终用户的最终 release
仓库,以便软件包可以在通过验证后从 develop
晋升到 testing
再到 release
。在 软件包晋升 中阅读有关晋升的更多信息。
让我们从本教程开始,转到下一节进行项目设置