GitLab CI/CD: Using Rules & the when Keyword for Pipeline Job Control
This chapter covers advanced pipeline job control in GitLab CI/CD using the rules keyword and the when condition. While previous chapters focused on controlling entire pipelines using workflow rules, this tutorial demonstrates how to apply precise conditional logic to individual jobs—allowing developers to handle scenarios like manual triggers, skipping jobs entirely, or executing steps based on pipeline variables and commit messages.
1. Why Do We Need Job-Level Rules? (Problem Statement & Status Quo)
In enterprise-level CI/CD pipelines, running every single job on every single commit is inefficient, expensive, and often counterproductive. While workflow:rules controls whether an entire pipeline is created, it acts too broadly when certain edge cases arise.
- The Limitations of Global Control: A global pipeline rule either allows or stops the entire pipeline execution. It cannot selectively disable or modify the behavior of a single job (such as a deployment or packaging step) while letting tests run.
- The Need for Granularity: Developers frequently need granular control over individual jobs. For example:
- Running a test suite only when a specific boolean variable is set to
yes. - Forcing a job to wait for a manual button click rather than running automatically.
- Restricting deployment or packaging jobs exclusively to commits prefixed with specific keywords (like
release).
- Running a test suite only when a specific boolean variable is set to
2. Core Mental Model: The rules and when Decision Engine
Think of GitLab CI/CD job rules as a bouncer at an exclusive club entrance checking a guest list against specific criteria in sequential order.
Real-Life Analogy
Imagine an automated assembly line in a factory. Most days, standard parts go through automatic welding and painting. However, if an inspector sets a clipboard toggle called run_test to "no", the testing station shuts down completely. If the toggle is "yes", the station includes the machine, but requires an engineer to physically press a manual "Start" button before welding begins.
3. Controlling Jobs with Pipeline Variables (when: never vs. Manual Triggers)
To demonstrate conditional job execution, we define a pipeline-level variable (run_test) and evaluate it inside a specific test job using the rules keyword.
Naive vs. Controlled Approach
- Naive Approach: Hardcoding scripts to check variables internally inside shell commands, which still incurs runner startup overhead and clutters build logs.
- Controlled Approach (
rules): Evaluating expressions at pipeline creation time to decide whether a job should be included (when: on_success/when: manual) or completely omitted (when: never).
YAML Configuration: Variable-Based Rules
stages:
- compile
- test
- package
variables:
RUN_TEST: "yes" # Default value for our test control variable
compile_job:
stage: compile
script:
- echo "Compiling the application..."
test_job:
stage: test
script:
- echo "Running automated test suite..."
rules:
- if: '$RUN_TEST == "no"'
when: never
- if: '$RUN_TEST == "yes"'
when: manual # Forces a manual click even if included
4. Step-by-Step Execution Walkthrough (Variable Scenarios)
Depending on the state of the RUN_TEST variable, GitLab evaluates the job inclusion and execution mode differently.
Scenario A: RUN_TEST: "yes" (Default State)
When the variable is set to yes, the YAML rules evaluate as follows:
- The first rule (
$RUN_TEST == "no") evaluates tofalse. - The second rule (
$RUN_TEST == "yes") evaluates totrue, setting the execution condition towhen: manual.
Scenario B: RUN_TEST: "no"
When the variable is changed to no:
- The first rule (
$RUN_TEST == "no") evaluates totrue. - The action
when: nevertriggers, causing GitLab to completely droptest_jobfrom the pipeline structure.
5. Advanced Job Control: Rules Based on Commit Messages ($CI_COMMIT_MESSAGE)
In enterprise workflows, you often want certain high-impact jobs—such as building production artifacts, publishing Docker images, or packaging releases—to run only when the commit message explicitly indicates a release.
YAML Configuration: Commit Message Filtering
Using GitLab's predefined CI/CD variables like $CI_COMMIT_MESSAGE, we can write regex-based rule conditions.
stages:
- compile
- test
- package
compile_job:
stage: compile
script:
- echo "Compiling source files..."
test_job:
stage: test
script:
- echo "Running unit tests..."
package_job:
stage: package
script:
- echo "Packaging application for production release..."
rules:
- if: '$CI_COMMIT_MESSAGE =~ /^release/'
when: on_success
Note: The operator
=~in GitLab CI/CD rules performs a regular expression match. The expression/^release/checks if the commit message string starts with the word "release".
6. Commit Message Flow Walkthrough
Let's examine how GitLab handles pipeline generation based on different commit messages.
Case 1: Standard Commit Message (No Release Prefix)
- Commit Message:
update gitlab ci ml file - Rule Evaluation:
$CI_COMMIT_MESSAGE =~ /^release/evaluates tofalse. - Pipeline Result:
Case 2: Release Commit Message (Matches Prefix)
- Commit Message:
release 5.0 - Rule Evaluation:
$CI_COMMIT_MESSAGE =~ /^release/evaluates totrue. - Pipeline Result:
7. Comparison of Job Control Strategies
8. Summary and Key Takeaways
- Granular Pipeline Control: While
workflow:rulescontrols entire pipeline creation, individual jobrulesprovide fine-grained execution control per task. - The Power of
when: never: Utilizingwhen: neverinside a rule condition completely excludes a job from the pipeline graph when specific variable criteria are met. - Manual Interventions: Setting
when: manualforces jobs (such as deployments or critical tests) to wait for a human operator to click the play button in the GitLab UI. - Predefined CI/CD Variables: You can inspect environment and commit metadata—such as
$CI_COMMIT_MESSAGE—to dynamically alter pipeline behavior based on developer comments. - Regular Expression Matching: Using
=~allows flexible pattern matching, such as checking if a commit message starts with specific prefixes likerelease. - Enterprise Best Practice: Combining standard pipeline structures with conditional job rules helps maintain clean, DRY (Don't Repeat Yourself) YAML configurations while gracefully handling complex edge cases.