Skip to content

.pipeline-policy-pre always runs, resulting in multiple pipelines for same MR

Summary

Jobs defined in a security policy's .pipeline-policy-pre stage always run, which is problematic when avoiding duplicating MR pipelines.

The .pipeline-policy-pre and .pipeline-policy-post stages should be treated the same way as the .pre and .post stages: if a pipeline would only have jobs in the .pipeline-policy-pre, .pipeline-policy-post, .pre, and .post stages (and no other stages), then don't create the pipeline. But that's not the current behavior, resulting in problems.

When a project is configured with workflow rules to avoid duplicate MR pipelines as documented at https://docs.gitlab.com/ci/pipelines/mr_pipeline_troubleshooting/#two-pipelines-when-pushing-to-a-branch and https://docs.gitlab.com/ci/yaml/workflow/#switch-between-branch-pipelines-and-merge-request-pipelines, such as by using:

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

then without a security policy attached, only one pipeline runs for an MR, as expected.

However, when the a security policy is attached to that project with a job in the .pipeline-policy-pre stage, that job always runs, resulting in 2 pipelines created for the MR: one MR pipeline (with the .pipeline-policy-pre job plus all the expected project defined jobs) and one branch pipeline (which only has the .pipeline-policy-pre job). That's bad - but not terrible, because, per https://docs.gitlab.com/ci/pipelines/mr_pipeline_troubleshooting/#the-merge-requests-pipeline-is-marked-as-failed-but-the-latest-pipeline-succeeded

When the project has Pipelines must succeed enabled and both pipelines types are present, the merge request pipelines are checked, not the branch pipelines.

The terrible problem occurs when the project addresses the duplicate MR pipeline concern by disabling MR pipelines in preference to branch pipeline, like this:

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: never

Now, when the security policy is attached, there are once again duplicate pipelines created for an MR, but now the MR pipeline only has the .pipeline-policy-pre job and doesn't have any of the project defined jobs, and since when an MR has both branch and MR pipelines the MR pipeline is preferred, then the MR status is incorrect and if the MR to set to automerge it would be automerged without requiring the project's defined pipeline to succeed.

Steps to reproduce

  1. Create a project, define a job in it, and set the workflow rules:
workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: never
  1. Create a security policy. Define a job in the .pipeline-policy-pre stage.

  2. Attach the security policy to the project.

Example Project

Security policies aren't available on gitlab.com.

What is the current bug behavior?

An MR to the project results in duplicate pipelines: one pipeline has only the .pipeline-policy-pre job, the other pipeline has the .pipeline-policy-pre job and the project's defined jobs.

What is the expected correct behavior?

The .pipeline-policy-pre should not be created when it would be the only job in the pipeline. In other words, .pipeline-policy-pre should behave the same way as .pre, as documented at https://docs.gitlab.com/ci/yaml/#stage-pre

If a pipeline contains only jobs in the .pre or .post stages, it does not run. There must be at least one other job in a different stage.

Relevant logs and/or screenshots

Output of checks

Results of GitLab environment info

Expand for output related to GitLab environment info

(For installations with omnibus-gitlab package run and paste the output of:
`sudo gitlab-rake gitlab:env:info`)

(For installations from source run and paste the output of:
`sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)

Results of GitLab application Check

Expand for output related to the GitLab application check

(For installations with omnibus-gitlab package run and paste the output of: sudo gitlab-rake gitlab:check SANITIZE=true)

(For installations from source run and paste the output of: sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true)

(we will only investigate if the tests are passing)

Possible fixes

Patch release information for backports

If the bug fix needs to be backported in a patch release to a version under the maintenance policy, please follow the steps on the patch release runbook for GitLab engineers.

Refer to the internal "Release Information" dashboard for information about the next patch release, including the targeted versions, expected release date, and current status.

High-severity bug remediation

To remediate high-severity issues requiring an internal release for single-tenant SaaS instances, refer to the internal release process for engineers.

Edited by 🤖 GitLab Bot 🤖