25

I have a gitlab pipeline where there are two stages, one is build and the other one is deploy. The build stage is run when a commit is made. I want a way to run the deploy job when the merge request is merged to master. I tried several things but no luck. Can anyone help?

stages:
  - build
  - deploy

dotnet:
script: "echo This builds!"
stage: build


production:
script: "echo This deploys!"
stage: deploy

only:
  refs:
    - master
Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Eats
  • 477
  • 1
  • 6
  • 13

4 Answers4

27

Try using the gitlab-ci.yml "rules" feature to check for the merge request event.

Your current gitlab-ci.yml will run your "dotnet" job every commit, merge request, schedule, and manually triggered pipeline.

https://docs.gitlab.com/ee/ci/yaml/#workflowrules

dotnet:
  script: "echo This builds!"
  stage: build
  rules:
    - if: '$CI_COMMIT_REF_NAME != "master" && $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"'

production:
  script: "echo This deploys!"
  stage: deploy
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == "master"'
Josh Correia
  • 3,807
  • 3
  • 33
  • 50
amBear
  • 900
  • 6
  • 7
  • 2
    I have already tried this and this will not work. This rule is saying that run the job on a merge request. I want to run a deployment when the merge request is merged to master. – Eats Sep 15 '20 at 01:36
  • I have updated the answer. I added the condition that the branch needs to be master. So now the full rule is: the pipeline needs to be soured from a merge request and ran against the master branch. – amBear Sep 15 '20 at 01:42
  • I tried this too but it did not work. When I pushed the commit it ran the build stage but when I merged the merge request no pipeline ran. – Eats Sep 15 '20 at 01:50
  • 2
    I updated my answer. This time I tested out the env variables we are using for conditionals. Proof: Commit: https://gitlab.com/atbeasley/problem-child/-/pipelines/189925730 Merge: https://gitlab.com/atbeasley/problem-child/-/pipelines/189925811 – amBear Sep 15 '20 at 02:40
  • Thank you for your response and the work you did, much appreciated. I figured that any changes I was making to the pipeline were not reflected, there is some weirdness going on with my git-lab pipelines :) – Eats Sep 15 '20 at 04:50
  • 2
    Now how do you avoid it runs on master when pushing directly on master? Because at the end of the day I've slightly the same question but would like to restrict running pipeline to merged merge requests – Nicko Glayre Feb 15 '22 at 16:46
  • 2
    You could improve your answer by: - Removing the 2nd last line ("rules:") from the code you posted - Replacing "master" by $CI_DEFAULT_BRANCH which would make your solution also work in case a project uses a different default branch name (e.g., "main") – Adrian Dymorz Feb 21 '22 at 13:57
  • Yes, @NickoGlayre I have exactly the same problem. – An old man in the sea. May 27 '22 at 10:52
  • 2
    Seems like `CI_BUILD_REF_NAME` is deprecated and `CI_COMMIT_REF_NAME` should be used instead. – Mateusz Jul 25 '22 at 22:51
  • I suggest to use ``$CI_DEFAULT_BRANCH`` instead of hardcoding ``master`` or ``main`` you can avoid a headache :) – Juan-Kabbali Jul 27 '23 at 09:45
5

If you want your job run on only after merging the merge request, then you can trigger a job based on the commit message, as shown below.

rules:
    - if: '$CI_COMMIT_MESSAGE =~ /See merge request/'

Basically, all the merge request comes with a "See merge request" commit message so you can depend on that message to trigger your job.

Josh Correia
  • 3,807
  • 3
  • 33
  • 50
sri05
  • 185
  • 3
  • 12
1

CI_MERGE_REQUEST_APPROVED variable seems to be designed for check approve status, not for triggering pipeline. (Issue, https://gitlab.com/gitlab-org/gitlab/-/issues/375908)

When you use merge request predefined variables, gitlab creates pipeline at merge request created, not at merge request approved.

Instead, use CI_COMMIT_BRANCH predefined variables with regular expression and restrict commit at master branch using branch access rights.

stages:
  - build
  - deploy

dotnet:
  stage: build
  rules:
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "master"
  script: "echo This builds!"

production:
  stage: deploy
  rules:
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "master"
  script: "echo This deploys!"

Edit answer for incorrect example. (edited at 2023. 01. 26)

Assume that we have rc and master branch. We can configure master branch as protected, and use only for merge request.

In this case, we can define gitlab-ci file like below.

stages:
  - build
  - deploy

dotnet:
  stage: build
  rules:
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "rc"
  script: "echo This builds!"

production:
  stage: deploy
  rules:
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "master"
  script: "echo This deploys!"

Thanks for notification @Kappacake

Mst
  • 11
  • 2
  • it looks to me that both the "dotnet" and the "production" jobs would run on the same conditions because the rules for them are identical. Did you mean to have different rules for them? – Kappacake Jan 19 '23 at 14:56
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 20 '23 at 11:57
  • 1
    @Kappacake You pointed out exactly what I meant. As the initial answer has an incorrect example, I will edit the answer soon. – Mst Jan 26 '23 at 14:24
-3

You can run the pipeline after merge by using Gitlab ci predefined variable $CI_MERGE_REQUEST_APPROVED this will return true after merge and available from gitlab v14.1.

If you want to run the pipeline when merge request is created to main branch you can use $CI_MERGE_REQUEST_TARGET_BRANCH_NAME with $CI_MERGE_REQUEST_APPROVED.

you can add the rule like this in your job.

rules:
  - if: $CI_MERGE_REQUEST_APPROVED && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"
  • That variable is only available in a merge request pipeline. OP is looking to run something upon actually merging to main, which runs in a branch pipeline. – Vedaad Shakib Jan 13 '23 at 01:11