-
Specify when jobs run with
rules
- Reuse rules in different jobs
-
Specify when jobs run with
only
andexcept
- Create a job that must be run manually
- Run a job after a delay
- Parallelize large jobs
- Use predefined CI/CD variables to run jobs only in specific pipeline types
- Regular expressions
- CI/CD variable expressions
- Troubleshooting
Choose when to run jobs
When a new pipeline starts, GitLab checks the pipeline configuration to determine which jobs should run in that pipeline. You can configure jobs to run depending on the status of variables, the pipeline type, and so on.
To configure a job to be included or excluded from certain pipelines, you can use:
Use needs
to configure a job to run as soon as the
earlier jobs it depends on finish running.
Specify when jobs run with rules
Use Rules are evaluated in order until the first match. When a match is found, the job
is either included or excluded from the pipeline, depending on the configuration.
See the Future keyword improvements are being discussed in our rules,
where anyone can add suggestions or requests.
The following example uses Alternatively, you can define a set of rules to exclude jobs in a few cases, but
run them in all other cases:
To configure a job to be executed only when the pipeline has been
scheduled, use the In this example, You can use all For example:
If the You can use parentheses with rules
to include or exclude jobs in pipelines.
rules
reference for more details.
rules
examples
if
to define that the job runs in only two specific cases:
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
(manual job)
allow_failure: true
(the pipeline continues running even if the manual job is not run)
when: on_success
(default)
allow_failure: false
(default)
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
clause as the final rule (not including when: never
), two
simultaneous pipelines may start. Both push pipelines and merge request pipelines can
be triggered by the same event (a push to the source branch for an open merge request).
See how to prevent duplicate pipelines
for more details.Run jobs for scheduled pipelines
rules
keyword.
make world
runs in scheduled pipelines, and make build
runs in branch and tag pipelines:
job:on-schedule:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
script:
- make world
job:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
script:
- make build
Complex rules
rules
keywords, like if
, changes
, and exists
, in the same
rule. The rule evaluates to true only when all included keywords evaluate to true.
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
allow_failure: true
Dockerfile
file or any file in /docker/scripts
has changed and $VAR
== “string value”,
then the job runs manually and is allowed to fail.
&&
and ||
to build more complicated variable expressions.
job1:
script:
- echo This rule uses parentheses.
rules:
- if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
Avoid duplicate pipelines
If a job uses rules
, a single action, like pushing a commit to a branch, can trigger
multiple pipelines. You don’t have to explicitly configure rules for multiple types
of pipeline to trigger them accidentally.
Some configurations that have the potential to cause duplicate pipelines cause a
pipeline warning to be displayed.
For example:
This job does not run when To avoid duplicate pipelines, you can:
Rewrite the rules to run the job only in very specific cases,
and avoid a final You can also avoid duplicate pipelines by changing the job rules to avoid either push (branch)
pipelines or merge request pipelines. However, if you use a For example, the following does not trigger double pipelines, but is not recommended
without You should not include both push and merge request pipelines in the same job without
Also, do not mix For every change pushed to the branch, duplicate pipelines run. One
branch pipeline runs a single job ( For behavior similar to the job:
script: echo "This job creates double pipelines!"
rules:
- if: '$CUSTOM_VARIABLE == "false"'
when: never
- when: always
$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.
workflow
to specify which types of pipelines
can run.
when
rule:
job:
script: echo "This job does NOT create double pipelines!"
rules:
- if: '$CUSTOM_VARIABLE == "true" && $CI_PIPELINE_SOURCE == "merge_request_event"'
- when: always
rule without
workflow: rules
, GitLab still displays a pipeline warning.
workflow: rules
:
job:
script: echo "This job does NOT create double pipelines!"
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never
- when: always
workflow:rules
that prevent duplicate pipelines:
job:
script: echo "This job creates double pipelines!"
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
only/except
jobs with rules
jobs in the same pipeline.
It may not cause YAML errors, but the different default behaviors of only/except
and rules
can cause issues that are difficult to troubleshoot:
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
), and one merge request pipeline
runs the other job (job-with-rules
). Jobs with no rules default
to except: merge_requests
, so job-with-no-rules
runs in all cases except merge requests.
Common
if
clauses for rules
only
/except
keywords, you can
check the value of the $CI_PIPELINE_SOURCE
variable:
Value | Description |
---|---|
api
| For pipelines triggered by the pipelines API. |
chat
| For pipelines created by using a GitLab ChatOps command. |
external
| When you use CI services other than GitLab. |
external_pull_request_event
| When an external pull request on GitHub is created or updated. See Pipelines for external pull requests. |
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. |
parent_pipeline
| For pipelines triggered by a parent/child pipeline with rules . Use this pipeline source in the child pipeline configuration so that it can be triggered by the parent pipeline.
|
pipeline
| For multi-project pipelines created by using the API with CI_JOB_TOKEN , or the trigger keyword.
|
push
| For pipelines triggered by a git push event, including for branches and tags.
|
schedule
| For scheduled pipelines. |
trigger
| For pipelines created by using a trigger token. |
web
| For pipelines created by using Run pipeline button in the GitLab UI, from the project’s CI/CD > Pipelines section. |
webide
| For pipelines created by using the WebIDE. |
The following 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.
job:
script: echo "Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "push"'
The following 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.
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:
-
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 == "main"'
: If changes are pushed tomain
. -
if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
: If changes are pushed to the default branch. Use when you want to have the same configuration in multiple projects with different default branches. -
if: '$CI_COMMIT_BRANCH =~ /regex-expression/'
: If the commit branch matches a regular expression. -
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_TITLE =~ /Merge branch.*/
: If the commit branch is the default branch and the commit message title matches a regular expression. For example, the default commit message for a merge commit starts withMerge branch
. -
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
.
Variables in rules:changes
You can use CI/CD variables in rules:changes
expressions to determine when
to add jobs to a pipeline:
docker build:
variables:
DOCKERFILES_DIR: 'path/to/files/'
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- changes:
- $DOCKERFILES_DIR/*
You can use the $
character for both variables and paths. For example, if the
$DOCKERFILES_DIR
variable exists, its value is used. If it does not exist, the
$
is interpreted as being part of a path.
Reuse rules in different jobs
Use You can use In the following example, To execute jobs only for the parent repository and not forks:
This example runs You can use You can use parentheses with When multiple entries are specified in You can skip a job if a change is detected in any file with a
If you change multiple files, but only one file ends in With some configurations that use With merge request pipelines,
it’s possible to define a job to be created based on files modified
in a merge request.
Use this keyword with For example:
In this scenario, if a merge request changes
files in the For example:
In this example, the pipeline might fail because of changes to a file in A later commit that doesn’t have changes in GitLab checks the most recent pipeline that passed. If the merge request is mergeable,
it doesn’t matter that an earlier pipeline failed because of a change that has not been corrected.
When you use this configuration, ensure that the most recent pipeline
properly corrects any failures from previous pipelines.
If you use multiple keywords with With In the following example, the With In the following example, the You can require that a job doesn’t run unless a user starts it. This is called a manual job.
You might want to use a manual job for something like deploying to production.
To specify a job as manual, add By default, manual jobs display as skipped when the pipeline starts.
You can use protected branches to more strictly
protect manual deployments from being run by unauthorized users.
Manual jobs can be either optional or blocking:
To run a manual job, you must have permission to merge to the assigned branch.
To run a manual job:
Use protected environments
to define a list of users authorized to run a manual job. You can authorize only
the users associated with a protected environment to trigger manual jobs, which can:
To protect a manual job:
Add an In the protected environments settings,
select the environment ( You can use protected environments with blocking manual jobs to have a list of users
allowed to approve later pipeline stages. Add
Use You can set the period with When a stage includes a delayed job, the pipeline doesn’t progress until the delayed job finishes.
You can use this keyword to insert delays between different stages.
The timer of a delayed job starts immediately after the previous stage completes.
Similar to other types of jobs, a delayed job’s timer doesn’t start unless the previous stage passes.
The following example creates a job named To stop the active timer of a delayed job, select Unschedule ().
This job can no longer be scheduled to run automatically. You can, however, execute the job manually.
To start a delayed job immediately, select Play ().
Soon GitLab Runner starts the job.
To split a large job into multiple smaller jobs that run in parallel, use the
Different languages and test suites have different methods to enable parallelization.
For example, use
and RSpec to run Ruby tests in parallel:
You can then navigate to the Jobs tab of a new pipeline build and see your RSpec
job split into three separate jobs.
You can create a one-dimensional matrix of parallel jobs:
You can also create a multi-dimensional matrix.
You can run a trigger job multiple times in parallel in a single pipeline,
but with different variable values for each instance of the job.
This example generates 6 parallel
You can use variables defined in You can fetch artifacts from a job created with For example, to fetch the artifacts from the job with a Quotes around the You can use predefined CI/CD variables to choose
which pipeline types jobs run in, with:
The following table lists some of the variables that you can use, and the pipeline
types the variables can control for:
For example, to configure a job to run for merge request pipelines and scheduled pipelines,
but not branch or tag pipelines:
The Only the tag or branch name can be matched by a regular expression.
The repository path, if given, is always matched literally.
To match the tag or branch name,
the entire ref name part of the pattern must be a regular expression surrounded by Regular expression flags must be appended after the closing Use anchors In GitLab 11.9.4, GitLab began internally converting the regexp used
in
are now supported.
From GitLab 11.9.7 to GitLab 14.9, GitLab provided a feature flag to let you
use unsafe regexp syntax. We’ve fully migrated to RE2 now, and that feature
flag is no longer available.
Use variable expressions to control which jobs are created in a pipeline after changes
are pushed to GitLab. You can use variable expressions with:
For example, with You can use the equality operators You can compare the values of two variables. For example:
You can compare a variable to the You can check if a variable is defined but empty. For example:
You can check for the existence of a variable by using just the variable name in
the expression. The variable must not be empty. For example:
You can do regex pattern matching on variable values with the Expressions evaluate as For example:
Pattern matching is case-sensitive by default. Use the
You can join multiple expressions using The precedence of operators follows the ,
so You can use parentheses to group expressions together. Parentheses take precedence over
You can nest parentheses to create complex conditions, and the inner-most expressions
in parentheses are evaluated first.
For example:
You might have jobs or pipelines that run unexpectedly when using Pipelines on branches or tags that don’t have an explicit association with a merge request
use a previous SHA to calculate the diff. This calculation is equivalent to Additionally, rules with You might see pipelines fail when a GitLab administrator runs a protected manual job
in a private project.
CI/CD jobs usually clone the project when the job starts, and this uses the permissions
of the user that runs the job. All users, including administrators, must be direct members
of a private project to clone the source of that project.
to change this behavior.
To run protected manual jobs:
If you didn't find what you were looking for,
search the docs.
If you want help with something specific and could use community support,
.
For problems setting up or using this feature (depending on your GitLab
subscription).!reference
tags to reuse rules in different
jobs. You can combine !reference
rules with regular job-defined rules:
.default_rules:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
job1:
rules:
- !reference [.default_rules, rules]
script:
- echo "This job runs for the default branch, but not schedules."
job2:
rules:
- !reference [.default_rules, rules]
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- echo "This job runs for the default branch, but not schedules."
- echo "It also runs for merge requests."
Specify when jobs run with
only
and except
only
and except
to control when to add jobs to pipelines.
only
to define when a job runs.
except
to define when a job does not run.
only:refs
/ except:refs
examples
only
or except
used without refs
is the same as
only:refs
/ except/refs
job
runs only for:
job:
# use special keywords
only:
- tags
- triggers
- schedules
job:
only:
- branches@gitlab-org/gitlab
except:
- main@gitlab-org/gitlab
- /^release/.*$/@gitlab-org/gitlab
job
for all branches on gitlab-org/gitlab
,
except main
and branches that start with release/
.
only: variables
/ except: variables
examples
except:variables
to exclude jobs based on a commit message:
end-to-end:
script: rake test:end-to-end
except:
variables:
- $CI_COMMIT_MESSAGE =~ /skip-end-to-end-tests/
&&
and ||
to build more complicated variable expressions:
job1:
script:
- echo This rule uses parentheses.
only:
variables:
- ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
only:variables
, the job runs when at least one of them evaluates to true
.
You can use &&
in a single entry when multiple conditions must be satisfied at the same time.
only:changes
/ except:changes
examples
.md
extension in the root directory of the repository:
build:
script: npm run build
except:
changes:
- "*.md"
.md
,
the build
job is still skipped. The job does not run for any of the files.
changes
, jobs or pipelines might run unexpectedly
Use
only:changes
with merge request pipelines
only: [merge_requests]
so GitLab can find the correct base
SHA of the source branch. File differences are correctly calculated from any further
commits, and all changes in the merge requests are properly tested in pipelines.
docker build service one:
script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
only:
refs:
- merge_requests
changes:
- Dockerfile
- service-one/**/*
service-one
directory or the Dockerfile
, GitLab creates
the docker build service one
job.
docker build service one:
script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
only:
changes:
- Dockerfile
- service-one/**/*
service-one/**/*
.
service-one/**/*
but does have changes to the Dockerfile
can pass. The job
only tests the changes to the Dockerfile
.
Combine multiple keywords with
only
or except
only
or except
, the keywords are evaluated
as a single conjoined expression. That is:
only
includes the job if all of the keys have at least one condition that matches.
except
excludes the job if any of the keys have at least one condition that matches.
only
, individual keys are logically joined by an AND
. A job is added to
the pipeline if the following is true:
(any listed refs are true) AND (any listed variables are true) AND (any listed changes are true) AND (any chosen Kubernetes status matches)
test
job is only created when all of the following are true:
main
.
variables
keyword matches.
kubernetes
service is active on the project.
test:
script: npm run test
only:
refs:
- main
- schedules
variables:
- $CI_COMMIT_MESSAGE =~ /run-end-to-end-tests/
kubernetes: active
except
, individual keys are logically joined by an OR
. A job is not
added if the following is true:
(any listed refs are true) OR (any listed variables are true) OR (any listed changes are true) OR (a chosen Kubernetes status matches)
test
job is not created when any of the following are true:
main
branch.
README.md
file in the root directory of the repository.
test:
script: npm run test
except:
refs:
- main
changes:
- "README.md"
Create a job that must be run manually
when: manual
to the job
in the .gitlab-ci.yml
file.
Types of manual jobs
allow_failure: true
by default.
allow_failure: false
to the job configuration.
Run a manual job
Protect manual jobs
environment
to the job. For example:
deploy_prod:
stage: deploy
script:
- echo "Deploy to production server"
environment:
name: production
url: https://example.com
when: manual
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
production
in this example) and add the users, roles or groups
that are authorized to trigger the manual job to the Allowed to Deploy list. Only those in
this list can trigger this manual job, as well as GitLab administrators
who are always able to use protected environments.
allow_failure: false
to the protected
manual job and the pipeline’s next stages only run after the manual job is triggered
by authorized users.
Run a job after a delay
when: delayed
to execute scripts after a waiting period, or if you want to avoid
jobs immediately entering the pending
state.
start_in
keyword. The value of start_in
is an elapsed time in seconds, unless a unit is
provided. start_in
must be less than or equal to one week. Examples of valid values include:
'5'
(a value with no unit must be surrounded by single quotes)
5 seconds
30 minutes
1 day
1 week
timed rollout 10%
that is executed 30 minutes after the previous stage completes:
timed rollout 10%:
stage: deploy
script: echo 'Rolling out 10% ...'
when: delayed
start_in: 30 minutes
Parallelize large jobs
parallel
keyword in your .gitlab-ci.yml
file.
# 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
Run a one-dimensional matrix of parallel jobs
deploystacks:
stage: deploy
script:
- bin/deploy
parallel:
matrix:
- PROVIDER: [aws, ovh, gcp, vultr]
Run a matrix of parallel trigger jobs
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]
deploystacks
trigger jobs, each with different values
for PROVIDER
and STACK
, and they create 6 different child pipelines with those variables.
deploystacks: [aws, monitoring]
deploystacks: [aws, app1]
deploystacks: [ovh, monitoring]
deploystacks: [ovh, backup]
deploystacks: [gcp, data]
deploystacks: [vultr, data]
Select different runner tags for each parallel matrix job
parallel: matrix
with the tags
keyword for dynamic runner selection:
deploystacks:
stage: deploy
parallel:
matrix:
- PROVIDER: aws
STACK: [monitoring, app1]
- PROVIDER: gcp
STACK: [data]
tags:
- ${PROVIDER}-${STACK}
Fetch artifacts from a
parallel:matrix
job
parallel:matrix
by using the dependencies
keyword. Use the job name
as the value for dependencies
as a string in the form:
<job_name> [<matrix argument 1>, <matrix argument 2>, ... <matrix argument N>]
RUBY_VERSION
of 2.7
and
a PROVIDER
of aws
:
ruby:
image: ruby:${RUBY_VERSION}
parallel:
matrix:
- RUBY_VERSION: ["2.5", "2.6", "2.7", "3.0", "3.1"]
PROVIDER: [aws, gcp]
script: bundle install
deploy:
image: ruby:2.7
stage: deploy
dependencies:
- "ruby: [2.7, aws]"
script: echo hello
dependencies
entry are required.
Use predefined CI/CD variables to run jobs only in specific pipeline types
push
events to a branch, like new commits or tags.
Variables
Branch
Tag
Merge request
Scheduled
CI_COMMIT_BRANCH
Yes
Yes
CI_COMMIT_TAG
Yes
Yes, if the scheduled pipeline is configured to run on a tag.
CI_PIPELINE_SOURCE = push
Yes
Yes
CI_PIPELINE_SOURCE = scheduled
Yes
CI_PIPELINE_SOURCE = merge_request_event
Yes
CI_MERGE_REQUEST_IID
Yes
job1:
script:
- echo
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "schedule"
- if: $CI_PIPELINE_SOURCE == "push"
when: never
Regular expressions
@
symbol denotes the beginning of a ref’s repository path.
To match a ref name that contains the @
character in a regular expression,
you must use the hex character code match \x40
.
/
.
For example, you can’t use issue-/.*/
to match all tag names or branch names
that begin with issue-
, but you can use /issue-.*/
.
/
. Pattern matching
is case-sensitive by default. Use the i
flag modifier, like /pattern/i
, to make
a pattern case-insensitive:
job:
# use regexp
only:
- /^issue-.*$/i
# use special keyword
except:
- branches
^
and $
to avoid the regular expression
matching only a substring of the tag name or branch name.
For example, /^issue-.*$/
is equivalent to /^issue-/
,
while just /issue/
would also match a branch called severe-issues
.
only
/ except
regex syntax
only
and except
keywords to .
CI/CD variable expressions
rules:if
:
job1:
variables:
VAR1: "variable1"
script:
- echo "Test variable comparison
rules:
- if: $VAR1 == "variable1"
Compare a variable to a string
==
and !=
to compare a variable with a
string. Both single quotes and double quotes are valid. The order doesn’t matter,
so the variable can be first, or the string can be first. For example:
if: $VARIABLE == "some value"
if: $VARIABLE != "some value"
if: "some value" == $VARIABLE
Compare two variables
if: $VARIABLE_1 == $VARIABLE_2
if: $VARIABLE_1 != $VARIABLE_2
Check if a variable is undefined
null
keyword to see if it is defined. For example:
if: $VARIABLE == null
if: $VARIABLE != null
Check if a variable is empty
if: $VARIABLE == ""
if: $VARIABLE != ""
Check if a variable exists
if: $VARIABLE
Compare a variable to a regex pattern
=~
and !~
operators.
Variable pattern matching with regular expressions uses the
.
true
if:
=~
.
!~
.
$VARIABLE =~ /^content.*/
$VARIABLE_1 !~ /^content.*/
i
flag modifier to make a
pattern case-insensitive. For example: /pattern/i
.
Join variable expressions together with
&&
or ||
&&
(and) or ||
(or), for example:
$VARIABLE1 =~ /^content.*/ && $VARIABLE2 == "something"
$VARIABLE1 =~ /^content.*/ && $VARIABLE2 =~ /thing$/ && $VARIABLE3
$VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/ && $VARIABLE3
&&
is evaluated before ||
.
Group variable expressions together with parentheses
&&
and ||
, so expressions enclosed in parentheses are evaluated first, and the
result is used for the rest of the expression.
($VARIABLE1 =~ /^content.*/ || $VARIABLE2) && ($VARIABLE3 =~ /thing$/ || $VARIABLE4)
($VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/) && $VARIABLE3
$CI_COMMIT_BRANCH == "my-branch" || (($VARIABLE1 == "thing" || $VARIABLE2 == "thing") && $VARIABLE3)
Troubleshooting
Jobs or pipelines run unexpectedly when using
changes:
rules: changes
or only: changes
without
merge request pipelines.
git diff HEAD~
and can cause unexpected behavior, including:
changes
rule always evaluates to true when pushing a new branch or a new tag to GitLab.
changes
always evaluate as true in scheduled pipelines.
All files are considered to have changed when a scheduled pipeline runs, so jobs
might always be added to scheduled pipelines that use changes
.
You are not allowed to download code from this project.
error message
Help & feedback
Docs
Edit this page
to fix an error or add an improvement in a merge request.
Create an issue
to suggest an improvement to this page.
Product
Create an issue
if there's something you don't like about this feature.
Propose functionality
by submitting a feature request.
to help shape new features.
Feature availability and product trials
to see all GitLab tiers and features, or to upgrade.
with access to all features for 30 days.
Get Help