在 GitLab 上構建 CI 流水線
本文介紹如何在 GitLab 上配置 CI 流水線。我在前面的文章中介紹了 基于 CMake 和 VSCodium 的構建系統(tǒng) 和 基于 GoogleTest 和 CTest 的單元測試。本文將在此基礎上進一步配置 CI 流水線。我會先演示如何布設和運行 CI 流水線,然后再介紹如何配置它。
CI 是指提交到代碼倉庫的代碼變更會被自動構建和測試。在開源領域,GitLab 是一個流行的 CI 流水線平臺。除了作為中心 Git 倉庫外,GitLab 還提供 CI/CD 流水線、問題跟蹤issue tracking 和 容器注冊表container registry功能。
相關術語
在進入正題之前,我先介紹在本文和 GitLab 文檔 中會遇到的常見術語。
- 持續(xù)交付continuous delivery(CD):自動化供應軟件,以供隨時交付
- 持續(xù)部署continuous deployment(CD):自動化軟件發(fā)布
- 流水線pipeline: CI/CD 的直接構件,它由階段和作業(yè)構成
- 階段stage:一組作業(yè)
- 作業(yè)job:某項需要執(zhí)行的具體任務,比如編譯、單元測試等
- 執(zhí)行器runner:實際執(zhí)行作業(yè)的服務
布設 CI 流水線
在下面的章節(jié)中,我將復用以前的 示例工程。點擊 GitLab 倉庫頁面右上角的 復刻Fork
Fork the project
設置執(zhí)行器
為了讓你對整個流程有所了解,我們先從在本地安裝執(zhí)行器講起。
參照執(zhí)行器服務 安裝指南 安裝好服務,然后注冊執(zhí)行器。
1、選擇 GitLab 項目頁面左側的 設置Settings,再選擇 CI/CD。
Select CI/CD in Settings
2、展開 執(zhí)行器Runners 區(qū)域,關閉 共享的執(zhí)行器Shared runners
Configure runner
3、在終端中運行 gitlab-runner register
,根據(jù)提示輸入以下注冊信息:
- GitLab 實例: https://gitlab.com/ (如上圖)
- 注冊令牌:從執(zhí)行器區(qū)域中獲取 (如上圖)
- 描述:按需自由填寫
- 標簽:可以不填
- 執(zhí)行環(huán)境:選 Shell
如果有需要,你可以在 ~/.gitlab-runner/config.toml
中修改這些配置。
4、用命令 gitlab-runner run
啟動執(zhí)行器。你可以在 GitLab 的項目設置界面執(zhí)行器區(qū)域看到執(zhí)行器的狀態(tài):
Available specific runners
運行流水線
前面已經(jīng)提過,流水線就是一組由執(zhí)行器執(zhí)行的作業(yè)。每個推送到 GitLab 的提交都會生成一個附加到該提交的流水線。如果多個提交被一起推送,那么只會為最后一個提交生成流水線。為了演示,我直接在 GitLab 在線編輯器中提交和推送修改。
打開 README.md
文件,添加一行數(shù)據(jù):
Web editor
現(xiàn)在提交修改。
這里注意默認的行為是為提交新建一個分支,為了簡便起見,我們擇提交到主分支。
Commit changes
提交后一會兒后,你就應該改能看到 GitLab 執(zhí)行器執(zhí)行的控制臺中有輸出消息:
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 --> 管道Pipelines,查看最近執(zhí)行的流水線:
Pipeline overview
選中流水線可以在詳情界面看到哪些作業(yè)失敗了,并能查看各個作業(yè)的輸出。
當遇到非零返回值是就認為作業(yè)執(zhí)行失敗了。在下面的例子中我通過調(diào)用 exit 1
強制讓作業(yè)執(zhí)行失?。?/p>
Job overview
CI 配置
階段、流水線和作業(yè)的配置都在倉庫根目錄的 .gitlab-ci.yml 文件中。我建議使用 GitLab 內(nèi)置的流水線編輯器,它會自動對配置進行檢查。
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
,以及三個作業(yè):build
、RunGTest
和 RunCTest
。其中作業(yè) build
屬于一個同名的階段,另外兩個作業(yè)屬于階段 test
。
script
小節(jié)下的命令就是一般的 Shell 命令。你可以認為是將它們逐行輸入到 Shell 中。
我要特別提及 產(chǎn)物artifact 這個特性。在示例中我定義了二進制的 Producer
為作業(yè) build
的產(chǎn)物。產(chǎn)物會被上傳到 GitLab 服務器,并且可以從服務器的這個頁面上被下載:
Pipeline artifacts
默認情況下,后續(xù)階段的作業(yè)會自動下載先前階段作業(yè)生成的所有產(chǎn)物。
你可以在 docs.gitlab.com 上查看 gitlab-ci.yml
參考指南。
總結
上面只是一個最基本的例子,讓你對持續(xù)集成的一般原則有一個了解。再演示中我禁用了共享執(zhí)行器,然而這才是 GitLab 的優(yōu)勢所在。你可以在一個干凈的容器化的環(huán)境中構架、測試和部署程序。除了使用 GitLab 提供的免費執(zhí)行器,你也可以用自己的容器作為執(zhí)行器。當然還有更高階的用法:用 Kubernetes 來協(xié)調(diào)調(diào)度執(zhí)行者容器,讓流水線適應大規(guī)模使用的使用場景。如需進一步了解,可以查看 about.gitlab.com。
如果你使用的是 Fedora,需要注意的一點是目前 GitLab 執(zhí)行者還不支持用 Podman 作為容器引擎。(LCTT 譯注:Podman 是 Fedora 自帶的容器引擎。)根據(jù) 議題issue #27119,對 Podman 支持已將列上日程。(LCTT 譯注:Podman 4.2 及以上版本增加了對于 GitLab 執(zhí)行器的支持。)
把重復性的操作描述成作業(yè),并將作業(yè)合并成流水線和階段,可以讓你跟蹤它們的質(zhì)量而不增加額外工作。。特別是在大型社區(qū)項目中,適當配置的 CI 可以告訴你提交的代碼是否對項目有改善,為你接受或拒絕合并請求提供依據(jù)。