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/