使用在每个项目中调用的YAML文件配置GitLab CI / CD 管道.gitlab-ci.yml
。
该.gitlab-ci.yml
文件定义管道的结构和顺序,并确定:
本主题涵盖CI / CD管道配置。有关其他CI / CD配置信息,请参阅:
我们有配置管道的完整示例:
.gitlab-ci.yml
企业中使用的大文件,请参阅的.gitlab-ci.yml
文件gitlab
。 有关GitLab CI / CD的其他信息:
- 观看CI / CD轻松配置视频。
- 在组织的 网络广播中观看“ 为CI / CD辩护”,以了解CI / CD的好处以及如何衡量CI / CD自动化的结果。
- 了解Verizon如何 使用GitLab 将重建工作从30天减少到8小时以下。
管道配置从作业开始。作业是.gitlab-ci.yml
文件的最基本元素。
工作是:
script
子句。 例如:
job1:
script: "execute-script-for-job1"
job2:
script: "execute-script-for-job2"
上面的示例是具有两个单独作业的最简单的CI / CD配置,其中每个作业执行一个不同的命令。当然,命令可以在存储库中直接执行代码(./configure;make;make install
)或运行脚本(test.sh
)。
乔布斯被拾起运动员和跑步者的环境中执行。重要的是,每个作业彼此独立运行。
.gitlab-ci.yml
GitLab CI / CD的每个实例都有一个称为Lint的嵌入式调试工具,该工具可以验证.gitlab-ci.yml
文件的内容。您可以在ci/lint
项目名称空间页面下找到Lint 。例如,https://gitlab.example.com/gitlab-org/project-123/-/ci/lint
。
每个作业必须具有唯一的名称,但是有一些保留keywords
名称不能用作作业名称:
image
services
stages
types
before_script
after_script
variables
cache
include
如果使用特定值(例如true
或false
)时出现验证错误,请尝试执行以下操作:
/bin/true
。 作业定义为定义作业行为的参数列表。
下表列出了作业的可用参数:
关键词 | 描述 |
---|---|
script |
由Runner执行的Shell脚本。 |
image |
使用Docker映像 也可用:image:name 和image:entrypoint 。 |
services |
使用Docker服务映像。也可用:services:name ,services:alias ,services:entrypoint ,和services:command 。 |
before_script |
覆盖作业之前执行的一组命令。 |
after_script |
覆盖作业后执行的一组命令。 |
stage |
定义一个作业阶段(默认值:)test 。 |
only |
限制创建作业的时间。也可用:only:refs ,only:kubernetes ,only:variables ,和only:changes 。 |
except |
限制未创建作业的时间。也可用:except:refs ,except:kubernetes ,except:variables ,和except:changes 。 |
rules |
评估和确定作业的选定属性以及是否创建作业的条件列表。不能与only / 一起使用except 。 |
tags |
用于选择Runner的标签列表。 |
allow_failure |
允许作业失败。失败的作业不会影响提交状态。 |
when |
什么时候开始工作。也可用:when:manual 和when:delayed 。 |
environment |
作业部署到的环境的名称。也可用:environment:name ,environment:url ,environment:on_stop ,environment:auto_stop_in 和environment:action 。 |
cache |
在后续运行之间应缓存的文件列表。也可用:cache:paths ,cache:key ,cache:untracked ,和cache:policy 。 |
artifacts |
成功时附加到作业的文件和目录列表。也可用:artifacts:paths ,artifacts:exclude ,artifacts:expose_as ,artifacts:name ,artifacts:untracked ,artifacts:when ,artifacts:expire_in ,artifacts:reports ,artifacts:reports:codequality ,artifacts:reports:junit ,artifacts:reports:cobertura ,和artifacts:reports:terraform 。在GitLab 企业版,这些都是可供选择: artifacts:reports:sast ,artifacts:reports:dependency_scanning ,artifacts:reports:container_scanning ,artifacts:reports:dast ,artifacts:reports:license_scanning ,artifacts:reports:license_management (在GitLab 13.0删除), ,artifacts:reports:performance ,artifacts:reports:load_performance 和artifacts:reports:metrics 。 |
dependencies |
通过提供要从中获取工件的作业列表,限制将哪些工件传递给特定作业。 |
coverage |
给定作业的代码覆盖率设置。 |
retry |
发生故障时可以自动重试作业的时间和次数。 |
timeout |
定义优先于项目范围设置的自定义作业级别超时。 |
parallel |
多少个作业实例应并行运行。 |
trigger |
定义下游管道触发器。 |
include |
允许此作业包括外部YAML文件。也可用:include:local ,include:file ,include:template ,和include:remote 。 |
extends |
该作业将要继承的配置条目。 |
pages |
上载作业结果以用于GitLab页面。 |
variables |
在作业级别上定义作业变量。 |
interruptible |
定义在通过新的运行使其冗余时是否可以取消作业。 |
resource_group |
限制作业并发。 |
release |
指示Runner生成Release对象。 |
types
和
type
被
弃用
。
必须在全局级别定义一些参数,这会影响管道中的所有作业。
可以使用default:
关键字将某些参数全局设置为所有作业的默认设置 。然后可以通过特定于作业的配置覆盖默认参数。
可以在default:
块内定义以下作业参数:
image
services
before_script
after_script
tags
cache
artifacts
retry
timeout
interruptible
在以下示例中,该ruby:2.5
图像被设置为除rspec 2.6
使用该ruby:2.6
图像的作业以外的所有作业的默认图像:
default:
image: ruby:2.5
rspec:
script: bundle exec rspec
rspec 2.6:
image: ruby:2.6
script: bundle exec rspec
inherit
在GitLab 12.9中引入。
您可以使用inherit:
参数禁用全局定义的默认值和变量的继承。
要启用或禁用全部variables:
或default:
参数的继承,请使用以下格式:
default: true
要么 default: false
variables: true
要么 variables: false
要仅继承default:
参数或的子集variables:
,请指定要继承的内容,未列出的任何内容均不会被继承。使用以下格式之一:
inherit:
default: [parameter1, parameter2]
variables: [VARIABLE1, VARIABLE2]
要么:
inherit:
default:
- parameter1
- parameter2
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
stages
stages
用于定义包含作业的阶段,并为管道全局定义。
的规范stages
允许具有灵活的多级管道。中的元素顺序stages
定义了作业执行的顺序:
让我们考虑以下示例,该示例定义了3个阶段:
stages:
- build
- test
- deploy
build
并行执行。 build
成功,则这些test
作业将并行执行。 test
成功,则这些deploy
作业将并行执行。 deploy
成功,则将提交标记为passed
。 failed
并且不执行后续作业。 还有两个边缘情况值得一提:
stages
被定义.gitlab-ci.yml
,那么build
, test
和deploy
允许被用作默认作业的阶段。 stage
,则为该作业分配test
阶段。 workflow:rules
在GitLab 12.5中 引入
顶级workflow:
密钥适用于整个管道,并将确定是否创建管道。当前,它接受与作业中定义的rules:
操作类似的单个 密钥,从而可以动态配置管道。 rules:
如果您不熟悉GitLab CI / CD和workflow: rules
,您可能会发现workflow:rules
模板有用。
要定义自己的workflow: rules
,当前可用的配置选项为:
if
:定义规则。 when
:可以设置为always
或never
仅设置。如果未提供,则默认值为always
。 如果管道尝试运行但不匹配任何规则,则将其删除并且无法运行。
例如,下面的配置,管道的所有运行push
事件(改变分支和新的标签),只要它们不具有-wip
在提交信息。预定管道和合并请求管道不会运行,因为没有规则允许它们。
workflow:
rules:
- if: $CI_COMMIT_REF_NAME =~ /-wip$/
when: never
- if: '$CI_PIPELINE_SOURCE == "push"'
这个例子有严格的规则,没有其他管道可以运行。
或者,您可以只使用when: never
规则,再使用最终when: always
规则来制定宽松的规则。这允许所有类型的管道,除了那些符合when: never
规则的管道:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never
- when: always
此示例从不允许用于计划或push
(分支和标签)管道的管道,但是在所有其他情况下都允许管道,包括合并请求管道。
与rules
在job中定义的一样,请注意不要使用允许合并请求管道和分支管道同时运行的配置,否则您可能会有重复的管道。
有用的工作流程规则条款:
条款 | 细节 |
---|---|
if: '$CI_PIPELINE_SOURCE == "merge_request_event"' |
允许或阻止合并请求管道。 |
if: '$CI_PIPELINE_SOURCE == "push"' |
允许或阻止分支管道和标记管道。 |
if: '$CI_COMMIT_BEFORE_SHA == '0000000000000000000000000000000000000000' |
在没有提交的情况下创建或推送新分支时,允许或阻止管道创建。这还将跳过标记和计划的管道。有关如何更严格定义这些规则的示例,请参见常见rules:if 条款。 |
workflow:rules
范本 在GitLab 13.0中引入。
我们提供了可与您的管道配合使用的预制模板,这些模板workflow: rules
针对常见情况进行了设置。使用这些将使事情变得容易,并防止重复的管道运行。
该Branch-Pipelines
模板 使您的管道针对分支和标签运行。
分支管道状态将显示在使用该分支作为源的合并请求中,但是此管道类型不支持“ 合并请求管道”提供的任何功能, 例如 “合并结果管道” 或“ 合并训练”。如果您有意避免使用这些功能,请使用此模板。
它包括以下内容:
include:
- template: 'Workflows/Branch-Pipelines.gitlab-ci.yml'
该MergeRequest-Pipelines
模板 使您的管道针对默认分支(通常是master
),标签和所有类型的合并请求管道运行。如上所述,如果您使用任何“ 合并请求管道”功能,请使用此模板。
它包括以下内容:
include:
- template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'
include
使用include
关键字允许包含外部YAML文件。这有助于将CI / CD配置分解为多个文件,并提高了长配置文件的可读性。也可以将模板文件存储在中央存储库中,并且项目包括其配置文件。这有助于避免重复配置,例如,所有项目的全局默认变量。
include
要求外部YAML文件具有扩展名.yml
或.yaml
,否则将不包含外部文件。
include
支持以下包含方法:
方法 | 描述 |
---|---|
local |
包括来自本地项目存储库的文件。 |
file |
包括来自其他项目存储库的文件。 |
remote |
包括来自远程URL的文件。必须公开可用。 |
template |
包括由GitLab提供的模板。 |
该include
方法不支持变量扩展。
.gitlab-ci.yml
所有方法包括的配置都是在管道创建时评估的。该配置是及时的快照,并保留在数据库中。
.gitlab-ci.yml
在创建下一个管道之前,对引用配置的任何更改都不会反映在GitLab中。
定义的文件include
为:
.gitlab-ci.yml
。 .gitlab-ci.yml
无论include
关键字的位置如何,始终首先评估并与的内容合并。 .gitlab-ci.yml
将覆盖包含的定义。
include
。您只能引用同一文件中的锚。您可以使用
extends
关键字
而不是使用YAML锚。
include:local
include:local
包含与相同存储库中的文件.gitlab-ci.yml
。使用相对于根目录(/
)的完整路径进行引用。
您只能在配置文件所在的同一分支上使用Git当前跟踪的文件。换句话说,当使用时include:local
,请确保它们.gitlab-ci.yml
和本地文件都在同一分支上。
所有嵌套的包含将在同一项目的范围内执行,因此可以使用本地,项目,远程或模板包含。
例:
include:
- local: '/templates/.gitlab-ci-template.yml'
可以将其定义为简短的本地包含:
include: '.gitlab-ci-production.yml'
include:file
在GitLab 11.7中引入。
要在同一GitLab实例下包含来自另一个私有项目的文件,请使用include:file
。使用相对于根目录(/
)的完整路径引用此文件。例如:
include:
- project: 'my-group/my-project'
file: '/templates/.gitlab-ci-template.yml'
您还可以指定ref
,默认为HEAD
项目的:
include:
- project: 'my-group/my-project'
ref: master
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:remote
include:remote
可以用于通过HTTP / HTTPS包含来自其他位置的文件,并使用完整URL进行引用。远程文件必须可以通过简单的GET请求公开访问,因为不支持远程URL中的身份验证模式。例如:
include:
- remote: 'https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml'
所有嵌套的include将在没有上下文的情况下作为公共用户执行,因此仅允许另一个远程或公共项目或模板。
include:template
在GitLab 11.7中引入。
include:template
可用于包括GitLab随附的.gitlab-ci.yml
模板 。
例如:
# File sourced from GitLab's template collection
include:
- template: Auto-DevOps.gitlab-ci.yml
多个include:template
文件:
include:
- template: Android-Fastlane.gitlab-ci.yml
- template: Auto-DevOps.gitlab-ci.yml
所有嵌套的包含将仅在用户许可下执行,因此可以使用项目,远程或模板包含。
在GitLab 11.9中引入。
嵌套包含可让您组成一组包含。
总共允许100个include,但是重复的include被视为配置错误。
从GitLab 12.4开始,解析所有文件的时间限制为30秒。
includes
例子 有可用的其他includes
示例列表。
以下是用于配置CI / CD管道的参数的详细说明。
image
用于指定要用于作业的Docker映像。
对于:
image
and services
from.gitlab-ci.yml
。 image:name
一个扩展泊坞窗配置选项。
有关更多信息,请参见的可用设置image
。
image:entrypoint
一个扩展泊坞窗配置选项。
有关更多信息,请参见的可用设置image
。
services
用于指定服务Docker映像,该映像链接到中指定的基本映像image
。
对于:
image
and services
from.gitlab-ci.yml
。 services:name
一个扩展泊坞窗配置选项。
有关更多信息,请参见的可用设置services
。
services:alias
一个扩展泊坞窗配置选项。
有关更多信息,请参见的可用设置services
。
services:entrypoint
一个扩展泊坞窗配置选项。
有关更多信息,请参见的可用设置services
。
services:command
一个扩展泊坞窗配置选项。
有关更多信息,请参见的可用设置services
。
script
script
是工作所需的唯一必需关键字。这是一个由Runner执行的shell脚本。例如:
job:
script: "bundle exec rspec"
脚本的YAML锚可用。
此参数还可以包含使用数组的多个命令:
job:
script:
- uname -a
- bundle exec rspec
script
命令将需要用单引号或双引号引起来。例如,包含冒号(
:
)的命令需要用引号引起来,以便YAML解析器知道将整个内容解释为字符串而不是“键:值”对。使用特殊字符时要小心:
:
,
{
,
}
,
[
,
]
,
,
,
&
,
*
,
#
,
?
,
|
,
-
,
<
,
>
,
=
,
!
,
%
,
@
,
`
。
如果任何脚本命令返回的退出代码都不为零,则该作业将失败,并且其他命令将不再执行。通过将退出代码存储在变量中,可以避免此行为:
job:
script:
- false || exit_code=$?
- if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;
before_script
和 after_script
在GitLab 8.7中引入,需要GitLab Runner v1.2。
before_script
用于定义一个命令,该命令应在每个作业(包括部署作业)之前,但在还原所有工件之后运行。这必须是一个数组。
中指定的before_script
脚本与main中指定的任何脚本串联在一起script
,并在单个shell中一起执行。
after_script
用于定义将在每个作业(包括失败的作业)之后运行的命令。这必须是一个数组。
指定的脚本在after_script
新的Shell中执行,与任何脚本before_script
或script
脚本分开 。结果,他们:
before_script
或定义的脚本所做的更改script
,包括:
script
脚本中导出的命令别名和变量。 before_script
或script
脚本安装的软件。 script
部分成功并且 after_script
超时或失败,则作业将以代码0
(Job Succeeded
)退出。 可能会覆盖全局定义的内容,before_script
或者after_script
如果您按作业设置它,则可以:
default:
before_script:
- global before script
job:
before_script:
- execute this instead of global before script
script:
- my command
after_script:
- execute this after my script
YAML锚before_script
和after_script
可用。
脚本输出可以使用ANSI转义码或运行输出ANSI转义码的命令或程序来着色。
例如,使用带有颜色代码的Bash:
job:
script:
- echo -e "\e[31mThis text is red,\e[0m but this text isn't\e[31m however this text is red again."
您可以在Shell变量甚至自定义环境变量中定义颜色代码,这使命令更易于阅读和重用。
例如,使用与上述相同的示例,并在中定义变量before_script
:
job:
before_script:
- TXT_RED="\e[31m" && TXT_CLEAR="\e[0m"
script:
- echo -e "${TXT_RED}This text is red,${TXT_CLEAR} but this part isn't${TXT_RED} however this part is again."
- echo "This text is not colored"
或使用PowerShell颜色代码:
job:
before_script:
- $esc="$([char]27)"; $TXT_RED="$esc[31m"; $TXT_CLEAR="$esc[0m"
script:
- Write-Host $TXT_RED"This text is red,"$TXT_CLEAR" but this text isn't"$TXT_RED" however this text is red again."
- Write-Host "This text is not colored"
您可以使用|
(文字)和>
(折叠)YAML多行块标量指示器将长命令分成多行命令以提高可读性。
script:
项目运行,或者
exit 1
在需要时将适当的命令添加到命令字符串中。
您可以使用|
(文字上的)YAML多行块标量指示器在script
作业描述部分的多行上编写命令。每行都被视为一个单独的命令。在作业日志中仅重复第一个命令,但仍执行其他命令:
job:
script:
- |
echo "First command line."
echo "Second command line."
echo "Third command line."
上面的示例在作业日志中呈现为:
$ echo First command line # collapsed multi-line command
First command line
Second command line.
Third command line.
的>
(折叠的)YAML多块标量指示器对待部分作为新的命令的开始之间的空行:
job:
script:
- >
echo "First command line
is split over two lines."
echo "Second command line."
这与编写没有>
或|
标量指示符的多行命令的行为类似:
job:
script:
- echo "First command line
is split over two lines."
echo "Second command line."
上面的两个示例在作业日志中均显示为:
$ echo First command line is split over two lines. # collapsed multi-line command
First command line is split over two lines.
Second command line.
当省略>
或|
块标量指示符时,GitLab将通过连接非空行来形成命令,因此请确保在连接时行可以运行。
此处的 Shell 文件也可与|
和>
运算符一起使用 。下面的示例将小写字母音译为大写字母:
job:
script:
- |
tr a-z A-Z << END_TEXT
one two three
four five six
END_TEXT
结果是:
$ tr a-z A-Z << END_TEXT # collapsed multi-line command
ONE TWO THREE
FOUR FIVE SIX
stage
stage
是按职位定义的,并依赖于stages
全局定义的职位。它允许将作业分为不同的阶段,并且相同的作业 stage
可以并行执行(取决于特定条件)。例如:
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
当使用自己的Runners时,默认情况下,GitLab Runner一次仅运行一个作业( 有关更多信息,请参见Runner全局设置中的 concurrent
标志)。
仅在以下情况下,作业将在您自己的跑步者上并行运行:
concurrent
设置已更改。 .pre
和 .post
在GitLab 12.4中引入。
每个管道均可使用以下阶段:
.pre
,这确保始终是管道的第一阶段。 .post
,确保始终是管道的最后阶段。 用户定义的阶段在.pre
之前和之后执行.post
。
的顺序.pre
和.post
也不能更改,即使在中乱序定义也是如此.gitlab-ci.yml
。例如,以下是等效配置:
按顺序配置:
stages:
- .pre
- a
- b
- .post
配置乱序:
stages:
- a
- .pre
- b
- .post
未明确配置:
stages:
- a
- b
.pre
或
.post
阶段中的作业,则不会创建管道。
extends
在GitLab 11.3中引入。
extends
定义要使用的作业extends
要继承的条目名称。
它是使用YAML锚点的替代方法,并且更具灵活性和可读性:
.tests:
script: rake test
stage: test
only:
refs:
- branches
rspec:
extends: .tests
script: rake rspec
only:
variables:
- $RSPEC
在上面的示例中,该rspec
作业继承自.tests
模板作业。GitLab将基于密钥执行反向深度合并。GitLab将:
rspec
内容.tests
递归合并。 这将导致以下rspec
工作:
rspec:
script: rake rspec
stage: test
only:
refs:
- branches
variables:
- $RSPEC
script: rake test
已被覆盖
script: rake rspec
。
如果确实要包含rake test
,请参阅before_script
和after_script
。
.tests
在此示例中,是一个隐藏的作业,但是也可以从常规作业中继承。
extends
支持多级继承,但是不建议使用三个以上级别。支持的最大嵌套级别为10。以下示例具有两个继承级别:
.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
在GitLab 12.0和更高版本中,还可以对使用多个父对象 extends
。
extends
能够合并哈希,但不能合并数组。用于合并的算法是“最近的范围获胜”,因此来自最后一个成员的键将始终覆盖在其他级别定义的任何内容。例如:
.only-important:
variables:
URL: "http://my-url.internal"
IMPORTANT_VAR: "the details"
only:
- master
- 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:
- master
- stable
tags:
- docker
image: alpine
script:
- rake rspec
请注意,在上面的示例中:
variables
部分已合并,但URL: "http://my-url.internal"
已被覆盖URL: "http://docker-url.internal"
。 tags: ['production']
已被覆盖tags: ['docker']
。 script
尚未合并,但script: ['echo "Hello world!"']
已被覆盖script: ['rake rspec']
。可以使用YAML锚点合并数组。 extends
和include
在一起 extends
与结合使用时可跨配置文件使用include
。
例如,如果您有本地included.yml
文件:
.template:
script:
- echo Hello!
然后,.gitlab-ci.yml
您可以像这样使用它:
include: included.yml
useTemplate:
image: alpine
extends: .template
这将运行一个名为作业的作业,该作业按照作业中的定义useTemplate
运行,并使用本地作业中定义的Docker映像。 echo Hello!
.template
alpine
rules
在GitLab 12.3中引入。
该rules
关键字可用于包括或管道排除作业。
规则将按顺序评估,直到第一个匹配为止。匹配后,根据配置将作业包括在管道中或从管道中排除。如果包含,则作业还会 添加某些属性。
rules
不能与之组合使用,
only/except
因为它是该功能的替代品。如果尝试执行此操作,则linter返回
key may not be used with rules
错误。
允许的作业属性rules
为:
when
:如果未定义,则默认为when: on_success
。
when: delayed
,start_in
则也是必需的。 allow_failure
:如果未定义,则默认为allow_failure: false
。 如果规则评估为true,并且when
除以外的其他任何值never
,则该作业将包含在管道中。
例如:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: delayed
start_in: '3 hours'
allow_failure: true
将来可能会将其他作业配置添加到规则中。如果没有有用的东西,请打开一个问题。
可用的规则子句为:
条款 | 描述 |
---|---|
if |
通过评估一条if 语句在管道中添加或排除作业。类似于only:variables 。 |
changes |
根据更改的文件在管道中添加或排除作业。与相同only:changes 。 |
exists |
根据特定文件的存在在管道中添加或排除作业。 |
顺序评估规则,直到找到匹配项。如果找到匹配项,则检查属性以查看是否应将作业添加到管道。如果未定义任何属性,则默认值为:
when: on_success
allow_failure: false
作业已添加到管道中:
when: on_success
,when: delayed
或when: always
。 when: on_success
,when: delayed
或when: always
(无规则)。 作业未添加到管道:
when: on_success
,when: delayed
或 when: always
。 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
(默认) 另外,您可以定义一组规则以在某些情况下排除作业,但在所有其他情况下运行它们:
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: on_success
,
always
或
delayed
作为最终规则,则可能同时启动两个管道。推送管道和合并请求管道都可以由同一事件触发(对于打开的合并请求,将其推送到源分支)。见
之间的重要区别
rules
和
only
/
except
了解更多详情。
rules
和only
/ 之间的差异except
only/except
默认情况下,使用定义的作业不会触发合并请求管道。您必须明确添加only: merge_requests
。
用定义的作业rules
可以触发所有类型的管道。您不必显式配置每种类型。
例如:
job:
script: "echo This creates double pipelines!"
rules:
- if: '$CUSTOM_VARIABLE == "false"'
when: never
- when: always
当此作业不运行$CUSTOM_VARIABLE
是假的,但它确实在运行的所有 其他管线,包括两个推(分支)和合并请求管道。使用此配置,每次推送到打开的合并请求的源分支都会导致重复的管道。明确允许在同一作业中同时使用推送和合并请求管道可能具有相同的效果。
我们建议使用workflow: rules
来限制允许的管道类型。仅允许合并请求管道,或仅允许分支管道,可以消除重复的管道。或者,您可以使用避免最终重写规则更严格,或when
(always
,on_success
或delayed
)。
另外,我们不建议将only/except
作业与rules
同一管道中的作业混合使用。它可能不会引起YAML错误,但调试确切的执行行为可以是不同的默认行为复杂,因为only/except
和rules
。
rules:if
rules:if
子句通过评估简单if
语句来确定是否将作业添加到管道。如果该if
语句为true,则将作业包括在管道中或从管道中排除。用简单的英语来说,if
规则可以解释为以下之一:
when: never
)。 rules:if
与only:variables
每个规则只接受一个表达式字符串而不是它们的数组稍有不同。可以 使用或将任何要求值的表达式集组合为一个表达式,并使用变量匹配语法。 &&
||
if:
子句基于预定义环境变量 或自定义环境变量的值进行评估。
例如:
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
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
or allow_failure
规则)始终匹配,并且在达到条件时始终使用。 if
changes
when
定义,则该规则使用when
作业的定义,on_success
如果未定义,则默认为。 when
每个规则定义一次,也可以在作业级别定义一次,这适用于所有规则。您不能when
在工作级别使用when
in规则。 if
条款rules
对于与only
/ except
关键字类似的行为,您可以检查$CI_PIPELINE_SOURCE
变量的值:
值 | 描述 |
---|---|
push |
对于git push 事件触发的管道,包括分支和标签。 |
web |
对于使用GitLab UI中的“运行管道”按钮创建的管道,请从项目的CI / CD>“管道”部分。 |
trigger |
对于使用触发令牌创建的管道。 |
schedule |
对于预定的管道。 |
api |
对于由管道API触发的管道。 |
external |
使用除GitLab以外的CI服务时。 |
pipeline |
对于通过结合使用APICI_JOB_TOKEN 创建的多项目管道。 |
chat |
对于使用GitLab ChatOps命令创建的管道。 |
webide |
对于使用WebIDE创建的管道。 |
merge_request_event |
对于在创建或更新合并请求时创建的管道。启用合并请求管道,合并结果管道和合并序列所必需。 |
external_pull_request_event |
在GitHub上创建或更新外部拉取请求时。有关外部拉取请求,请参见管道。 |
parent_pipeline |
对于由触发管道父/子管道用rules ,在孩子管道配置使用,以便它可以由父母管道被触发。 |
例如:
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"'
本示例将作业作为合并请求管道 和计划管道中的when: on_success
作业运行。它不能在任何其他管道类型中运行。
if
子句的其他常用变量:
if: $CI_COMMIT_TAG
:如果为标签推送更改。 if: $CI_COMMIT_BRANCH
:如果将更改推送到任何分支。 if: '$CI_COMMIT_BRANCH == "master"'
:如果将更改推送到master
。 if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
:如果将更改推送到默认分支(通常为master
)。如果在可能具有不同默认分支的多个项目中重用同一配置,则很有用。 if: '$CI_COMMIT_BRANCH =~ /regex-expression/'
:如果commit分支与正则表达式匹配。 if: '$CUSTOM_VARIABLE !~ /regex-expression/'
:如果自定义变量 CUSTOM_VARIABLE
并没有匹配的正则表达式。 if: '$CUSTOM_VARIABLE == "value1"'
:如果自定义变量CUSTOM_VARIABLE
是value1
。 为了避免在创建分支而未进行任何更改时运行管道,请检查的值$CI_COMMIT_BEFORE_SHA
。其值为 0000000000000000000000000000000000000000
:
要跳过所有空分支上的管道,还要跳过标签和时间表:
rules:
- if: $CI_COMMIT_BEFORE_SHA == '0000000000000000000000000000000000000000'
when: never
要在分支为空时跳过分支管道:
rules:
- if: $CI_COMMIT_BRANCH && $CI_COMMIT_BEFORE_SHA != '0000000000000000000000000000000000000000'
rules:changes
为了确定是否应将作业添加到管道,rules: changes
子句会检查由Git push事件更改的文件。
rules: changes
的工作方式与only: changes
和except: changes
完全相同,接受路径数组。同样,如果没有Git推送事件,则始终返回true。它仅应用于分支管道或合并请求管道。
例如:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- changes:
- Dockerfile
when: manual
allow_failure: true
在此示例中:
workflow: rules
仅允许管道用于所有作业的合并请求。 Dockerfile
已更改,则将该作业作为手动作业添加到管道中,并允许管道继续运行,即使未触发该作业(allow_failure: true
)。 Dockerfile
尚未更改,请不要将作业添加到任何管道(与相同when: never
)。 rules:exists
在GitLab 12.4中引入。
exists
接受路径数组,如果其中任何一个路径作为存储库中的文件存在,则将匹配。
例如:
job:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- exists:
- Dockerfile
您还可以使用全局模式来匹配存储库中任何目录中的多个文件。
例如:
job:
script: bundle exec rspec
rules:
- exists:
- spec/**.rb
exists
与模式一起使用限制为10000个检查。第10000次检查后,带有图案化球形的规则将始终匹配。
rules:allow_failure
在GitLab 12.8中引入。
您可以allow_failure: true
在rules:
不停止管道本身的情况下使用来允许作业失败或手动作业等待操作。未定义使用rules:
默认为allow_failure: false
if的所有作业allow_failure:
。
规则级rules:allow_failure
选项将覆盖作业级 allow_failure
选项,并且仅在作业由特定规则触发时才应用。
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
when: manual
allow_failure: true
在此示例中,如果第一个规则匹配,则作业将具有when: manual
和allow_failure: true
。
要合相if
,changes
以及exists
与AND子句,在相同的规则中使用它们。
在以下示例中:
Dockerfile
或中的任何文件docker/scripts/
更改了AND,我们将手动运行该作业$VAR == "string value"
。 docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: '$VAR == "string value"'
changes: # Will 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, this is implied any time rules are listed.
诸如branches
或之refs
类的当前可用于 only
/的关键字except
尚不可用,rules
因为在这种情况下,它们的用法和行为正在被单独考虑。我们的史诗rules
中正在讨论未来的关键字改进,以改进,任何人都可以添加建议或请求。
only
/ except
(基本) rules
语法定义时,工作应该运行与否的改进,功能更强大的解决方案。考虑使用
rules
而不是来
only/except
充分利用管道。
only
和except
是两个参数,用于设置作业策略以限制创建作业的时间:
only
定义将为其运行作业的分支和标签的名称。 except
定义将不运行作业的分支和标签的名称 。 有一些适用于作业策略的规则:
only
并且except
具有包容性。如果作业规范中同时定义了only
和except
,则ref将由only
和过滤except
。 only
并except
允许使用正则表达式(受支持的regexp语法)。 only
并except
允许指定存储库路径以过滤派生作业。 另外,only
并except
允许使用特殊关键字:
值 | 描述 |
---|---|
branches |
当管道的Git参考是分支时。 |
tags |
当管道的Git参考是标签时。 |
api |
对于由管道API触发的管道。 |
external |
使用除GitLab以外的CI服务时。 |
pipelines |
对于通过结合使用API创建的多项目管道CI_JOB_TOKEN 。 |
pushes |
对于git push 事件触发的管道,包括分支和标签。 |
schedules |
对于预定的管道。 |
triggers |
对于使用触发令牌创建的管道。 |
web |
对于使用GitLab UI中的“运行管道”按钮创建的管道,请从项目的CI / CD>“管道”部分。 |
merge_requests |
对于在创建或更新合并请求时创建的管道。启用合并请求管道,合并结果管道和合并序列。 |
external_pull_requests |
在GitHub上创建或更新外部拉取请求时(有关外部拉取请求,请参见管道)。 |
chat |
对于使用GitLab ChatOps命令创建的管道。 |
在以下示例中,job
将仅对以开头的引用运行issue-
,而所有分支都将被跳过:
job:
# use regexp
only:
- /^issue-.*$/
# use special keyword
except:
- branches
模式匹配默认情况下区分大小写。使用i
标志修饰符,例如 /pattern/i
使模式不区分大小写:
job:
# use regexp
only:
- /^issue-.*$/i
# use special keyword
except:
- branches
在此示例中,job
将仅对带标签的引用运行,或者通过API触发器或管道时间表显式请求构建时运行:
job:
# use special keywords
only:
- tags
- triggers
- schedules
存储库路径可用于仅对父存储库执行作业,而不能用于派生:
job:
only:
- branches@gitlab-org/gitlab
except:
- master@gitlab-org/gitlab
- /^release/.*$/@gitlab-org/gitlab
上面的示例将在上job
的所有分支上运行gitlab-org/gitlab
,但master
名称以开头的分支除外release/
。
如果作业没有only
规则,only: ['branches', 'tags']
则默认设置。如果没有except
规则,则为空。
例如,
job:
script: echo 'test'
转换为:
job:
script: echo 'test'
only: ['branches', 'tags']
因为@
用于表示ref的存储库路径的开头,所以匹配包含@
正则表达式中字符的ref名称需要使用十六进制字符代码match \x40
。
正则表达式只能匹配标签或分支名称。如果给定存储库路径,则始终在字面上匹配。
如果将使用正则表达式匹配标记或分支名称,则模式的整个ref名称部分必须是正则表达式,并且必须用包围/
。(在结束符后附加正则表达式标志/
。)因此issue-/.*/
无法匹配以开头的所有标记名或分支名issue-
。
^
和
$
避免正则表达式仅匹配标记名称或分支名称的子字符串。例如,
/^issue-.*$/
等于
/^issue-/
,而just
/issue/
还要匹配名为的分支
severe-issues
。
only
/正则except
表达式语法 在GitLab 11.9.4中,GitLab开始在内部将用于only
和except
参数的regexp转换为RE2。
这意味着仅 支持Ruby Regexp提供的功能子集。由于计算复杂性,RE2限制了所提供的功能集,这意味着某些功能在GitLab 11.9.4中变得不可用。例如,负面的前瞻。
对于从11.9.7到GitLab 12.0的GitLab版本,GitLab提供了一个功能标记,管理员可以启用它,从而允许用户使用不安全的regexp语法。这带来了与以前允许的语法版本的兼容性,并允许用户正常迁移到新语法。
Feature.enable(:allow_unsafe_ruby_regexp)
only
/ except
(高级) GitLab支持简单策略和复杂策略,因此可以使用数组和哈希配置方案。
有四个键可用:
refs
variables
changes
kubernetes
如果在only
或下使用多个键except
,则这些键将作为单个联合表达式求值。那是:
only:
表示“如果所有条件都匹配,则包括此作业”。 except:
表示“如果满足任何条件,则排除此工作”。 使用only
,各个键在逻辑上由AND连接:
(任何参考)AND(任何变量)AND(任何变化)AND(如果Kubernetes是活动的)
在以下示例中,当满足以下所有条件时,test
将only
创建作业:
master
。 variables
关键字匹配。 kubernetes
服务在项目上处于活动状态。 test:
script: npm run test
only:
refs:
- master
- schedules
variables:
- $CI_COMMIT_MESSAGE =~ /run-end-to-end-tests/
kubernetes: active
except
被实现为对此完整表达式的否定:
NOT((任何参考)AND(任何变量)AND(任何变化)AND(如果Kubernetes处于活动状态))
这意味着将键视为由OR联接。这种关系可以描述为:
(任何参考)或(任何变量)或(任何变化)或(如果Kubernetes处于活动状态)
在以下示例中,如果满足以下任一条件,test
则不会创建作业:
master
。 README.md
存储库的根目录中的文件已更改。 test:
script: npm run test
except:
refs:
- master
changes:
- "README.md"
only:refs
/except:refs
refs
GitLab 10.0中引入的策略。
该refs
策略可以采用与简化的唯一/例外配置相同的值 。
在下面的示例中,deploy
仅在为分支计划了管道或为管道运行时才创建作业master
:
deploy:
only:
refs:
- master
- schedules
only:kubernetes
/except:kubernetes
kubernetes
GitLab 10.0中引入的策略。