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) + "](" + (.web_url|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)
中でやってるのは以下の通りです。
- tag1、tag2が打たれたタイムスタンプを取得する
- 1で取得したタイムスタンプをdateコマンドで1分後ろにずらす
- 2を使ってMRリストを取得するAPIリクエストを投げてタイトルとIDのリストを取得する
- jqで加工してMarkdown形式で出力する
tag1、tag2のタイムスタンプをそのまま使ってしまうとtag1・tag2がマージコミットだった場合に出力されるMRリストに含まれない可能性があるのでdate
コマンドで1分後ろにずらしています。
またクエリにヒットするのはタイムスタンプの間に更新があったMRリストなので、もしマージされたあとにコメント書いたりして更新されたものがあるとヒットしてしまいます。このへんは運用で除外するように対処しました。
あとはMR一覧を取得するAPIは一度に取得できる数がデフォルトだと20件なので、per_pageで最大値である100
を指定しています。
これを日々行うことで、リリース前後でどのbugfixがどのタグに含まれているか追跡するのが楽になりました。