Pull Request の commit log に「指摘修正」が含まれていたらコメントする
これは GitHub Advent Calendar 2024 23日目の記事です.
コードレビューで「指摘修正」という commit message を見たことはありませんか. commit message はあとから履歴を見たときに見出しとなる重要な文章です. 「指摘修正」という commit log が連なっているともはや履歴としての意味をなさなくなってしまいます, と先人たちも言っています.
そもそもコードレビューを受けたり、指摘内容を修正したりするのはソフトウェアを開発する過程のひとつにすぎません。
ただの過程(もしくはただの作業)をソフトウェアの歴史として残したとて、後から見た人は「知らんがな」で終わってしまいます。[1]
指摘されたので修正しました〜というメッセージはあとから見たときに有益になることは少ないと思う。[2]
commit message の規約が定まっていれば指摘しやすいですが, そうでない場合は指摘するのも大変です[3]. コードの内容について指摘したら(されたら), commit message の内容にも指摘する(される)というのは心理的なハードルも高く見逃されがちです. こういうときは機械を使って解消します. 今回は GitHub Actions を使って Pull Request の commit log に「指摘修正」が含まれていたらコメント追加します.
完成したものはこちらになります.
name: Check commit message contains 「指摘修正」
on:
pull_request:
branches:
- master
permissions:
contents: read
pull-requests: write
jobs:
check-commit-message:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: commit_message
name: Check Commit Message
run: |
echo matches=`git log --format=%B origin/${{ github.base_ref }}..origin/${{ github.head_ref }} -E --grep='(指摘.*修正|レビュー.*修正|指摘.*対応|レビュー.*対応)'` >> $GITHUB_OUTPUT
- name: Create PR comment
if: steps.commit_message.outputs.matches
run: |
cat << EOF > comment.md
## コミットメッセージは具体的に書きましょう
コミットメッセージに「指摘修正」や「レビュー修正」などの曖昧な表現が含まれています。
コミットログは変更履歴の見出しとしての役割を担っているため、より具体的に変更内容について記述すると良いでしょう。
またコミットメッセージを簡潔に書くことができないような場合は、コミットを複数に分割することを検討してみてください。
例えば、以下のように書き換えることができます。
- 「マジックナンバーを定数に置き換え」
- 「早期リターンを使うように変更」
EOF
- name: Add PR comment
if: steps.commit_message.outputs.matches
run: |
gh pr comment ${{ github.event.number }} --body-file comment.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
実装
実装の方針としては, Pull Request の差分の commit log から「指摘修正」のような特定の文言が含まれていれば, 該当する Pull Request にコメントを追加するとすればよさそうです.
まず Pull Request の差分の commit log を取得します. git log
では <commit1>..<commit2>
という引数を追加すると commit1
から commit2
までの commit log を取得できます. また GitHub Actions では github
context に Pull Request の merge 先 base_ref
と merge 元 head_ref
があるのでこれらを使って Pull Request の差分の commit log を取得できます[4].
注意すべきは GitHub Actions 上で動かすため, actions/checkout
の fetch-depth
を適切に設定する必要があります[5]. 今回はめんどうなので fetch-depth: 0
にして全ての commit log を fetch しておきます. また local branch ではないので, branch の ref には origin
が必要です(1敗).
ここまでをワークフローの step として書くと以下のようになります.
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: commit_message
name: Check Commit Message
run: |
git log origin/${{ github.base_ref }}..origin/${{ github.head_ref }}
次に commit log から「指摘修正」のような特定の文言が含まれているかを検出します. 流行りのAI? いいえ, 男は黙って正規表現. メンバーの学習によって検出頻度は収束していくはずなので, 検出ロジックはてきとうでも問題ないでしょう.
git log
にはそのものずばり --grep
があります. 今回は「指摘修正」や「レビュー修正」のような文言を抜き出します. またフォーマットを指定して message だけを取得します.
あとはこれを GITHUB_OUTPUT
に入れて後続の step で使えるようにするだけです.
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: commit_message
name: Check Commit Message
run: |
echo matches=`git log --format=%B origin/${{ github.base_ref }}..origin/${{ github.head_ref }} -E --grep='(指摘.*修正|レビュー.*修正|指摘.*対応|レビュー.*対応)'` >> $GITHUB_OUTPUT
この結果をもとに Pull Request にコメントを追加します. Pull Request にコメントを追加する方法については過去に記事を書いているので詳細は以下を参考にしてください.
GitHub CLI を使ってコメントを追加するのが簡単です. コメントの内容には「指摘修正」という commit message がよくないということだけではなく, どんな commit message を書くべきかということも記載します. こういうときこそ生成AIの出番です.
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: commit_message
name: Check Commit Message
run: |
echo matches=`git log --format=%B origin/${{ github.base_ref }}..origin/${{ github.head_ref }} -E --grep='(指摘.*修正|レビュー.*修正|指摘.*対応|レビュー.*対応)'` >> $GITHUB_OUTPUT
- name: Create PR comment
if: steps.commit_message.outputs.matches
run: |
cat << EOF > comment.md
## コミットメッセージは具体的に書きましょう
コミットメッセージに「指摘修正」や「レビュー修正」などの曖昧な表現が含まれています。
コミットログは変更履歴の見出しとしての役割を担っているため、より具体的に変更内容について記述すると良いでしょう。
またコミットメッセージを簡潔に書くことができないような場合は、コミットを複数に分割することを検討してみてください。
例えば、以下のように書き換えることができます。
- 「マジックナンバーを定数に置き換え」
- 「早期リターンを使うように変更」
EOF
- name: Add PR comment
if: steps.commit_message.outputs.matches
run: |
gh pr comment ${{ github.event.number }} --body-file comment.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
これですべての step が完成しました.
簡単な機械検出も GitHub Actions なら一瞬で実装できます. どんどん GitHub Actions を使って自動化していきましょう.
Discussion