LoginSignup
12
0

More than 1 year has passed since last update.

BitriseとGitHub APIを用いてGitHubリポジトリのリリースノートを自動作成する

Last updated at Posted at 2022-12-23

この記事はLIFULL Advent Calendar 2022の24日目の記事として投稿しています。
普段はiOSアプリの開発に携わっており、その中で得た経験を今回記事としてアウトプットします。
※とはいえ、今回はSwiftとかiOS系の記事ではないです笑(若干関わりますが)

背景

普段関わるプロジェクトのリポジトリでは、アプリのリリースのたびにリリースタグを切ってリリースノートを作成しています。
アプリがリリースされて数日経って不具合がないことを確認できたらstableブランチにマージを行い、そのタイミングでリリースノートを手動で作成すると言った運用フローです。

ところがstableマージを行った後に、リリーサーがリリースノートを作成することが漏れてしまうことがありました。
あと、手順としてはそこまで難しくないけど地味にめんどくさいなと感じていました。

じゃあこのフローを自動化しよう!ということで実現しました。
開発環境ではCI/CDサービスとしてBitriseを用いていたので、これを活用することにしました。

通常のリリースノート作成

まずはそもそものフローをおさらいしてみましょう。

GitHubのReleasesから、Draft a new releaseをクリックすると下記の画面になります。
その後、リリースタグ名・ベースとするブランチ名・タイトルを入力して画面中央部にそのリリースでの変更内容や説明を自由に記述します。
この本文は、Generate release notesをクリックすると前のリリースからの変更差分をコミット単位で箇条書き形式で、自動生成されます。
release-note-img.png

Generateして作成したリリースの一つの例はこのようなイメージになります(大半を割愛しててすみません笑)
release-note-sample

Bitriseの設定

Workflowの全体図

リリースノートの作成を自動化するWorkflowはこのような流れで設定しました。
workflow
SSH Keyの確認やリポジトリのクローン等のフローは一般的な設定になるのでここでは割愛して、リリースノートの作成に関連する部分を取り上げて紹介します。(画像赤枠部分です。)

Sciptフロー

手順としては大きく3つあります

  1. Xcodeからリリースバージョンを取得
  2. リリースノートの本文用に前回バージョンの変更差分を取得
  3. 取得した差分を見やすい形に直す

これらをそれぞれ分けて説明していきます。

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_nameprevious_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フロー

このフローでは、下記画像のように必要な項目に値を埋め込んでいく作業になります。
github_release_example.png

実際に設定した値は下記のようなイメージです。
$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がマージされたタイミングでリリースノートを作成したかったので、そのタイミングで設定しました。
github_release_example.png

結果

Stableマージがされたタイミングでリリースノート作成フローが開始し、無事Slackに成功した通知が送られてきました。
筆者もリアクションで喜んでいるのがわかりますね。
release-note-sample
GitHubのReleasesのページを確認しても、最新版のリリースノートが作成されていました!

おわりに

今回は主にBitriseとGitHubのAPIを用いてリリースノート作成を自動化させてみました。

Bitriseはチョットサワッタコトアル程度で、GitHubのAPIはナニソレオイシイノ?レベル、shellも大学の授業でなら...って具合でしたが、調べながら独力で解決までできました。
リリースタグを作ること自体はもっと簡単にできますが、今回はGenerate release notesを押した時の本文を取得して表示させるところまでを実現している記事は見つからなかったので色々試行錯誤しました。
この記事がどなたかの参考になると幸いです。

自分の未開拓な領域の挑戦をさせてくれた職場やチームに感謝です。
できることがまたひとつ増えたので、この知見を活かして別の改善もできるようになりたいですね。

それではみなさん、メリークリスマス!

参照

12
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
0