extends
Introduced in GitLab 11.3.
extends
defines entry names that a job that uses extends
is going to inherit from.
It’s an alternative to using YAML anchors and is a little more flexible and readable:
1 .tests: # YAML anchors 2 script: rake test 3 stage: test 4 only: 5 refs: 6 - branches 7 8 rspec: 9 extends: .tests 10 script: rake rspec 11 only: 12 variables: 13 - $RSPEC
In the example above, the rspec
job inherits from the .tests
template job. GitLab will perform a reverse deep merge based on the keys. GitLab will:
- Merge the
rspec
contents into.tests
recursively. - Not merge the values of the keys.
This results in the following rspec
job:
1 rspec: 2 script: rake rspec 3 stage: test 4 only: 5 refs: 6 - branches 7 variables: 8 - $RSPEC
Note: Note that script: rake test
has been overwritten by script: rake rspec
.
.tests
in this example is a hidden job, but it’s possible to inherit from regular jobs as well.
.tests 这里是一个隐藏job,但是依然可以被普通的jobs继承.
Using extends
and include
together
extends 结合 include 一起使用是个不错的选择,这样可以跨配置文件进行配置继承,增加配置文件的可读性:
extends
works across configuration files combined with include
.
For example, if you have a local included.yml
file: (将要被包含的文件,其中配置将被继承)
1 .template: 2 script: 3 - echo Hello!
Then, in .gitlab-ci.yml
you can use it like this:
1 include: included.yml 2 3 useTemplate: 4 image: alpine 5 extends: .template
####
rules
Introduced in GitLab 12.3.
The rules
keyword is a way to set job policies that determine whether or not jobs are added to pipelines.
A list of individual rule clauses are evaluated in order, until one matches. When matched, the job is either included or excluded from the pipeline, depending on the configuration. If included, the job also has certain attributes added to it.
rule中独立的规则按照顺序被逻辑判断,直到有一个条件成立。当找到符合的条件,就可以确认这个job是否被加入到此pipeline当中,这取决于when: [values]配置,If when
is evaluated to any value except never
, the job is included in the pipeline。
Caution: rules can’t be used in combination with only/except because it is a replacement for that functionality. If you attempt to do this, the linter returns a key may not be used
with rules error.
注意: rules 模块 不能和 only/except 模块同时使用,可能会产生逻辑冲突。
For example:
1 docker build: 2 script: docker build -t my-image:$CI_COMMIT_REF_SLUG . 3 rules: 4 - if: '$CI_COMMIT_BRANCH == "master"' 5 when: delayed 6 start_in: '3 hours' 7 allow_failure: true
Additional job configuration may be added to rules in the future.
Rules clauses
Available rule clauses are:
Clause | Description |
---|---|
if |
Add or exclude jobs from a pipeline by evaluating an if statement. Similar to only:variables . |
changes |
Add or exclude jobs from a pipeline based on what files are changed. Same as only:changes . |
exists |
Add or exclude jobs from a pipeline based on the presence of specific files. |
Rules are evaluated in order until a match is found.
rules模块中的规则是依次进行逻辑判断.
If a match is found, the attributes are checked to see if the job should be added to the pipeline. If no attributes are defined, the defaults are:
job默认添加以下attributes:
when: on_success
allow_failure: false
The job is added to the pipeline: # job被添加到pipeline的情况
- If a rule matches and has
when: on_success
,when: delayed
orwhen: always
. - If no rules match, but the last clause is
when: on_success
,when: delayed
orwhen: always
(with no rule).
The job is not added to the pipeline: # job不被添加到pipeline的情况
- If no rules match, and there is no standalone
when: on_success
,when: delayed
orwhen: always
. - If a rule matches, and has
when: never
as the attribute.
For example, using if
clauses to strictly limit when jobs run: #严格匹配限制条件
1 job: 2 script: "echo Hello, Rules!" 3 rules: 4 - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' 5 when: manual 6 allow_failure: true 7 - if: '$CI_PIPELINE_SOURCE == "schedule"'
In this example:
- If the pipeline is for a merge request, the first rule matches, and the job is added to the merge request pipeline with attributes of:
when: manual
(manual job)allow_failure: true
(allows the pipeline to continue running even if the manual job is not run)
- If the pipeline is not for a merge request, the first rule doesn’t match, and the second rule is evaluated.
- If the pipeline is a scheduled pipeline, the second rule matches, and the job is added to the scheduled pipeline. Since no attributes were defined, it is added with:
when: on_success
(default)allow_failure: false
(default)
- In all other cases, no rules match, so the job is not added to any other pipeline.
Alternatively, you can define a set of rules to exclude jobs in a few cases, but run them in all other cases: #你可以配置exclude|include规则的条件,而其余条件全部为include|exclude
1 job: 2 script: "echo Hello, Rules!" 3 rules: 4 - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' 5 when: never 6 - if: '$CI_PIPELINE_SOURCE == "schedule"' 7 when: never 8 - when: on_success
- If the pipeline is for a merge request, the job is not be added to the pipeline.
- If the pipeline is a scheduled pipeline, the job is not be added to the pipeline.
- In all other cases, the job is added to the pipeline, with
when: on_success
.
Differences between rules
and only
/except
A very important difference between rules
and only/except
, is that jobs defined with only/except
do not trigger merge request pipelines without explicit(明确) configuration. rules
can trigger all types of pipelines, without explicitly configuring each type. (如果没有明确配置 merge request pipeline,那么only/except 是不会自动触发的.rules 可以触发任何类型的pipelines,不需要明确配置每种类型.)
For example:
job:
script: "echo This creates double pipelines!"
rules:
- if: '$CUSTOM_VARIABLE == "false"'
when: never
- when: always
This job does not run when $CUSTOM_VARIABLE
is false, but it does run in all other pipelines, including both push (branch) and merge request pipelines. With this configuration, every push to an open merge request’s source branch causes duplicated pipelines. Explicitly allowing both push and merge request pipelines in the same job could have the same effect. (在同一个job中同时允许push pipeline 和 merge request pipeline 所产生的效果是一样的.)
We recommend using workflow: rules
to limit which types of pipelines are permitted. Allowing only merge request pipelines, or only branch pipelines, eliminates(消除) duplicated pipelines. Alternatively(或者), you can rewrite the rules to be stricter, or avoid using a final when
(always
, on_success
or delayed
).
建议使用 workflow: rules
to 限制哪种类型的 pipelines 被允许(Allowing only merge request pipelines, or only branch pipelines)。
Also, we don’t recommend mixing only/except
jobs with rules
jobs in the same pipeline. It may not cause YAML errors, but debugging the exact execution behavior can be complex due to the different default behaviors of only/except
and rules
. 不建议 only/except
jobs with rules
jobs in the same pipeline,就算不会出错,也增加了逻辑复杂度。
####
rules:if
rules:if
clauses determine whether or not jobs are added to a pipeline by evaluating a simple if
statement. If the if
statement is true, the job is either included or excluded from a pipeline. In plain English, if
rules can be interpreted as one of:
- “If this rule evaluates to true, add the job” (default).
- “If this rule evaluates to true, do not add the job” (by adding
when: never
).
rules:if
differs slightly from only:variables
by accepting only a single expression string per rule, rather than an array of them. Any set of expressions to be evaluated can be conjoined into a single expression by using &&
or ||
, and use the variable matching syntax.
if:
clauses are evaluated based on the values of predefined environment variables or custom environment variables.
For example:
1 job: 2 script: "echo Hello, Rules!" 3 rules: 4 - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"' 5 when: always 6 - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/' 7 when: manual 8 allow_failure: true 9 - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' # Checking for the presence of a variable is possible
Some details regarding the logic that determines the when
for the job:
- If none of the provided rules match, the job is set to
when: never
and is not included in the pipeline. - A rule without any conditional clause, such as a
when
orallow_failure
rule withoutif
orchanges
, always matches, and is always used if reached. - If a rule matches and has no
when
defined, the rule uses thewhen
defined for the job, which defaults toon_success
if not defined.
For behavior similar to the only
/except
keywords, you can check the value of the $CI_PIPELINE_SOURCE
variable.
Value | Description |
---|---|
push |
For pipelines triggered by a git push event, including for branches and tags. |
web |
For pipelines created by using Run pipeline button in the GitLab UI, from the project’s CI/CD > Pipelines section. |
trigger |
For pipelines created by using a trigger token. |
schedule |
For scheduled pipelines. |
api |
For pipelines triggered by the pipelines API. |
external |
When using CI services other than GitLab. |
pipelines |
For multi-project pipelines created by using the API with CI_JOB_TOKEN . |
chat |
For pipelines created by using a GitLab ChatOps command. |
webide |
For pipelines created by using the WebIDE. |
merge_request_event |
For pipelines created when a merge request is created or updated. Required to enable merge request pipelines, merged results pipelines, and merge trains. |
external_pull_request_event |
When an external pull request on GitHub is created or updated. See Pipelines for external pull requests. |
parent_pipeline |
For pipelines triggered by a parent/child pipeline with rules , use this in the child pipeline configuration so that it can be triggered by the parent pipeline. |
For example:
1 job: 2 script: "echo Hello, Rules!" 3 rules: 4 - if: '$CI_PIPELINE_SOURCE == "schedule"' 5 when: manual 6 allow_failure: true 7 - if: '$CI_PIPELINE_SOURCE == "push"'
This example runs the job as a manual job in scheduled pipelines or in push pipelines (to branches or tags), with when: on_success
(default). It does not add the job to any other pipeline type.
这种情况,只有在 '$CI_PIPELINE_SOURCE == "schedule"' 或 '$CI_PIPELINE_SOURCE == "push"' 两个event产生时,该job才会被加入到pipeline。
Another example:
1 job: 2 script: "echo Hello, Rules!" 3 rules: 4 - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' 5 - if: '$CI_PIPELINE_SOURCE == "schedule"'
This example runs the job as a when: on_success
job in merge request pipelines and scheduled pipelines. It does not run in any other pipeline type.
Other commonly used variables for if
clauses:
if: $CI_COMMIT_TAG
: If changes are pushed for a tag.if: $CI_COMMIT_BRANCH
: If changes are pushed to any branch.if: '$CI_COMMIT_BRANCH == "master"'
: If changes are pushed tomaster
.if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
: If changes are pushed to the default branch (usuallymaster
). Useful if reusing the same configuration in multiple projects with potentially different default branches.if: '$CI_COMMIT_BRANCH =~ /regex-expression/'
: If the commit branch matches a regular expression.if: '$CUSTOM_VARIABLE !~ /regex-expression/'
: If the custom variableCUSTOM_VARIABLE
does not match a regular expression.if: '$CUSTOM_VARIABLE == "value1"'
: If the custom variableCUSTOM_VARIABLE
is exactlyvalue1
.
rules:changes
To determine if jobs should be added to a pipeline, rules: changes
clauses check the files changed by Git push events. (changes 条件判断检查Git push事件是否导致监测的文件发生变化)
rules: changes
works exactly the same way as only: changes
and except: changes
, accepting an array of paths. Similarly, it always returns true if there is no Git push event. It should only be used for branch pipelines or merge request pipelines.
For example:
1 workflow: 2 rules: 3 - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' 4 5 docker build: 6 script: docker build -t my-image:$CI_COMMIT_REF_SLUG . 7 rules: 8 - changes: 9 - Dockerfile 10 when: manual 11 allow_failure: true
In this example:
workflow: rules
allows only pipelines for merge requests for all jobs.- If
Dockerfile
has changed, add the job to the pipeline as a manual job, and allow the pipeline to continue running even if the job is not triggered (allow_failure: true
). - If
Dockerfile
has not changed, do not add job to any pipeline (same aswhen: never
).
rules:exists
exists
accepts an array of paths and will match if any of these paths exist as files in the repository.
For example:
1 job: 2 script: docker build -t my-image:$CI_COMMIT_REF_SLUG . 3 rules: 4 - exists: 5 - Dockerfile
You can also use glob patterns to match multiple files in any directory within the repository. (可以使用全局匹配,匹配仓库下任务目录中的多个文件)
1 job: 2 script: bundle exec rspec 3 rules: 4 - exists: 5 - spec/**.rb
Note: For performance reasons, using exists
with patterns is limited to 10000 checks. After the 10000th check, rules with patterned globs will always match.
rules:allow_failure
Introduced in GitLab 12.8.
You can use allow_failure: true
within rules:
to allow a job to fail, or a manual job to wait for action, without stopping the pipeline itself. All jobs using rules:
default to allow_failure: false
if allow_failure:
is not defined.
The rule-level rules:allow_failure
option overrides the job-level allow_failure
option, and is only applied when the job is triggered by the particular rule.
1 job: 2 script: "echo Hello, Rules!" 3 rules: 4 - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"' 5 when: manual 6 allow_failure: true
In this example, if the first rule matches, then the job will have when: manual
and allow_failure: true
.
Complex rule clauses
To conjoin if
, changes
, and exists
clauses with an AND, use them in the same rule.
In the following example:
- We run the job manually if
Dockerfile
or any file indocker/scripts/
has changed AND$VAR == "string value"
. - Otherwise, the job won’t be included in the pipeline.
1 docker build: 2 script: docker build -t my-image:$CI_COMMIT_REF_SLUG . 3 rules: 4 - if: '$VAR == "string value"' 5 changes: # Will include the job and set to when:manual if any of the follow paths match a modified file. 6 - Dockerfile 7 - docker/scripts/* 8 when: manual 9 # - when: never would be redundant here, this is implied any time rules are listed.
Keywords such as branches
or refs
that are currently available for only
/except
are not yet available in rules
as they are being individually considered for their usage and behavior in this context. Future keyword improvements are being discussed in our epic for improving rules
, where anyone can add suggestions or requests.
---
参考链接:
- https://docs.gitlab.com/ee/ci/yaml/