使用其他文件中的 CI/CD 配置
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
您可以使用 include 在 CI/CD 作业中包含外部 YAML 文件。
包含单个配置文件
要包含单个配置文件,请单独使用 include 并选择以下任一语法选项:
-
在同一行:
include: 'my-config.yml' -
作为数组中的单个项目:
include: - 'my-config.yml'
如果文件是本地文件,其行为与 include:local 相同。如果文件是远程文件,则与 include:remote 相同。
包含配置文件数组
您可以包含配置文件数组:
-
如果未指定
include类型,每个数组项默认为include:local或include:remote,根据需要:include: - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml' - 'templates/.after-script-template.yml' -
您可以定义单个项目数组:
include: - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml' -
您可以定义数组并明确指定多个
include类型:include: - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml' - local: 'templates/.after-script-template.yml' - template: Auto-DevOps.gitlab-ci.yml -
您可以定义一个同时包含默认和特定
include类型的数组:include: - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml' - 'templates/.after-script-template.yml' - template: Auto-DevOps.gitlab-ci.yml - project: 'my-group/my-project' ref: main file: 'templates/.gitlab-ci-template.yml'
使用包含配置文件中的 default 配置
您可以在配置文件中定义一个 default 部分。当您将 default 部分与 include 关键字一起使用时,默认值将应用于管道中的所有作业。
例如,您可以将 default 部分与 before_script 一起使用。
名为 /templates/.before-script-template.yml 的自定义配置文件内容:
default:
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- gem install bundler --no-document
- bundle install --jobs $(nproc) "${FLAGS[@]}".gitlab-ci.yml 的内容:
include: 'templates/.before-script-template.yml'
rspec1:
script:
- bundle exec rspec
rspec2:
script:
- bundle exec rspec默认的 before_script 命令会在两个 rspec 作业中的 script 命令之前执行。
覆盖包含的配置值
当您使用 include 关键字时,可以覆盖包含的配置值以适应您的管道需求。
以下示例展示了一个在 .gitlab-ci.yml 文件中自定义的 include 文件。特定的 YAML 定义变量和 production 作业的详细信息被覆盖。
名为 autodevops-template.yml 的自定义配置文件内容:
variables:
POSTGRES_USER: user
POSTGRES_PASSWORD: testing_password
POSTGRES_DB: $CI_ENVIRONMENT_SLUG
production:
stage: production
script:
- install_dependencies
- deploy
environment:
name: production
url: https://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH.gitlab-ci.yml 的内容:
include: 'https://company.com/autodevops-template.yml'
default:
image: alpine:latest
variables:
POSTGRES_USER: root
POSTGRES_PASSWORD: secure_password
stages:
- build
- test
- production
production:
environment:
url: https://domain.com.gitlab-ci.yml 文件中定义的 POSTGRES_USER 和 POSTGRES_PASSWORD 变量以及 production 作业的 environment:url 覆盖了 autodevops-template.yml 文件中定义的值。其他关键字保持不变。此方法称为合并。
include 的合并方法
include 配置通过以下过程与主配置文件合并:
- 包含的文件按照配置文件中定义的顺序读取,并且包含的配置按相同顺序合并。
- 如果包含的文件也使用
include,则该嵌套的include配置首先合并(递归)。 - 如果参数重叠,在合并包含文件的配置时,最后包含的文件优先。
- 在所有使用
include添加的配置合并后,主配置与包含的配置合并。
此合并方法是深度合并,其中哈希映射在配置的任何深度合并。要合并哈希映射"A"(包含已合并的配置)和"B"(下一个配置片段),键和值的处理方式如下:
- 当键仅存在于 A 中时,使用 A 中的键和值。
- 当键同时存在于 A 和 B 中,且它们的值都是哈希映射时,合并这些哈希映射。
- 当键同时存在于 A 和 B 中,且其中一个值不是哈希映射时,使用 B 中的值。
- 否则,使用 B 中的键和值。
例如,对于由两个文件组成的配置:
-
.gitlab-ci.yml文件:include: 'common.yml' variables: POSTGRES_USER: username test: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: manual artifacts: reports: junit: rspec.xml -
common.yml文件:variables: POSTGRES_USER: common_username POSTGRES_PASSWORD: testing_password test: rules: - when: never script: - echo LOGIN=${POSTGRES_USER} > deploy.env - rake spec artifacts: reports: dotenv: deploy.env
合并结果为:
variables:
POSTGRES_USER: username
POSTGRES_PASSWORD: testing_password
test:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
script:
- echo LOGIN=${POSTGRES_USER} > deploy.env
- rake spec
artifacts:
reports:
junit: rspec.xml
dotenv: deploy.env在此示例中:
- 变量仅在所有文件合并后才会被评估。包含文件中的作业可能会使用不同文件中定义的变量值。
rules是一个数组,因此无法合并。顶级文件优先。artifacts是一个哈希映射,因此可以进行深度合并。
覆盖包含的配置数组
您可以使用合并来扩展和覆盖包含模板中的配置,但不能添加或修改数组中的单个项目。例如,要在扩展的 production 作业的 script 数组中添加一个额外的 notify_owner 命令:
autodevops-template.yml 的内容:
production:
stage: production
script:
- install_dependencies
- deploy.gitlab-ci.yml 的内容:
include: 'autodevops-template.yml'
stages:
- production
production:
script:
- install_dependencies
- deploy
- notify_owner如果 install_dependencies 和 deploy 未在 .gitlab-ci.yml 文件中重复,则 production 作业的 script 中将只有 notify_owner。
使用嵌套包含
您可以在配置文件中嵌套 include 部分,然后将其包含在另一个配置中。例如,对于嵌套三层的 include 关键字:
.gitlab-ci.yml 的内容:
include:
- local: /.gitlab-ci/another-config.yml/.gitlab-ci/another-config.yml 的内容:
include:
- local: /.gitlab-ci/config-defaults.yml/.gitlab-ci/config-defaults.yml 的内容:
default:
after_script:
- echo "Job complete."使用重复的 include 条目进行嵌套包含
您可以在主配置文件和嵌套包含中多次包含相同的配置文件。
如果任何文件使用覆盖更改包含的配置,则 include 条目的顺序可能会影响最终配置。最后一次包含的配置会覆盖之前包含该文件的任何时间。例如:
-
defaults.gitlab-ci.yml文件的内容:default: before_script: echo "Default before script" -
unit-tests.gitlab-ci.yml文件的内容:include: - template: defaults.gitlab-ci.yml default: # 覆盖包含的默认值 before_script: echo "Unit test default override" unit-test-job: script: unit-test.sh -
smoke-tests.gitlab-ci.yml文件的内容:include: - template: defaults.gitlab-ci.yml default: # 覆盖包含的默认值 before_script: echo "Smoke test default override" smoke-test-job: script: smoke-test.sh
使用这三个文件,包含的顺序会改变最终配置。
-
如果
unit-tests首先包含,.gitlab-ci.yml文件的内容为:include: - local: unit-tests.gitlab-ci.yml - local: smoke-tests.gitlab-ci.yml最终配置为:
unit-test-job: before_script: echo "Smoke test default override" script: unit-test.sh smoke-test-job: before_script: echo "Smoke test default override" script: smoke-test.sh -
如果
unit-tests最后包含,.gitlab-ci.yml文件的内容为:include: - local: smoke-tests.gitlab-ci.yml - local: unit-tests.gitlab-ci.yml -
最终配置为:
unit-test-job: before_script: echo "Unit test default override" script: unit-test.sh smoke-test-job: before_script: echo "Unit test default override" script: smoke-test.sh
如果没有文件覆盖包含的配置,则 include 条目的顺序不影响最终配置。
在 include 中使用变量
在 .gitlab-ci.yml 文件的 include 部分中,您可以使用:
- 项目变量。
- 群组变量。
- 实例变量。
- 项目预定义变量(
CI_PROJECT_*)。 - 触发器变量。
- 定时管道变量。
- 手动运行管道变量。
CI_PIPELINE_SOURCE和CI_PIPELINE_TRIGGERED预定义变量。$CI_COMMIT_REF_NAME预定义变量。
例如:
include:
project: '$CI_PROJECT_PATH'
file: '.compliance-gitlab-ci.yml'您不能使用作业中定义的变量,或在定义所有作业默认变量的全局 variables 部分中定义的变量。包含在作业之前被评估,因此这些变量不能与 include 一起使用。
有关如何包含预定义变量及其对 CI/CD 作业影响的示例,请参阅此 CI/CD 变量演示。
您不能在动态子管道配置的 include 部分中使用 CI/CD 变量。问题 378717 提议修复此问题。
在 include 中使用 rules
您可以将 rules 与 include 一起使用,以有条件地包含其他配置文件。
您只能将 rules 与某些变量以及以下关键字一起使用:
include 与 rules:if
使用 rules:if 根据 CI/CD 变量的状态有条件地包含其他配置文件。例如:
include:
- local: builds.yml
rules:
- if: $DONT_INCLUDE_BUILDS == "true"
when: never
- local: builds.yml
rules:
- if: $ALWAYS_INCLUDE_BUILDS == "true"
when: always
- local: builds.yml
rules:
- if: $INCLUDE_BUILDS == "true"
- local: deploys.yml
rules:
- if: $CI_COMMIT_BRANCH == "main"
test:
stage: test
script: exit 0include 与 rules:exists
使用 rules:exists 根据文件的存在性有条件地包含其他配置文件。例如:
include:
- local: builds.yml
rules:
- exists:
- exception-file.md
when: never
- local: builds.yml
rules:
- exists:
- important-file.md
when: always
- local: builds.yml
rules:
- exists:
- file.md
test:
stage: test
script: exit 0在此示例中,GitLab 检查当前项目中是否存在 file.md。
如果您在来自不同项目的包含文件中使用 include 与 rules:exists,请仔细检查您的配置。GitLab 检查另一个项目中文件的存在性。例如:
# my-group/my-project 中的管道配置
include:
- project: my-group/other-project
ref: other_branch
file: other-file.yml
test:
script: exit 0
# my-group/other-project 中 ref other_branch 上的 other-file.yml
include:
- project: my-group/my-project
ref: main
file: my-file.yml
rules:
- exists:
- file.md在此示例中,GitLab 在运行管道的项目/引用中搜索 file.md 的存在性,而不是在 my-group/other-project 的 commit ref other_branch 中。
要更改搜索上下文,您可以将 rules:exists:paths 与 rules:exists:project 一起使用。例如:
include:
- project: my-group/my-project
ref: main
file: my-file.yml
rules:
- exists:
paths:
- file.md
project: my-group/my-project
ref: maininclude 与 rules:changes
使用 rules:changes 根据已更改的文件有条件地包含其他配置文件。例如:
include:
- local: builds1.yml
rules:
- changes:
- Dockerfile
- local: builds2.yml
rules:
- changes:
paths:
- Dockerfile
compare_to: 'refs/heads/branch1'
when: always
- local: builds3.yml
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
paths:
- Dockerfile
test:
stage: test
script: exit 0在此示例中:
- 当
Dockerfile已更改时,包含builds1.yml。 - 当
Dockerfile相对于refs/heads/branch1已更改时,包含builds2.yml。 - 当
Dockerfile已更改且管道源是合并请求事件时,包含builds3.yml。builds3.yml中的作业也必须配置为在合并请求管道中运行。
使用 include:local 和通配符文件路径
您可以在 include:local 中使用通配符路径(* 和 **)。
示例:
include: 'configs/*.yml'当管道运行时,GitLab:
-
将
configs目录中的所有.yml文件添加到管道配置中。 -
不添加
configs目录子文件夹中的.yml文件。要允许这样做,请添加以下配置:# 这匹配 `configs` 及其任何子文件夹中的所有 `.yml` 文件。 include: 'configs/**.yml' # 这仅匹配 `configs` 子文件夹中的所有 `.yml` 文件。 include: 'configs/**/*.yml'
故障排除
Maximum of 150 nested includes are allowed! 错误
管道的嵌套包含文件最大数量为 150。如果您在管道中收到 Maximum 150 includes are allowed 错误消息,可能是由于:
- 某些嵌套配置包含过多的额外嵌套
include配置。 - 嵌套包含中存在意外循环。例如,
include1.yml包含include2.yml,而include2.yml又包含include1.yml,形成递归循环。
为帮助降低此风险,请使用管道编辑器编辑管道配置文件,该编辑器会验证是否达到限制。您可以一次删除一个包含文件,以尝试缩小导致循环或过多包含文件的配置文件范围。
在 GitLab 16.0 及更高版本中,GitLab Self-Managed 的用户可以更改最大包含数值。
SSL_connect SYSCALL returned=5 errno=0 state=SSLv3/TLS write client hello 和其他网络故障
使用 include:remote 时,GitLab 尝试通过 HTTP(S) 获取远程文件。此过程可能因各种连接问题而失败。
SSL_connect SYSCALL returned=5 errno=0 state=SSLv3/TLS write client hello 错误发生在 GitLab 无法建立与远程主机的 HTTPS 连接时。如果远程主机有速率限制以防止服务器因请求过载,则可能导致此问题。
例如,GitLab.com 的 GitLab Pages 服务器受到速率限制。重复尝试获取托管在 GitLab Pages 上的 CI/CD 配置文件可能导致达到速率限制并引发错误。您应避免在 GitLab Pages 站点上托管 CI/CD 配置文件。
在可能的情况下,使用 include:project 从 GitLab 实例内的其他项目获取配置文件,而无需进行外部 HTTP(S) 请求。