目录
1. 用途
2. 机制
2.1. Rules attributes
2.2. Rules clauses
2.3. rules:if
2.3.1. Common if clauses for rules
2.4. rules:changes
2.5. rules:exists
3. 综合示例
3.1. 示例1:根据 commit meesage 触发
3.2. 示例2:根据 Tag 触发
1. 用途?
.gitlab-ci.yml 的 rules 配置,能让我们根据自定义的筛选条件,控制 job 是否执行:
一个例子:
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "schedule"'
2. 机制
The rules keyword can be used to include or exclude jobs in pipelines.
Rules are evaluated in order until the first match. 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.
2.1. Rules attributes
The job attributes you can use with rules are:
If a rule evaluates to true, and when has any value except never, the job is included in the pipeline.
For example:
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
2.2. Rules clauses
Available rule clauses are:
Rules are evaluated in order until a match is found. 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:
The job is added to the pipeline:
The job is not added to the pipeline:
For example, using if clauses to strictly limit when jobs run:
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "schedule"'
In this example:
Alternatively, you can define a set of rules to exclude jobs in a few cases, but run them in all other cases:
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
2.3. rules:if
rules:if clauses determine whether or not jobs are added to a pipeline by evaluating an 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:
Any set of expressions to be evaluated can be conjoined into a single expression by using && or ||, and the variable matching operators (==, !=, =~ and !~).
Unlike variables in script sections, variables in rules expressions are always formatted as $VARIABLE.
For example:
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
Some details regarding the logic that determines the when for the job:
2.3.1. Common if clauses for rules
You can check the value of the $CI_PIPELINE_SOURCE variable:
For example:
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "push"'
Another example:
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
Other commonly used variables for if clauses:
2.4. rules:changes
rules:changes determines whether or not to add jobs to a pipeline by checking for changes to specific files.
It’s recommended to only use rules: changes with branch pipelines or merge request pipelines. For example, it’s common to use rules: changes with merge request pipelines:
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
In this example:
To use rules: changes with branch pipelines instead of merge request pipelines, change the if: clause in the example above to:
rules:
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH
To implement a rule similar to except:changes, use when: never.
2.5. rules:exists
exists accepts an array of paths and matches if any of these paths exist as files in the repository:
job:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- exists:
- Dockerfile
You can also use glob patterns to match multiple files in any directory in the repository:
job:
script: bundle exec rspec
rules:
- exists:
- spec/**.rb
For performance reasons, using exists with patterns is limited to 10,000 checks. After the 10,000th check, rules with patterned globs always match.
3. 综合示例
3.1. 示例1:根据 commit meesage 触发
publish-modern-docs:
stage: build
trigger:
include: sef/sef_docs_modern/.gitlab-ci.yml
rules:
- if: '$CI_COMMIT_MESSAGE =~ /^docs/'
changes:
- sef/sef_docs_modern/**/*
3.2. 示例2:根据 Tag 触发
build_sef:
stage: build
trigger:
include: sef/.gitlab-ci_sef.yml
rules:
- if: $CI_COMMIT_TAG
参考:
rules: https://docs.gitlab.com/ee/ci/yaml/README.html#rules