Answers: <p>This is because despite looking like a conditional with an <code>if:</code> statement,</p>
  <pre class="lang-yaml prettyprint-override"><code>rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  </code></pre>
  <p>This <strong>actually does change the behavior</strong>, <a href="https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html" rel="nofollow noreferrer">it enables &quot;Merge Request Pipelines&quot; by satisfying the criteria,</a>.</p>
  <blockquote>
  <p>Your project’s .gitlab-ci.yml file must be configured with jobs that run in merge request pipelines. To do this, you can use:</p>
  <ul>
  <li>rules.</li>
  <li>only/except.</li>
  </ul>
  </blockquote>
  <p>Assume we have a repo <code>foo</code> and we fork it into <code>bar</code>. If we open a merge request (adding a new file) from <code>bar</code> to <code>foo</code>, you'll see the same high level overview,</p>
  <p><a href="https://i.sstatic.net/FHjeOl.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/FHjeOl.png" alt="New merge request" /></a></p>
  <p>But adding the rule <code>$CI_PIPELINE_SOURCE == 'merge_request_event'</code> causes a few different things to happen,</p>
  <ul>
  <li>The pipeline is no longer a &quot;Push Pipeline&quot; it's a <a href="https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html" rel="nofollow noreferrer">&quot;Merge Request Pipeline&quot;</a> and it has a different tag.</li>
  <li>The pipeline is no longer run on the fork, but from the &quot;base&quot; project</li>
  <li>The commit the pipeline runs on is no longer run on the fork, but from <code>refs/merge_requests</code> in the &quot;base&quot; project.</li>
  </ul>
  <p>I believe this gives a better idea of how this process works, but you should read the full official documentation page on <a href="https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html" rel="nofollow noreferrer">&quot;Merge Request Pipelines&quot;</a> to compliment any understanding this gives.</p>
  <h1>Without <em>&quot;Merge Request Pipelines&quot;</em></h1>
  <p>However, everything is different from this point on. When you're <strong>NOT</strong> using &quot;Merged Request Pipelines&quot;, the merge request page will link to the pipeline like this,</p>
  <p><a href="https://i.sstatic.net/5duoGm.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/5duoGm.png" alt="link to pipeline" /></a></p>
  <p>Note <em>&quot;Pipeline&quot;</em> here is more correctly &quot;Push Pipeline&quot;. If you click on that number, the pipeline itself will show under <code>bar</code> <strong>the fork</strong> for example under this path <code>bar/-/pipelines/455884</code></p>
  <p><a href="https://i.sstatic.net/JkYPDl.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/JkYPDl.png" alt="Pipelines in bar" /></a></p>
  <p>And it will show the job,</p>
  <p><a href="https://i.sstatic.net/QXlzKm.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/QXlzKm.png" alt="Job detail from bar" /></a></p>
  <p>If you dump the environment from that job you'll see</p>
  <pre><code>CI_PIPELINE_SOURCE=push
  </code></pre>
  <p>And this is true. The pipeline <strong>is running on the branch</strong> (in this case <code>foobar</code>), and that can be seen on <code>bar/-/tree/foobar</code>,</p>
  <p><a href="https://i.sstatic.net/8CiY1l.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/8CiY1l.png" alt="foobar branch" /></a></p>
  <h1>With <em>&quot;Merge Request Pipelines&quot;</em></h1>
  <p>Now let's add the configuration and rerun,</p>
  <pre class="lang-yaml prettyprint-override"><code>rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  </code></pre>
  <p>Now you'll see this on the merge request sitting on <code>foo</code>,</p>
  <p><a href="https://i.sstatic.net/Pb5kQm.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Pb5kQm.png" alt="Foo's merge request" /></a></p>
  <p>Immediately take note to it saying <em>&quot;Merge request pipeline&quot;</em> rather than <em>&quot;Pipeline&quot;</em>. When you click on that pipeline number #455999 you'll be taken <strong>NOT</strong> to bar's pipelines, as you were above, but instead to foo's pipelines, <code>foo/-/pipelines/455999</code> and here you'll see this summary which has the tag <code>merge_request</code>.</p>
  <p><a href="https://i.sstatic.net/nBchkl.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/nBchkl.png" alt="Merge Request Pipeline summary" /></a></p>
  <p>Clicking on the job's tab, you'll be taken to foo's jobs, <code>foo/-/pipelines/455999/builds</code> and you'll see this,</p>
  <p><a href="https://i.sstatic.net/UkMge.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/UkMge.png" alt="Merged Request Pipeline Job" /></a></p>
  <p>And that's showing you that the merge request no longer comes from the branch <code>foobar</code> in reality, it's pulled foobar down to the git merge request directory <code>foo/-/commits/refs/merge-requests/1/head</code> and the merge request now points to that, which resembles the commit <strong>AFTER</strong> it has merged.</p>
  <hr />
  <p><a href="https://gitlab.com/groups/gitlab-org/-/epics/2783#note_1826457181" rel="nofollow noreferrer">I posted this comment on the GitLab Rule Epic to let them know my thoughts on this</a></p>
  
Answers: CC BY-SA 4.0
Answers: 2024-03-21T22:57:04.363Z
Answers: 2024-06-18T14:45:56.240Z
Answers: 2024-06-18T14:45:56.240Z
Answers: Evan Carroll
Body: <p>I have in my gitlab.yml file,</p>
  <pre class="lang-yaml prettyprint-override"><code>rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  </code></pre>
  <p>Before adding that my pipeline was working fine. I just wanted to make it such that the job above was <em>only</em> run on <code>merge_request_event</code>. Now that I added that, the <em>behavior</em> seems to change. How is this rule implemented?</p>
  
Tags: <gitlab><gitlab-ci>
Title: How does $CI_PIPELINE_SOURCE == 'merge_request_event' work?
UserDisplayName: Evan Carroll
ThreadText: # How does $CI_PIPELINE_SOURCE == 'merge_request_event' work?
  
  (Asked by: username_0 on 2024-03-21)
  
  I have in my gitlab.yml file,
  
  ```yaml
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  
  ```
  
  Before adding that my pipeline was working fine. I just wanted to make it such that the job above was *only* run on `merge_request_event`. Now that I added that, the *behavior* seems to change. How is this rule implemented?
  
  **Tags:** gitlab, gitlab-ci
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2024-03-21. Score: 0 | Accepted answer
  
  This is because despite looking like a conditional with an `if:` statement,
  
  ```yaml
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  
  ```
  
  This **actually does change the behavior**, [it enables "Merge Request Pipelines" by satisfying the criteria,](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html).
  
  > Your project’s .gitlab-ci.yml file must be configured with jobs that run in merge request pipelines. To do this, you can use:
  >
  > * rules.
  > * only/except.
  
  Assume we have a repo `foo` and we fork it into `bar`. If we open a merge request (adding a new file) from `bar` to `foo`, you'll see the same high level overview,
  
  [![New merge request](https://i.sstatic.net/FHjeOl.png)](https://i.sstatic.net/FHjeOl.png)
  
  But adding the rule `$CI_PIPELINE_SOURCE == 'merge_request_event'` causes a few different things to happen,
  
  * The pipeline is no longer a "Push Pipeline" it's a ["Merge Request Pipeline"](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html) and it has a different tag.
  * The pipeline is no longer run on the fork, but from the "base" project
  * The commit the pipeline runs on is no longer run on the fork, but from `refs/merge_requests` in the "base" project.
  
  I believe this gives a better idea of how this process works, but you should read the full official documentation page on ["Merge Request Pipelines"](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html) to compliment any understanding this gives.
  
  # Without *"Merge Request Pipelines"*
  
  However, everything is different from this point on. When you're **NOT** using "Merged Request Pipelines", the merge request page will link to the pipeline like this,
  
  [![link to pipeline](https://i.sstatic.net/5duoGm.png)](https://i.sstatic.net/5duoGm.png)
  
  Note *"Pipeline"* here is more correctly "Push Pipeline". If you click on that number, the pipeline itself will show under `bar` **the fork** for example under this path `bar/-/pipelines/455884`
  
  [![Pipelines in bar](https://i.sstatic.net/JkYPDl.png)](https://i.sstatic.net/JkYPDl.png)
  
  And it will show the job,
  
  [![Job detail from bar](https://i.sstatic.net/QXlzKm.png)](https://i.sstatic.net/QXlzKm.png)
  
  If you dump the environment from that job you'll see
  
  ```
  CI_PIPELINE_SOURCE=push
  
  ```
  
  And this is true. The pipeline **is running on the branch** (in this case `foobar`), and that can be seen on `bar/-/tree/foobar`,
  
  [![foobar branch](https://i.sstatic.net/8CiY1l.png)](https://i.sstatic.net/8CiY1l.png)
  
  # With *"Merge Request Pipelines"*
  
  Now let's add the configuration and rerun,
  
  ```yaml
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  
  ```
  
  Now you'll see this on the merge request sitting on `foo`,
  
  [![Foo's merge request](https://i.sstatic.net/Pb5kQm.png)](https://i.sstatic.net/Pb5kQm.png)
  
  Immediately take note to it saying *"Merge request pipeline"* rather than *"Pipeline"*. When you click on that pipeline number #455999 you'll be taken **NOT** to bar's pipelines, as you were above, but instead to foo's pipelines, `foo/-/pipelines/455999` and here you'll see this summary which has the tag `merge_request`.
  
  [![Merge Request Pipeline summary](https://i.sstatic.net/nBchkl.png)](https://i.sstatic.net/nBchkl.png)
  
  Clicking on the job's tab, you'll be taken to foo's jobs, `foo/-/pipelines/455999/builds` and you'll see this,
  
  [![Merged Request Pipeline Job](https://i.sstatic.net/UkMge.png)](https://i.sstatic.net/UkMge.png)
  
  And that's showing you that the merge request no longer comes from the branch `foobar` in reality, it's pulled foobar down to the git merge request directory `foo/-/commits/refs/merge-requests/1/head` and the merge request now points to that, which resembles the commit **AFTER** it has merged.
  
  ---
  
  [I posted this comment on the GitLab Rule Epic to let them know my thoughts on this](https://gitlab.com/groups/gitlab-org/-/epics/2783#note_1826457181)
  
  
  ---
  
  