つばくろぐ @takamii228

知は力なり

GitLabでtagとtagの間に含まれるMRリストを取得する

GitLabであるタグに含まれるMRのリストをトレースする必要があったので、GitLabのAPIとjqを使ってtagとtagに間含まれるMRリストを出力して、Markdown形式のリリースノートを出力するシェルを組みました。

#!/bin/sh

BASE_URL="GITLAB_HOSTNAME"
API_TOKEN="GITLAB_APITOKEN"
PROJECT_ID="xx"
PROJECT_NAME="yyy"
REPOSITOEY_NAME="zzz"

TAG_FROM_AUTHORD_DATE=`curl -X GET -H "PRIVATE-TOKEN: ${API_TOKEN}" "${BASE_URL}/api/v4/projects/${PROJECT_ID}/repository/tags/${1}" | jq -r .commit.authored_date`
TAG_TO_AUTHORD_DATE=`curl -X GET -H "PRIVATE-TOKEN: ${API_TOKEN}" "${BASE_URL}/api/v4/projects/${PROJECT_ID}/repository/tags/${2}" | jq -r .commit.authored_date`

# tagを切ったコミットハッシュのMRが含まれない可能性があるため1分ずらす
TAG_FROM_AUTHORD_DATE=`date -v+1M -j -f "%Y-%m-%dT%T.000Z" ${TAG_FROM_AUTHORD_DATE} +%Y-%m-%dT%T.000Z`
TAG_TO_AUTHORD_DATE=`date -v+1M -j -f "%Y-%m-%dT%T.000Z" ${TAG_TO_AUTHORD_DATE} +%Y-%m-%dT%T.000Z`

curl -X GET -H "PRIVATE-TOKEN: ${API_TOKEN}" "${BASE_URL}/api/v4/projects/${PROJECT_ID}/merge_requests?state=merged&updated_after=${TAG_FROM_AUTHORD_DATE}&updated_before=${TAG_TO_AUTHORD_DATE}&target_branch=master&view=simple&per_page=100" | jq -r 'sort_by(.iid)| .[] | "- [" + (.title|tostring) + "](${BASE_URL}/${PROJECT_NAME}/${REPOSITOEY_NAME}/merge_requests/" + (.iid|tostring) + ")"'

使い方は引数に2つのタグを入れるだけです。

# 実行方法と出力サンプル
$ ./generate-releasenote.sh tag1 tag2
- [MR Title1](${BASE_URL}/${PROJECT_NAME}/${REPOSITOEY_NAME}/merge_requests/mr_id1)
- [MR Title2](${BASE_URL}/${PROJECT_NAME}/${REPOSITOEY_NAME}/merge_requests/mr_id2)
- [MR Title3](${BASE_URL}/${PROJECT_NAME}/${REPOSITOEY_NAME}/merge_requests/mr_id3)

中でやってるのは以下の通りです。

  1. tag1、tag2が打たれたタイムスタンプを取得する
  2. 1で取得したタイムスタンプをdateコマンドで1分後ろにずらす
  3. 2を使ってMRリストを取得するAPIリクエストを投げてタイトルとIDのリストを取得する
  4. jqで加工してMarkdown形式で出力する

tag1、tag2のタイムスタンプをそのまま使ってしまうとtag1・tag2がマージコミットだった場合に出力されるMRリストに含まれない可能性があるのでdateコマンドで1分後ろにずらしています。

注意点としてはマージ先のブランチを考慮にいれてないので、もし複数のブランチへのMRがある場合はそれらは区別されずに表示されます。jqのクエリにmerge先のブランチも指定するようにすれば対応できると思います。

またクエリにヒットするのはタイムスタンプの間に更新があったMRリストなので、もしマージされたあとにコメント書いたりして更新されたものがあるとヒットしてしまいます。このへんは運用で対処しました。

あとはMR一覧を取得するAPIは一度に取得できる数がデフォルトだと20件なので、per_pageで最大値である100を指定しています。

これを日々行うことで、リリース前後でどのbugfixがどのタグに含まれているか追跡するのが楽になりました。

https://docs.gitlab.com/ce/api/merge_requests.html