Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GitlabCI. Get merge request ID during master branch build

Each time a new pull request is merged, the master branch is being built. During this stage those steps are proceeded:

  1. A new Git tag is created (version is incremented automatically).
  2. The library is published to the registry.
  3. A new email is send to all the users that are tracking new versions.

I want to add the direct link to the merge request that was merged and triggered this release in the mail. Though I can get the information (the MR ID) during the merge request build itself, I don't understand how can I retrieve it once MR is merged.

Is there any approach to overcome this problem?

like image 676
Semyon Kirekov Avatar asked Sep 20 '25 16:09

Semyon Kirekov


1 Answers

My other answer works, but I'd like to add a more reliable one, in the sense that it doesn't rely on the merge commits message template (see doc).

This answer is an improvement on the idea "Get the latest merged pipeline" (accepted answer), which is not failproof if several MRs are merged quickly.

Solution

Find the MR whose merge_commit_sha matches the CI_COMMIT_SHA.

Note: This assumes that in the project's settings (General/Merge requests), the "Merge method" is set to "Merge commit" (default).

Implementation details

  1. Get the commit sha of the current build: just take the predefined variable CI_COMMIT_SHA (I think git rev-parse HEAD should also work).
  2. Get the list of all merged MRs (use the merge requests API).
  3. Find the MR whose merge_commit_sha matches CI_COMMIT_SHA. (use a tool like jq).

Here's a full script that works:

API_MR_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests"
curl --header "PRIVATE-TOKEN: ${YOUR_API_TOKEN}" "${API_MR_URL}?scope=all&state=merged" > mrs.json
yq '.[] | select(.merge_commit_sha == strenv(CI_COMMIT_SHA)) | .iid' mrs.json

That's it!

Note: I used the yq tool instead of the more standard jq, but that's just because I'm more familiar with it. In any case, for this to work you need to install jq/yq at the beginning of your script, or choose an image that has it to run your job.

Pagination caveat

Annoyingly, the Gitlab API only returns a limited number of results per "page" (20 by default, max 100). If you are unlucky, the MR you are looking for might not be on the first page. For a completely failproof script, we thus need to iterate through all the pages. Here we go:

total_pages="$( curl --include --header "PRIVATE-TOKEN: ${YOUR_API_TOKEN}" "${API_MR_URL}?scope=all&state=merged&per_page=100" | egrep '^X-Total-Pages' | egrep -o '[0-9]+' )"
page=1
while [[ "${page}" -le "${total_pages}" ]] ; do
  curl --header "PRIVATE-TOKEN: ${CTE_DBT_API_TOKEN}" "${API_MR_URL}?scope=all&state=merged&per_page=100&page=${page}" > mrs.json
  mr_iid="$(yq '.[] | select(.merge_commit_sha == strenv(CI_COMMIT_SHA)) | .iid' mrs.json)"
  if [[ "${mr_iid}" -gt 0 ]] ; then
    echo "Found matching MR: ${mr_iid}"
    break
  fi
  page=$((page + 1))
done
like image 145
Seub Avatar answered Sep 22 '25 05:09

Seub