'Accept merge request without running manual stages

I have a pipeline with 3 stages: build, deploy-test and deploy-prod. I want stages to have following behavior:

  • always run build
  • run deploy-test automatically when on master or manually when on other branches
  • run deploy-prod manually, only available on master branch

My pipeline configuration seems to achieve that but I have a problem when trying to merge branches into master. I don't want to execute deploy-test stage on every branch before doing merge. Right now I am required to do that as the merge button is disabled with a message Pipeline blocked. The pipeline for this merge request requires a manual action to proceed. The setting Pipelines must succeed in project is disabled.

I tried adding additional rule to prevent deploy-test stage from running in merge requests but it didn't change anything:

rules:
   - if: '$CI_MERGE_REQUEST_ID'
     when: never
   - if: '$CI_COMMIT_BRANCH == "master"'
     when: on_success
   - when: manual

Full pipeline configuration:

stages:
  - build
  - deploy-test
  - deploy-prod

build:
  stage: build
  script:
    - echo "build"

deploy-test:
  stage: deploy-test
  script:
    - echo "deploy-test"
  rules:
    - if: '$CI_COMMIT_BRANCH == "master"'
      when: on_success
    - when: manual

deploy-prod:
  stage: deploy-prod
  script:
    - echo "deploy-prod"
  only:
    - master


Solution 1:[1]

The only way I got it to work was to set ?? Skipped pipelines are considered successful in Setttings > General > Merge requests > Merge Checks

Gitlab Settings > General > Merge Checks with checked Skipped pipelines are considered successful option

and marking the manual step as "allow_failure"

upload:
  stage: 'upload'
  rules:
    # Only allow uploads for a pipeline source whitelisted here.
    # See: https://docs.gitlab.com/ee/ci/jobs/job_control.html#common-if-clauses-for-rules
    - if: $CI_COMMIT_BRANCH
      when: 'manual'
      allow_failure: true

After this clicking the Merge when Pipeline succeeds button … Screenshot of Gitlab after pressing Merge when Pipeline success Button

… will merge the MR without any manual interaction:

Screenshot showing that the MR was merged without running the last step

Solution 2:[2]

I've opened a merge request from branch "mybranch" into "master" with the following .gitlab-ci.yml:

image: alpine

stages:
  - build
  - deploy-test
  - deploy-prod

build:
  stage: build
  script:
    - echo "build"

# run deploy-test automatically when on master or manually when on other branches
# Don't run on merge requests

deploy-test:
  stage: deploy-test
  script:
    - echo "deploy-test"
  rules:
    - if: $CI_MERGE_REQUEST_ID
      when: never
    - if: '$CI_COMMIT_BRANCH == "master"'
      when: on_success
    - when: manual


# run deploy-prod manually, only available on master branch

deploy-prod:
  stage: deploy-prod
  script:
    - echo "deploy-prod"
  rules:
    - if: '$CI_COMMIT_BRANCH == "master"'
      when: manual

Notes:

  • only is deprecated, so I replaced it with if
  • I added Alpine image to make the jobs run faster (slimmer container); it doesn't affect the logic

When I pushed changes to branch "mybranch", GitLab did the following:

  • showed a blue "Merge when pipeline succeeds" button on my MR
  • ran "build" stage
  • skipped "deploy-prod" stage (only available on "master" branch)
  • gave me a manual "play" button to run the job on "mybranch"
  • at this point, the pipeline status is "blocked" and the MR is showing "Pipeline blocked. The pipeline for this merge request requires a manual action to proceed"
  • now I manually start the "deploy-test" stage by selecting the Play icon in the Pipelines screen
  • pipeline status indicator changes to "running" and then to "passed"
  • my merge request shows the pipeline passed and gives me the green "Merge" button

Solution 3:[3]

There are a number of variables that are available to the pipeline on runtime - Predefined variables reference Some are available specifically for pipelines associated with merge requests - Predefined variables for merge request pipelines

You can utilize one or more of these variables to determine if you would want to run the deploy-test job for that merge request.

For example, you could use mention the phrase "skip_cicd" in your merge request title, access it with CI_MERGE_REQUEST_TITLE variable and create a rule. Your pipeline would look somewhat like this (please do test the rule, I have edited the pipeline off the top of my head and could be wrong) -

stages:
  - build
  - deploy-test
  - deploy-prod

build:
  stage: build
  script:
    - echo "build"

deploy-test:
  stage: deploy-test
  script:
    - echo "deploy-test"
  rules:
    - if: '$CI_MERGE_REQUEST_TITLE == *"skip_cicd"*'
      when: never
    - if: '$CI_COMMIT_BRANCH == "master"'
      when: on_success
    - when: manual

deploy-prod:
  stage: deploy-prod
  script:
    - echo "deploy-prod"
  only:
    - master

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Aleksey Tsalolikhin
Solution 3 Shavya Agrawal