Course page
Log in

You are watching a free preview. Enroll to open all 25 lessons, track progress and ask the course tutor.

Enroll for $44.99

Section 1: Pipeline fundamentals

Controlling when jobs run with rules

Article 11 min Lesson 2 of 25 Preview

Not every job should run on every commit. Deployments should run only on the main branch; expensive end to end tests might run only on merge requests that touch certain files. The rules keyword controls this.

Rules basics

deploy-staging:
  stage: deploy
  script: ./deploy.sh staging
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Rules are evaluated in order. The first matching rule decides whether the job is added to the pipeline and with which options. If no rule matches, the job is not added.

Common conditions

rules:
  - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  - if: $CI_COMMIT_TAG
  - if: $CI_PIPELINE_SOURCE == "schedule"
  - changes:
      - src/**/*
      - requirements.txt
  • merge_request_event creates merge request pipelines, which run in the context of the merge request.
  • CI_COMMIT_TAG is set for tag pipelines, useful for releases.
  • schedule matches pipelines started by a pipeline schedule.
  • changes matches when listed files changed.

Avoiding duplicate pipelines

A classic problem: pushing to a branch with an open merge request creates two pipelines, a branch pipeline and a merge request pipeline. Use workflow: rules at the top of the file to decide which kind of pipeline runs at all:

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: $CI_COMMIT_BRANCH
    - if: $CI_COMMIT_TAG

This runs merge request pipelines for branches with open merge requests, branch pipelines otherwise, and tag pipelines for releases.

when and allow_failure

rules:
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    when: manual
    allow_failure: false

when: manual adds a job that waits for someone to press play, useful for production deployments. allow_failure: false makes the pipeline wait for it, so it is shown as blocked rather than passed.

Prefer rules over only and except

Older pipelines use only and except. They still work, but rules is more expressive and is the recommended approach. When you touch an old job, consider migrating it.

Test your rules

Rules are logic, and logic has bugs. Use the pipeline editor's simulation to see which jobs would run for a given branch, and keep rules short and commented so reviewers can follow them.

← → switch lessons