プルリクエスト時にラベルから自動でチェックリストを作成・更新するGitHub Actionを作成した
今回はPull Requestを読み取ってこんな感じのチェックリストを自動生成する kasaikou/pr-checklist-action
というGitHub Actionを作成したのでその紹介をする記事です。
TL;DR
- プルリクエストテンプレートにチェックリストを入れがちだけど、知見が溜まっていくに従ってチェック項目が増えていくのはつらいよ
- そこで、設定されたラベルをもとにチェックリストを自動作成する GitHub Actions を作ったよ
-
actions/labeler
と併用することでラベル設定のめんどくささはactions/labeler
が解決するから、それに相乗りするだけでいいよ - 基本的にはチェックリスト用のコメントが作成されるけれど、少しテンプレートを変更することで今までのプルリクエストテンプレートっぽいチェックリストを作成することもできるよ
背景とかコンセプト
個人での開発でも仕事での開発でもそうですが、多くの人が 「N+1問題を考慮した実装になっているか?」「ちゃんとテストを追加したか?」 というようなチェックリストを pull_request_template.md
に書いていると思います。
私見ですが、こういったチェックリストはプルリクエスト毎に関わった人全員が必ず見るものであるため、コントリビュータ同士で知見を共有する場としても非常に有用なものだと思っており、必要に応じてどんどん追加していくべきものだと思っています。
しかし、プルリクエスト毎に出てくるがゆえに、肥大化していくとプルリクエストテンプレートが大きなものになっていき、認知負荷が増大していきます。
それだけではなく、本来プルリクエストでフォーカスしていない部分の知見も表示され続けるため、「プルリクエストとは関係のないチェックリストを埋める」という事務作業に追われてしまいます。
最終的には、 「関係ないチェックリストにチェックしていく意味ないよね」 となってプルリクエストテンプレートにあるチェックリストは得てして形骸化しがちです。
チェックリストは関係のあるところだけを抽出して表示するべきだと考え、今回の Action を作成しました。
機能と使い方
チェックリストの一覧が書かれたYAMLファイルと、GitHub Actionsのワークフローファイルを作成していきます。
はじめに、チェックリストの一覧がまとめられたYAMLファイル pr-checklist.yaml
を作成します。
contents:
- name: SQL
rules:
- labels: [^sql$]
checks:
- N+1問題を考慮したか?
- コンテナを接続して行う単体テストを追加したか?
- name: GitHub Actions
rules:
- labels: [^repo/workflow$]
checks:
- "`run-name` プロパティを設定したか?"
- "`concurrency` プロパティを設定したか?"
- "各 job にタイムアウトを設定したか?"
各カテゴリごとにチェックリストを複数設定することができます。また、 labels
で複数の正規表現を登録することができます。
次に、ワークフローファイル .github/workflow/pr-checklist.yaml
を作成します。
on:
pull_request:
branches: [main]
# ラベルの変更毎に実行するようにする
types: [opened, synchronize, labeled, unlabeled]
jobs:
run:
permissions:
contents: read # actions/checkout で必要
pull-requests: write # PR コメントを追加修正するために必要
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: kasaikou/pr-checklist-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
config: pr-checklist.yaml
あとはプルリクエストを作成したりラベルを追加削除したりすると画像のようなチェックリストが勝手に追加更新されていきます。
actions/labeler
との併用
推奨: さて、上述した方法で一応 Action 自体は使用できるのですが、ラベルを設定するめんどくささがまだあります。
そこで、ブランチ名や変更ファイル名などからラベルを自動設定するために、actions/labeler と併用すること を考えます。
すでに actions/labelerが設定されている場合は、後続ステップに kasaikou/pr-checklist-action
を設定するだけで、ラベル設定後に自動でチェックリストが生成されます。
on:
pull_request:
jobs:
run:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/labeler@v5
+ - uses: kasaikou/pr-checklist-action@main
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ config: pr-checklist.yaml
あえて導入しなかった機能
今回、ラベルからチェックリストを自動生成する Action を作成しましたが、当初の予定ではブランチ名や変更ファイル名などからでもフィルタリングできるように対応する予定でした(実装を見に行くとまだその形跡が残っています)。
今回対応しなかった理由は以下の通り。
-
実装がめんどくさい割にメリットがあまりなかった
- 他の方が作った Action なども見ていたのですが、git コマンドなども取り入れたりして面倒だなあという気持ちになってしまってやめました。正直この理由が一番大きいです。すでに labeler で実現できているのであれば相乗りしてしまう方が手っ取り早いです。
-
actions/labeler
と重複して設定するメリットが思いつかなかった- 微妙にフォーカスしている部分が違うからといって
actions/labeler
でもpr-checklist-action
でも似たような設定をする意味があまりなさそうでした。 - それよりも、逆に設定ファイルを既存の
actions/labeler
に寄せてしまって、あとから二重で変更する手間を削減するメリットの方が大きいと思われます。
- 微妙にフォーカスしている部分が違うからといって
おまけ: プルリクエストテンプレートに挿入ポイントを設定する
pull_request_template.md
を以下のように変更すると、 kasaikou/pr-checklist-action
は画像のように、今までのプルリクエストテンプレートのようにプルリクエストのボディ内を更新するようになります。
## Background
## Changes
+## Checks
+
+<!-- Generated by kasaikou/pr-checklist-action, DO NOT EDIT. -->
+<!-- Generated by kasaikou/pr-checklist-action up to here. -->
## Assignee Memo
内部動作の解説
さて、自動生成されたコメントを見てみると、次のようになっています。
<!-- Generated by kasaikou/pr-checklist-action, DO NOT EDIT. -->
#### Typescript Source
- [x] Run `yarn build`?
#### Action Config
- [x] (If new property) Add property into `README.md`?
<!-- Generated by kasaikou/pr-checklist-action up to here. -->
コメントの開始と終了に、以下のようなHTMLコメントが追加されており、その中に生成されたテキストが挿入されます。
<!-- Generated by kasaikou/pr-checklist-action, DO NOT EDIT. -->
<!-- Generated by kasaikou/pr-checklist-action up to here. -->
この Action では、この開始と終了の2種類のHTMLコメントのあるプルリクエストのコメントに対してチェックリストの Upsert を行います。
この検証はプルリクエスト内のコメントだけでなく、プルリクエストのボディに対してもチェックが行っています。
そのため、プルリクエストテンプレートに先ほどのようなテキストを挿入することで自動更新する場所を指定することができます。
「Action の自作」という観点から見たメモ書き
- 今回の GitHub Actions は TypeScript を用いて作成した。
- GraphQL でのデータ取得を使う場面多かったかなあ。
- 単体テストがちゃんと書けていないので、はやくどうにかしたい。
- リポジトリ名が現在の状態になるまで何度か変更しており、命名が下手だなあ、という気持ちになるなどした。
Discussion