GitHub Actionsによるマージ済Pull request一覧の自動生成
本記事では、特定のHTMLコメントタグで区切られたPull Request(PR)内のセクションを、GitHub Actionsを利用して自動的に更新するワークフローについて解説します。このワークフローは、PRのベースブランチとHEADブランチ間のマージ済みPR番号リストを抽出し、指定されたセクションに挿入します。
背景
アプリの開発プロセスにおいて、リリース対象ブランチ(例: develop、release/x.y.z)からデフォルトブランチ(例: main)へPRを作成する際、そのリリースに含まれる変更内容、特にマージされた個別のPRリストを本文に記載したいことがあります。このリストを手動で維持管理するには工数がかかり、また更新漏れのリスクも伴います。
今回はこれを自動で生成、更新するためのGitHub Actionsを作成します。
Pull Requestテンプレートの準備
本ワークフローは、PR本文内に更新対象範囲を示す特定のHTMLコメントタグが存在することを前提としています。以下にテンプレートの例を示します。
### Details
<!--pr_diff_start-->
- If any.
<!--pr_diff_end--><!--pr_diff_start--> と <!--pr_diff_end-->によって囲まれた部分が、後述するワークフローによってマージ済みPRリストに置換されます。
マージ済みPRリストを生成するGitHub Actions ワークフロー
マージ済みPRリストを生成するため、以下のGitHub Actionsワークフロー(.github/workflows/pr-diff.yml)を定義します。
name: Update merged pr diff
on:
pull_request:
branches:
- main
jobs:
update-merged-pr-diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Replace release diff
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const baseBranch = context.payload.pull_request.base.ref;
const branchName = context.payload.pull_request.head.ref;
let gitLogRawOutput = '';
let gitLogError = '';
const gitLogOptions = {
ignoreReturnCode: true,
listeners: {
stdout: (data) => { gitLogRawOutput += data.toString(); },
stderr: (data) => { gitLogError += data.toString(); }
}
};
const exitCode = await exec.exec('git', [
'log',
'--merges',
'--pretty=%s',
`origin/${baseBranch}..origin/${branchName}`
], gitLogOptions);
if (exitCode !== 0) {
core.error(`git log failed with exit code ${exitCode}`);
core.error(gitLogError);
core.setFailed('Failed to get git log.');
return;
}
const prMatches = gitLogRawOutput.match(/#[0-9]+/g);
let mergedPrsOutput = '';
if (prMatches) {
mergedPrsOutput = prMatches.map(match => `- ${match}`).join('\n');
}
const body = context.payload.pull_request.body;
const replacedBody = body.replace(/<!--pr_diff_start-->.*<!--pr_diff_end-->/s, `<!--pr_diff_start-->\n\n${mergedPrsOutput}\n<!--pr_diff_end-->`);
github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
body: replacedBody
});導入手順
- リポジトリ内のPRテンプレートファイル(例:
.github/PULL_REQUEST_TEMPLATE.md)に、<!--pr_diff_start-->と<!--pr_diff_end-->コメントを記述する - 上記のワークフローを
.github/workflows/pr-diff.ymlとしてリポジトリに配置する
実行結果
上記設定後、mainブランチをターゲットとするPRが作成されるか、またはそのPRのヘッドブランチが更新されると、本ワークフローが自動的にトリガーされます。ワークフローはPRの差分に含まれるマージ済みPR番号リストを算出し、PR本文の<!--pr_diff_start--> と <!--pr_diff_end-->で囲まれたセクションをそのリストで上書き更新します。
マージ済PR一覧をgithub-actions botが生成し、PR本文に自動的に反映していることがわかります。
GitHubではPR番号をリスト形式で記述すると、PRタイトルが表示され自動的にPRにリンクされるようになるので、これでPR本文を見たときに次のようにマージ済のPRのタイトル一覧が表示されるようになります。
mainへのPull requestのタイトルにバージョン番号などを書いておけば、マージ済のPRを見に行ったときにリンクされたPRが表示されるので、どのバージョンでリリースされたPRなのかがすぐに分かるようになりますね。
もし一部のPull requestでだけこのワークフローを作動させたい場合は、特定ラベルを付与した場合のみ動作させるなどの工夫をするといいかもしれません。
まとめ
今回のGitHub Actionsワークフローを使うことで、Pull Request本文内の特定セクションにおけるマージ済みPRリストの更新作業を自動化できます。
同じような課題を抱えている方がいれば、ぜひ試してみてください。
