CI 配置内部机制
工作流规则
GitLab 项目的流水线通过 GitLab CI/CD 的 workflow:rules 关键字 功能创建。
以下场景始终会创建流水线:
main分支(包括定时任务、推送、合并等操作)- 合并请求
- 标签
- 稳定版、
auto-deploy和安全分支
流水线创建还受以下 CI/CD 变量影响:
- 若设置
$FORCE_GITLAB_CI,则创建流水线(不推荐使用)。详见 避免$FORCE_GITLAB_CI。 - 若未设置
$GITLAB_INTERNAL,则不创建流水线。
其他任何情况(例如推送无对应合并请求的分支)均不创建流水线。
这些工作流规则的权威定义在 .gitlab-ci.yml 中。
避免 $FORCE_GITLAB_CI
流水线非常复杂,我们需要明确要触发的流水线类型,清楚知道应运行哪些作业、不应运行哪些作业。
若使用 $FORCE_GITLAB_CI 强制触发流水线,我们实际上无法确定流水线类型。可能导致未运行目标作业,或运行了过多无关作业。
更多背景信息请参考:避免 blanket changes to avoid unexpected run
以下是目前使用 $FORCE_GITLAB_CI 的位置列表,应逐步移除其使用:
下一节将介绍如何在不使用 $FORCE_GITLAB_CI 的情况下启用流水线。
$FORCE_GITLAB_CI 替代方案
本质上,我们通过不同变量启用不同流水线。例如 $START_AS_IF_FOSS:当需要触发跨项目 FOSS 流水线时,设置 $START_AS_IF_FOSS,并配合 $ENABLE_RSPEC_UNIT、ENABLE_RSPEC_SYSTEM 等变量,以启用 as-if-foss 跨项目下游流水线中需要运行的具体作业。
相比 $FORCE_GITLAB_CI 的优势在于:$START_AS_IF_FOSS 专为此用途设计,可完全控制流水线行为;而 $FORCE_GITLAB_CI 因用于多种目的,无法确定具体触发的流水线类型。
默认镜像
默认镜像定义在 .gitlab-ci.yml。
包含 Ruby、Go、Git、Git LFS、Chrome、Node、Yarn、PostgreSQL 和 Graphics Magick。
流水线使用的镜像配置在 gitlab-org/gitlab-build-images 项目中,该项目通过推送镜像到 gitlab/gitlab-build-images 实现冗余。
当前构建镜像版本可在 “Used by GitLab 部分” 查看。
默认变量
除 预定义 CI/CD 变量 外,每个流水线还包含 .gitlab-ci.yml 中定义的默认变量。
变量命名
自 2025 年 3 月起,新添加的专用于单体 CI 流水线的环境变量将以 GLCI_ 为前缀。
这有助于区分环境变量的用途:CI(GLCI_)、产品(GITLAB_)或非我们拥有的工具和系统。从而更好地评估流水线配置中环境变量变更的影响。
阶段(Stages)
当前阶段包括:
sync:用于将变更从gitlab-org/gitlab同步到gitlab-org/gitlab-foss。prepare:包含为后续阶段作业准备产物的作业。build-images:包含为后续阶段作业或下游流水线准备 Docker 镜像的作业。fixtures:包含为前端测试准备 fixtures 的作业。lint:包含代码检查和静态分析作业。test:包含大部分测试及数据库/迁移作业。post-test:包含从test阶段作业构建报告或收集数据的作业(例如覆盖率、Knapsack 元数据等)。review:包含构建 CNG 镜像、部署并针对预览应用运行端到端测试的作业(详见 预览应用),还包括文档预览应用作业。qa:包含针对review阶段部署的预览应用执行 QA 任务的作业。post-qa:包含从qa阶段作业构建报告或收集数据的作业(例如预览应用性能报告)。pages:包含将各种报告部署为 GitLab Pages 的作业(例如coverage-ruby和webpack-report(位于https://gitlab-org.gitlab.io/gitlab/webpack-report/,但存在 部署问题))。notify:包含向 Slack 通知各类失败的作业。
依赖代理(Dependency Proxy)
部分作业使用 Docker Hub 的镜像,同时使用 ${GITLAB_DEPENDENCY_PROXY_ADDRESS} 作为镜像路径前缀,以便从我们的 依赖代理 拉取镜像。默认情况下,该变量从 ${GITLAB_DEPENDENCY_PROXY} 的值设置。
CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX是 GitLab 预定义 CI/CD 变量,提供通过依赖代理拉取镜像的顶级组镜像前缀。GITLAB_DEPENDENCY_PROXY是gitlab-org和gitlab-com组中的 CI/CD 变量,定义为${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/。GITLAB_DEPENDENCY_PROXY_ADDRESS在gitlab-org/gitlab项目中定义,默认为"${GITLAB_DEPENDENCY_PROXY}",但在某些情况下会被覆盖(见下文解决方法部分)。
在 gitlab-org/gitlab 中,我们因 解决方法 使用 GITLAB_DEPENDENCY_PROXY_ADDRESS。在 gitlab-org 和 gitlab-com 组的其他任何地方,应使用 GITLAB_DEPENDENCY_PROXY 启用依赖代理。对于其他项目,可依赖 CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX 预定义 CI/CD 变量启用依赖代理:
# 在 gitlab-org/gitlab 项目中
image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}alpine:edge
# 在 gitlab-org 和 gitlab-com 组的其他任何项目中
image: ${GITLAB_DEPENDENCY_PROXY}alpine:edge
# 在 gitlab-org 和 gitlab-com 组之外的项目中
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine:edge位于任何其他个人命名空间或组中的 fork 除非在本地也定义了 GITLAB_DEPENDENCY_PROXY,否则会回退到 Docker Hub。
当流水线由项目访问令牌用户启动时的解决方法
当流水线由项目访问令牌用户启动时(例如自动更新主项目中 Gitaly 版本的 release-tools approver bot 用户),依赖代理不可访问,作业在 “Preparing the “docker+machine” executor” 步骤失败。为此,我们添加特殊工作流规则覆盖 ${GITLAB_DEPENDENCY_PROXY_ADDRESS} 变量,避免使用依赖代理:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $GITLAB_USER_LOGIN =~ /project_\d+_bot\d*/'
variables:
GITLAB_DEPENDENCY_PROXY_ADDRESS: ""我们不直接覆盖 ${GITLAB_DEPENDENCY_PROXY} 变量,因为组级变量优先级高于 .gitlab-ci.yml 变量。
外部 CI/CD 密钥
作为 https://gitlab.com/groups/gitlab-org/quality/engineering-productivity/-/epics/46 的一部分,2024 年 2 月起我们开始自用 GCP Secret Manager 来 存储 ADD_JH_FILES_TOKEN CI 变量。
为此,创建了 qual-ci-secret-mgmt-e78c9b95 GCP 项目。
通用作业定义
大多数作业 [扩展自 .gitlab/ci/global.gitlab-ci.yml 中定义的少数 CI 定义](../../ci/yaml/_index.md#extends),这些定义作用于单个 配置关键字。
| 作业定义 | 描述 |
|---|---|
.default-retry |
允许作业在 unknown_failure、api_failure、runner_system_failure、job_execution_timeout 或 stuck_or_timeout_failure 时 重试。 |
.default-before_script |
允许作业使用适用于需要运行数据库的 Ruby/Rails 任务(如测试)的默认 before_script 定义。 |
.repo-from-artifacts |
允许作业从 clone-gitlab-repo 的产物中获取仓库而非克隆。这可减少 GitLab.com Gitaly 负载,并因从产物下载快于克隆而略微提升速度。注意应避免与 needs: [] 的作业一起使用,否则作业启动延迟,而我们通常希望所有作业尽快启动。仅在有其他依赖的作业上使用,避免等待时间比克隆更长。此行为可通过 CI_FETCH_REPO_GIT_STRATEGY 控制。详情见 通过产物而非从 Gitaly 克隆/拉取获取仓库。 |
.setup-test-env-cache |
允许作业使用适用于为后续 Ruby/Rails 任务设置测试环境的默认 cache 定义。 |
.ruby-cache |
允许作业使用适用于 Ruby 任务的默认 cache 定义。 |
.static-analysis-cache |
允许作业使用适用于静态分析任务的默认 cache 定义。 |
.qa-cache |
允许作业使用适用于 QA 任务的默认 cache 定义。 |
.yarn-cache |
允许作业使用适用于执行 yarn install 的前端任务的默认 cache 定义。 |
.assets-compile-cache |
允许作业使用适用于编译资源的前端任务的默认 cache 定义。 |
.use-pg14 |
允许作业使用 postgres 14、redis 和 rediscluster 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-pg14-ee |
同 .use-pg14,但额外使用 elasticsearch 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-pg15 |
允许作业使用 postgres 15、redis 和 rediscluster 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-pg15-ee |
同 .use-pg15,但额外使用 elasticsearch 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-pg16 |
允许作业使用 postgres 16、redis 和 rediscluster 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-pg16-ee |
同 .use-pg16,但额外使用 elasticsearch 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-pg17 |
允许作业使用 postgres 17、redis 和 rediscluster 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-pg17-ee |
同 .use-pg17,但额外使用 elasticsearch 服务(具体版本见 .gitlab/ci/global.gitlab-ci.yml)。 |
.use-buildx |
允许作业使用 docker buildx 工具构建 Docker 镜像。 |
.as-if-foss |
通过设置 FOSS_ONLY='1' CI/CD 变量模拟 FOSS 项目。 |
.use-docker-in-docker |
允许作业使用 Docker in Docker。详情见 CI/CD 配置手册。 |
rules、if: 条件和 changes: 模式
我们广泛使用 rules 关键字。
所有 rules 定义在 rules.gitlab-ci.yml 中定义,然后通过 extends 包含在具体作业中。
rules 定义由 if: 条件和 changes: 模式组成,这些也在 rules.gitlab-ci.yml 中定义,并通过 YAML 锚点 包含在 rules 定义中。
if: 条件
if: 条件 |
描述 | 备注 |
|---|---|---|
if-not-canonical-namespace |
当项目不在规范命名空间(gitlab-org/ 和 gitlab-cn/)或安全命名空间(gitlab-org/security)时匹配。 |
用于为 fork 创建作业(使用 when: on_success 或 when: manual),或不为 fork 创建作业(使用 when: never)。 |
if-not-ee |
当项目非 EE 版(项目名非 gitlab 或 gitlab-ee)时匹配。 |
仅用于 FOSS 项目创建作业(使用 when: on_success 或 when: manual),或不为 EE 项目创建作业(使用 when: never)。 |
if-not-foss |
当项目非 FOSS 版(项目名非 gitlab-foss、gitlab-ce 或 gitlabhq)时匹配。 |
仅用于 EE 项目创建作业(使用 when: on_success 或 when: manual),或不为 FOSS 项目创建作业(使用 when: never)。 |
if-default-refs |
当流水线针对 master、main、/^[\d-]+-stable(-ee)?$/(稳定分支)、/^\d+-\d+-auto-deploy-\d+$/(自动部署分支)、/^security\//(安全分支)、合并请求或标签时匹配。 |
注意:默认配置下不会为分支创建作业。 |
if-master-refs |
当当前分支为 master 或 main 时匹配。 |
|
if-master-push |
当当前分支为 master 或 main 且流水线源为 push 时匹配。 |
|
if-master-schedule-maintenance |
当当前分支为 master 或 main 且流水线按 2 小时计划运行时匹配。 |
|
if-master-schedule-nightly |
当当前分支为 master 或 main 且流水线按夜间计划运行时匹配。 |
|
if-auto-deploy-branches |
当当前分支为自动部署分支时匹配。 | |
if-master-or-tag |
当流水线针对 master 或 main 分支或标签时匹配。 |
|
if-merge-request |
当流水线针对合并请求时匹配。 | |
if-merge-request-title-as-if-foss |
当流水线针对合并请求且 MR 有标签 ~"pipeline:run-as-if-foss" 时匹配。 |
|
if-merge-request-title-update-caches |
当流水线针对合并请求且 MR 有标签 ~"pipeline:update-cache" 时匹配。 |
|
if-merge-request-labels-run-all-rspec |
当流水线针对合并请求且 MR 有标签 ~"pipeline:run-all-rspec" 时匹配。 |
|
if-merge-request-labels-run-cs-evaluation |
当流水线针对合并请求且 MR 有标签 ~"pipeline:run-CS-evaluation" 时匹配。 |
|
if-security-merge-request |
当流水线针对安全合并请求时匹配。 | |
if-security-schedule |
当流水线针对安全计划流水线时匹配。 | |
if-nightly-master-schedule |
当流水线针对设置了 $NIGHTLY 的 master 计划流水线时匹配。 |
|
if-dot-com-gitlab-org-schedule |
限制仅在 GitLab.com 上 gitlab-org 组的计划流水线中创建作业。 |
|
if-dot-com-gitlab-org-master |
限制仅在 GitLab.com 上 gitlab-org 组的 master 或 main 分支中创建作业。 |
|
if-dot-com-gitlab-org-merge-request |
限制仅在 GitLab.com 上 gitlab-org 组的合并请求中创建作业。 |
|
if-dot-com-ee-schedule |
限制仅在 GitLab.com 上 gitlab-org/gitlab 项目的计划流水线中创建作业。 |
changes: 模式
changes: 模式 |
描述 |
|---|---|
ci-patterns |
仅针对 CI 配置相关变更创建作业。 |
ci-build-images-patterns |
仅针对 build-images 阶段相关的 CI 配置变更创建作业。 |
ci-review-patterns |
仅针对 review 阶段相关的 CI 配置变更创建作业。 |
ci-qa-patterns |
仅针对 qa 阶段相关的 CI 配置变更创建作业。 |
yaml-lint-patterns |
仅针对 YAML 相关变更创建作业。 |
docs-patterns |
仅针对文档相关变更创建作业。 |
frontend-dependency-patterns |
仅当前端依赖更新时创建作业(例如 package.json 和 yarn.lock 变更)。 |
frontend-patterns-for-as-if-foss |
仅对影响 FOSS 的前端相关变更创建作业。 |
backend-patterns |
仅针对后端相关变更创建作业。 |
db-patterns |
仅针对数据库相关变更创建作业。 |
backstage-patterns |
仅针对 backstage 相关变更创建作业(即 Danger、fixtures、RuboCop、specs)。 |
code-patterns |
仅针对代码相关变更创建作业。 |
qa-patterns |
仅针对 QA 相关变更创建作业。 |
code-backstage-patterns |
code-patterns 和 backstage-patterns 的组合。 |
code-qa-patterns |
code-patterns 和 qa-patterns 的组合。 |
code-backstage-qa-patterns |
code-patterns、backstage-patterns 和 qa-patterns 的组合。 |
static-analysis-patterns |
仅针对静态分析配置相关变更创建作业。 |
自定义退出码
GitLab CI 使用自定义退出码对作业失败类型进行分类,有助于自动化失败跟踪和重试逻辑。查看触发自动重试的退出码,请参考 GitLab 全局 CI 配置中的重试规则。
下表列出当前退出码及其含义:
| 退出码 | 描述 |
|---|---|
| 110 | 网络连接错误 |
| 111 | 磁盘空间不足 |
| 112 | 已知的不可靠测试失败 |
| 160 | 上传/下载作业产物失败 |
| 161 | 5XX 服务器错误 |
| 162 | Gitaly 启动失败 |
| 163 | RSpec 作业超时 |
| 164 | Redis 集群错误 |
| 165 | 段错误 |
| 166 | EEXIST: 文件已存在 |
| 167 | gitlab.com 过载 |
| 168 | gRPC 资源耗尽 |
| 169 | SQL 查询限制 exceeded |
| 170 | SQL 表被写保护 |
随着新失败模式的出现,此列表可扩展。为避免与标准 Bash 退出码冲突,新自定义码必须为 160 或更高。
最佳实践
何时使用 extends:、<<: *xyz(YAML 锚点)或 !reference
关键要点
- 若需扩展哈希,应使用
extends - 若需扩展数组,需使用
!reference,或作为最后手段使用YAML 锚点 - 对于更复杂的情况(例如扩展数组内的哈希、扩展哈希内的数组等),必须使用
!reference或YAML 锚点
extends 和 YAML 锚点能做什么?
extends
- 哈希的深度合并
- 数组不合并,会覆盖(来源)
YAML 锚点
- 哈希不深度合并,但可用于扩展哈希(见下例)
- 数组不合并,但可用于扩展数组(见下例)
一个优秀示例
此示例展示如何使用 !reference 和 YAML 锚点扩展复杂 YAML 数据结构:
.strict-ee-only-rules:
# `rules` 是哈希数组
rules:
- if: '$CI_PROJECT_NAME !~ /^gitlab(-ee)?$/ '
when: never
# `if-security-merge-request` 是哈希
.if-security-merge-request: &if-security-merge-request
if: '$CI_PROJECT_NAMESPACE == "gitlab-org/security"'
# `code-qa-patterns` 是数组
.code-qa-patterns: &code-qa-patterns
- "{package.json,yarn.lock}"
- ".browserslistrc"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
.qa:rules:as-if-foss:
rules:
# 我们直接扩展哈希数组
- !reference [".strict-ee-only-rules", rules]
# 我们用哈希扩展单个数组项
- <<: *if-security-merge-request
# `changes` 是数组,因此传递整个数组
changes: *code-qa-patterns
qa:selectors-as-if-foss:
# 我们将 .qa:rules:as-if-foss 的规则包含在此作业中
extends:
- .qa:rules:as-if-foss扩展 .fast-no-clone-job 作业
为规范项目下载分支需 20-30 秒。
部分作业仅需有限文件,可通过 GitLab API 下载。
可通过向作业添加以下模式跳过 git clone/git fetch:
场景 1:作业中未定义 before_script
此规则也适用于作业扩展的父部分。
只需扩展 .fast-no-clone-job:
修改前:
# 注意:作业中无 `extends:`
a-job:
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "无需 git clone!"修改后:
# 注意:作业中无 `extends:`
a-job:
extends:
- .fast-no-clone-job
variables:
FILES_TO_DOWNLOAD: >
scripts/rspec_helpers.sh
scripts/slack
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "无需 git clone!"场景 2:作业中已定义 before_script 块(或其扩展的作业中)
此场景需:
- 如场景 1 扩展
.fast-no-clone-job(这将合并FILES_TO_DOWNLOAD变量与其他变量) - 确保
.fast-no-clone-job的before_script部分引用到作业使用的before_script中
修改前:
.base-job:
before_script:
echo "来自 .base-job 的问候"
a-job:
extends:
- .base-job
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "无需 git clone!"修改后:
.base-job:
before_script:
echo "来自 .base-job 的问候"
a-job:
extends:
- .base-job
- .fast-no-clone-job
variables:
FILES_TO_DOWNLOAD: >
scripts/rspec_helpers.sh
scripts/slack
before_script:
- !reference [".fast-no-clone-job", before_script]
- !reference [".base-job", before_script]
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "无需 git clone!"注意事项
- 若脚本依赖
git访问仓库,此模式无效(因无克隆或拉取的仓库) - 使用此模式的作业需有
curl可用 - 若作业中需运行
bundle install(即使使用BUNDLE_ONLY),需:- 下载存储在
gitlab-org/gitlab项目中的 gem- 可使用
download_local_gemsshell 命令
- 可使用
- 包含
Gemfile、Gemfile.lock和Gemfile.checksum(如适用)
- 下载存储在
此模式用于何处?
- 目前用于以下作业,且不阻塞私有仓库:
review-build-cng-env用于:GITALY_SERVER_VERSIONGITLAB_ELASTICSEARCH_INDEXER_VERSIONGITLAB_KAS_VERSIONGITLAB_PAGES_VERSIONGITLAB_SHELL_VERSIONscripts/trigger-build.rbVERSION
review-deploy用于:GITALY_SERVER_VERSIONGITLAB_SHELL_VERSIONscripts/review_apps/review-apps.shscripts/review_apps/seed-dast-test-data.shVERSION
rspec:coverage用于:config/bundler_setup.rbGemfileGemfile.checksumGemfile.lockscripts/merge-simplecovspec/simplecov_env_core.rbspec/simplecov_env.rb
prepare-as-if-foss-env用于:scripts/setup/generate-as-if-foss-env.rb
此外,使用此模式时始终从 API 下载 scripts/utils.sh(此文件包含 .fast-no-clone-job 的代码)。
Runner 标签
在 GitLab.com 上,普通和特权 Runner 均可用。对于 gitlab-org 组中的项目及其 fork,作业应仅添加以下标签之一:
gitlab-org:作业随机使用普通和特权 Runner。gitlab-org-docker:作业必须使用特权 Runner。若需要 Docker-in-Docker 支持,使用gitlab-org-docker替代gitlab-org。
gitlab-org-docker 标签由上述 .use-docker-in-docker 作业定义添加。
为确保与 fork 兼容,避免同时使用 gitlab-org 和 gitlab-org-docker。无实例 Runner 同时具有这两个标签。对于 gitlab-org 项目的 fork,若同时提供两个标签,作业将卡住(因无匹配 Runner)。
更多信息请见 GitLab 仓库手册页面。
在规范项目中使用 gitlab Ruby gem
在规范项目中调用 require 'gitlab' 时,若 $LOAD_PATH 包含 lib(加载应用 config/application.rb 或测试 spec/spec_helper.rb 时会发生),将要求 lib/gitlab.rb 文件。
这意味着在上述条件下无法加载 gitlab gem,即使能加载,常量名也会冲突,破坏内部假设并导致随机错误。若正在使用 the gitlab Ruby gem 的脚本,需注意:
1 - 条件性 gem 引入
为避免潜在冲突,仅在 Gitlab 常量未定义时引入 gem:
# 错误
require 'gitlab'
# 正确
if Object.const_defined?(:RSpec)
# 测试中,我们知道要存根 `Gitlab`,直接忽略
else
require 'gitlab'
if Gitlab.singleton_class.method_defined?(:com?)
abort 'lib/gitlab.rb 已加载,这意味着我们无法再加载客户端,无法继续'
end
end2 - 在测试中完全模拟 gitlab gem
在测试中,require 'gitlab' 将引用 lib/gitlab.rb 文件:
# 错误
allow(GitLab).to receive(:a_method).and_return(...)
# 正确
client = double('GitLab')
# 为便于存根客户端,考虑使用返回客户端的方法。
# 然后可存根该方法返回我们的模拟客户端,进一步存根其方法。
#
# 以下遵循此模式
let(:instance) { described_class.new }
allow(instance).to receive(:gitlab).and_return(client)
allow(client).to receive(:a_method).and_return(...)若需查询作业等,以下片段有用:
# 错误
allow(GitLab).to receive(:pipeline_jobs).and_return(...)
# 正确
#
# rubocop:disable RSpec/VerifiedDoubles -- 我们不直接加载 Gitlab 客户端
client = double('GitLab')
allow(instance).to receive(:gitlab).and_return(client)
jobs = ['job1', 'job2']
allow(client).to yield_jobs(:pipeline_jobs, jobs)
def yield_jobs(api_method, jobs)
messages = receive_message_chain(api_method, :auto_paginate)
jobs.inject(messages) do |stub, job_name|
stub.and_yield(double(name: job_name))
end
end
# rubocop:enable RSpec/VerifiedDoubles3 - 不要用 bundle exec 执行脚本
使用 bundle exec 执行会改变 Ruby 的 $LOAD_PATH,调用 require 'gitlab' 时将加载 lib/gitlab.rb:
# 错误
bundle exec scripts/my-script.rb
# 正确
scripts/my-script.rbCI 配置测试
我们现在有 RSpec 测试来验证 CI 配置变更,通过使用更新后的 YAML 文件模拟流水线创建。这些测试及当前测试覆盖文档可在 spec/dot_gitlab_ci/job_dependency_spec.rb 中找到。
测试如何工作
借助 Ci::CreatePipelineService,我们可以模拟使用不同属性(如分支名、MR 标签、流水线源(计划 vs 推送)、流水线类型(合并列车 vs 合并结果)等)创建流水线。这是 GitLab CI Lint API 用于验证 CI/CD 配置的相同服务。
这些测试会针对更新 CI 配置的合并请求自动运行。但团队成员可通过在合并请求中添加标签 ~“pipeline:skip-ci-validation” 来跳过这些测试。
鼓励本地运行这些测试,因其提供最快反馈。