dheeraj
dheeraj

Reputation: 55

gitlab only condition when merge from feature and merge request approved

Im trying some changes related to rules but not successful requirement: When a feature-A or feature-B is merged to develop , when merge req is approved the build stage should run. Thanks !

    build_development:
    stage: build
    # when: manual
    script:
    - | 
       echo "Intiating application docker build and push to ECR.."
  tags: 
    - docker
  # only:
  #   - merge_requests
  #   - develop
  # except:
  #   - prod
  # rules:
  #   - if: '$CI_MERGE_REQUEST_APPROVED == "true" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == /^feature-.*$/' 
  #     when: always
  rules:
    - if: '$CI_MERGE_REQUEST_APPROVED == "true" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^develop$/'
      when: always

Upvotes: 0

Views: 2291

Answers (2)

binhdt2611
binhdt2611

Reputation: 17

GitLab doesn't provide a direct way to trigger CI/CD pipeline when a Merge Request is approved. However, it is possible to achieve your desire but it involves coding skills, and it seems to be more complicated. I was able to implement this solution, so you can try my way.

The key things in my solution are to use:

  • $CI_MERGE_REQUEST_APPROVED: is a pre-defined variable which can only be used when "merge request approvals is available" and the "merge request has been approved". If you're using a free account on GitLab SAAS, you can't use this variable until you upgrade to at least Premium account, or you've hosted your own GitLab server.
  • GitLab Webhook: check out merge request events to see what actions have been made in your Merge Request. The action we care about is "approved" action, it means when you click "Approve" on your MR, GitLab Webhook will send this event in a form of JSON format called Payloads to your custom Webhook Receiver script (you'll need to write your own script)

Steps to implement:

  1. Create your personal access token (you can also use a project/group access token instead).
  2. Configure Merge request approvals (Free account won't see this) under your project -> Settings -> Merge requests. Add at least 1 to All eligible users in the Approval rules.
  3. Add rules to your CI job:

    job:
      stage: build
      script:
        - echo "This pipeline is triggered only after the merge request is approved"
      rules:
        # This rule makes sure your CI Job:
        #  - Won't run when MR is not created
        #  - Won't run when MR is created but the target branch is not "develop"
        #  - Won't run when MR is created, target branch is "develop", but the MR is not approved. 
        - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" && $CI_MERGE_REQUEST_APPROVED

The job runs only when MR is created AND target branch is develop AND the MR is approved. However, when we click "Approve" then, pipeline won't be triggered even if all rules have been satisfied. That's because the job is evaluated only by the time you push code to the feature branch. That's when your MR isn't approved. Once you approve the MR, your job won't be evaluated again. That's why we have to use Webhook to achieve this part.

  1. Build your own Webhook Receiver Script for receiving data sent from GitLab Webhook, once the script receives an "approved" action from the event, it makes a POST request to GitLab API to create a pipeline on your MR. Here is an e.g. of POST request written in python that calls to GitLab API in order to create a MR pipeline.

    import requests
    MR_URL = "https://gitlab.com/api/v4/projects/123456/merge_requests/1/pipelines"
    trigger = requests.post(MR_URL, headers={"PRIVATE-TOKEN": "your_personal_token"})

It depends on your preferred language, choose anything you like. You can have a look at GitLab - Trigger CI/CD pipeline run only when a merge request approved to see my code example written in Python + Flask. After you completed your script, deploy it on a server (e.g. VPS or EC2, etc.).

You'll need to note down URL and Secret Key when you have your script and server available

  • URL: is the URL where your script is hosted with an URI. Something looks like e.g. https:/your-server-ip-or-domain/webhooks. I would recommend you should use domain instead. Then you'll configure this domain point to your server IP. The URI /webhooks is the custom API of your script where you want GitLab Webhook to send a POST request of MR events to this API.

  • Secret Key: is a random string that you've created by yourself, and you use this key to verify authentication between GitLab Webhook and your webhook receiver script.

  1. Configure Webhook Gitlab with Trigger section: merge request events and register your created URL at step 4 along with its secret key here.

Now, your custom script will trigger your pipeline when you click "Approve" on your MR.

Upvotes: 0

sytech
sytech

Reputation: 41119

There are two key elements to understand here:

  • rules: (as well as only:/except:) are evaluated at the time the pipeline is created
  • Merge request approvals do not trigger pipeline events

Therefore, if your merge request is not approved at the time the pipeline is created then any job requiring CI_MERGE_REQUEST_APPROVED to be true will not be included in the pipeline, even if the merge request is approved afterwards. Approving an MR will not change the existing pipeline and it will not trigger a new pipeline.

In order to get the effect you want, you will have to manually trigger a new pipeline from the MR. To do this, after approving the MR:

  1. Open the pipelines tab in the merge request
  2. Click the "run pipeline" button

Upvotes: 0

Related Questions