Working with Job Rules and Conditions
1. Defining Job Rules
| Property | Values | Description |
|---|---|---|
| rules | array |
Array of rule objects that define when a job runs |
| rules[].if | string |
Condition to evaluate using GitLab CI/CD variables and operators |
| rules[].when | string |
When to run the job: on_success, on_failure, always, or never |
| rules[].exists | array |
List of files or directories to check for existence |
| rules[].changes | array |
List of files to check for changes since last commit |
| rules[].variables | object |
Variables to set if the rule matches |
Example: Basic job rules with if
deploy:
script:
- echo "Deploying..."
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: on_success
Example: Using changes to trigger jobs
test:
script:
- echo "Running tests..."
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
changes:
- src/**/*
when: on_success
Example: Setting variables in rules
build:
script:
- echo "Building..."
rules:
- if: '$CI_COMMIT_BRANCH == "develop"'
variables:
ENV: development
when: on_success
Note: Rules are evaluated in order, and the first matching rule determines whether the job runs. If no rules match, the job does not run.
2. Using if Conditionals
| Condition | Description | Example |
|---|---|---|
| if | Defines a condition to evaluate before running the job | if: $CI_PIPELINE_SOURCE == "merge_request" |
| unless | Defines a condition to skip the job if it evaluates to true | unless: $CI_COMMIT_TAG |
Example: Conditional Job Execution
deploy:
stage: deploy
script:
- echo "Deploying to production"
if: $CI_COMMIT_BRANCH == "main"
Note: The
if and unless conditions support GitLab CI/CD predefined variables and custom variables.
Warning: The
if condition is evaluated before the job starts, and it can be used to prevent jobs from running based on branch, tag, or custom conditions.
3. Matching File Changes
| Rule | Description | Example |
|---|---|---|
| changes | Triggers the job if files matching a pattern have changed in the commit. | |
| exists | Triggers the job if a file or directory exists in the commit. | |
Example: Using changes to run tests only on JS files
test_js:
stage: test
script:
- npm run test:js
rules:
- changes:
- src/**/*.js
- tests/**/*.js
Note: The
changes rule compares the files in the current commit with those in the previous commit. It does not consider file deletions or renames.
4. Using exists for File Detection
| Rule | Description | Example |
|---|---|---|
| exists | Checks if a file or directory exists in the project | |
Example: Using exists in a job rule
job_with_file_check:
script:
- echo "Running job"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
exists:
- .gitlab-ci.yml
Note: The
exists rule can be used to conditionally run jobs based on the presence of files or directories in the project.
5. Controlling Job Creation
| Rule | Description | Example |
|---|---|---|
| only | Defines when a job runs based on branch/tag names or other conditions. | |
| except | Excludes jobs from running on specified branches/tags. | |
| rules | Allows defining multiple conditions with priorities and variables. | |
| when | Controls when a job runs (e.g., on_success, manual, never). | |
Example: Using rules for conditional job execution
deploy_staging:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "staging"
when: on_success
- if: $CI_PIPELINE_SOURCE == "merge_request"
when: manual
script:
- echo "Deploying to staging environment"
Note: Rules are evaluated in order, and the first matching rule determines job behavior.
6. Setting Variables in Rules
| Property | Description | Example |
|---|---|---|
| rules | List of rule objects that determine when a job runs | |
Example: Setting Variables Based on Branch
job_name:
rules:
- if: $CI_COMMIT_BRANCH == "main"
variables:
ENV: "production"
- if: $CI_COMMIT_BRANCH == "develop"
variables:
ENV: "staging"
Example: Conditional Variable with GitLab Variables
deploy_job:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request"
variables:
DEPLOY_ENV: "staging"
MR_ID: $CI_MERGE_REQUEST_IID
- if: $CI_PIPELINE_SOURCE == "push"
variables:
DEPLOY_ENV: "production"
7. Combining Multiple Rule Conditions
| Condition | Description | Example |
|---|---|---|
| rules | Array of rule objects to evaluate in order | |
| if | Condition to evaluate using GitLab CI/CD variables | ${CI_COMMIT_BRANCH} == 'main' |
| changes | Triggers job only if files match the pattern | changes: ['src/**/*'] |
| exists | Triggers job only if file exists in the repository | exists: ['config.json'] |
Example: Combining multiple conditions in a rule
deploy:
stage: deploy
rules:
- if: "${CI_COMMIT_BRANCH} == 'main'"
changes:
- 'src/**'
exists:
- 'config/deploy.yaml'
when: on_success
- if: "${CI_PIPELINE_SOURCE} == 'merge_request'"
when: never
Note: Rules are evaluated in order, and the first matching rule determines whether the job runs.
8. Using allow_failure with Rules
| Property | Description | Values | Notes |
|---|---|---|---|
| allow_failure | Controls whether a job should be allowed to fail without stopping the pipeline | true or false |
When set to true, the job is marked as allowed to fail. If it fails, the pipeline continues. |
| rules | Defines conditions under which a job should run or be skipped | Array of rule objects | Each rule can include if, changes, exists, or when |
Example: Using allow_failure with rules
job_with_rules:
script:
- echo "Running job"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request"
allow_failure: true
- if: $CI_COMMIT_BRANCH == "main"
allow_failure: false
Note:
allow_failure can be used in conjunction with rules to control job behavior based on conditions. When a job is allowed to fail, it does not block the pipeline from proceeding.
9. Creating Manual Jobs (when: manual)
| Property | Value | Description |
|---|---|---|
| when | manual |
Specifies that the job must be manually started from the GitLab UI. |
Example: Manual Job Configuration
deploy_to_staging:
stage: deploy
script:
- echo "Deploying to staging..."
when: manual
allow_failure: false
Note: Manual jobs can be triggered by users with appropriate permissions in the GitLab project.
Warning: Jobs configured with
when: manual will not run automatically and must be started manually from the GitLab UI or API.
10. Using only and except
| Directive | Description | Usage | Notes |
|---|---|---|---|
| only | Specifies which branches or tags should run the job | only: |
Job runs only on matching branches or tags |
| except | Specifies which branches or tags should NOT run the job | except: |
Job is excluded from running on matching branches or tags |
Note:
only and except can be used together, but only takes precedence.