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は日々進化しているので、活用して効率化を進めていきましょう。

