.codechina-ci.yml
文件的关键字参考
本文档包含.codechina-ci.yml
文件中的配置选项。
当你在编辑.codechina-ci.yml
的过程中,你可以通过 CI Lint 工具进行验证。
流水线任务关键字
流水线任务是由一系列定义了流水线任务行为的关键词组成的。
可用于流水线任务的关键字包括:
关键字 | 描述 |
---|---|
after_script |
覆盖在流水线任务后执行的一组命令 |
allow_failure |
允许流水线任务失败,失败的流水线任务不会导致流水线运行失败 |
artifacts |
成功时附加到流水线任务的文件和目录列表 |
before_script |
覆盖在流水线任务之前执行的一组命令 |
cache |
缓存的可用于后续运行的文件列表 |
coverage |
给定流水线任务的代码覆盖率设置 |
dependencies |
通过提供要从中获取artifacts 的流水线任务列表来限制将哪些artifacts 传递给特定任务 |
environment |
流水线任务部署到的环境的名称 |
except |
控制何时不创建流水线任务 |
extends |
配置当前流水线任务继承自的配置条目 |
image |
使用 Docker 镜像 |
include |
引用外部的 yaml 文件 |
inherit |
选择所有流水线任务继承的全局默认值 |
interruptible |
定义当新的运行变得多余时是否可以取消该流水线任务 |
needs |
在 stage 排序之前执行流水线任务 |
only |
控制何时创建流水线任务 |
pages |
上传流水线任务的结果与 GitCode Pages 一起使用 |
parallel |
并行运行的流水线任务实例数量 |
release |
指导 runner 生成一次发布 |
resource_group |
限制流水线任务的并发 |
retry |
在失败的情况下可以自动重试流水线任务的次数 |
rules |
用于评估和确定流水线任务的选定属性以及它是否已创建的条件列表 |
script |
需要由 Runner 执行的 Shell 脚本 |
secrets |
CI/CD 隐藏流水线任务的 needs
|
services |
使用 Docker 服务镜像 |
stage |
定义流水线任务的阶段 |
tags |
用于选择 runner 的标签列表 |
timeout |
定义优先于项目范围设置的自定义流水线任务超时时间(任务级别) |
trigger |
定义下游流水线的触发器 |
variables |
定义流水线任务级别的变量 |
when |
何时运行流水线任务 |
不可用的流水线任务名称
以下关键词不可用作流水线任务的名称:
image
services
stages
types
before_script
after_script
variables
cache
include
自定义默认关键字值
你可以为某些关键字设置全局默认值。未定义一个或多个所列关键字的流水线任务使用default:
中定义的值。
以下这些流水线任务关键字可以在default:
部分中定义:
以下示例将ruby:3.0
镜像设置为流水线中所有流水线任务的默认值,而rspec 2.7
流水线任务则不使用默认值,因为它使用特定于流水线任务的image:
部分覆盖了默认值:
default:
image: ruby:3.0
rspec:
script: bundle exec rspec
rspec 2.7:
image: ruby:2.7
script: bundle exec rspec
全局关键字
某些关键字在流水线任务中未定义,这些关键字控制流水线的行为或者导入额外的流水线配置:
关键字 | 描述 |
---|---|
stages |
流水线阶段的名称和顺序 |
workflow |
控制运行的流水线类型 |
include |
从其他 YAML 文件导入配置 |
stages
使用 stages 来定义该阶段中包含的流水线任务组。stages 是为流水线全局定义的。在流水线任务中使用 stage 以定义流水线任务属于哪个阶段。
stages 的顺序定义了流水线任务的执行顺序:
- 同一阶段的流水线任务并行运行
- 下一阶段的流水线任务在上一阶段的流水线任务成功完成后运行
例如:
stages:
- build
- test
- deploy
-
build
中所有的流水线任务并行执行。 - 如果
build
中的所有流水线任务都成功,则test
中的流水线任务并行执行。 - 如果
test
中的所有流水线任务都成功,则deploy
中的流水线任务并行执行。 - 如果
deploy
中的所有流水线任务都成功,则流水线标记为通过。
如果任何流水线任务失败,流水线将被标记为 failed
并且后续阶段的流水线任务不会启动。当前阶段的流水线任务不会停止并继续运行。
如果 .codechina-ci.yml
文件中没有定义 stages,则 build
,test
和 deploy
是默认的流水线阶段。
如果流水线任务未指定 stage
,则将该流水线任务分配至test
阶段。
如果定义了一个 stage ,但没有流水线任务使用它,则该阶段在流水线中不可见。这对于合规性流水线配置很有用,因为:
- stage 可以在合规性配置中定义,但如果不使用则保持隐藏。
- 当开发人员在流水线任务定义中使用它们时,定义的 stage 变得可见。
要使流水线任务更早开始并忽略 stage 顺序,请使用needs
关键字。
workflow
使用workflow:
以确定流水线是否被创建。在顶层定义此关键字,使用rules:
类似于rules:
在流水线任务中定义的单个关键字。
你可以使用workflow:rules
模板导入预配置的workflow: rules
条目。
workflow: rules
接受以下这些关键字:
-
if
:检查此rules
以确定何时运行流水线。 -
when
:指定当 ifrules
评估为真时要做什么。- 要运行流水线,请设置为 always。
- 要防止流水线运行,请设置为 never。
-
variables
: 如果未定义,则使用别处定义的变量。
当没有 rules
评估为真时,流水线不会运行。
workflow: rules
的一些示例if
条款:
示例 rules
|
描述 |
---|---|
if: '$CI_PIPELINE_SOURCE == "merge_request_event"' |
控制合并请求流水线何时运行 |
if: '$CI_PIPELINE_SOURCE == "push"' |
控制分支流水线和 Tag 流水线何时运行 |
if: $CI_COMMIT_TAG |
控制 Tag 流水线何时运行 |
if: $CI_COMMIT_BRANCH |
控制分支流水线何时运行 |
有关更多示例,请参阅通用 if rules 条款。
在以下示例中,流水线针对所有 push 事件(对分支和新标签的更改)运行。提交消息中含-draft
的推送事件不会运行流水线,因为它们被设置为when: never
。计划或合并请求的流水线也不会运行,因为没有 rules
对它们评估为真:
workflow:
rules:
- if: $CI_COMMIT_MESSAGE =~ /-draft$/
when: never
- if: '$CI_PIPELINE_SOURCE == "push"'
这个例子有严格的 rules
,流水线不会在其他任何情况下运行。
或者,所有 rules
都可以when: never
,并带有最终 when: always
rules
。符合when: never
rules
的流水线不会运行,所有其他流水线类型运行:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never
- when: always
以上示例中,阻止了计划或push(分支和标签)流水线的流水线运行。最终when: always
rules
运行所有其他流水线类型,包括合并请求流水线。
如果你的 rules
同时匹配分支流水线和合并请求流水线,则可能会出现重复的流水线。
workflow:rules:variables
你可以在 workflow:rules:
中使用 variables
来定义特定流水线条件的变量。
例如:
variables:
DEPLOY_VARIABLE: "default-deploy"
workflow:
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
variables:
DEPLOY_VARIABLE: "deploy-production" # Override globally-defined DEPLOY_VARIABLE
- if: $CI_COMMIT_REF_NAME =~ /feature/
variables:
IS_A_FEATURE: "true" # Define a new variable.
- when: always # Run the pipeline in other cases
job1:
variables:
DEPLOY_VARIABLE: "job1-default-deploy"
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
variables: # Override DEPLOY_VARIABLE defined
DEPLOY_VARIABLE: "job1-deploy-production" # at the job level.
- when: on_success # Run the job in other cases
script:
- echo "Run script with $DEPLOY_VARIABLE as an argument"
- echo "Run another script if $IS_A_FEATURE exists"
job2:
script:
- echo "Run script with $DEPLOY_VARIABLE as an argument"
- echo "Run another script if $IS_A_FEATURE exists"
当分支是默认分支时:
-
job1DEPLOY_VARIABLE
是job1-deploy-production
-
job2DEPLOY_VARIABLE
是deploy-production
当分支是feature
时:
job1DEPLOY_VARIABLE
是job1-default-deploy
,IS_A_FEATURE 是true
job2DEPLOY_VARIABLE
是default-deploy
,IS_A_FEATURE 是true
当分支是其它分支时:
job1DEPLOY_VARIABLE
是job1-default-deploy
job2DEPLOY_VARIABLE
是default-deploy
workflow:rules 模板
我们为一些常见场景提供了 workflow: rules
设置的模板。这些模板有助于防止重复运行流水线。
Branch-Pipelines
模板可以使你的流水线为分支和 Tags 运行。
分支流水线状态显示在使用分支作为源的合并请求中。但是,这种流水线类型不支持合并请求流水线提供的任何功能 ,例如合并结果流水线或合并列车。此模板有意避免使用这些功能。
可以通过以下方式引用它:
include:
- template: 'Workflows/Branch-Pipelines`.codechina-ci.yml`'
MergeRequest-Pipelines
模板可以使你的流水线针对默认分支、Tags 和所有类型的合并请求运行流水线。如果使用任何合并请求功能的流水线,请使用此模板。
可以通过以下方式引用它:
include:
- template: 'Workflows/MergeRequest-Pipelines`.codechina-ci.yml`'
在分支流水线和合并请求流水线之间切换
要在创建合并请求后将流水线从分支流水线切换到合并请求流水线,在 .codechina-ci.yml
文件中添加 workflow: rules
部分。
如果同时使用两种流水线类型,则可能会同时运行重复的流水线。为防止重复运行流水线,请使用CI_OPEN_MERGE_REQUESTS
变量。
以下示例适用于仅运行分支和合并请求流水线,但不为任何其他情况运行流水线的项目:
- 当分支没有打开合并请求时运行分支流水线
- 当分支的合并请求打开时运行合并请求流水线
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH'
如果流水线由以下因素触发:
- 合并请求,运行合并请求流水线。例如,合并请求流水线可以通过推送到具有关联打开合并请求的分支来触发。
- 对分支的更改,但该分支的合并请求已打开,请不要运行分支流水线。
- 对分支的更改,但没有任何打开的合并请求,运行分支流水线。
你还可以向现有workflow
部分添加 rules
,以便在创建合并请求时从分支流水线切换到合并请求流水线。
将此 rules
添加到该workflow
部分的顶部,然后是已经存在的其他 rules
:
workflow:
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- ... # Previously defined workflow rules here
在分支上运行的流水线触发器有一个$CI_COMMIT_BRANCH
集合,可能会被类似的 rules
阻止。触发流水线的流水线源为trigger
或pipeline
,因此&& $CI_PIPELINE_SOURCE == "push"
确保 rules
不会阻止触发流水线。
include
用于include
在 CI/CD 配置中包含外部 YAML 文件。你可以将一个长的codechina-ci.yml
文件分解为多个文件以提高可读性,或减少同一配置在多个位置的重复。
你还可以将模板文件存储在中央存储库中,并通过include
将它们存储在项目中。
include
要求外部 YAML 文件具有扩展名.yml
或.yaml
,否则不引用外部文件。
你不能在不同 YAML 文件之间通过使用 YAML 锚点的方式来 include
.yaml
。你只能引用同一文件中的锚点。要重用来自不同 YAML 文件的配置,请使用!reference
标签 或 extends
关键字。
include
支持以下引用方法:
关键词 | 方法 |
---|---|
local |
引用本地项目存储库中的文件 |
file |
引用来自不同项目存储库的文件 |
remote |
引用来自远程 URL 的文件,必须可以公开访问。 |
template |
引用模板 |
流水线启动时,.codechina-ci.yml
会评估所有方法引用的文件配置。配置是一个及时的快照并储存在数据库中。.codechina-ci.yml
在下一个流水线启动之前,不会同步对引用文件配置的任何更改。
这些include
文件是:
- 与
.codechina-ci.yml
文件中的那些深度合并 =.codechina-ci.yml
无论include
关键字的位置如何,始终首先评估并与文件内容合并。
使用合并本地配置的 CI/CD 配置的方法来自定义和覆盖引用的配置。
.codechina-ci.yml
文件中的本地配置会覆盖引用的配置。
include
变量
你可以 在文件的部分中使用一些预定义的变量include
.codechina-ci.yml
:
include:
project: '$CI_PROJECT_PATH'
file: '.compliance-codechina-ci.yml'
include:local
使用include:local
引用在同一个存储库中的.codechina-ci.yml
文件。使用相对于根目录 (/) 的完整路径。
如果使用include:local
,请确保.codechina-ci.yml
文件和本地文件位于同一分支上。
你不能通过 Git 子模块路径包含本地文件。
所有嵌套的包含都在同一个项目的范围内执行,因此可以使用本地、项目、远程或模板引用。
例子:
include:
- local: '/templates/.codechina-ci-template.yml'
你还可以使用较短的语法来定义路径:
include: '.codechina-ci-production.yml'
使用本地引用而不是符号链接。
include:local
带通配符文件路径
你可以在include:local
中使用通配符路径(*
和**
)。
例子:
include: 'configs/*.yml'
当流水线运行时:
- 将
.yml
目录中的所有文件添加configs
到流水线配置中。 - 不在
.yml
目录的子文件夹中添加文件configs
。为此,请添加以下配置:# This matches all `.yml` files in `configs` and any subfolder in it. include: 'configs/**.yml' # This matches all `.yml` files only in subfolders of `configs`. include: 'configs/**/*.yml'
include:file
要引用来自另一个私有项目的文件,请使用include:file
。你仅可以将include:file
与include:project
组合使用。使用相对于根目录 (/)的完整路径。
例如:
include:
- project: 'my-group/my-project'
file: '/templates/.gitlab-ci-template.yml'
你还可以指定一个ref
, 如果不指定值,则 ref
默认为项目的 HEAD
:
include:
- project: 'my-group/my-project'
ref: main
file: '/templates/.gitlab-ci-template.yml'
- project: 'my-group/my-project'
ref: v1.0.0
file: '/templates/.gitlab-ci-template.yml'
- project: 'my-group/my-project'
ref: 787123b47f14b552955ca2786bc9542ae66fee5b # Git SHA
file: '/templates/.gitlab-ci-template.yml'
所有嵌套的引用都在目标项目的范围内执行。你可以使用本地(相对于目标项目)、项目、远程或模板引用。
一个项目中的多个文件
你可以引用来自同一项目的多个文件:
include:
- project: 'my-group/my-project'
ref: main
file:
- '/templates/.builds.yml'
- '/templates/.tests.yml'
include:remote
include:remote
与完整 URL 一起使用,可以引用来自不同位置的文件。因为不支持远程 URL 中的身份验证,远程文件必须可通过 HTTP/HTTPS GET
请求公开访问。例如:
include:
- remote: 'https://codechina.csdn.net/example-project/-/raw/main/.codechina-ci.yml'
所有嵌套引用都以公共用户身份在没有上下文的情况下执行,因此你只能使用include
公共项目或模板。
include:template
使用include:template
引用 .codechina-ci.yml
模板。
例如:
# File sourced from the GitLab template collection
include:
- template: Auto-DevOps.codechina-ci.yml
多个include:template文件:
include:
- template: Android-Fastlane.codechina-ci.yml
- template: Auto-DevOps.codechina-ci.yml
所有嵌套引用仅在用户许可的情况下执行,因此可以使用项目、远程或模板引用。
嵌套引用
使用嵌套引用来组成一组引用。最多可以有 100 个引用,但不能有重复的引用,解析所有文件的时间限制为 30 秒。
关键字详情
接下来,我们介绍如何通过关键字来配置 CI/CD 流水线。
image
使用image
指定用于流水线任务的 Docker 镜像。
更多:
- 用法示例,请参见
.codechina-ci.yml
文件中的 定义image
。 - 详细使用信息,参考 Docker 集成文档。
image:name
一个扩展 Docker 配置选项。
有关更多信息,请参阅 的可用设置image。
image:entrypoint
一个扩展 Docker 配置选项。
有关更多信息,请参阅 的可用设置image。
services
使用services
指定 Docker 镜像,链接到指定的基本镜像。
更多:
- 用法示例,请参见
.codechina-ci.yml
文件中的定义services
。 - 详细使用信息,参考Docker集成文档。
- 示例服务,请参阅GitLab CI/CD 服务。
services:name
一个扩展 Docker 配置选项。
services:alias
一个扩展 Docker 配置选项。
services:entrypoint
一个扩展 Docker 配置选项。
services:command
一个扩展 Docker 配置选项。
script
使用script
为 Runner 指定要执行的 shell 脚本。
除触发器流水线任务外的所有流水线任务都需要一个script
关键字。
例如:
job:
script: "bundle exec rspec"
你可以使用 YAML 锚点的 script
.
script
关键字也可以包含一组命令:
job:
script:
- uname -a
- bundle exec rspec
有时,script
命令必须用单引号或双引号括起来。例如,包含冒号 ( :) 的命令必须用单引号 ( ')括起来。YAML 解析器需要将文本解释为字符串而不是“键:值”对。
例如,此脚本中使用了冒号:
job:
script:
- curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects"
要被视为有效的 YAML,你必须将整个命令用单引号括起来。如果命令已使用单引号,则应将它们更改为双引号 ( "):
job:
script:
- 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"'
你可以使用CI Lint工具验证语法是否有效。
使用这些字符时也要小心:
-
{
,}
,[
,]
,,
,&
,*
,#
,?
,|
,-
,<
,>
,=
,!
,%
,@
,`
如果任何脚本命令返回零以外的退出代码,则流水线任务失败并且不会执行进一步的命令。将退出代码存储在变量中以避免这种行为:
job:
script:
- false || exit_code=$?
- if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;
before_script
使用before_script
定义应在每次流水线任务之前运行的命令组,但需要在artifacts
恢复后。
你在 before_script
其中指定的脚本与你在 main script
中指定的任何脚本连接在一起。组合后的脚本在单个 shell 中一起执行。
before_script
如果在流水线任务中定义它,则可以覆盖全局定义:
default:
before_script:
- echo "Execute this script in all jobs that don't already have a before_script section."
job1:
script:
- echo "This script executes after the global before_script."
job:
before_script:
- echo "Execute this script instead of the global before_script."
script:
- echo "This script executes after the job's `before_script`"
可以在before_script
中使用 YAML 锚点。
after_script
使用after_script
定义每个流水线任务后运行命令组,包括失败的流水线任务。
如果流水线任务超时或被取消,则after_script
不会执行。
你指定的after_script
脚本在新 shell 中执行,与任何 before_script
或script
脚本分开 。通过这样:
- 将当前流水线任务目录设置回默认值。
- 无法访问
before_script
或script
中定义的脚本所做的更改,包括:-
script
脚本中导出的命令别名和变量。 - 工作树之外的更改(取决于运行程序执行程序),例如由
before_script
或script
脚本安装的软件。
-
- 有一个单独的超时,它被硬编码为 5 分钟。
- 不影响流水线任务的退出代码。如果该
script
部分成功并且after_script
超时或失败,则流水线任务将退出并显示代码0
(Job Succeeded
)。
default:
after_script:
- echo "Execute this script in all jobs that don't already have an after_script section."
job1:
script:
- echo "This script executes first. When it completes, the global after_script executes."
job:
script:
- echo "This script executes first. When it completes, the job's `after_script` executes."
after_script:
- echo "Execute this script instead of the global after_script."
可以在after_script
中使用 YAML 锚点。
Script
语法
你可以在script
中使用语法来:
- 将长命令拆分为多行命令。
- 使用颜色代码使流水线任务日志更易于查看。
- 创建自定义可折叠部分以简化流水线任务日志输出。
stage
使用stage
定义在哪一个阶段运行流水线任务。流水线任务在同一 stage
可以并行执行(某些条件下)。
没有stage
条目的流水线任务默认使用test
阶段。如果没有在流水线中定义stages
,则可以使用 5 个默认阶段,它们按以下顺序执行:
例如:
stages:
- build
- test
- deploy
job 0:
stage: .pre
script: make something useful before build stage
job 1:
stage: build
script: make build dependencies
job 2:
stage: build
script: make build artifacts
job 3:
stage: test
script: make test
job 4:
stage: deploy
script: make deploy
job 5:
stage: .post
script: make something useful at the end of pipeline
使用你自己的 Runner
当你使用自建的 Runner 时,默认情况下每个 Runner 一次仅运行一项流水线任务。如果流水线任务在不同的 Runner 上运行,它们可以并行运行。
如果你只有一个 Runner ,并且 Runner 的 concurrent
设置大于 1,则流水线任务可以并行运行。
.pre
和 .post
将pre
和post
用于需要在流水线中首先或最后运行的流水线任务。
-
.pre
保证始终是流水线中的第一阶段。 -
.post
保证始终是流水线中的最后阶段。
用户定义的阶段将在 .pre
之后和 .post
之前执行。
你必须在.pre
或.post
以外的至少一个阶段有一个流水线任务。
你不能更改 .pre
和 .post
的顺序,即使你在.codechina-ci.yml
文件中不按顺序定义它们。例如,以下配置是等效的:
stages:
- .pre
- a
- b
- .post
stages:
- a
- .pre
- b
- .post
stages:
- a
- b
extends
使用 extends
重用配置部分。它是YAML 锚点的替代品, 并且更加灵活、有更强的可读性。你可以使用extends
从引用的配置文件中重用配置。
在以下示例中,rspec
流水线任务使用 .tests
模板流水线任务中的配置。 系统会:
- 根据键执行反向深度合并。
- 将
.tests
内容与rspec
流水线任务合并。 - 不合并键的值。
.tests:
script: rake test
stage: test
only:
refs:
- branches
rspec:
extends: .tests
script: rake rspec
only:
variables:
- $RSPEC
结果 rspec
的流水线任务是:
rspec:
script: rake rspec
stage: test
only:
refs:
- branches
variables:
- $RSPEC
.tests
在这个例子中是一个隐藏流水线任务,但也可以从常规流水线任务扩展配置。
extends
支持多级继承。你应该避免使用三个以上的级别,但你仍可以使用多达 11 个级别。以下示例具有两个继承级别:
.tests:
only:
- pushes
.rspec:
extends: .tests
script: rake rspec
rspec 1:
variables:
RSPEC_SUITE: '1'
extends: .rspec
rspec 2:
variables:
RSPEC_SUITE: '2'
extends: .rspec
spinach:
extends: .tests
script: rake spinach
你也可以为 extends
设置多个父级。
合并请求详情
你可以将 extends
用于合并散列但不能用于数组。用于合并的算法是“最接近的范围获胜”,因此来自最后一个成员的键值总是覆盖其他级别上定义的任何内容。例如:
.only-important:
variables:
URL: "http://my-url.internal"
IMPORTANT_VAR: "the details"
only:
- main
- stable
tags:
- production
script:
- echo "Hello world!"
.in-docker:
variables:
URL: "http://docker-url.internal"
tags:
- docker
image: alpine
rspec:
variables:
GITLAB: "is-awesome"
extends:
- .only-important
- .in-docker
script:
- rake rspec
结果 rspec
的流水线任务是:
rspec:
variables:
URL: "http://docker-url.internal"
IMPORTANT_VAR: "the details"
GITLAB: "is-awesome"
only:
- main
- stable
tags:
- docker
image: alpine
script:
- rake rspec
在这个例子中:
- 这些
variables
部分合并,但URL: "http://docker-url.internal"
覆盖URL: "http://my-url.internal"
-
tags: ['docker']
覆盖tags: ['production']
-
script
不合并,但script: ['rake rspec']
覆盖script: ['echo "Hello world!"']
。你可以使用YAML 锚点来合并数组。
extends
和 include
一起使用
要重用来自不同配置文件的配置,你可以将 extends
和 include
结合起来使用。
在以下示例中,script
在included.yml
文件中定义了a
。然后,在.codechina-ci.yml
文件中,extends
引用了以下script
内容:
-
included.yml
:.template: script: - echo Hello!
-
. codechina-ci.yml
:include: included.yml useTemplate: image: alpine extends: .template
rules
rules
用于在流水线中添加或排除流水线任务。
rules
按顺序评估,直到第一次匹配。找到匹配项后,会将该流水线任务包含在流水线中或从流水线中排除,取决于具体的配置。流水线任务还可以添加某些属性。
rules
替换 only/except
,并且它们不能在同一个流水线任务中一起使用。如果你在一个流水线任务配置为使用这两个关键字,则 linter
会返回 key may not be used with rules
的错误提示。
Rules attributes
rules
中你可以使用的流水线任务属性是:
-
when
: 如果未定义,则默认为when: on_success
。- 如果用作
when: delayed
,start_in
也是必需的。
- 如果用作
-
allow_failure
: 如果未定义,则默认为allow_failure: false
。 -
variables
: 如果未定义,则使用别处定义的变量。
如果 rules
评估为真,并且 when
具有除 never
之外的任何值,则流水线任务将包含在流水线中。
例如:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: delayed
start_in: '3 hours'
allow_failure: true
Rules
条款
可用的Rules
条款有:
条款 | 描述 |
---|---|
if |
通过评估if 语句向流水线中添加或排除流水线任务。类似于 only:variables
|
changes |
根据更改的文件从流水线中添加或排除流水线任务。与 only:changes 相同 |
exists |
根据特定文件的存在与否向流水线中添加或排除流水线任务 |
rules
按顺序进行评估,直到找到匹配项。如果找到匹配项,则会检查属性以查看是否应将流水线任务添加到流水线中。如果未定义属性,则默认值为:
when: on_success
allow_failure: false
流水线任务被添加到流水线中:
- 如果
rules
匹配并且具有when: on_success
,when: delayed
或when: always
- 如果没有
rules
匹配,但最后一个子句是when: on_success
,when: delayed
或when: always
(没有rules
)
流水线任务未添加到流水线中:
- 如果没有
rules
匹配,并且没有独立的when: on_success
,when: delayed
或when: always
- 如果
rules
匹配,并且具有when: never
作为属性
以下示例用于if
严格限制流水线任务何时运行:
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "schedule"'
- 如果流水线用于合并请求,则第一个规则匹配,并且流水线任务将添加到合并请求流水线中 ,其属性为:
-
when: manual
(手工流水线任务) -
allow_failure: true
(即使未运行手动流水线任务,流水线也会继续运行)
-
- 如果流水线不是用于合并请求,则第一条规则不匹配,并评估第二条规则。
- 如果流水线是计划流水线,则第二条规则匹配,并将流水线任务添加到计划流水线。没有定义属性,因此添加了:
-
when: on_success
(默认) -
allow_failure: false
(默认)
-
- 在所有其他情况下,没有规则匹配,因此不会将流水线任务添加到任何其他流水线。
或者,你可以定义一组在少数情况下排除流水线任务的 rules
,但在所有其他情况下运行它们:
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- when: on_success
- 如果流水线用于合并请求,则不会将流水线任务添加到流水线中。
- 如果流水线是计划流水线,则不会将流水线任务添加到流水线中。
- 在所有其他情况下,流水线任务将添加到流水线中,带有
when: on_success
。
如果你使用
when:
条款作为最终规则(不包括when: never
),则可能会同时启动两个流水线。推送流水线和合并请求流水线都可以由同一事件触发(推送到源分支以获取开放合并请求)。
避免重复的流水线
如果流水线任务使用rules,则单个操作(例如将提交推送到分支)可以触发多个流水线。你不必为多种类型的流水线显式配置规则来意外触发它们。
例如:
job:
script: echo "This job creates double pipelines!"
rules:
- if: '$CUSTOM_VARIABLE == "false"'
when: never
- when: always
当$CUSTOM_VARIABLE
是 false
时此流水线任务不运行,但它在所有其他流水线中运行,包括推(分支)和合并请求两个流水线。使用此配置,每次推送到开放合并请求的源分支都会导致重复的流水线。
为避免重复流水线,你可以:
-
使用
CI_OPEN_MERGE_REQUESTS
CI/CD 变量workflow:rules
在分支和合并请求流水线之间进行切换,而不产生重复的流水线。你还可以在单个流水线任务规则中使用此变量。 -
使用
workflow
指定只在分支流水线或只在合并请求流水线中运行。 -
重写规则以仅在非常特定的情况下运行流水线任务,并避免最终的
when:
规则:job: script: echo "This job does NOT create double pipelines!" rules: - if: '$CUSTOM_VARIABLE == "true" && $CI_PIPELINE_SOURCE == "merge_request_event"'
你还可以通过更改流水线任务规则来避免重复流水线,以避免推送(分支)流水线或合并请求流水线。但是,如果你使用没有规则 workflow: rules
的 - when: always
,系统仍会显示流水线警告。
例如,以下不会触发双流水线,但不推荐没有workflow: rules
:
job:
script: echo "This job does NOT create double pipelines!"
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never
- when: always
你不应在同一流水线任务中同时包含推送和合并请求流水线的 workflow:rules
,以免防止重复流水线:
job:
script: echo "This job creates double pipelines!"
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
此外,不要将同一流水线中的 only/except
流水线任务与 rules
流水线任务混合在一起。它可能不会引起 YAML 错误,但不同的默认行为的 only/except
和 rules
可能会导致一些难以解决的问题:
job-with-no-rules:
script: echo "This job runs in branch pipelines."
job-with-rules:
script: echo "This job runs in merge request pipelines."
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
对于推送到分支的每个更改,都会运行重复的流水线。一个分支流水线运行单个流水线任务 ( job-with-no-rules
),一个合并请求流水线运行另一个流水线任务 ( job-with-rules
)。没有规则的流水线任务默认为 except: merge_requests
,因此 job-with-no-rules
在除合并请求之外的所有情况下都会运行。
rules:if
使用 rules:if
条款指定何时向流水线添加流水线任务:
- 如果if语句为真,则将流水线任务添加到流水线中。
- 如果某个if语句为真,但与
when: never
结合使用,则不会将流水线任务添加到流水线中。 - 如果没有任何if语句为真,则不会将流水线任务添加到流水线中。
rules:if
与 only:variables
略有不同,它的每个规则只接受一个表达式字符串而不是数组。任何一组要计算的表达式都可以通过使用 &&
或 ||
,以及变量匹配运算符 (==
, !=
, =~
和 !~
) 连成一个表达式。
与 script
中的变量不同,规则表达式中的变量始终格式为 $VARIABLE
。
if:
条款根据预定义 CI/CD 变量 或自定义 CI/CD 变量的值进行评估。
例如:
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: always
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/'
when: manual
allow_failure: true
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' # Checking for the presence of a variable is possible
有关确定 when
流水线任务的逻辑的一些详细信息:
- 如果提供的规则都不匹配,则流水线任务将设置为
when: never
并且不包含在流水线中。 - 没有任何条款的规则,例如
when
或allow_failure
规则没有if
或者没有changes
,总是匹配,并且总是在符合时使用。 - 如果规则匹配到并且未定义
when
,则使用when
规则定义的流水线任务,,且未定义的情况下默认为on_success
。 - 你可以为每个规则定义一次
when
,也可以在流水线任务级别定义一次,这将适用于所有规则。你不能在流水线任务级别when
与规则when
混合使用。
rules
的通用 if
条款
对于类似于 only/except
关键字的行为,你可以检查 $CI_PIPELINE_SOURCE
变量的值:
值 | 描述 |
---|---|
api |
由 pipelines API 触发的流水线 |
chat |
使用 GitLab ChatOps 命令创建的流水线 |
external |
当你使用 GitLab 以外的 CI 服务 |
external_pull_request_event |
在 GitHub 上创建或更新外部拉取请求时 |
merge_request_event |
对于在创建或更新合并请求时创建的流水线。需要启用合并请求流水线、合并结果流水线和 merge trains
|
parent_pipeline |
对于由带有 rules 的父/子流水线触发的流水线。在子流水线配置中使用此流水线源,以便它可以由父流水线触发 |
pipeline |
对于通过使用带有CI_JOB_TOKEN 的API创建的多项目流水线,或 trigger 关键字 |
push |
对于由“git push”事件触发的流水线,包括分支和标签 |
schedule |
计划流水线 |
trigger |
对于使用 trigger token 创建的流水线 |
web |
对于使用 UI 中的 流水线 按钮创建的流水线,来自项目的 Devops > 流水线 部分 |
webide |
对于使用 WebIDE 创建的流水线 |
以下示例在计划的流水线或推送中将流水线任务作为手动流水线任务运行流水线(到分支或标签),带有 when: on_success
(默认)。它不会将流水线任务添加到任何其他流水线类型。
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "push"'
以下示例中当 when: on_success
时将在合并请求流水线和计划流水线运行流水线任务
。它不会在任何其他流水线类型中运行。
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
if
条款的其他常用变量:
-
if: $CI_COMMIT_TAG
:如果为标签推送更改。 -
if: $CI_COMMIT_BRANCH
:如果更改被推送到任何分支。 -
if: '$CI_COMMIT_BRANCH == "main"'
:如果更改被推送到main
。 -
if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
:如果更改被推送到默认分支。当你想在多个相同的配置中使用具有不同默认分支的项目。 -
if: '$CI_COMMIT_BRANCH =~ /regex-expression/'
:如果提交分支匹配正则表达式。 -
if: '$CUSTOM_VARIABLE !~ /regex-expression/'
: 如果自定义变量CUSTOM_VARIABLE
不 匹配正则表达式。 -
if: '$CUSTOM_VARIABLE == "value1"'
:如果自定义变量CUSTOM_VARIABLE
值 正是value1
。
rules:changes
使用 rules:changes
当改特定文件时将流水线任务添加到流水线。
rules: changes
的工作方式与 only: changes
和 except: changes
相同。它接受一组路径。你应该只对分支使用 rules: changes
流水线或合并请求流水线。例如,通常对合并请求流水线使用rules: changes
:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- Dockerfile
when: manual
allow_failure: true
在这个例子中:
- 如果流水线是合并请求流水线,将检查
Dockerfile
是否有更改。 - 如果
Dockerfile
已更改,则将流水线任务作为手动流水线任务添加到流水线中,并且流水线 即使流水线任务没有被触发(allow_failure: true
)也会继续运行。 - 如果
Dockerfile
没有改变,则不会向任何流水线添加流水线任务(与when: never
相同)。
要将 rules: changes
用于分支流水线而不是合并请求流水线,将之前示例中的 if:
子句更改为:
rules:
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH
要实现类似于 except:changes
的规则,
使用 when: never
。
你可以将
rules: changes
与其他流水线类型一起使用,但不推荐使用。因为当没有 Gitpush
事件时,rules: changes
总是评估为true
。标记流水线、计划流水线等没有有 Gitpush
事件 与他们有关。rules: changes
流水线任务始终添加到这些流水线中,如果没有if:
语句将流水线任务限制为分支或合并请求流水线的话。
rules:changes
中的变量
你可以在 rules:changes
表达式中使用 CI/CD 变量来确定何时向流水线添加流水线任务:
docker build:
variables:
DOCKERFILES_DIR: 'path/to/files/'
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- changes:
- $DOCKERFILES_DIR/*
你可以将 $
字符用于变量和路径。例如,如果 $DOCKERFILES_DIR
变量存在,它的值被使用。如果不存在,则 $
被解释为路径的一部分。
rules:exists
当存储库中存在某些文件时,使用 exists
来运行流水线任务。你可以使用一组路径。
在以下示例中,如果存储库中的任何位置存在 Dockerfile
,job
就会运行:
job:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- exists:
- Dockerfile
exists
的路径相对于项目目录 ($CI_PROJECT_DIR
),不能直接链接到项目目录之外。
你可以使用 glob 的模式在存储库中匹配任何目录中的多个文件:
job:
script: bundle exec rspec
rules:
- exists:
- spec/**.rb
Glob 模式用 Ruby 解释 File.fnmatch
带有标志 File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB
。
出于性能原因,最多匹配 10,000 个 exists
模式。在第 10,000 次检查之后,带有 glob 的规则将始终匹配。
rules:allow_failure
你可以在 rules:
中使用 allow_failure: true
来允许流水线任务失败,或等待一个手动流水线任务的操作,而不停止流水线本身。所有使用 rules:
的流水线任务在你没有定义 allow_failure:
的情况下默认为 allow_failure: false
。
规则级别的 rules:allow_failure
选项覆盖流水线任务级别 allow_failure
选项,仅在特定规则触发流水线任务后进行。
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
when: manual
allow_failure: true
在此示例中,如果第一条规则匹配,则流水线任务具有 when: manual
和 allow_failure: true
。
rules:variables
在 rules:
中使用 variables
来定义特定条件的变量。
例如:
job:
variables:
DEPLOY_VARIABLE: "default-deploy"
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
variables: # Override DEPLOY_VARIABLE defined
DEPLOY_VARIABLE: "deploy-production" # at the job level.
- if: $CI_COMMIT_REF_NAME =~ /feature/
variables:
IS_A_FEATURE: "true" # Define a new variable.
script:
- echo "Run script with $DEPLOY_VARIABLE as an argument"
- echo "Run another script if $IS_A_FEATURE exists"
复杂规则条款
要将 if
、 changes
和 exists
条款用 AND
连接起来,并用在同一条规则中。
在以下示例中:
- 如果
Dockerfile
文件或/docker/scripts
中的任何文件发生了变化,并且$VAR
== "string value",则流水线任务手动运行 - 否则,流水线任务不包含在流水线中。
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: '$VAR == "string value"'
changes: # Include the job and set to when:manual if any of the follow paths match a modified file.
- Dockerfile
- docker/scripts/*
when: manual
# - "when: never" would be redundant here. It is implied any time rules are listed.
诸如 branches
或 refs
之类的关键字可用于 only
/except
,但在 rules
中不可用。
你可以使用括号 []
和 &&
和 ||
来构建更复杂的变量表达式。
job1:
script:
- echo This rule uses parentheses.
rules:
if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
only
/ except
你可以使用 only
和 except
来控制何时向流水线添加流水线任务。
- 使用
only
来定义流水线任务何时运行。 - 使用
except
定义流水线任务何时 不 运行。
四个关键字可以与 only
和 except
一起使用:
only:refs
/ except:refs
使用 only:refs
和 except:refs
关键字来控制何时将流水线任务添加到基于分支名称或流水线类型的流水线。
关键字类型:流水线任务关键字。你只能将其用作流水线任务的一部分。
可能的输入:包含任意数量的数组:
-
分支名称,例如
main
或my-feature-branch
。 -
正则表达式匹配分支名称,例如
/^feature-.*/
。 -
以下关键词:
关键词 说明 api
对于由 pipelines API 触发的流水线 branches
当流水线的 Git 引用是分支时 chat
对于使用 ChatOps命令创建的流水线 external
当你使用 GitLab 以外的 CI 服务时 external_pull_requests
在 GitHub 上创建或更新外部拉取请求时 merge_request
对于在创建或更新合并请求时创建的流水线。启用合并请求流水线、合并的结果流水线 和 merge trains
pipelines
对于通过使用带有 CI_JOB_TOKEN
的API创建的多项目流水线,或trigger
关键字push
对于由“git push”事件触发的流水线,包括分支和标签 schedules
计划流水线 tags
当流水线的 Git 引用是标签时 triggers
对于使用 trigger token
创建的流水线web
对于使用 UI 中的 流水线 按钮创建的流水线,来自项目的 DevOps > 流水线 部分
only:refs
和 except:refs
示例:
job1:
script: echo
only:
- main
- /^issue-.*$/
- merge_requests
job2:
script: echo
except:
- main
- /^stable-branch.*$/
- schedules
更多细节:
-
计划流水线在特定分支上运行,因此流水线任务配置为
only: branch
也可以计划流水线上运行。添加except: schedules
以防止使用only: branch
的流水线任务在预定流水线上运行。 -
only
或except
不使用任何其他关键字等价于only: refs
或except: refs
。比如下面两个job的配置是一样的行为:job1: script: echo only: - branches job2: script: echo only: refs: - branches
-
如果流水线任务不使用
only
、except
或rules
,则only
默认设置为branches
和tag
。例如,
job1
和job2
是等价的:job1: script: echo 'test' job2: script: echo 'test' only: - branches - tags
only:variables
/ except:variables
使用 only:variables
或 except:variables
关键字来控制何时添加流水线任务
到流水线,基于 CI/CD 变量 的状态。
关键字类型:流水线任务关键字。你只能将其用作流水线任务的一部分。
可能的输入:CI/CD 变量表达式 的数组。
only:variables
示例:
deploy:
script: cap staging deploy
only:
variables:
- $RELEASE == "staging"
- $STAGING
only:changes
/ except:changes
当 Git 推送事件修改文件时,使用 changes
关键字和 only
来运行一个流水线任务,或者使用 except
来跳过一个流水线任务。
在具有以下引用的流水线中使用changes
:
分支
external_pull_requests
merge_requests
关键字类型:流水线任务关键字。你只能将其用作流水线任务的一部分。
可能的输入:包含任意数量的数组:
- 文件路径。
- 单个目录的通配符路径,例如
path/to/directory/*
,或一个目录及其所有子目录,例如path/to/directory/**/*
。 - 通配符 (glob) 所有路径具有相同扩展名或多个扩展名的文件,例如
*.md
或path/to/directory/*.{rb,py,sh}
。 - 根目录或所有目录中文件的通配符路径,用双引号括起来。例如
"*.json"
或"**/*.json"
。
only:changes
示例:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
only:
refs:
- branches
changes:
- Dockerfile
- docker/scripts/*
- dockerfiles/**/*
- more_scripts/*.{rb,py,sh}
更多细节:
- 如果你使用除
branches
、external_pull_requests
或merge_requests
以外的引用,changes
无法确定给定文件是新文件还是旧文件,并且总是返回true
。 - 如果你将
only: changes
与其他引用一起使用,流水线任务将忽略更改并始终运行。 - 如果你将
except: changes
与其他引用一起使用,流水线任务将忽略更改并且
only:kubernetes
/ except:kubernetes
当 Kubernetes 服务在项目中处于活动状态时,使用 only:kubernetes
或 except:kubernetes
来控制是否将流水线任务添加到流水线中。
关键字类型:特定于流水线任务。你只能将其用作流水线任务的一部分。
可能的输入:kubernetes
策略只接受 active
关键字。
only:kubernetes
示例:
deploy:
only:
kubernetes: active
在此示例中,deploy
流水线任务仅在 Kubernetes 服务处于活动状态时运行在项目中。
needs
使用 needs:
来乱序执行流水线任务。流水线任务之间的关系可使用 needs
可视化为有向无环图。
你可以忽略阶段排序并运行一些流水线任务,而无需等待其他流水线任务完成。多个阶段的流水线任务可以同时运行。
以下示例创建四个执行路径:
- Linter:
lint
流水线任务立即运行,无需等待build
阶段完成,因为它没有需求(needs: []
)。 - Linux 路径:
linux:rspec
和linux:rubocop
流水线任务在linux:build
运行后立即运行,流水线任务无需等待mac:build
完成即可完成。 - macOS 路径:
mac:rspec
和mac:rubocop
流水线任务在mac:build
运行后立即运行,流水线任务完成,无需等待linux:build
完成。 -
production
流水线任务在所有先前流水线任务完成后立即运行,即:linux:build
、linux:rspec
、linux:rubocop
、mac:build
、mac:rspec
、mac:rubocop
。
linux:build:
stage: build
mac:build:
stage: build
lint:
stage: test
needs: []
linux:rspec:
stage: test
needs: ["linux:build"]
linux:rubocop:
stage: test
needs: ["linux:build"]
mac:rspec:
stage: test
needs: ["mac:build"]
mac:rubocop:
stage: test
needs: ["mac:build"]
production:
stage: deploy
要求和限制
- 在 GitLab 13.9 及更早版本中,如果
needs:
指的是因only
、except
或rules
等可能不会添加到的流水线任务,则流水线可能无法创建。 -
needs:
数组中单个流水线任务可以需要的最大流水线任务数是有限的,限制是:50。 - 如果
needs:
是指使用parallel
关键字的流水线任务,这取决于并行创建的所有流水线任务,而不仅仅是一项流水线任务。它也下载默认情况下来自所有并行流水线任务的artifacts
。如果artifacts
有相同的名称,它们会相互覆盖,并且只保存最后下载的一个。 -
needs:
类似于dependencies:
,因为它必须使用先前阶段的流水线任务,这意味着不可能创建循环依赖项。根据流水线任务当前阶段也不可能。 - 必须为所有有关键字
needs:
或被其引用的流水线任务明确定义阶段。
needs
下载 artifacts
使用 当流水线任务使用 needs
时,默认情况下它不再下载前一阶段的所有 artifacts
,因为具有 medds
的流水线任务可以在早期阶段完成之前开始。当存在 needs
时,你只能从 needs:
配置中列出的流水线任务下载 artifacts
。
使用 artifacts: true
(默认值)或 artifacts: false
在出现在使用 needs
的流水线任务中来控制何时下载 artifacts
。
在以下示例中,rspec
流水线任务下载了 build_job
的 artifacts
,但是rubocop
流水线任务不会:
build_job:
stage: build
artifacts:
paths:
- binaries/
rspec:
stage: test
needs:
- job: build_job
artifacts: true
rubocop:
stage: test
needs:
- job: build_job
artifacts: false
在以下示例中,rspec
流水线任务从所有三个 build_jobs
中下载 artifacts
。其中 artifacts
设置为:
- 对
build_job_1
设置为true
。 - 对于
build_job_2
和build_job_3
,默认为true
。
rspec:
needs:
- job: build_job_1
artifacts: true
- job: build_job_2
- build_job_3
needs
跨项目下载 artifacts
流水线中使用 needs
从最多五个流水线任务下载 artifacts
:
- 在同一项目中的其他 ref
- 在不同的项目、组和命名空间中
build_job:
stage: build
script:
- ls -lhR
needs:
- project: namespace/group/project-name
job: build-1
ref: main
artifacts: true
build_job
从 group/project-name
项目的 main
分支上最新成功的 build-1
流水线任务下载 artifacts
。如果项目在
相同的组或命名空间,你可以从 project:
关键字中省略它们。例如,
project: group/project-name
或 project: project-name
。
运行流水线的用户必须至少具有对组或项目的Reporter
访问权限,或者组/项目是公开可见的。
artifacts
下载
同一项目中流水线间的 使用 needs
从当前项目中的不同流水线下载 artifacts
。将 project
关键字设置为当前项目的名称,并指定一个 ref
。
在以下示例中,build_job
从 ref 为 other-ref
的 build-1
流水线任务下载最新成功的 artifacts
:
build_job:
stage: build
script:
- ls -lhR
needs:
- project: group/same-project-name
job: build-1
ref: other-ref
artifacts: true
project:
、job:
和 ref
也支持 CI/CD 变量形式的参数。
例如:
build_job:
stage: build
script:
- ls -lhR
needs:
- project: $CI_PROJECT_PATH
job: $DEPENDENCY_JOB_NAME
ref: $ARTIFACTS_DOWNLOAD_REF
artifacts: true
你无法从 parallel:
中运行的流水线任务下载 artifacts
。
要在父子流水线之间下载 artifacts
,使用 needs:pipeline
。
你不应从相同的 ref 下正在运行的流水线下载 artifacts
,在同一个 ref 上运行的流水线可能会覆盖 artifacts
。
artifacts
下载到子流水线
子流水线可以从它的父流水线或同一父流水线中的另一个子流水线流水线任务中下载 artifacts
。
例如,以下是一个会创建一些 artifacts
的父流水线:
create-artifact:
stage: build
script: echo 'sample artifact' > artifact.txt
artifacts:
paths: [artifact.txt]
child-pipeline:
stage: test
trigger:
include: child.yml
strategy: depend
variables:
PARENT_PIPELINE_ID: $CI_PIPELINE_ID
子流水线中的流水线任务可以从父流水线:create-artifact
流水线任务中下载 artifacts
:
use-artifact:
script: cat artifact.txt
needs:
- pipeline: $PARENT_PIPELINE_ID
job: create-artifact
pipeline
接受一个流水线 ID,它必须是一个存在于给定流水线的相同父流水线层次结构中的流水线。
pipeline
不接受当前的流水线 ID ($CI_PIPELINE_ID
)。如果要从当前流水线中的流水线任务下载 artifacts
,请使用 needs
的基本形式。
needs
可选 如果需要的是流水线中有时不存在的流水线任务,请在 needs
配置中添加 optional: true
。如果未定义,optional: false
是默认值。
使用 rules
、only
或 except
的流水线任务可能并不总是存在于流水线中。当流水线启动时,在运行之前它会检查 needs
的关系。如果没有设置optional: true
,且需要的关系指向不存在的流水线任务时会阻止流水线启动并导致流水线产生一个类似如下错误:
'job1' job needs 'job2' job, but it was not added to the pipeline
在下面这个例子中:
- 当分支为默认分支时,流水线中存在
build
流水线任务,rspec
流水线任务在开始之前等待它完成。 - 当分支不是默认分支时,流水线中不存在
build
流水线任务。rspec
流水线任务立即运行(类似于needs: []
),因为它的needs
与build
流水线任务的关系是可选的。
build:
stage: build
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
rspec:
stage: test
needs:
- job: build
optional: true
tags
使用 tags
从所有的 Runner 列表中选择一个特定的可用于项目的 Runner。
当你注册 Runner 时,你可以指定 Runner 的 tag,比如ruby
、postgres
、development
等。
在以下示例中,流水线任务由同时定义了 ruby
和 postgres
tag 的 Runner 运行。
job:
tags:
- ruby
- postgres
你可以使用 tag 在不同平台上运行不同的流水线任务。比如,如果你有一个带有 osx
标签的 OS X Runner 和一个带有 windows
标签的 Windows Runner,你可以通过以下设置在每个平台上运行一个流水线任务:
windows job:
stage:
- build
tags:
- windows
script:
- echo Hello, %USERNAME%!
osx job:
stage:
- build
tags:
- osx
script:
- echo "Hello, $USER!"
allow_failure
当你想让流水线任务失败而不影响 CI 组合的其余部分时,请使用 allow_failure
。它的默认值为 false
,manual 使用
when: manual
语法时除外。
在使用 rules:
的流水线任务中,所有流水线任务默认为 allow_failure: false
,包括 when: manual
流水线任务。
当 allow_failure
设置为 true
并且流水线任务失败时,流水线任务会在 UI 中显示橙色警告。但是,流水线的逻辑流仍会将流水线任务视为
成功/通过,并且该流水线不会被 block。
假设所有其他流水线任务都成功,流水线任务的 stage 及其流水线显示相同的橙色警告。但是,与之关联的提交被标记为 passed
,并且没有警告提示。
在以下示例中,job1
和 job2
并行运行,如果 job1
失败,它不会停止下一个阶段的运行,因为它被标记为 allow_failure: true
:
job1:
stage: test
script:
- execute_script_that_will_fail
allow_failure: true
job2:
stage: test
script:
- execute_script_that_will_succeed
job3:
stage: deploy
script:
- deploy_to_staging
allow_failure:exit_codes
使用 allow_failure:exit_codes
动态控制是否应该允许流水线任务失败。你可以列出哪些退出代码不被视为失败。对于任何其他退出代码,流水线任务失败:
test_job_1:
script:
- echo "Run a script that results in exit code 1. This job fails."
- exit 1
allow_failure:
exit_codes: 137
test_job_2:
script:
- echo "Run a script that results in exit code 137. This job is allowed to fail."
- exit 137
allow_failure:
exit_codes:
- 137
- 255
when
使用 when
来实现在失败或不管失败的情况下运行的流水线任务。
when
的有效值为:
-
on_success
(默认)- 只有在早期阶段的所有流水线任务都成功时才执行流水线任务,或者当它们设置了allow_failure: true
时,总是视作成功的。 -
on_failure
- 仅在较早阶段的至少一项流水线任务失败时才执行流水线任务。 -
always
- 无论早期阶段的流水线任务状态如何,都执行流水线任务。 -
manual
- 手动 执行流水线任务。 -
delayed
- 延迟流水线任务的执行 指定的持续时间。 -
never
:- 使用流水线任务
rules
,不执行流水线任务。 - 使用
workflow:rules
,不运行流水线。
- 使用流水线任务
在以下示例中,脚本代码:
- 只有当
build_job
失败时才执行cleanup_build_job
。 - 始终执行
cleanup_job
作为流水线的最后一步,不管成功或失败。 - 在 UI 中手动运行时执行
deploy_job
。
stages:
- build
- cleanup_build
- test
- deploy
- cleanup
build_job:
stage: build
script:
- make build
cleanup_build_job:
stage: cleanup_build
script:
- cleanup build when failed
when: on_failure
test_job:
stage: test
script:
- make test
deploy_job:
stage: deploy
script:
- make deploy
when: manual
cleanup_job:
stage: cleanup
script:
- cleanup after jobs
when: always
when:manual
手动流水线任务是一种不会自动执行的流水线任务,它必须由用户启动。你可能希望将手动流水线任务用于部署到生产之类的事情。
要实现一个手动的流水线,请将 when: manual
添加到其配置中。
流水线启动时,手动流水线任务显示为已跳过且不会自动运行。它们可以从流水线、流水线任务、环境和部署视图中启动执行。
手动流水线任务可以是可选的或阻塞的:
-
可选:手动流水线任务默认设置为 `allow_failure: true 并且被认为是可选的。可选手工流水线任务的状态并不影响整体的流水线状态。即使所有手动流水线任务都失败,流水线也可以成功运行。
-
阻塞:要将手动流水线任务设置为阻塞,请将
allow_failure: false
添加到其配置中。阻塞的手动流水线任务会在其被定义的下一阶段停止流水线的进一步执行。要让流水线继续运行,请单击阻塞手动流水线任务上的 {play} 按钮。项目中设置了流水线成功时合并的合并请求在有流水线阻塞的情况下无法合并。阻塞的流水线显示 阻塞 的状态。
当你使用 rules:
时,allow_failure
的值默认为 false
,包括手动流水线任务。
要触发手动流水线任务,用户必须具有合并到指定分支的权限。你可以使用 保护分支 来更限制未经授权的用户运行保护手动部署。
when:delayed
使用 when: delay
在等待期后执行脚本,或者如果你想避免流水线任务立即进入 pending
状态。
你可以使用 start_in
关键字设置时间范围。start_in
的值是以秒为单位的时间范围,除非提供了时间单位。start_in
必须小于或等于 1 周。有效值的示例包括:
'5'
5 seconds
30 minutes
1 day
1 week
Delay 设置的时间不计算在流水线用量中,但默认流水线超时时间为60分钟,建议不要设置过长,否则会因为超时导致流水线的失败。
当阶段包含延迟流水线任务时,流水线在延迟流水线任务完成之前不会进行。你可以使用此关键字在不同阶段之间插入延迟。
延迟流水线任务的计时器在前一阶段完成后立即启动。与其他类型的流水线任务类似,除非前一阶段通过,否则延迟流水线任务的计时器不会启动。
以下示例创建了一个名为 timed rollout 10%
的流水线任务,该流水线任务在前一阶段完成 30 分钟后执行:
timed rollout 10%:
stage: deploy
script: echo 'Rolling out 10% ...'
when: delayed
start_in: 30 minutes
要停止延迟流水线任务的活动计时器,请单击 {time-out} (Unschedule) 按钮。之后,将无法再安排此流水线任务自动运行。但是,你可以手动执行流水线任务。
要立即开始延迟流水线任务,请单击 play 按钮。很快,Runner 将接手并开始工作。
environment
使用 environment
定义流水线任务部署到的环境。
例如:
deploy to production:
stage: deploy
script: git push production HEAD:main
environment: production
你可以使用以下方法为 environment
关键字进行赋值:
- 纯文本,如
production
。 - 变量,包括 CI/CD 变量、预定义、安全或变量,在
.codechina-ci.yml
文件中定义。
你不能使用在 script
部分中定义的变量。
如果你指定了一个 environment
且不存在具有该名称的环境,就会新建这个环境。
environment:name
为 environment
设置名称。例如:
deploy to production:
stage: deploy
script: git push production HEAD:main
environment:
name: production
常见的环境名称是 qa
、staging
和 production
,但你可以使用任何你想要的名字。
你可以使用以下命令为 name
关键字进行赋值:
- 纯文本,如
staging
。 - 变量,包括在
.codechina-ci.yml
文件中定义的 CI/CD 变量、预定义、安全或变量。
你不能使用在 script
部分中定义的变量。
环境 name
可以包含:
- Letters
- Digits
- Spaces
-
_
/
$
{
}
environment:url
为 environment
设置 URL。例如:
deploy to production:
stage: deploy
script: git push production HEAD:main
environment:
name: production
url: https://prod.example.com
流水线任务完成后,你可以使用合并请求中的按钮访问 URL,环境或部署页面。
你可以使用以下方法为 url
关键字进行赋值:
- 纯文本,如
https://prod.example.com
。 - 变量,包括在
.codechina-ci.yml
文件中定义 CI/CD 变量、预定义、安全或变量。
你不能使用在 script
部分中定义的变量。
environment:on_stop
关闭(停止)环境可以在 environment
下定义使用 on_stop
关键字来实现。它声明了一个不同的流水线任务来关闭环境。
阅读 environment:action
部分的示例。
environment:action
使用 action
关键字来指定准备、启动或停止环境的流水线任务。
| 值 | 说明 |
|-----------|------------------------------------ -------------------------------------------------- -------------------------------------------------- ---------------|
| start
| 默认值。表示流水线任务启动环境。部署是在流水线任务启动后创建的 |
| prepare
| 表示流水线任务只准备环境。它不会触发部署 |
| stop
| 表示流水线任务停止部署。请参阅下面的示例 |
举个例子:
review_app:
stage: deploy
script: make deploy-app
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_ENVIRONMENT_SLUG.example.com
on_stop: stop_review_app
stop_review_app:
stage: deploy
variables:
GIT_STRATEGY: none
script: make delete-app
when: manual
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
在上面的例子中,review_app
流水线任务部署到 review
环境。在 on_stop
下列出了一个新的 stop_review_app
流水线任务。在 review_app
流水线任务完成后,它会基于 when
下定义的内容触发 stop_review_app
流水线任务。在这个例子中,它被设置为 manual
,所以它需要一个 manual action 并从 UI 中手动运行。
在示例中,GIT_STRATEGY
设置为 none
。如果 stop_review_app
流水线任务是自动触发,删除分支后,运行程序不会尝试检查代码。
该示例还覆盖了全局变量。如果你的 stop
environment
流水线任务取决于在全局变量上,在设置 GIT_STRATEGY
时使用 anchor variables在不覆盖全局变量的情况下更改流水线任务。
stop_review_app
流水线任务需要定义以下关键字:
-
when
,定义于:- 流水线任务级别。
-
在规则条款中。如果你使用
rules:
和when: manual
,你还应该设置allow_failure: true
以便可以完成流水线即使流水线任务没有运行。
environment:name
environment:action
此外,每个流水线任务都应该有匹配的 rules
或 only/except
配置。
在上面的示例中,如果配置不相同:
-
stop_review_app
流水线任务可能不会包含在所有引用了review_app
流水线任务的流水线中。 - 无法触发
action: stop
来自动停止环境。
environment:auto_stop_in
auto_stop_in
关键字用于指定环境的生命周期,当过期时,系统会自动停止它们。
例如,
review_app:
script: deploy-review-app
environment:
name: review/$CI_COMMIT_REF_NAME
auto_stop_in: 1 day
当为 review_app
创建环境时,环境的生命周期设置为 “1 天”。每次部署审查应用程序时,该生命周期也会重置为 “1 天”。
environment:kubernetes
使用 kubernetes
关键字将部署配置为与你的项目相关联的 Kubernetes cluster
。
例如:
deploy:
stage: deploy
script: make deploy-app
environment:
name: production
kubernetes:
namespace: production
此配置使用 production
Kubernetes 命名空间,将 deploy
流水线任务部署到 production
环境。
Kubernetes 配置不支持由 GitLab 管理的 Kubernetes cluster。
environment:deployment_tier
使用 deployment_tier
关键字指定部署环境的层级:
deploy:
script: echo
environment:
name: customer-portal
deployment_tier: production
动态环境
使用 CI/CD 变量 来动态命名环境。
例如:
deploy as review app:
stage: deploy
script: make deploy
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_ENVIRONMENT_SLUG.example.com/
在这个例子中,deploy as review app
流水线任务被标记为动态部署创建 review/$CI_COMMIT_REF_NAME
环境。$CI_COMMIT_REF_NAME
是由 Runner 设置的 CI/CD 变量。$CI_ENVIRONMENT_SLUG
变量基于环境名称,可适用于 URL 中。如果 deploy as review app
流水线任务在名为 pow
的分支中运行,则这个环境可以通过 https://review-pow.example.com/
这样的 URL 访问。
常见的用法是为分支创建动态环境并使用它们作为审查应用程序。你可以在以下位置查看使用 Review Apps 的示例 https://gitlab.com/gitlab-examples/review-apps-nginx/。
cache
使用 cache
指定流水线任务之间要使用的文件和目录列表的缓存。你只能使用本地工作副本中的路径。
如果在流水线任务范围之外定义了 cache
,则它会是一个全局设置并且所有流水线任务都将使用该配置。
缓存在流水线和流水线任务之间共享。缓存在 artifacts 之前恢复。
cache:paths
使用 paths
命令选择要缓存的文件或目录。路径相对于项目目录 ($CI_PROJECT_DIR
),不能直接链接到项目目录之外。你可以使用使用 glob 的通配符模式。
缓存 binaries
中以 .apk
文件结尾和 .config
文件结尾的所有文件:
rspec:
script: test
cache:
paths:
- binaries/*.apk
- .config
本地定义的缓存覆盖全局定义的选项。以下例子中 rspec
流水线任务只缓存 binaries/
:
cache:
paths:
- my/files
rspec:
script: test
cache:
key: rspec
paths:
- binaries/
缓存在流水线任务之间是共享的,因此如果你使用不同的不同流水线任务的路径,你还应该设置不同的 cache:key
,否则缓存内容可能会被覆盖。
cache:key
key
关键字定义了流水线任务之间缓存的亲和性。你可以为所有流水线任务使用一个缓存,或者为流水线任务生成缓存,或为每个分支生成缓存,或任何其他适合你工作流程的方式来生成缓存。你可以微调缓存,包括在不同流水线任务甚至不同分支之间缓存数据。
cache:key
变量可以使用任何预定义变量。如果不是
设置,默认值只是字面上的 default
,这意味着默认情况下一切缓存都在流水线和流水线任务之间共享。
比如,要为每个分支启用缓存:
cache:
key: "$CI_COMMIT_REF_SLUG"
paths:
- binaries/
如果你使用 Windows Batch 运行你的 shell 脚本,则需要替换 $
和 %
:
cache:
key: "%CI_COMMIT_REF_SLUG%"
paths:
- binaries/
cache:key
变量不能包含 /
字符或等效字符 URI 编码的 %2F
,也禁止仅由点(.
、%2E
)组成的值。
如果未找到指定的 cache:key
,你可以指定使用 fallback 缓存键 。
多个缓存
你最多可以有四个缓存:
test-job:
stage: build
cache:
- key:
files:
- Gemfile.lock
paths:
- vendor/ruby
- key:
files:
- yarn.lock
paths:
- .yarn-cache/
script:
- bundle install --path=vendor
- yarn install --cache-folder .yarn-cache
- echo Run tests...
如果多个缓存与一个 Fallback 缓存键 组合在一起,如果未找到多个缓存,则多次获取回退。
回退缓存键
你可以使用$CI_COMMIT_REF_SLUG
variable 来指定你的cache:key
。例如,如果你的 $CI_COMMIT_REF_SLUG
是 test
你可以设置一个流水线任务
下载标有 test
的缓存。
如果没有找到带有这个标签的缓存,也就是缓存不存在时,你可以指定使用CACHE_FALLBACK_KEY
。
在下面的例子中,如果未找到 $CI_COMMIT_REF_SLUG
,则流水线任务使用通过CACHE_FALLBACK_KEY
变量定义的键:
variables:
CACHE_FALLBACK_KEY: fallback-key
cache:
key: "$CI_COMMIT_REF_SLUG"
paths:
- binaries/
cache:key:files
cache:key:files
关键字扩展了 cache:key
功能,使其可以更容易重用一些缓存,并减少重建它们的频率,从而加快后续流水线运行。
当你引用了 cache:key:files
时,你还必须列出用于生成密钥的项目文件(最多两个文件)。缓存 key
是根据指定文件的最近提交(最多两个,如果列出了两个文件)计算的 SHA 校验的。如果指定文件在任何提交中都没有更改,那么后退键是 default
。
cache:
key:
files:
- Gemfile.lock
- package.json
paths:
- vendor/ruby
- node_modules
这个例子中,为 Ruby
和 Node.js
依赖项创建缓存,并与当前版本的 Gemfile.lock
和 package.json
文件相关联。每当这些文件发生变化时,会计算新的缓存键并创建新的缓存。未来任何流水线任务运行使用了由相同的 Gemfile.lock
和 package.json
的 cache:key:files
都使用新的缓存,而不是重建这些依赖项。
cache:key:prefix
当你想将前缀与通过 cache:key:files
计算的 SHA 结合起来时,将 prefix
关键字与 key:files
一起使用。例如,如果添加了 test
作为 prefix
,结果 key 为test-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5
。如果给定文件在任何提交中都没有更改,则会在 default
上添加前缀,因此示例中的 key 是 test-default
。
像cache:key
一样,prefix
可以使用任何预定义变量,但不能包括:
-
/
字符(或等效的 URI 编码的%2F
) - 仅由
.
组成的值(或等效的 URI 编码的%2E
)
cache:
key:
files:
- Gemfile.lock
prefix: ${CI_JOB_NAME}
paths:
- vendor/ruby
rspec:
script:
- bundle exec rspec
例如,添加了 $CI_JOB_NAME
的 prefix
后密钥看起来像:rspec-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5
,并且流水线任务缓存在不同的分支之间共享。如果某个分支中的 Gemfile.lock
发生变化,则该分支对 cache:key:files
有一个新的 SHA 校验并生成一个新的缓存 key,并为该键创建一个新的缓存。如果没有找到 Gemfile.lock
,则将前缀添加到 default
,因此示例中的 key 会是 rspec-default
。
cache:untracked
设置 untracked: true
以缓存 Git 中未跟踪的所有文件存储库:
rspec:
script: test
cache:
untracked: true
缓存所有 Git 未跟踪文件和 binaries
中的文件:
rspec:
script: test
cache:
untracked: true
paths:
- binaries/
cache:when
cache:when
根据流水线任务的状态来定义何时保存缓存。你可以将 cache:when
设置为:
-
on_success
(默认):仅在流水线任务成功时保存缓存。 -
on_failure
:仅在流水线任务失败时保存缓存。 -
always
:始终保存缓存。
例如,无论流水线任务是否成功,都要存储缓存:
rspec:
script: rspec
cache:
paths:
- rspec/
when: 'always'
cache:policy
缓存流水线任务的默认行为是在开始执行时下载文件,并在最后重新上传它们。任何流水线任务的更改将保留以供将来运行。这种行为被称为pull-push
缓存政策。
如果你知道该流水线任务不会更改缓存文件,则可以跳过上传步骤,通过在流水线任务中设置 policy: pull
。可以在较早的阶段中添加普通缓存流水线任务以确保缓存保持更新:
stages:
- setup
- test
prepare:
stage: setup
cache:
key: gems
paths:
- vendor/bundle
script:
- bundle install --deployment
rspec:
stage: test
cache:
key: gems
paths:
- vendor/bundle
policy: pull
script:
- bundle exec rspec ...
当你有许多使用缓存并行执行的流水线任务时,请使用 pull
策略。该策略可以加速流水线任务执行并减少缓存服务器上的负载。
如果你的流水线任务无条件地重新创建缓存,参考之前的内容,可以跳过下载步骤。为此,可以将 policy: push
添加到流水线任务中。
artifacts
使用 artifacts
指定文件和目录列表。当它 succeeds, fails, or always 时附加到流水线任务中。
流水线任务完成后, artifacts
将发送到 codechina。如果他们的大小不超过 500M (目前设置的最大 artifacts
大小),就可以在 UI 中进行下载。
默认情况下,后期的流水线任务会自动下载所有通过早期阶段的流水线任务创建的 artifacts
。你可以使用 dependencies
命令控制流水线任务中的 artifacts
下载行为。
使用 needs
关键字时,流水线任务只能下载来自在 needs
配置中定义的流水线任务的 artifacts
。
默认情况下,仅为成功的流水线任务收集流水线任务 artifacts
,并且在 caches 之后恢复 artifacts
。
dependencies
默认情况下,前一阶段的所有 artifacts
将传递给每个流水线任务。但是,你可以使用 dependencies
关键字来定义要从中获取 artifacts
的有限流水线任务列表。你还可以设置一个完全不下载任何 artifacts
流水线任务。
要使用此功能,请在流水线任务上下文中定义 dependencies
并提供一个应从先前流水线任务中下载 artifacts
的流水线任务列表。
你可以在当前阶段之前执行的阶段定义流水线任务。如果你从当前或即将到来的阶段定义流水线任务,则会发生错误。
要防止流水线任务下载 artifacts
,请定义一个空数组。
当你使用 dependencies
时,并不考虑上一个流水线任务的状态。如果流水线任务失败或者是未触发的手动流水线任务,则不会发生错误。
以下示例定义了两个带有 artifacts
的流水线任务:build:osx
和 build:linux
。当 test:osx
执行时,build:osx
中的 artifacts
在构建的上下文中下载和提取。同样的事情发生于 test:linux
和来自 build:linux
的 artifacts
。
流水线任务 deploy
下载所有先前流水线任务的 artifacts
,因为 stage 优先级:
build:osx:
stage: build
script: make build:osx
artifacts:
paths:
- binaries/
build:linux:
stage: build
script: make build:linux
artifacts:
paths:
- binaries/
test:osx:
stage: test
script: make test:osx
dependencies:
- build:osx
test:linux:
stage: test
script: make test:linux
dependencies:
- build:linux
deploy:
stage: deploy
script: make deploy
当依赖流水线任务失败时
如果设置为依赖项的流水线任务 artifacts
是 过期的
或 已删除
,则
依赖流水线任务失败。
artifacts:exclude
exclude
可以防止将文件添加到 artifacts
中。
类似于 artifacts:paths
,exclude
路径是相对于项目目录的。你可以使用通配符 glob 或 doublestar.PathMatch
模式。
例如,要存储在 binaries/
中的所有文件,而不存储 binaries/
中的子目录 *.o
文件:
artifacts:
paths:
- binaries/
exclude:
- binaries/**/*.o
与 artifacts:paths
不同,exclude
路径不是递归的。要排除目录的所有内容,你可以显式匹配它们而不是匹配目录本身。
例如,要存储 binaries/
中的所有文件,但不包括位于 temp/
子目录中的文件:
artifacts:
paths:
- binaries/
exclude:
- binaries/temp/**/*
artifacts:untracked
匹配的文件也可以使用artifacts:exclude
来排除。
artifacts:expire_in
使用 expire_in
指定流水线任务的 artifacts
在它们过期并被删除之前存储多长时间。expire_in
设置不会影响到:
- 来自最新流水线任务的
artifacts
,除非保留最新的流水线任务artifacts
是在项目级别禁用的。 - 流水线
artifacts
。以下情况的到期日期将无法指定:- 来自最新流水线的流水线
artifacts
将永远保留。 - 其它一周后删除
artifacts
的流水线。
- 来自最新流水线的流水线
expire_in
的值是以秒为单位的时间范围,除非提供了单位。有效值包括:
'42'
42 seconds
3 mins 4 sec
2 hrs 20 min
2h20min
6 mos 1 day
47 yrs 6 mos and 4d
3 weeks and 2 days
never
要在上传后一周使 artifacts
过期,你可以这样设置:
job:
artifacts:
expire_in: 1 week
当 artifacts
上传并存储之后,到期时间段开始启动计时。如果到期时间未定义,则默认为 30 天。
要覆盖到期日期并保护 artifacts
不被自动删除,你可以这样做:
- 使用流水线任务页面上的保留按钮。
- 将
expire_in
的值设置为never
。
过期后, artifacts
默认每小时删除一次(使用 cron 流水线任务),并且不再可以进行访问。
artifacts:expose_as
使用 expose_as
关键字在合并请求 UI 中公开流水线任务的 artifacts
。
例如,要匹配单个文件:
test:
script: ["echo 'test' > file.txt"]
artifacts:
expose_as: 'artifact 1'
paths: ['file.txt']
在进行了如上的配置后,会在相关的合并请求中添加一个 artifact 1 的链接并指向 file1.txt
。要访问链接,在合并请求概述中的流水线图下方选择 **查看暴露的 artifacts
**即可。
匹配整个目录的示例:
test:
script: ["mkdir test && echo 'test' > test/file.txt"]
artifacts:
expose_as: 'artifact 1'
paths: ['test/']
注意事项:
- 使用变量定义
artifacts:paths
时,不会在合并请求 UI 中显示artifacts
。 - 每个合并请求最多可以显示 10 个流水线任务的
artifacts
。 - 不支持全局模式。
- 如果指定了目录,并且目录中不止一个文件的话,则链接到流水线任务
artifacts
浏览器。 - 对于带有
.html
、.htm
、.txt
、.json
、.xml
和.log
扩展名,且Pages :- 启用,则自动呈现
artifacts
。 - 未启用,文件显示在
artifacts
浏览器中。
- 启用,则自动呈现
artifacts:name
使用 name
命令定义创建的 artifacts
的名称。你可以为每个存档指定唯一的名称。artifacts:name
变量可以使用任何预定义变量。默认名称是artifacts
,下载后会变成artifacts.zip
。
要使用当前流水线任务的名称创建存档,你可以这样做:
job:
artifacts:
name: "$CI_JOB_NAME"
paths:
- binaries/
使用当前分支或标记的名称创建存档,仅包含 binaries
目录中的文件,你可以这样做:
job:
artifacts:
name: "$CI_COMMIT_REF_NAME"
paths:
- binaries/
如果你的分支名称包含 /
(例如feature/my-feature
)建议使用 $CI_COMMIT_REF_SLUG
而不是$CI_COMMIT_REF_NAME
来命名 artifacts
。
使用当前流水线任务和当前分支的名称或 tag 创建存档,并且仅包含 binaries
目录中的文件,你可以这样做:
job:
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
paths:
- binaries/
要使用当前 stage 和分支名称的名称创建存档,你可以这样做:
job:
artifacts:
name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
paths:
- binaries/
如果你使用 Windows Batch 运行你的 shell 脚本,则需要替换 $
和 %
:
job:
artifacts:
name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%"
paths:
- binaries/
如果你使用 Windows PowerShell 运行你的 shell 脚本,则需要替换 $
和 $env:
:
job:
artifacts:
name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME"
paths:
- binaries/
artifacts:paths
路径是相对于项目目录($CI_PROJECT_DIR
)的,不能直接设置项目外面的链接。你可以使用使用 glob 的通配符模式和 doublestar.Glob
模式。
要限制特定流水线任务从哪些流水线任务获取 artifacts
,请参阅 dependencies。
要包含 binaries
和 .config
中的所有文件,你可以这样做:
artifacts:
paths:
- binaries/
- .config
要禁用 artifacts
传递,请使用空 dependencies 来定义流水线任务:
job:
stage: build
script: make build
dependencies: []
你可能只想为发行版创建 artifacts
以避免使用太多的临时 artifacts
去占用构建服务器的存储。
仅为发行版创建 artifacts
(default-job
不创建 artifacts
),你可以这样做:
default-job:
script:
- mvn test -U
except:
- tags
release-job:
script:
- mvn package -U
artifacts:
paths:
- target/*.war
only:
- tags
你也可以对目录使用通配符。例如,如果你想获取所有以 xyz
结尾的目录中的文件:
job:
artifacts:
paths:
- path/*xyz/*
artifacts:public
使用 artifacts:public
来确定流水线任务的 artifacts
是否公开可用。
artifacts:public
的默认值为 true
,这意味着匿名和访客用户可以下载公共流水线中的 artifacts
:
artifacts:
public: true
拒绝匿名用户和访客用户对公共流水线中 artifacts
的读取访问,可以将 artifacts:public
设置为 false
:
artifacts:
public: false
artifacts:reports
使用 artifacts:reports
从流水线任务中收集测试报告、代码质量报告和安全报告。它还会在合并请求和流水线视图的 UI 中公开这些报告。
无论流水线任务结果如何(成功或失败),都会收集测试报告。你可以使用 artifacts:expire_in
来设置过期时间。
如果你还希望能够浏览报告输出文件,请使用artifacts:paths
关键字。
artifacts:reports:cobertura
cobertura
报告收集 Cobertura 覆盖 XML 文件。收集的 Cobertura 覆盖率报告作为 artifacts
上传并显示在合并请求中。
Cobertura 最初是为 Java 开发的,但也有很多其他语言(如 JavaScript、Python、Ruby 等)的第三方端口。
artifacts:reports:codequality
codequality
报告收集代码质量问题。
收集的代码质量报告作为 artifacts
上传到并在合并请求中汇总。
artifacts:reports:dotenv
dotenv
报告收集一组环境变量作为 artifacts
。
收集的变量被注册为流水线任务的运行时创建的变量,这对于在流水线任务完成后设置动态环境 URL 会非常有用。
原始 dotenv 规则 有几个例外:
- 变量键只能包含字母、数字和下划线 (
_
)。 -
.env
文件的最大大小为 5 KB。 - 最大继承变量数为 20。
- 不支持
.env
文件中的变量替换。 -
.env
文件不能有空行或注释(以#
开头)。 -
env
文件中的键值不能有空格或换行符 (\n
),包括使用单引号或双引号时。 - 不支持在解析过程中引用转义 (
key = 'value'
->{key: "value"}
)。
artifacts:reports:junit
junit
报告收集 JUnit 报告格式 XML 文件 作为 artifacts
。虽然 JUnit 最初是用 Java 开发的,但有很多第三方端口用于其他JavaScript、Python、Ruby 等语言。
有关更多详细信息和示例,请参阅单元测试报告。下面是从 Ruby 的 RSpec 测试工具收集 JUnit 报告格式 XML 文件的示例:
rspec:
stage: test
script:
- bundle install
- rspec --format RspecJunitFormatter --out rspec.xml
artifacts:
reports:
junit: rspec.xml
收集到的单元测试报告作为 artifacts
上传并显示在合并请求中。
如果你使用的 JUnit 工具导出到多个 XML 文件,请指定单个流水线任务中的多个测试报告路径
将它们连接成一个文件。使用文件名模式(junit: rspec-*.xml
),文件名数组(junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]
),或其组合(junit: [rspec.xml, test-results/TEST-*.xml]
)的方式。
artifacts:reports:terraform
terraform
报告获取 Terraform tfplan.json
文件。收集到的计划报告作为 artifacts
上传并显示在合并请求中。
artifacts:untracked
使用 artifacts:untracked
将所有 Git 未跟踪文件添加为 artifacts
(以及使用 artifacts:paths
中定义的路径)。artifacts:untracked
忽略配置在存储库 .gitignore
中的文件。
发送所有 Git 未跟踪文件:
artifacts:
untracked: true
发送所有 Git 未跟踪文件和 binaries
中的文件:
artifacts:
untracked: true
paths:
- binaries/
发送所有未跟踪的文件,但 排除 *.txt
文件:
artifacts:
untracked: true
exclude:
- "*.txt"
artifacts:when
使用 artifacts:when
在流水线任务失败或不论失败与否时上传 artifacts
。
artifacts:when
可以设置为以下值之一:
-
on_success
(默认):仅在流水线任务成功时上传artifacts
。 -
on_failure
:仅在流水线任务失败时上传artifacts
。 -
always
:始终上传artifacts
。例如,当需要上传artifacts
对失败的测试进行故障排除时会非常有用。
例如,仅在流水线任务失败时上传 artifacts
:
job:
artifacts:
when: on_failure
coverage
使用 coverage
配置如何从流水线任务输出。
正则表达式是此处预期的唯一有效值。所以,使用 /
包裹是强制性的,以一致且明确地表示
一个正则表达式字符串。如果需要的话,你必须转义特殊字符以从字面上匹配它们。
例如:
job1:
script: rspec
coverage: '/Code coverage: \d+\.\d+/'
当流水线任务输出中至少有一行与正则表达式匹配时,则覆盖率会显示在 UI 中。如果流水线任务输出中有多个匹配的行,则使用最后一行。对于匹配的行,第一次出现 \d+(\.\d+)?
是代码覆盖率。前面的空内容会被删除。
子流水线的覆盖率输出并未记录或显示
retry
使用 retry
配置一个流水线任务失败时的重试次数。
当一个流水线任务失败时,该流水线任务会被重新处理,直至达到由 retry
关键字指定限制的次数。
如果 retry
设置为 2
,并且流水线任务在第二次运行(第一次重试)中成功,则不会再次重试。retry
值必须是一个正整数,从 0
到 2
(最多重试两次,总共运行三次)。
以下示例重试所有失败情况:
test:
script: rspec
retry: 2
默认情况下,在所有失败情况下都会重试流水线任务。为了更好地控制重试失败,retry
可以是具有以下键的散列:
-
max
:最大重试次数。 -
when
:要重试的失败 case。
当 Runner 系统故障时最多重试两次,你可以这样做:
test:
script: rspec
retry:
max: 2
when: runner_system_failure
如果除了 Runner 系统故障之外还有其他故障,流水线任务不会重试。
要重试多个失败 cases,when
也可以是一个失败 cases 数组:
test:
script: rspec
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure
when
的可能值为:
-
always
:在任何失败时重试(默认)。 -
unknown_failure
:失败原因未知时重试。 -
script_failure
:脚本失败时重试。 -
api_failure
:API 失败时重试。 -
stuck_or_timeout_failure
:当流水线任务卡住或超时时重试。 -
runner_system_failure
:如果存在运行器系统故障(例如,流水线任务设置失败),则重试。 -
missing_dependency_failure
:如果缺少依赖项,则重试。 -
runner_unsupported
:如果 Runner 不受支持,则重试。 -
stale_schedule
:如果无法执行延迟的流水线任务,则重试。 -
job_execution_timeout
:如果脚本超过为流水线任务设置的最大执行时间,则重试。 -
archived_failure
:如果流水线任务已存档且无法运行,则重试。 -
unmet_prerequisites
:如果流水线任务未能完成先决任务,则重试。 -
scheduler_failure
:如果调度程序未能将流水线任务分配给运行程序,则重试。 -
data_integrity_failure
:如果检测到结构完整性问题,则重试。
你可以使用变量指定特定流水线任务执行阶段的重试次数。
timeout
使用 timeout
为特定流水线任务配置超时。例如:
build:
script: build.sh
timeout: 3 hours 30 minutes
test:
script: rspec
timeout: 3h 30m
流水线任务级超时可以超过项目级超时时间 ,但不能 超过 Runner 设置的超时时间。
parallel
使用 parallel
配置要并行运行的流水线任务实例的数量。该值可以是 2 到 50。
parallel
关键字创建并行运行的同一流水线任务的 N 个实例。它们的命名顺序是从 job_name 1/N
到 job_name N/N
:
test:
script: rspec
parallel: 5
每个并行流水线任务都有一个 CI_NODE_INDEX
和 CI_NODE_TOTAL
预定义 CI/CD 变量 设置。
不同的语言和测试套件有不同的方法来实现并行。例如,使用 Semaphore Test Boosters和 RSpec 并行运行 Ruby 测试:
# Gemfile
source 'https://rubygems.org'
gem 'rspec'
gem 'semaphore_test_boosters'
test:
parallel: 3
script:
- bundle
- bundle exec rspec_booster --job $CI_NODE_INDEX/$CI_NODE_TOTAL
警告:
Test Boosters 会向其作者报告使用统计数据。
然后,你可以导航到新流水线构建的 流水线任务 选项卡,这时你会发现 RSpec 的流水线任务已经分为三个独立的流水线任务。
matrix
流水线任务
并行 使用 matrix:
在单个流水线中并行运行流水线任务多次,但每个流水线任务实例都有不同的变量值。可以有 2 到 50 个流水线任务。
流水线任务只有在有多个 Runner 或单个 Runner 被配置为同时运行多个流水线任务时才能并行运行。
每个流水线任务都获得相同的 CI_NODE_TOTAL
CI/CD 变量 值和唯一的 CI_NODE_INDEX
值。
deploystacks:
stage: deploy
script:
- bin/deploy
parallel:
matrix:
- PROVIDER: aws
STACK:
- monitoring
- app1
- app2
- PROVIDER: ovh
STACK: [monitoring, backup, app]
- PROVIDER: [gcp, vultr]
STACK: [data, processing]
上面的例子生成了 10 个并行的 deploystacks
流水线任务,对于 PROVIDER
和 STACK
每个流水线任务具有不同的值:
deploystacks: [aws, monitoring]
deploystacks: [aws, app1]
deploystacks: [aws, app2]
deploystacks: [ovh, monitoring]
deploystacks: [ovh, backup]
deploystacks: [ovh, app]
deploystacks: [gcp, data]
deploystacks: [gcp, processing]
deploystacks: [vultr, data]
deploystacks: [vultr, processing]
matrix
流水线任务
一维 你还可以在单个流水线任务中使用一维矩阵:
deploystacks:
stage: deploy
script:
- bin/deploy
parallel:
matrix:
- PROVIDER: [aws, ovh, gcp, vultr]
matrix
触发流水线任务
并行 使用 matrix:
在单个流水线中多次并行运行 trigger 流水线任务,但每个流水线任务实例都有不同的变量值。
deploystacks:
stage: deploy
trigger:
include: path/to/child-pipeline.yml
parallel:
matrix:
- PROVIDER: aws
STACK: [monitoring, app1]
- PROVIDER: ovh
STACK: [monitoring, backup]
- PROVIDER: [gcp, vultr]
STACK: [data]
此示例生成 6 个并行的 deploystacks
触发器流水线任务,对于 PROVIDER
和 STACK
每个流水线任务具有不同的值,它们使用这些变量创建了 6 个不同的子流水线。
deploystacks: [aws, monitoring]
deploystacks: [aws, app1]
deploystacks: [ovh, monitoring]
deploystacks: [ovh, backup]
deploystacks: [gcp, data]
deploystacks: [vultr, data]
trigger
使用 trigger
定义下游流水线触发器。当开始一个 trigger
流水线任务时,会创建下游流水线。
带有trigger
的流水线任务只能使用有限的关键字集。例如,你不能用 script
,before_script
,或 after_script
。
你可以使用此关键字创建两种不同类型的下游流水线:
- 多项目流水线
- 子流水线
你可以查看哪个流水线任务触发了下游流水线。在流水线图中,并将鼠标悬停在下游流水线流水线任务上即可查看。
你可以在与 trigger
相同的流水线任务中使用 when:manual
。
trigger
语法
多项目流水线的基本 你可以使用 trigger
关键字和下游项目的完整路径配置下游触发器:
rspec:
stage: test
script: bundle exec rspec
staging:
stage: deploy
trigger: my/deployment
trigger
语法
多项目流水线的复杂 你可以配置一个用分支名称来创建的具有以下功能的下游流水线:
rspec:
stage: test
script: bundle exec rspec
staging:
stage: deploy
trigger:
project: my/deployment
branch: stable
要从触发的流水线镜像状态:
trigger_job:
trigger:
project: my/project
strategy: depend
要从上游流水线镜像状态:
upstream_bridge:
stage: test
needs:
pipeline: other/project
trigger
语法
子流水线的 要创建子流水线,请指定包含子流水线配置的 YAML 文件路径:
trigger_job:
trigger:
include: path/to/child-pipeline.yml
类似于多项目流水线,可以从触发的流水线中镜像状态:
trigger_job:
trigger:
include:
- local: path/to/child-pipeline.yml
strategy: depend
使用生成的配置文件触发子流水线
你还可以通过动态生成的配置文件触发子流水线:
generate-config:
stage: build
script: generate-ci-config > generated-config.yml
artifacts:
paths:
- generated-config.yml
child-pipeline:
stage: test
trigger:
include:
- artifact: generated-config.yml
job: generate-config
generated-config.yml
是从 artifacts
中提取出来的,并被用作触发子流水线的配置。
使用来自另一个项目的文件触发子流水线
使用来自同一私有项目的文件触发子流水线实例,使用 include:file
:
child-pipeline:
trigger:
include:
- project: 'my-group/my-pipeline-library'
ref: 'main'
file: '/path/to/child-pipeline.yml'
trigger:strategy
链接流水线
使用 默认情况下,一旦创建了下游流水线,trigger
流水线任务就会以 success
状态完成。
要强制 trigger
流水线任务等待下游(多项目或子)流水线完成,请配置 strategy: depend
。此设置使触发流水线任务以 running
状态等待,直到触发流水线完成。此时,trigger
流水线任务与下游流水线任务完成并显示。
此设置有助于保持流水线的线性执行。在以下示例中,来自后续阶段的流水线任务在开始之前会等待触发的流水线成功完成,这样做可以减少并行化。
trigger_job:
trigger:
include: path/to/child-pipeline.yml
strategy: depend
通过 API 调用触发流水线
要强制重建特定分支、 tag 或提交,你可以使用触发 token
调用 API 。
触发 token
不同于 trigger
关键字。
interruptible
interruptible
表示如果新的流水线运行变得多余,则应取消正在运行的流水线任务。默认为false
(不可中断)。尚未开始(pending
)的流水线任务被认为是可中断的并且可以安全的取消。此值仅在 自动取消冗余流水线功能启用时可用。
启用后,如果以下任一情况为真,则在同一分支上启动新流水线时会立即取消流水线:
- 流水线中的所有流水线任务都设置为可中断的。
- 任何不间断的流水线任务尚未开始。
将流水线任务设置为可以在启动后安全取消的可中断流水线任务(例如,构建流水线任务)。
在以下示例中,新流水线运行会导致现有运行流水线变为:
- 取消,如果只有
step-1
正在运行或 pending。 - 不会取消,一旦
step-2
开始运行。
不间断流水线任务开始运行后,流水线无法取消。
stages:
- stage1
- stage2
- stage3
step-1:
stage: stage1
script:
- echo "Can be canceled."
interruptible: true
step-2:
stage: stage2
script:
- echo "Can not be canceled."
step-3:
stage: stage3
script:
- echo "Because step-2 can not be canceled, this step can never be canceled, even though it's set as interruptible."
interruptible: true
resource_group
有时在一个环境中同时运行多个流水线任务或流水线可能会导致部署过程中出现错误。
为避免这些错误,请使用 resource_group
属性来确保 Runner 不会同时运行某些流水线任务。资源组的行为与其他编程语言中的信号量极为相似。
当在 .codechina-ci.yml
文件中为流水线任务定义了 resource_group
关键字时,同一项目的不同流水线中的流水线任务执行是相互排斥的。如果属于同一资源组的多个流水线任务同时进入队列,Runner 只选择其中一项流水线任务并运行。其他流水线任务需要等到 resource_group
空闲后才开始运行。
例如:
deploy-to-production:
script: deploy
resource_group: production
在这种情况下,两个独立流水线中的 deploy-to-production
流水线任务永远不能同时运行。因此,你可以确保在生产环境中永远不会发生并发部署。
你可以为每个环境定义多个资源组。例如,部署到物理设备时,你可能有多个物理设备。可以部署到每台设备,但在任何给定时间内每个设备只能有一个部署。
resource_group
值只能包含字母、数字、-
、_
、/
、$
、{
、}
、.
和空格。它不能以/
开头或结尾。
具有跨项目/父子流水线的流水线级并发控制
你可以为对并发敏感的下游流水线定义resource_group
。trigger
关键字 可以触发下游流水线。resource_group
关键字 可以与它共存。这有助于控制部署流水线的并发性,同时运行非敏感的流水线任务。
以下示例在一个项目中有两个流水线配置。当流水线开始运行时,非敏感流水线任务首先执行,不受其他并发执行的流水线影响。但是,在这之前系统会确保没有其他部署流水线在运行触发部署(子)流水线。如果其他部署流水线正在运行,系统会等到这些流水线完成,然后再运行另一个。
# .codechina-ci.yml (parent pipeline)
build:
stage: build
script: echo "Building..."
test:
stage: test
script: echo "Testing..."
deploy:
stage: deploy
trigger:
include: deploy.codechina-ci.yml
strategy: depend
resource_group: AWS-production
# deploy.codechina-ci.yml (child pipeline)
stages:
- provision
- deploy
provision:
stage: provision
script: echo "Provisioning..."
deployment:
stage: deploy
script: echo "Deploying..."
你必须使用trigger
关键字定义 strategy:depend
。这将确保在下游流水线完成之前不会释放锁。
release
使用 release
创建一个 release。需要 release-cli
在你的 Runner Docker 或 shell 执行器中可用。
release
支持以下这些关键字:
tag_name
description
-
name
(可选) -
ref
(可选) -
milestones
(可选) -
released_at
(可选) -
assets:links
(可选)
仅当流水线任务处理没有错误时才会创建 release。如果 Rails API在 release 创建期间返回错误,则 release
流水线任务失败。
release-cli
Docker 镜像
你必须指定用于 release-cli
的 Docker 镜像:
image:registry.gitlab.com/gitlab-org/release-cli:latest
release-cli
shell 执行程序的对于 Runner shell 执行程序,你可以为你的 [支持的操作系统和架构] (https://release-cli-downloads.s3.amazonaws.com/latest/index.html) 手动下载并安装 release-cli
,安装后完成后就可以使用release
关键字了。
在 Unix/Linux 上安装
- 下载适用于你系统的二进制文件,以下示例适用于 amd64 系统:
curl --location --output /usr/local/bin/release-cli "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-linux-amd64"
- 赋予其执行权限:
sudo chmod +x /usr/local/bin/release-cli
- 验证
release-cli
是否可用:
$ release-cli -v
release-cli version 0.6.0
在 Windows PowerShell 上安装
- 在你系统的某处创建一个文件夹,例如
C:\CSDN\Release-CLI\bin
New-Item -Path 'C:\CSDN\Release-CLI\bin' -ItemType Directory
1.下载可执行文件:
PS C:\> Invoke-WebRequest -Uri "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-windows-amd64.exe" -OutFile "C:\CSDN\Release-CLI\bin\release-cli.exe"
Directory: C:\CSDN\Release-CLI
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/16/2021 4:17 AM bin
- 将目录添加到你的环境变量
$env:PATH
中:
$env:PATH += ";C:\GitLab\Release-CLI\bin"
- 验证
release-cli
是否可用:
PS C:\> release-cli -v
release-cli version 0.6.0
使用自定义 SSL CA 证书
当 release-cli
使用带有自定义证书的 HTTPS 请求通过API 创建 release 时,你可以使用 ADDITIONAL_CA_CERT_BUNDLE
CI/CD 变量来配置自定义 SSL CA 证书并将它用于验证。ADDITIONAL_CA_CERT_BUNDLE
值应包含text representation of the X.509 PEM public-key certificate或包含证书颁发机构的 path/to/file
。例如,要在 .codechina-ci.yml
文件中配置此值,请使用以下命令:
release:
variables:
ADDITIONAL_CA_CERT_BUNDLE: |
-----BEGIN CERTIFICATE-----
MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
...
jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
-----END CERTIFICATE-----
script:
- echo "Create release"
release:
name: 'My awesome release'
tag_name: '$CI_COMMIT_TAG'
ADDITIONAL_CA_CERT_BUNDLE
值也可以配置为UI 中的自定义变量,
要么是一个 file
,它需要证书的路径;要么是一个变量,它需要证书的文本内容。
script
除 trigger 流水线任务之外的所有流水线任务都必须具有 script
关键字。一个 release
流水线任务可以使用脚本命令的输出,但在你不需要的时候你也可以使用占位符脚本:
script:
- echo 'release job'
一个流水线可以有多个 release
流水线任务,例如:
ios-release:
script:
- echo 'iOS release job'
release:
tag_name: v1.0.0-ios
description: 'iOS release v1.0.0'
android-release:
script:
- echo 'Android release job'
release:
tag_name: v1.0.0-android
description: 'Android release v1.0.0'
release:tag_name
你必须为 release 指定一个 tag_name
。该 tag 可以引用现有的 Git tag 或者你可以指定一个新的 tag。
当存储库中不存在指定的 tag 时,将从流水线的关联 SHA 创建一个新的 tag。
例如,从 Git tag 创建发布时:
job:
release:
tag_name: $CI_COMMIT_TAG
description: 'Release description'
也可以创建任何唯一的标签,在这种情况下,only: tags
不是强制性的。比如下方的示例:
job:
release:
tag_name: ${MAJOR}_${MINOR}_${REVISION}
description: 'Release description'
- 只有当流水线任务的主脚本成功时才会创建发布。
- 如果发布已经存在,则不会更新并且带有
release
关键字的流水线任务失败。 -
release
在script
之后、after_script
之前执行。
release:name
版本名称。如果省略,则使用 release: tag_name
的值填充。
release:description
指定发布的详细描述。你还可以指定一个包含描述内容的文件。
Read description from a file
你可以在 $CI_PROJECT_DIR
中指定一个包含描述的文件。该文件路径必须是相对于项目目录($CI_PROJECT_DIR
)的,如果文件是一个符号链接,它就不能驻留在 $CI_PROJECT_DIR
之外。./path/to/file
和文件名不能包含空格。
job:
release:
tag_name: ${MAJOR}_${MINOR}_${REVISION}
description: './path/to/CHANGELOG.md'
release:ref
如果 release: tag_name
还不存在,则从 ref
创建 release。ref
可以是提交 SHA、另一个 tag 名称或分支名称。
release:milestones
与 release 相关的每个里程碑的标题。
release:released_at
release 准备就绪的日期和时间。如果未定义的话则默认使用当前日期和时间。应该用引号引起来并用符合 ISO 8601 格式来表示。
released_at: '2021-03-15T08:00:00Z'
release:assets:links
在发布中包含资产链接。
注意:需要
release-cli
版本 v0.4.0 或更高版本。
assets:
links:
- name: 'asset1'
url: 'https://example.com/assets/1'
- name: 'asset2'
url: 'https://example.com/assets/2'
filepath: '/pretty/url/1' # optional
link_type: 'other' # optional
release
的完整示例
如果你结合之前的 release
例子,你会得到两个选项,这取决于你如何生成 tag 。你不能同时使用这些选项,因此请选择一个来使用:
-
在推送 Git tag 或添加 Git tag 时创建 release :
release_job: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest rules: - if: $CI_COMMIT_TAG # Run this job when a tag is created manually script: - echo 'running release_job' release: name: 'Release $CI_COMMIT_TAG' description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION must be defined tag_name: '$CI_COMMIT_TAG' # elsewhere in the pipeline. ref: '$CI_COMMIT_TAG' milestones: - 'm1' - 'm2' - 'm3' released_at: '2021-05-29T14:05:00Z' # Optional, is auto generated if not defined, or can use a variable. assets: # Optional, multiple asset links links: - name: 'asset1' url: 'https://example.com/assets/1' - name: 'asset2' url: 'https://example.com/assets/2' filepath: '/pretty/url/1' # optional link_type: 'other' # optional
-
要在提交推送至默认分支或合并到默认分支时自动创建 release,使用一个用变量定义的新 Git tag:
注意:在
before_script
或script
中设置的环境变量不可扩展到同一份流水线任务中使用。prepare_job: stage: prepare # This stage must run before the release stage rules: - if: $CI_COMMIT_TAG when: never # Do not run this job when a tag is created manually - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch script: - echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables - echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file artifacts: reports: dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs release_job: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest needs: - job: prepare_job artifacts: true rules: - if: $CI_COMMIT_TAG when: never # Do not run this job when a tag is created manually - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch script: - echo 'running release_job for $TAG' release: name: 'Release $TAG' description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG tag_name: '$TAG' # variables must be defined elsewhere ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the milestones: # prepare_job - 'm1' - 'm2' - 'm3' released_at: '2021-05-29T14:05:00Z' # Optional, is auto generated if not defined, or can use a variable. assets: links: - name: 'asset1' url: 'https://example.com/assets/1' - name: 'asset2' url: 'https://example.com/assets/2' filepath: '/pretty/url/1' # optional link_type: 'other' # optional
将资产发布为通用包
你可以使用通用包来托管你的发布资产。
release-cli
命令行
release
节点下的条目被转换为 bash
命令行并发送到包含了 release-cli的 Docker 容器,你也可以直接从 script
条目调用 release-cli
。
例如,如果你使用上方例子中的 YAML:
release-cli create --name "Release $CI_COMMIT_SHA" --description "Created using the release-cli $EXTRA_DESCRIPTION" --tag-name "v${MAJOR}.${MINOR}.${REVISION}" --ref "$CI_COMMIT_SHA" --released-at "2020-07-15T08:00:00Z" --milestone "m1" --milestone "m2" --milestone "m3" --assets-link "{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\",\"link_type\":\"other\"}
secrets
使用 secrets
指定流水线任务需要的 CI/CD Secrets。它应该是一个 hash 值,键应该是可供流水线任务使用的变量的名称。每个秘密的值都保存在一个临时文件中。这个文件的路径存储在这些变量中。
pages
使用 pages
将静态内容上传到 GitCode 中。内容会作为网站发布。你必须:
- 将任何静态内容放在
public/
目录中。 - 定义
artifacts
和public/
目录的路径。
以下示例将所有文件从项目的根目录移动到 public/
目录。.public
在 cp
时将不会复制 public/
,以避免陷入无限循环:
pages:
stage: deploy
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- main
注,目前 GitCode 单独提供了 Pages 服务,不再支持通过 CI YAML 文件触发的 Pages 部署,具体可参考 Pages 帮助文档。
inherit
使用 inherit:
来控制全局定义继承和变量。
要启用或禁用所有 default:
或 variables:
关键字的继承,请使用:
-
default: true
或default: false
-
variables: true
或variables: false
要仅继承 default:
关键字或 variables:
的子集,请指定你想继承的内容。任何未列出的内容都不会集成。请使用以下格式中的一种:
inherit:
default: [keyword1, keyword2]
variables: [VARIABLE1, VARIABLE2]
或者:
inherit:
default:
- keyword1
- keyword2
variables:
- VARIABLE1
- VARIABLE2
在以下示例中:
-
rubocop
:- 继承:没有继承任何内容。
-
rspec
:- 继承:默认的
image
和WEBHOOK_URL
变量。 -
不 继承:默认的
before_script
和DOMAIN
变量。
- 继承:默认的
-
capybara
:- 继承:默认的
before_script
和image
。 -
不 继承:
DOMAIN
和WEBHOOK_URL
变量。
- 继承:默认的
-
karma
:- 继承:默认的
image
和before_script
,以及DOMAIN
变量。 -
不 继承:
WEBHOOK_URL
变量。
- 继承:默认的
default:
image: 'ruby:2.4'
before_script:
- echo Hello World
variables:
DOMAIN: example.com
WEBHOOK_URL: https://my-webhook.example.com
rubocop:
inherit:
default: false
variables: false
script: bundle exec rubocop
rspec:
inherit:
default: [image]
variables: [WEBHOOK_URL]
script: bundle exec rspec
capybara:
inherit:
variables: false
script: bundle exec capybara
karma:
inherit:
default: true
variables: [DOMAIN]
script: karma
variables
CI/CD 变量是一些传递给流水线任务的可配置值。它们可以在全局以及每个流水线任务中设置。
有两种类型的变量。
-
自定义变量:
你可以在 GitCode UI 中的
.codechina-ci.yml
文件中定义它们的值,或通过 API 来定义。你还可以在手动运行流水线中输入变量。 - 预定义变量:这些值由 Runner 自己设置。比如
CI_COMMIT_REF_NAME
,它是指构建项目的分支或 tag。
定义好变量后,你可以在所有执行的中使用它。
变量用于非敏感的项目配置,例如:
variables:
DEPLOY_SITE: "https://example.com/"
deploy_job:
stage: deploy
script:
- deploy-script --url $DEPLOY_SITE --path "/"
deploy_review_job:
stage: deploy
variables:
REVIEW_PATH: "/review"
script:
- deploy-review-script --url $DEPLOY_SITE --path $REVIEW_PATH
变量的名称和值只能使用整数和字符。
如果在 .codechina-ci.yml
文件的顶部定义了一个变量,那么这个变量就是全局的,这意味着它适用于所有流水线任务。如果是在某个流水线任务重定义的变量,则它只可用于该流水线任务。
如果为特定流水线任务定义了与全局变量同名的变量,则特定于流水线任务的变量将覆盖全局变量。
所有 YAML 中定义的变量对关联的 Docker 服务容器同样生效。
你可以使用 YAML 变量锚点。
在手动流水线中预填充变量
当手动运行流水线时可使用 value
和 description
预先填充的流水线级(全局)变量:
variables:
DEPLOY_ENVIRONMENT:
value: "staging" # Deploy to staging by default
description: "The deployment target. Change this variable to 'canary' or 'production' if needed."
当你手动运行流水线时,你无法将对流水线任务级别的变量进行预填充操作。
使用变量配置 Runner 行为
你可以使用 CI/CD variables 来配置运行程序如何处理 Git 请求:
GIT_STRATEGY
GIT_SUBMODULE_STRATEGY
GIT_CHECKOUT
GIT_CLEAN_FLAGS
GIT_FETCH_EXTRA_FLAGS
-
GIT_DEPTH
(浅克隆) -
GIT_CLONE_PATH
(自定义构建目录) -
TRANSFER_METER_FREQUENCY
(artifacts
/缓存更新频率) -
ARTIFACT_COMPRESSION_LEVEL
(artifacts
存档器压缩级别) -
CACHE_COMPRESSION_LEVEL
(缓存归档压缩级别)
你还可以使用变量来配置 Runner 的次数尝试流水线任务执行的某些阶段。
YAML 特定的功能
在你的 .codechina-ci.yml
文件中,你可以使用一些 YAML 特定的特性,比如锚点(&
)、别名(*
)、和 map 合并(<<
)。使用这些特性可以减少 .codechina-ci.yml
文件中的代码复杂性。
点击阅读更多有关各种 YAML 功能 的信息。
在大多数情况下,extends
关键字 对用户更友好,你应该尽可能地使用它。
你可以使用 YAML 锚点来合并 YAML 。
锚
YAML 有一个叫做“锚点”的功能,可以允许你在整个文档中复制内容。
使用锚点复制或继承属性。将锚点与隐藏的流水线任务 结合起来用作你的流水线任务模板。当有重复的键,系统会基于键执行反向深度合并。
当使用 include
时,你将无法跨文件使用 YAML 锚点关键词。锚只在定义它们的文件中生效。如果要在不同的 YAML 文件中重用配置,你可以使用 !reference
tags 或 extends
关键词。
以下示例中,使用锚点和合并映射。它创建了 test1
和 test2
两个流水线任务,并继承了 .job_template
的配置,每个流水线任务都定义了自己的自定义 script
:
.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration'
image: ruby:2.6
services:
- postgres
- redis
test1:
<<: *job_configuration # Merge the contents of the 'job_configuration' alias
script:
- test1 project
test2:
<<: *job_configuration # Merge the contents of the 'job_configuration' alias
script:
- test2 project
&
设置了锚点的名称(job_configuration
),<<
表示“合并给定 hash 到当前的 hash 中,然后 *
引用了锚点(还是job_configuration
)。这个例子的扩展版本是:
.job_template:
image: ruby:2.6
services:
- postgres
- redis
test1:
image: ruby:2.6
services:
- postgres
- redis
script:
- test1 project
test2:
image: ruby:2.6
services:
- postgres
- redis
script:
- test2 project
你可以使用锚点来定义两组不同的服务。例如,test:postgres
和 test:mysql
,他们共享 .job_template
中定义的 script
,但使用不同的 services
,可以这样定义 .postgres_services
和 .mysql_services
:
.job_template: &job_configuration
script:
- test project
tags:
- dev
.postgres_services:
services: &postgres_configuration
- postgres
- ruby
.mysql_services:
services: &mysql_configuration
- mysql
- ruby
test:postgres:
<<: *job_configuration
services: *postgres_configuration
tags:
- postgres
test:mysql:
<<: *job_configuration
services: *mysql_configuration
上面这个例子的扩展版本是:
.job_template:
script:
- test project
tags:
- dev
.postgres_services:
services:
- postgres
- ruby
.mysql_services:
services:
- mysql
- ruby
test:postgres:
script:
- test project
services:
- postgres
- ruby
tags:
- postgres
test:mysql:
script:
- test project
services:
- mysql
- ruby
tags:
- dev
你可以看到将隐藏的流水线任务用作模板时使用起来非常方便,并且 tags: [postgres]
覆盖 tags: [dev]
。
脚本的 YAML 锚点
你可以在 script、before_script
、以及 after_script
中使用 YAML 锚点 ,让其在多个流水线任务中使用预定义的命令:
.some-script-before: &some-script-before
- echo "Execute this script first"
.some-script: &some-script
- echo "Execute this script second"
- echo "Execute this script too"
.some-script-after: &some-script-after
- echo "Execute this script last"
job1:
before_script:
- *some-script-before
script:
- *some-script
- echo "Execute something, for this job only"
after_script:
- *some-script-after
job2:
script:
- *some-script-before
- *some-script
- echo "Execute something else, for this job only"
- *some-script-after
变量的 YAML 锚点
使用 YAML 锚点 和 variables
给跨多个流水线任务的变量重复赋值。当流水线任务需要一个特定的 variables
块时,你也可以使用 YAML 锚点,以避免会覆盖全局变量。
以下示例显示如何在不影响 SAMPLE_VARIABLE
变量使用的情况下覆盖 GIT_STRATEGY
变量:
# global variables
variables: &global-variables
SAMPLE_VARIABLE: sample_variable_value
ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value
# a job that must set the GIT_STRATEGY variable, yet depend on global variables
job_no_git_strategy:
stage: cleanup
variables:
<<: *global-variables
GIT_STRATEGY: none
script: echo $SAMPLE_VARIABLE
隐藏的流水线任务
如果你想暂时禁用一个流水线任务,并且不希望使用注释掉所有的定义流水线任务的行这种方式:
# hidden_job:
# script:
# - run test
这样情况下,你可以用一个点(.
)开始它的名字,它不会被 CI/CD 处理。在下面的例子中,.hidden_job
将被忽略:
.hidden_job:
script:
- run test
使用此功能来忽略流水线任务,或使用 YAML 特性功能将隐藏流水线任务转换成模板。
!reference
tags
使用 !reference
自定义 YAML 标签,可以从其他流水线任务中选择关键字配置部分并在当前部分中重用它。与 YAML 锚点 不同,你可以使用 !reference
标签重用 included 配置,包括其中的配置文件也可以重用。
在以下示例中,来自两个不同位置的 script
和 after_script
在 test
流水线任务中被重用:
-
setup.yml
:.setup: script: - echo creating environment
-
.codechina-ci.yml
:include: - local: setup.yml .teardown: after_script: - echo deleting environment test: script: - !reference [.setup, script] - echo running my own command after_script: - !reference [.teardown, after_script]
在下面的例子中,test-vars-1
重用了 .vars
中的所有变量,而 test-vars-2
选择一个特定的变量并将其作为新的 MY_VAR
变量重用。
.vars:
variables:
URL: "http://my-url.internal"
IMPORTANT_VAR: "the details"
test-vars-1:
variables: !reference [.vars, variables]
script:
- printenv
test-vars-2:
variables:
MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
script:
- printenv
你不能重复使用已经包含 !reference
标签的部分。只支持一层嵌套。
跳过流水线
要在不触发流水线的情况下推送提交,请在你的提交消息中添加 [ci skip]
或 [skip ci]
,支持大写。
或者,如果你使用 Git 2.10 或更高版本,请使用 ci.skip
Git push option。ci.skip
推送选项不会跳过合并请求流水线。
处理 Git 推送
当在单个 git push
调用中推送多个更改时,系统将最多创建四个分支流水线或 tag 流水线。
此限制不会影响任何更新的合并请求流水线。所有更新的合并请求在创建时都使用的是合并请求流水线的流水线。
弃用的关键字
以下关键字已弃用。
types
全局定义的警告:
types
已弃用,可能会在未来版本中删除。请使用stages
代替。
type
流水线任务定义的警告:
type
已弃用,可能会在未来的某一版本中删除。请使用stage
代替。
image
、services
、cache
、before_script
、after_script
全局定义的不推荐在全局范围内定义 image
、services
、cache
、before_script
和 after_script
。可能会从未来的版本中删除支持。
使用 default:
代替。例如:
default:
image: ruby:3.0
services:
- docker:dind
cache:
paths: [vendor/]
before_script:
- bundle config set path vendor/bundle
- bundle install
after_script:
- rm -rf tmp/