本文介绍如何在 GitLab 上为 C++ 项目配置 CI 流水线。我之前的文章 介绍了如何基于 CMake 和 VSCodium 设置构建系统,以及如何集成基于 GoogleTest 和 CTest 的单元测试。本文是对扩展配置以使用 CI 流水线的后续介绍。首先,我将演示流水线设置及其执行。接下来是 CI 配置本身。
持续集成 (CI) 简单来说就是指提交到中央代码仓库的代码更改会被自动构建和测试。在开源领域中,用于设置 CI 流水线的流行平台是 GitLab。除了中央 Git 代码仓库,GitLab 还提供 CI/CD 流水线配置、问题跟踪和容器注册表。
术语须知
在深入探讨 DevOps 哲学的这个领域之前,我将先解释本文和 GitLab 文档中遇到的一些常用术语
- 持续交付 (CD):自动配置应用程序,旨在部署它们。
- 持续部署 (CD):自动发布软件
- 流水线:CI/CD 的顶层组件,定义阶段和作业
- 阶段:必须成功执行的作业集合
- 作业:任务的定义(例如,编译,执行单元测试)
- Runner:实际执行作业的服务
设置 CI 流水线
我将重用之前文章中的示例项目,这些项目在 GitLab 上可用。要按照后续章节中描述的步骤操作,请单击右上角的 Fork 按钮,fork 示例项目

Stephan Avenwedde (CC BY-SA 4.)
设置 runner
要了解所有组件如何协同工作,请从最底层开始,在本地系统上安装 runner。
请按照适用于您系统的 GitLab runner 服务的安装说明进行操作。安装完成后,您必须注册 runner。
1. 在 GitLab 页面上,选择项目,然后在左侧窗格中,导航至 设置 并选择 CI/CD。

Stephan Avenwedde (CC BY-SA 4.0)
2. 展开 Runner 部分,并将 共享 Runner 切换为关闭(黄色标记)。请注意令牌和 URL(绿色标记);我们将在下一步中使用它们。

Stephan Avenwedde (CC BY-SA 4.0)
3. 现在打开终端并输入 gitlab-runner register
。该命令会调用一个脚本,该脚本会要求您输入一些信息。以下是答案
- GitLab 实例:https://gitlab.com/(如上截图所示)
- 注册令牌:从 Runner 部分选取(如上截图所示)
- 描述:可自由选择
- 标签:这是可选的。您无需提供标签
- 执行器:此处选择 Shell
如果您以后想修改配置,可以在 ~/.gitlab-runner/config.toml
中找到它。
4. 现在,使用命令 gitlab-runner run
启动 runner。runner 现在正在等待作业。您的 runner 现在在 GitLab 项目设置的 Runner 部分中可用

Stephan Avenwedde (CC BY-SA 4.0)
执行流水线
如前所述,流水线是由 runner 执行的作业集合。每次推送到 GitLab 的提交都会生成附加到该提交的流水线。如果一起推送多个提交,则仅为最后一个提交创建流水线。为了演示目的启动流水线,请直接通过 GitLab 的 Web 编辑器提交并推送更改。
对于第一个测试,打开 README.md
并添加一行

Stephan Avenwedde (CC BY-SA 4.0)
现在提交您的更改。
请注意,默认设置为 创建新分支。为了简单起见,请选择 提交到主分支。

Stephan Avenwedde (CC BY-SA 4.0)
提交后几秒钟,您应该会在 GitLab runner 执行的控制台窗口中注意到一些输出
Checking for jobs... received job=1975932998 repo_url=https://gitlab.com/hANSIc99/cpp_testing_sample.git runner=Z7MyQsA6
Job succeeded duration_s=3.866619798 job=1975932998 project=32818130 runner=Z7MyQsA6
在 GitLab 的项目概览中,在右侧窗格中选择 CI/CD --> 流水线。您可以在此处找到最近执行的流水线列表。

Stephan Avenwedde (CC BY-SA 4.0)
如果您选择一个流水线,您将获得详细的概览,您可以在其中检查哪个作业失败(如果流水线失败),并查看各个作业的输出。
如果返回非零值,则认为作业已失败。在以下情况下,我只是调用了 bash 命令 exit 1
(第 26 行)以使作业失败

Stephan Avenwedde (CC BY-SA 4.0)
CI 配置
阶段、流水线和作业配置在仓库根目录下的 .gitlab-ci.yml 文件中进行。我建议使用 GitLab 的内置流水线编辑器编辑配置,因为它会在编辑过程中自动检查准确性。
stages:
- build
- test
build:
stage: build
script:
- cmake -B build -S .
- cmake --build build --target Producer
artifacts:
paths:
- build/Producer
RunGTest:
stage: test
script:
- cmake -B build -S .
- cmake --build build --target GeneratorTest
- build/Generator/GeneratorTest
RunCTest:
stage: test
script:
- cmake -B build -S .
- cd build
- ctest --output-on-failure -j6
该文件定义了 build 和 test 阶段。接下来,它定义了三个作业:build、RunGTest 和 RunCTest。build 作业分配给同名阶段,而其他作业分配给 test 阶段。
script 部分下的命令是普通的 shell 命令。您可以像在 shell 中逐行键入它们一样阅读它们。
我想指出一个特殊功能:artifacts(工件)。在本例中,我将 Producer 二进制文件定义为 build 作业的工件。工件被上传到 GitLab 服务器,可以从那里下载

Stephan Avenwedde (CC BY-SA 4.0)
默认情况下,稍后阶段的作业会自动下载早期阶段作业创建的所有工件。
gitlab-ci.yml
参考文档可在 docs.gitlab.com 上找到。
总结
上面的示例是一个基本的示例,但它展示了持续集成的基本原理。在上面关于设置 runner 的部分中,我禁用了共享 runner,但这实际上是 GitLab 的优势所在。您可以在干净的容器化环境中构建、测试和部署您的应用程序。除了 GitLab 提供的免费月度配额的免费 runner 之外,您还可以提供您自己的基于容器的自托管 runner。当然,还有一种更高级的方法:您可以使用 Kubernetes 编排基于容器的 runner,这使您可以自由地扩展流水线的处理能力。您可以在 about.gitlab.com 上阅读更多相关信息。
由于我运行的是 Fedora,我必须提到 Podman 尚不支持作为 GitLab runner 的容器引擎。根据 gitlab-runner 问题 #27119,Podman 支持已在列表中。
将重复步骤描述为作业并将它们组合在流水线和阶段中,使您能够跟踪它们的质量,而不会造成额外的工作。尤其是在大型社区项目中,您必须决定是否接受或拒绝合并请求,配置正确的 CI 方法可以告诉您提交的代码是会改进还是会 ухудшить 项目。
评论已关闭。