Trigger jobs on a CI/CD pipeline on merge of the merge request

142 Views Asked by At

I am currently working on a CI/CD pipeline on gitlab. I have 5 different stages :

  • install
  • test
  • package
  • deploy
  • cleanup

What I want to do is to trigger the cleanup jobs that clean the deployed dev instances of the application.

I tried few different options using gitlab rules, I tried to get the merged event using :

cleanup:graphql_ci:
  before_script: *graphql_before_script
  stage: cleanup
  script:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_STATE == "merged"'

But I found out that the $CI_MERGE_REQUEST_STATE variable is not a gitlab variable. Is there any way to trigger a job on a merge request when the button of merge is clicked or something like this ?

1

There are 1 best solutions below

0
sytech On

Is there any way to trigger a job on a merge request when the button of merge is clicked or something like this ?

There isn't really a great way to do this. Keep in mind that, when you merge a branch into another, this is basically just a normal git push action on the target branch.

Technically, it's possible to use git to infer if a commit was a merge commit, but GitLab doesn't expose this information in any predefined environment variable that you could use in a rules: definition.

One way you can try to do this, is by using a rule that identifies a merge commit by the merge commit message. By default merge commit messages will have the template that ends each git message with See merge request %project_path&!%mr_iid% so, commits usually look like this:

The commit message title, (usually the MR title)

This is the mr description

See merge request mygroup/mysubgroup/myproject!123

So, you could use this to write a rule that checks for this default message on the commit that gets made when merging an MR:

myjob:
  rules:
    - if: $CI_COMMIT_MESSAGE =~ /(.*)See merge request [\w\/\-\_]+!\d+$/

However, one caveat here is that the commit message for merges can be overridden, so this is just a best effort.


Another method would be to not use rules: but instead, process this requirement as part of the job itself. You could have the job effectively be a no-op if it's determined that the present and simply exit 0 -- otherwise, allow the job script to continue if it is a merge commit.

For example, applying this method (to which I don't make any assertions about its correctness/completeness), you can do something like this:

.on_merge_commit:
  before_script:
    - |
      is_merge_commit=$(git rev-parse --verify "$CI_COMMIT_SHA"^2 2> /dev/null)
      
      if [[ -z "$is_merge_commit" ]]; then
         echo "not a merge commit, exiting" > /dev/stderr
         exit 0
      fi


myjob:
  extends: .on_merge_commit
  script:
    - echo "this message will only appear on merge commits"

Cleaning up environments

What I want to do is to trigger the cleanup jobs that clean the deployed dev instances of the application.

In your scenario, however, there is another option. When using GitLab's environments features, you can define a job to run whenever an environment is "stopped", to clean it up. GitLab also supports stopping an environment when a merge request is merged or closed. This is part of GitLab's review apps methodology. In this way, you can make sure that your environments are cleaned up when an MR is merged or closed.

Using the example from the docs:

deploy_review:
  stage: deploy
  script:
    - echo "Deploy a review app"
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    on_stop: stop_review
  rules:
    - if: $CI_MERGE_REQUEST_ID

stop_review:
  stage: deploy
  script:
    - echo "Remove review app"
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    action: stop
  rules:
    - if: $CI_MERGE_REQUEST_ID
      when: manual

In your case, the deploy_review job is the job that deploys your application to your 'dev instances'. The stop_review job would be triggered when the merge request is closed or merged and you would define this job to clean the environment. The job names are just examples -- the important parts are the environment:, environment:action, and environment:on_stop keywords.