Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between different GitLab CI Merge Request rules

As several other users, I'm facing issues with duplicate pipelines in GitLab CI/CD. While there is some documentation on how to prevent this scattered around in the GitLab docs, my impression is that the indivdual docs pages and sections are rather inconsistent.

My question is, what are the differences between the following rules? Or, more specifically, are there cases in which these rules are evaluated differently?

  • Switch between branch pipelines and merge request pipelines suggest this to identify merge request pipelines:

    if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    
  • Additionally, Switch between branch pipelines and merge request pipelines also uses this rule in combination with $CI_COMMIT_BRANCH &&:

    if: '$CI_OPEN_MERGE_REQUESTS'
    
  • Moreover, the MergeRequest-Pipelines.gitlab-ci.yml uses a third rule:

    if: $CI_MERGE_REQUEST_IID
    

Any explanation or hints to docs pages I might have overlooked is highly appreciated.

like image 524
Sören Henning Avatar asked Mar 26 '26 18:03

Sören Henning


1 Answers

In order to avoid duplicate pipeline creation and the requirement that you want to switch between Branch-Pipelines and Merge-Request-Pipelines I recommend using these workflow rules

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

There is another SO-question that asks how to prevent duplicate pipelines here

The Explanation(s):

In the following section I will try to explain your different rules and how GitLab CI will evaluate them during pipeline creation.

The merge_request_event-rule

Using this rule:

if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

will create a pipeline each time a Merge-Request is created/updated, but there will also be a pipeline created for the branch if you do not have another prevention mechanism (rule). As the variable naming also points out, this is about the source of the pipeline trigger, other sources could be schedule, push, trigger etc.

The CI_OPEN_MERGE_REQUESTS variable:

Using a rule like:

if: '$CI_OPEN_MERGE_REQUESTS'

GitLab will create new pipelines if there is an open Merge-Request for this branch. Pipelines because there will be a Merge-Request pipeline (denoted with the detached flag) and a branch pipeline for the branch you pushed changes.

if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'

This rule above will create a pipeline for your branch when, and only when there is an open MR on that branch.

if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never

When using the above combination no pipeline will be created if there are open Merge-Requests on that branch, which might also be undesirable since the CI should run tests for branches and/or Merge-Requests.

But how to be able to have pipelines for MRs and Branches, but prevent duplications in pipeline creation?

- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
  when: never
- if: '$CI_COMMIT_BRANCH' || '$CI_COMMIT_TAG'

With this rule set above GitLab will create pipelines for branches and Merge-Requests (the detached ones), as well as pipelines for git-tags, but it will prevent GitLab from duplicating pipelines. The last rule evaluates to true either when there is a commit to a branch or there is a git-tag.

Further links

  • Official docs on switching between MR- and Branch-Pipelines
  • Docs on how to avoid duplicate pipelines with rules examples
like image 182
SPMSE Avatar answered Mar 31 '26 08:03

SPMSE



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!