Copilot PRレビュー対応ワークフロー
概要
GitHub Copilot によるPRレビューコメントへの対応を効率化します。レビューコメントの取得から修正、返信、スレッド解決までを自動化し、PRレビュー対応時間を15分→3分に短縮(80%削減)します。
重要: ブランチ保護ルールにより、全てのコメントを解決しないとマージできません。
入力形式
スキル呼び出し時にPR番号を指定してください:
/copilot-review <PR番号>
または
/copilot-review
PR番号: <番号>
実行プロセス
ステップ1: レビューコメント取得
GitHub APIを使用してPRのレビューコメントを取得します。
コマンド:
gh api repos/foie0222/baken-kaigi/pulls/<PR番号>/comments \
--jq '.[] | {id, path, line, body, user: .user.login}'
出力例:
{
"id": 123456789,
"path": "backend/src/domain/ports/race_data_provider.py",
"line": 25,
"body": "Consider adding type hints for the return value",
"user": "copilot"
}
判断基準:
- Copilotによるコメント(
user: "copilot")のみを対象 - 人間のレビュアーコメントは別途確認を促す
ステップ2: コメント内容の分析と優先度付け
レビューコメントを以下のカテゴリーに分類:
Critical(即座に対応):
- セキュリティ脆弱性
- バグの可能性
- テスト不足
High(優先対応):
- 型ヒント不足
- エラーハンドリング不足
- コード品質問題
Medium(推奨対応):
- 命名規則
- コメント不足
- リファクタリング提案
Low(任意対応):
- コードスタイル
- 軽微な改善提案
ステップ3: 対応方針の提案
各コメントに対して以下のいずれかを提案:
- 修正する: コメントの指摘を受け入れて修正
- 説明を返信: 現状の実装理由を説明し、修正不要と判断
- 代替案を提示: 別のアプローチを提案
提案フォーマット:
📝 レビューコメント #1 [Critical]
ファイル: backend/src/domain/ports/race_data_provider.py:25
指摘: Consider adding type hints for the return value
提案: 修正する
理由: 型ヒントはコードの可読性と保守性を向上させる
修正内容: 戻り値の型ヒントを追加
ステップ4: 修正実施
ユーザーの承認後、Editツールを使用して修正を実施します。
修正パターン:
パターン1: 型ヒント追加
# Before
def get_race(self, race_id):
pass
# After
def get_race(self, race_id: RaceId) -> RaceData | None:
pass
パターン2: エラーハンドリング追加
# Before
data = response.json()
return data["value"]
# After
try:
data = response.json()
return data.get("value")
except (KeyError, ValueError) as e:
logger.error(f"Failed to parse response: {e}")
return None
パターン3: テスト追加
def test_get_race_not_found():
"""存在しないレースIDの場合Noneを返す."""
# Arrange
provider = MockRaceDataProvider()
race_id = RaceId("invalid_id")
# Act
result = provider.get_race(race_id)
# Assert
assert result is None
ステップ5: コミット・プッシュ
修正をコミットしてプッシュします。
コマンド:
git add <修正ファイル>
git commit -m "fix: Copilotレビュー指摘対応 - <概要>"
git push
コミットメッセージ例:
fix: Copilotレビュー指摘対応 - 型ヒント追加fix: Copilotレビュー指摘対応 - エラーハンドリング改善test: Copilotレビュー指摘対応 - テストケース追加
ステップ6: コメントに返信
修正内容または説明をコメントに返信します。
コマンド:
gh api repos/foie0222/baken-kaigi/pulls/<PR番号>/comments/<コメントID>/replies \
-X POST \
-f body='<返信内容>'
返信テンプレート:
修正した場合:
✅ 修正しました。
変更内容:
- <変更1>
- <変更2>
コミット: <コミットハッシュ>
説明で対応する場合:
📝 現在の実装理由
<理由の説明>
そのため、この指摘については現状維持とさせていただきます。
ステップ7: スレッド解決
修正完了後、レビュースレッドを解決します。
ステップ7-1: スレッドID取得
gh api graphql -f query='
query {
repository(owner: "foie0222", name: "baken-kaigi") {
pullRequest(number: <PR番号>) {
reviewThreads(first: 20) {
nodes {
id
isResolved
comments(first: 1) {
nodes {
databaseId
body
}
}
}
}
}
}
}'
ステップ7-2: スレッド解決
gh api graphql -f query='
mutation {
resolveReviewThread(input: {threadId: "<スレッドID>"}) {
thread {
isResolved
}
}
}'
ステップ8: 対応完了確認
全てのコメントに対応したことを確認します。
確認コマンド:
# 未解決のスレッド数を確認
gh api graphql -f query='
query {
repository(owner: "foie0222", name: "baken-kaigi") {
pullRequest(number: <PR番号>) {
reviewThreads(first: 20) {
nodes {
isResolved
}
}
}
}
}' --jq '.data.repository.pullRequest.reviewThreads.nodes | map(select(.isResolved == false)) | length'
期待値: 0(全スレッド解決済み)
出力形式
📊 Copilot レビュー対応サマリー
PR番号: #<番号>
レビューコメント総数: <件数>
対応状況:
✅ 修正済み: <件数>
📝 説明返信: <件数>
⏭️ スキップ: <件数>
詳細:
---
📝 コメント #1 [Critical]
ファイル: backend/src/domain/ports/race_data_provider.py:25
指摘: Consider adding type hints for the return value
対応: ✅ 修正済み
返信: "型ヒントを追加しました。"
---
次のアクション:
- [ ] 全スレッド解決確認(gh api graphqlで確認)
- [ ] CI/CD成功確認
- [ ] マージ実行
エラーハンドリング
頻出エラーと対処法
GraphQL API認証エラー
Error: HTTP 401: Unauthorized- 対処:
gh auth loginで再認証
- 対処:
スレッドIDが見つからない
Error: Invalid thread ID- 対処: GraphQLクエリで最新のスレッドIDを再取得
コメント返信に失敗
Error: Resource not accessible by integration- 対処:
ghCLI の権限スコープを確認(repoスコープが必要)
- 対処:
マージブロック
Error: Required reviews not satisfied- 対処: 全スレッドが解決されているか確認
命名規則/パターン
コミットメッセージ
fix: Copilotレビュー指摘対応 - <具体的な修正内容>- 複数ファイル修正の場合は概要を記載
返信メッセージ
- 簡潔に(3行以内)
- 絵文字で状態を明示(✅, 📝, ⚠️)
- コミットハッシュを含める
使用例
例1: 型ヒント不足の指摘に対応
/copilot-review 42
📊 Copilot レビュー対応サマリー
PR番号: #42
レビューコメント総数: 3件
対応状況:
✅ 修正済み: 2件
📝 説明返信: 1件
詳細:
---
📝 コメント #1 [High]
ファイル: backend/src/domain/ports/race_data_provider.py:25
指摘: Consider adding type hints for the return value
対応: ✅ 修正済み
返信: "戻り値の型ヒントを追加しました。"
コミット: abc1234
---
📝 コメント #2 [Medium]
ファイル: backend/src/api/handlers/races.py:50
指摘: Consider extracting this to a separate function
対応: 📝 説明返信
返信: "現状のロジックは十分シンプルであり、抽出するとかえって複雑になると判断しました。"
---
次のアクション:
- [x] 全スレッド解決確認
- [ ] CI/CD成功確認
- [ ] マージ実行
例2: セキュリティ指摘への対応
/copilot-review 45
📊 Copilot レビュー対応サマリー
PR番号: #45
レビューコメント総数: 1件
対応状況:
✅ 修正済み: 1件
詳細:
---
📝 コメント #1 [Critical]
ファイル: backend/src/api/handlers/races.py:30
指摘: Potential SQL injection vulnerability
対応: ✅ 修正済み
返信: "パラメータ化クエリに変更し、SQLインジェクションを防止しました。"
コミット: def5678
---
次のアクション:
- [x] 全スレッド解決確認
- [x] CI/CD成功確認
- [ ] マージ実行
参照コマンド
GitHub CLI (gh) コマンド一覧
# PR一覧表示
gh pr list
# PR詳細表示
gh pr view <PR番号>
# レビューコメント取得
gh api repos/foie0222/baken-kaigi/pulls/<PR番号>/comments
# コメントに返信
gh api repos/foie0222/baken-kaigi/pulls/<PR番号>/comments/<コメントID>/replies \
-X POST -f body='返信内容'
# スレッド情報取得
gh api graphql -f query='...'
# スレッド解決
gh api graphql -f query='mutation { resolveReviewThread(...) }'
GraphQL クエリテンプレート
未解決スレッド一覧取得
query {
repository(owner: "foie0222", name: "baken-kaigi") {
pullRequest(number: <PR番号>) {
reviewThreads(first: 20) {
nodes {
id
isResolved
comments(first: 1) {
nodes {
body
path
}
}
}
}
}
}
}
スレッド解決
mutation {
resolveReviewThread(input: {threadId: "<スレッドID>"}) {
thread {
isResolved
}
}
}
注意事項
- ブランチ保護: 全コメント解決しないとマージ不可
- CI/CD: レビュー対応後も必ずCI/CDの成功を確認
- 人間レビュー: Copilot以外のレビューコメントは別途対応
- 過剰な修正: 指摘が不適切な場合は説明返信で対応(盲目的に修正しない)
- git worktree: 作業は feature ブランチで実施