github-pr-release は、あるリリースに含まれるPull Requestをいい感じにリストアップしたリリース用のPRを作ってくれる便利ツールです。
自分が開発に携わっているチームではリリースノートをGitHubのリリース機能で残しているのですが、その内容はgithub-pr-release
がまとめてくれたPRリストから作られており、人力コピペ作業が発生していました。
今回は GitHub Actions を使って、リリース用PRがマージされたらその内容をコピーしたGitHubリリースを生成するようにしてみました。
実現したこと
まずgithub-pr-release
で開発用ブランチ → 本番環境用ブランチへのリリースPRを作ります。
そのリリースに含まれる修正内容がPRの概要にリストアップされていますね。
このリリースPRをマージすると、自動でPRの概要をコピーしたGitHubのリリースが作られます。
GitHub Actions の定義
これを実現する GitHub Actions の定義例はこちら。
on:
pull_request:
types: [closed]
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@0.3.0
env:
PRODUCTION_BRANCH: release
TZ: Asia/Tokyo
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const pr = context.payload.pull_request
if (!(pr.merged && pr.base.ref === process.env.PRODUCTION_BRANCH)) return;
const merged_at = new Date(pr.merged_at);
const tag_name = String(merged_at.getFullYear()).padStart(4, '0')
+ String(merged_at.getMonth() + 1).padStart(2, '0')
+ String(merged_at.getDate()).padStart(2, '0')
+ String(merged_at.getHours()).padStart(2, '0')
+ String(merged_at.getMinutes()).padStart(2, '0')
+ String(merged_at.getSeconds()).padStart(2, '0');
github.repos.createRelease({
...context.repo,
draft: true,
tag_name: tag_name,
name: tag_name,
target_commitish: process.env.GITHUB_SHA,
body: pr.body
});
部分ごとに解説します。
ワークフローをトリガーするイベント
GitHub Actions では、PRのマージを pull_request
イベントの closed
アクティビティで検知できます。1
on:
pull_request:
types: [closed]
PRがマージされずにクローズされた場合も起動するため、マージされたPRのみに対象を絞りたい場合は、ワークフローが起動したあとに別途チェックする必要があります。
ステップで実行するアクション
アクション actions/github-script を利用することで、 ワークフロー内で GitHub API を利用した処理が簡単に記述できるようになります。
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@0.3.0
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
// code
※ actions/github-script
は実験段階のリポジトリのため、今後のバージョンアップで破壊的な仕様変更が起きる可能性があります。
マージされたリリースPRの取得
actions/github-script
のスクリプト内では、github
とcontext
の2つの引数が提供されます。github
は GitHub APIのクライアント、context
は実行中のワークフローのコンテキスト情報が含まれるオブジェクトです。pull_request
イベントの場合、マージされたPRの情報もcontext
オブジェクトから参照できます。
const pr = context.payload.pull_request
if (!(pr.merged && pr.base.ref === process.env.PRODUCTION_BRANCH)) return;
対象でない pull_request
イベントでリリース作成処理を走らせないために、
ここではcloseされたPRがマージされているか、本番環境用ブランチに向けられているかを確認しています。
リリースの作成
github
引数で渡されるGitHub APIクライアントを使ってリリースを作成します。context
から取得したリリースPRの概要をリリースのbody
として登録しています。
github.repos.createRelease({
...context.repo,
draft: true,
tag_name: tag_name,
name: tag_name,
target_commitish: process.env.GITHUB_SHA,
body: pr.body
});
タグを打つ対象のコミットにはリリースPRのマージコミットを指定しており、 pull_request
イベントではGITHUB_SHA
環境変数からコミットハッシュ値が取得できます。
リリースに紐付けるタグやタイトルの形式は現場によって変えてください。ここではリリースPRのマージ日時をタグとして利用しています。
おわりに
GitHub Actions を使うことで、GitHub上の運用効率化が簡単にできるようになりました。
Actionsは日々進化しているので、活用して効率化を進めていきましょう。