この記事はLIFULL Advent Calendar 2022の24日目の記事として投稿しています。
普段はiOSアプリの開発に携わっており、その中で得た経験を今回記事としてアウトプットします。
※とはいえ、今回はSwiftとかiOS系の記事ではないです笑(若干関わりますが)
背景
普段関わるプロジェクトのリポジトリでは、アプリのリリースのたびにリリースタグを切ってリリースノートを作成しています。
アプリがリリースされて数日経って不具合がないことを確認できたらstable
ブランチにマージを行い、そのタイミングでリリースノートを手動で作成すると言った運用フローです。
ところがstableマージを行った後に、リリーサーがリリースノートを作成することが漏れてしまうことがありました。
あと、手順としてはそこまで難しくないけど地味にめんどくさいなと感じていました。
じゃあこのフローを自動化しよう!ということで実現しました。
開発環境ではCI/CDサービスとしてBitrise
を用いていたので、これを活用することにしました。
通常のリリースノート作成
まずはそもそものフローをおさらいしてみましょう。
GitHubのReleasesから、Draft a new release
をクリックすると下記の画面になります。
その後、リリースタグ名・ベースとするブランチ名・タイトルを入力して画面中央部にそのリリースでの変更内容や説明を自由に記述します。
この本文は、Generate release notes
をクリックすると前のリリースからの変更差分をコミット単位で箇条書き形式で、自動生成されます。
Generateして作成したリリースの一つの例はこのようなイメージになります(大半を割愛しててすみません笑)
Bitriseの設定
Workflowの全体図
リリースノートの作成を自動化するWorkflowはこのような流れで設定しました。
SSH Keyの確認やリポジトリのクローン等のフローは一般的な設定になるのでここでは割愛して、リリースノートの作成に関連する部分を取り上げて紹介します。(画像赤枠部分です。)
Sciptフロー
手順としては大きく3つあります
- Xcodeからリリースバージョンを取得
- リリースノートの本文用に前回バージョンの変更差分を取得
- 取得した差分を見やすい形に直す
これらをそれぞれ分けて説明していきます。
Xcodeからリリースバージョンを取得
まずはXcodeからリリースバージョン番号を管理している値がBuild Settingsにあるので、それを取得するようにします。
自分の環境ではリリースタグは単なる数値形式(X.X.X
)ではなく、release-verX.X.X
といった形式で作成しているのでそれに合わせます。
作成した文字列の値は、次のStepのGithub Release
で用いるので、envman
コマンドで環境変数として追加します。
# XcodeのBuild Settingsから最新バージョンのナンバーを取得
version=$(sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' {プロジェクト名}.xcodeproj/project.pbxproj)
if [ -z "${version}" ]; then
echo "[ERROR] failed to get MARKETING_VERSION"
exit 1
fi
# リリースタグのバージョン文字列を生成(ここではGIT_TAGという名前で定義)
envman add --key GIT_TAG --value "release-ver${version}"
リリースノートの本文用に前回バージョンの変更差分を取得
ここではGitHubのReleases API
を用いてGenerate release notesを押した時の内容に関するデータを取得します。
今回リリースする予定のバージョンと現在リリースしているバージョンの差分を知りたいので、POST_BODY
ではtag_name
とprevious_tag_name
の2つのパラメータの指定が必要です。
また、target_commitish
はリリースノートの作成をするベースのブランチを指定するのですが、デフォルトだとmaster(main)
になっているようです。
自分の環境では運用ルールとしてstable
ブランチをベースにリリースノートを作成するのでここではstable
を指定します。
# 前回バージョン(現在リリースされている最新バージョン)の取得
previous_version=$(curl \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_ACCESS_TOKEN" \
https://api.github.com/repos/$GITHUB_ORGANIZATION_NAME/$GITHUB_REPOSITORY_NAME/releases/latest | jq -r .tag_name)
# POSTする際に必要なパラメータを整形
POST_BODY="{\"tag_name\":\"release-ver${version}\", \"previous_tag_name\":\"${previous_version}\", \"target_commitish\":\"stable\"}"
# Generate release noteを押した時の中身を取得
body=$(curl \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_ACCESS_TOKEN" \
https://api.github.com/repos/$GITHUB_ORGANIZATION_NAME/$GITHUB_REPOSITORY_NAME/releases/generate-notes \
-d "$POST_BODY" | jq .body | sed 's/"//g')
取得した差分を見やすい形に直す
上記の結果をそのまま渡して作成すると、リリースノート自体は作成できるものの、本文はコミットの箇条書きが項目ごとに改行されずに1行の長い文章として表示されてしまっていました。
よって、項目ごとに改行して見やすい形に直してあげます。
今回は愚直に一時的なtxtファイルを作成して、その中に改行し直した文章を出力。その後その中身をBodyとして渡してあげるという流れにしました。
不要になったファイルも最後に削除しています。
# Generate Release Noteの結果の改行部分を変換する
echo -e "${body}" > tmp.txt
sed 's/\n//g' tmp.txt
body=$(cat tmp.txt)
# Release Note用のBodyを作成
envman add --key RELEASE_NOTE_BODY --value "${body}"
# 不要になったtxtファイルを削除
rm tmp.txt
GitHub Releaseフロー
このフローでは、下記画像のように必要な項目に値を埋め込んでいく作業になります。
実際に設定した値は下記のようなイメージです。
$GIT_TAG
と$RELEASE_NOTE_BODY
は前のScriptフローで定義した環境変数になります。
他の値に関しては、Secretsで定義した環境変数等を使うようにすると良いかと思います。
項目 | 値 |
---|---|
Personal API token | [自分のGithubのPersonal Access Token] |
Username | [自分のGithubのユーザ名] |
Repository URL | [対象のGithubのリポジトリURL] |
Tag | $GIT_TAG |
Commit | stable |
Release name | $GIT_TAG |
Release body | $RELEASE_NOTE_BODY |
トリガーの設定
BitriseのWorkflow Editor > Triggers
から、PUSH
を選択して必要なトリガーを設定します。
今回はStableにリリースのPRがマージされたタイミングでリリースノートを作成したかったので、そのタイミングで設定しました。
結果
Stableマージがされたタイミングでリリースノート作成フローが開始し、無事Slackに成功した通知が送られてきました。
筆者もリアクションで喜んでいるのがわかりますね。
GitHubのReleasesのページを確認しても、最新版のリリースノートが作成されていました!
おわりに
今回は主にBitriseとGitHubのAPIを用いてリリースノート作成を自動化させてみました。
Bitriseはチョットサワッタコトアル
程度で、GitHubのAPIはナニソレオイシイノ?
レベル、shellも大学の授業でなら...
って具合でしたが、調べながら独力で解決までできました。
リリースタグを作ること自体はもっと簡単にできますが、今回はGenerate release notesを押した時の本文を取得して表示させるところまでを実現している記事は見つからなかったので色々試行錯誤しました。
この記事がどなたかの参考になると幸いです。
自分の未開拓な領域の挑戦をさせてくれた職場やチームに感謝です。
できることがまたひとつ増えたので、この知見を活かして別の改善もできるようになりたいですね。
それではみなさん、メリークリスマス!