Gitlab run a pipeline job when a merge request is merged
Asked Answered
L

4

31

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
Lucubration answered 15/9, 2020 at 0:27 Comment(0)
T
31

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"'
Turku answered 15/9, 2020 at 1:29 Comment(12)
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.Lucubration
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.Turku
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.Lucubration
I updated my answer. This time I tested out the env variables we are using for conditionals. Proof: Commit: gitlab.com/atbeasley/problem-child/-/pipelines/189925730 Merge: gitlab.com/atbeasley/problem-child/-/pipelines/189925811Turku
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 :)Lucubration
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 requestsSkirl
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")Venetian
Yes, @NickoGlayre I have exactly the same problem.Romanticism
Seems like CI_BUILD_REF_NAME is deprecated and CI_COMMIT_REF_NAME should be used instead.Hydrastinine
I suggest to use $CI_DEFAULT_BRANCH instead of hardcoding master or main you can avoid a headache :)Swimmingly
Anyone managed to do this and still know the source branch name? In my case i want deploy my APIs if a MR is merged and there are differences between origin/main and the branch getting merged (in a specific folder). To do this i need to know the name of the merging branch, which i am unable to doHaggle
You can add a test stage that just runs printenv to output all the Environment Variables.Erasme
I
7

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.

Idun answered 11/3, 2022 at 11:36 Comment(2)
This does not trigger any action for me. My rule looks like this: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "test" && $CI_COMMIT_MESSAGE =~ '/See merge request/' What am I missing?Rhymester
@Rhymester you need to remove $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "test". 'merge_request_event' is called only on merge request create or push to source branch in merge request.. not after merge. and use $CI_COMMIT_REF_NAME instead of $CI_MERGE_REQUEST_TARGET_BRANCH_NAMEMichaelamichaele
V
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

Vieva answered 16/1, 2023 at 7:45 Comment(3)
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?Delivery
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.Juju
@Delivery You pointed out exactly what I meant. As the initial answer has an incorrect example, I will edit the answer soon.Vieva
S
-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"
Shavonda answered 4/11, 2022 at 6:16 Comment(1)
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.Overmatch

© 2022 - 2024 — McMap. All rights reserved.