1

I have a stage1 where it creates a merge request then after the merge request is approved by 3 approvers I manually trigger the stage2. But, I want to find a way where I can check the merge request approval status created in stage1 and trigger the stage2 job automatically.

Vardhan
  • 11
  • 3

1 Answers1

1

In order to achieve this we will use the Gitlab API and the jq package. Firstly, let's define the jobs.

job_that_creates_mr is the job that creates the merge request and has to wait for 3 approvers before triggering the job_that_triggers_automatically_when_mr_approved

In job_that_creates_mr, I assume that you use the gitlab API for it and specifically https://docs.gitlab.com/ee/api/merge_requests.html#create-mr

POST /projects/:id/merge_requests

In order to proceed we will need the merge request id, so adjust the way you create the mr, an example would be:

MERGE_REQUEST_IID=$(curl -XPOST -s --header "PRIVATE-TOKEN: <access_token>" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests" --form "source_branch=<source_branch>" --form "target_branch=<target_branch>" --form "title=<mr_title>"  | jq '.iid')

By piping the result to jq we get the merge request id

Next we need to the number of current approvers for the mr with iid that we found previously, to get this we will use https://docs.gitlab.com/ee/api/merge_request_approvals.html#merge-request-level-mr-approvals

GET /projects/:id/merge_requests/:merge_request_iid/approvals

An example command would be:

NUMBER_OF_APPROVERS=$(curl -s --header "PRIVATE-TOKEN: <access_token>" https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests/$MERGE_REQUEST_IID/approvals  | jq '.approved_by | length')

Now a template gitlab-ci.yml would be:

stages:
  - run_after_approval
  - create_mr


job_that_triggers_automatically_when_mr_approved:
  stage: run_after_approval
  script: 
    - echo 'I run automatically, even though it says manual'
  when: manual

job_that_creates_mr:
  stage: create_mr
  script: 
    - apk add curl jq
    - |
      MERGE_REQUEST_IID=$(curl -XPOST -s --header "PRIVATE-TOKEN: <access_token>" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests" --form "source_branch=<source_branch>" --form "target_branch=<target_branch>" --form "title=<mr_title>"  | jq '.iid')
      NUMBER_OF_APPROVERS=0
      while [[ $NUMBER_OF_APPROVERS -lt 3 ]]
      do
        NUMBER_OF_APPROVERS=$(curl -s --header "PRIVATE-TOKEN: <access_token" https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests/$MERGE_REQUEST_IID/approvals  | jq '.approved_by | length')
        sleep 60
      done
      JOB_ID=$(curl -s --header "PRIVATE-TOKEN: <access_token>" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/pipelines/$CI_PIPELINE_ID/jobs" | jq '.[] | select(.name=="job_that_triggers_automatically_when_mr_approved") | .id')
      curl -XPOST --header "PRIVATE-TOKEN: <access_token" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/$JOB_ID/play"

Note: In this example change job_that_triggers_automatically_when_mr_approved, with your job name

The idea is that you have the ordering swapped so the job_that_triggers_automatically_when_mr_approved is registered first in the pipeline but as a manual job.

Then the job that create the merge request waits until the number of approvers is 3, and then plays the job_that_triggers_automatically_when_mr_approved.

Tolis Gerodimos
  • 3,782
  • 2
  • 7
  • 14
  • ` - | MERGE_REQUEST_IID=$(curl -XPOST -s --header "PRIVATE-TOKEN: " "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests" --form "source_branch=" --form "target_branch=" --form "title=" | jq '.iid') echo $MERGE_REQUEST_IID NUMBER_OF_APPROVERS=$(curl -s --header "PRIVATE-TOKEN: – alwaysday1 Jun 16 '23 at 01:54