Skip to content

👷 PR の AI レビューを GitHub Actions で行う - #2217

Closed
tatuharu wants to merge 2 commits into
masterfrom
dev/tatuharu_claude_review
Closed

tatuharu wants to merge 2 commits into
masterfrom
dev/tatuharu_claude_review

Conversation

@tatuharu

@tatuharu tatuharu commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

master 向けの PR が作られたり更新されたりしたときに、Claude Code が PR をレビューし、tatuharu のアカウントでレビューと返信を投稿するワークフローを追加します。これまで手元の環境で行っていた PR の監視・レビュー・実機検証・投稿を、GitHub Actions で行えるようにするためのものです。

変更後の挙動

  • 起動は pull_request_target の opened・reopened・synchronize・ready_for_review と、PR 番号を指定する workflow_dispatch。Draft、フォークからの PR、tatuharu が作った PR は対象外です。
  • 初めてのレビューでは、本文を冒頭の定型文と「指摘はありません。」または指摘の一覧だけにし、指摘の詳細は行コメントに書きます。これまでの AI レビューと同じ形式です。
  • 指摘のあとに push があると、AI のスレッドごとに修正を確かめ、1行目に「解消」「一部未解消」「未解消」のどれかを書いて返信します。新しいコミットで入った不具合は新しい指摘にします。
  • PR の変更がすべて Asset/data/ の中にあるときは、DevSpace の検証ランナー(Minecraft 1.20.4)で動作を確かめてから書きます。それ以外の変更を含む PR はコードを読むだけにします。
  • リポジトリの変数 CLAUDE_REVIEW_POST を true にするまでは投稿せず、投稿する内容を実行結果の概要に出すだけです。

設計

Claude が読む PR の本文・コメント・コードには、Claude への指示が仕込まれていることがあります。そのため、PR を読むジョブには GitHub への書き込み権限を渡さず、投稿は別のジョブが形式を検査してから行います。

ジョブ 権限・secret 役割
collect contents・pull-requests の読み取り PR の情報と既存のスレッドを API から集め、レビューするかを決める。PR のコードは checkout しない
review contents の読み取り、CLAUDE_CODE_OAUTH_TOKEN Claude がレビュー・実機検証・推敲をして review.json を書く
post CLAUDE_REVIEW_POST_TOKEN review.json を検査してから投稿する。Claude は動かさない
  • pull_request_target なので、動くのは master のワークフローです。PR の head は devspace/Asset にデータとして取り出し、ランナーでは実行しません。サーバーがデータパックとして読むだけです。
  • DevSpace・yomiyasu・Claude Code・各 action は、ワークフローに書いた版やコミットに固定しています。
  • Claude の道具を絞っています。ファイルの道具は作業フォルダの中だけ(--restricted)で、書き込みは work/ の下だけ、コマンドは scripts/verify.sh と yomiyasu の呼び出し口だけです。CLAUDE_CODE_SUBPROCESS_ENV_SCRUB で、Bash の子プロセスから認証情報の環境変数を消します。
  • yomiyasu は作業フォルダの外も読めるので、呼び出し口の .github/claude-review/yomiyasu.py で、渡すファイルを work/ の下に限ります。
  • post は、1行目の定型文、本文が「指摘はありません。」か指摘の一覧だけであること、コードの外の @ メンション、トークンらしい文字列、返信先が AI のスレッドか、レビューした head が今の head と同じかを検査します。
  • 投稿の末尾に <!-- claude-review head=… diff=… --> を埋め込みます。変更ファイルとその内容が前回の投稿から変わっていなければ、レビューし直しません。この記録がないこれまでの AI レビューは、レビューの commit_id を前回の head とみなします。

マージ後に必要な設定

  1. environment claude-review を作り、配備ブランチを master に限ります。
  2. その environment に、secret CLAUDE_CODE_OAUTH_TOKEN(claude setup-token で作るトークン)と CLAUDE_REVIEW_POST_TOKEN(tatuharu の fine-grained PAT。Asset の Pull requests の読み書きだけ)を置きます。
  3. 投稿しない状態で何件かの PR の結果を確かめてから、変数 CLAUDE_REVIEW_POST を true にします。

CLAUDE_CODE_OAUTH_TOKEN は発行した人のサブスクリプションの利用枠を使います。利用枠の上限に達すると review ジョブが失敗するので、そのときは workflow_dispatch で再実行します。GitHub Actions の実行時間は、公開リポジトリなので課金されません。

検証

  • node --test .github/tests/claude-review.test.cjs(12件)で、collect の対象外の判定、データパックだけの変更かの判定、前回からの差分がないときの省略、強制 push 後の扱い、post の形式の検査、投稿しないときの表示、投稿時の記録の付与とアカウントの確認、yomiyasu の呼び出し口が work/ の外のファイルと標準入力を拒むことを確かめました。API と yomiyasu を置き換えた試験です。
  • Claude Code 2.1.296 を、ワークフローと同じ権限の指定で手元で動かしました。work/ の外への書き込み、env・printenv、作業フォルダの外の読み取り、curl・python3 -c、git diff --output などの書き込みを伴う git は拒否され、許可した検証コマンドだけが通りました。CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 で、子プロセスから認証情報の環境変数が消えることも確かめました。
  • collect を、[Artifact1465] ヴァースティル・プラズマの作成 #2089・✨ [Artifact 1694] アクアバレットを作成 #2216・✨ [Artifact 1413] ライターを作成 #2015 の実際のデータで読み取りだけ動かし、これまでの AI レビューのスレッドと前回の head を読めることを確かめました。

GitHub Actions の上ではまだ動かしていません。ランナーでの検証サーバーの起動、CI でのトークンの利用、environment を master に限ったときに pull_request_target から secret を読めるかは、マージ後の投稿しない状態での実行で確かめます。

@tatuharu tatuharu closed this Oct 31, 2026
@tatuharu
tatuharu deleted the dev/tatuharu_claude_review branch October 31, 2026 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant