エンジニアの中田です。現在、社内の有志エンジニアが協力して、Goodpatch 社内向けのツールを開発しています。このプロジェクトで、私は iOS App を開発しており、GitHub Actions を使用して社内メンバーへのリリースフローを自動化しています。本記事では、gh api
コマンドを活用して Pull Request の本文(リリースノート)を自動生成する Tips を紹介します。
この iOS プロジェクトは、トランクベース開発のスタイルで実装を進めています。
社内にリリースする際は、repo 内の GitHub Actions のページから、該当するワークフローを選び Run workflow
をクリックします。
このワークフローが、Release 用ブランチと Pull Request を作成します。その後、この Pull Request を main ブランチにマージすると、iOS App をビルドするワークフローが走り、Firebase App Distribution へ ipa ファイルをアップロードする流れです。
Pull Request の本文(リリースノート)を自動生成
Pull Request の本文には、前回のリリースとの差分をもとに作成したリリースノートを記述して、変更履歴を残したいと思います。
GitHub には、GitHub Release のリリースノートを自動的に生成する機能があります。
Automatically generated release notes - GitHub Docs
今回はこの機能の API を利用します。
POST /repos/{owner}/{repo}/releases/generate-notes
GitHub Actions からこの API を呼び出す方法はいくつかあると思いますが、今回は、GitHub CLI の gh api コマンドを使います。API を呼び出してリリースノートの本文をBODY
へ代入するコードは次のとおりです。
BODY=$(gh api --method POST -H "Accept: application/vnd.github+json" /repos/{owner}/{repo}/releases/generate-notes -f tag_name="v$VERSION" -f target_commitish='main' | jq --raw-output .body)
jq --raw-output
するとunescapeされた文字列を出力してくれます。
Pull Requestを作成
Pull Request は、GitHub CLI の gh pr createを使って作成します。
gh pr create --base main --head "release/v$VERSION" --title "release v$VERSION" --body "$BODY" --label "release"
このコマンドを実行すると、次のような Pull Request が作成されます 🎉
GitHub Actions のワークフロー
このワークフロー .github/workflows/create_release_pr.yml
の全文は次のとおりです。
name: Create a Release Pull Request on: workflow_dispatch: jobs: create_pr: runs-on: macos-12 steps: - uses: actions/checkout@v3 # https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-ruby#caching-dependencies - uses: actions/cache@v3 with: path: vendor/bundle key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} restore-keys: | ${{ runner.os }}-gems- - name: Bundle install run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 - name: Bump minor version then create a release branch and tag run: bundle exec fastlane bump_minor - name: Create a pull request env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | VERSION=$(agvtool what-marketing-version -terse1) BODY=$(gh api --method POST -H "Accept: application/vnd.github+json" /repos/{owner}/{repo}/releases/generate-notes -f tag_name="v$VERSION" -f target_commitish='main' | jq --raw-output .body) gh pr create --base main --head "release/v$VERSION" --title "release v$VERSION" --body "$BODY" --label "release"
補足
on: workflow_dispatch:
ワークフローを実行するトリガーとして workflow_dispatch を指定することで、手動でワークフローを実行できるようになります。
Fastfile
iOS Appのバージョンとビルド番号を更新する処理、リリース用のブランチの作成、tagの追加は、fastlane を使っています。
fastlane/Fastfile
の該当箇所を抜粋します。
# fastlane/Fastfile desc "Bump minor version" lane :bump_minor do increment_version_number(bump_type: "minor") increment_build_number commit_and_tag end def commit_and_tag version_number = get_version_number target: 'XXX' build_number = get_build_number branch_name = "#{version_number}" message = "ci: bump version v#{version_number} (#{build_number})" sh "git checkout -b 'release/v#{branch_name}'" sh "git commit -a -m '#{message}'" sh 'git push origin HEAD' add_git_tag(tag: "v#{version_number}") sh 'git push --tags' end
前述のワークフローの次の箇所で実行されます。
run: bundle exec fastlane bump_minor
リリースノート本文のカスタマイズ
GitHub Releaseのリリースノートは .github/release.yml
でカスタマイズできます。先ほどの Pull Request のスクリーンショットでは、次の release.yml
を使用しています。
changelog: categories: - title: Features labels: - enhancement - feature - title: Bug Fixes labels: - bug - title: Other Changes labels: - "*"
カスタマイズの詳細は Configuring automatically generated release notes - GitHub Docs を参照してください。
おわりに
GitHub Actions のワークフロー内で gh
コマンドを実行することで、簡単にリリースノートを自動作成したり、Pull Request を作成できることが分かりました。
今回、自動生成したリリースノートは、Pull Requestの本文として利用していますが、Pull Request本文を GitHub Actionsのワークフローから参照することで、Firebase App Distributionのリリースノートにも活用できそうです。