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.
1 Answers
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
.

- 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= – alwaysday1 Jun 16 '23 at 01:54" --form "target_branch= " --form "title= " | jq '.iid') echo $MERGE_REQUEST_IID NUMBER_OF_APPROVERS=$(curl -s --header "PRIVATE-TOKEN: