-
Notifications
You must be signed in to change notification settings - Fork 10
129 lines (111 loc) · 6.17 KB
/
Copy pathpr-review.yml
File metadata and controls
129 lines (111 loc) · 6.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Stage 4 — PR Review (manual)
#
# Triggered with `@claude-bot` on a pull request comment, by the repo owner or
# by the developer automation identity (the `implement-issue` review loop
# posts via scripts/request-pr-review.sh, using scripts/gh-agent.sh's default
# `dev` role). Reviews the diff against docs/agents/rules.md and the checklist
# in .github/claude-bot.md.
#
# Migration window: the automation account is being renamed bess-agent ->
# bess-developer (see scripts/gh-agent.sh's --as dev role and CLAUDE.md's
# "General bot rules"). Add 'bess-developer' to the gate below in the SAME
# commit that renames the account, never before — pre-authorising an
# unregistered username on a public repo is exploitable by anyone who
# registers it first.
name: PR Review
on:
issue_comment:
types: [created]
jobs:
review:
name: Review PR
if: |
(github.event.comment.user.login == github.repository_owner ||
github.event.comment.user.login == 'bess-agent') &&
github.event.issue.pull_request != null &&
contains(github.event.comment.body, '@claude-bot')
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: actions/create-github-app-token@v2
id: app-token
with:
app-id: ${{ secrets.CLAUDE_REVIEWER_APP_ID }}
private-key: ${{ secrets.CLAUDE_REVIEWER_PRIVATE_KEY }}
- uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ steps.app-token.outputs.token }}
trigger_phrase: "@claude-bot"
# 60 turns was not enough and failed SILENTLY-ish: on PR #623 the run
# ended `Execution failed: Reached maximum number of turns (60)` after
# posting only an early scratch comment, so the PR showed a stray
# review and no verdict for 16 minutes while the run was already dead.
# A caller waiting on a verdict cannot tell that from a slow review.
#
# The cap is hit because this reviewer earns its keep: it checks the
# branch out, runs the suite, REVERTS the fix to confirm the tests go
# red without it, then runs black/ruff/mypy/shellcheck. That is the
# behaviour worth paying for, and it costs turns proportional to the
# diff. 120 leaves headroom for a multi-file PR while still bounding a
# runaway.
claude_args: "--max-turns 120 --permission-mode bypassPermissions"
prompt: |
You are the **PR Review** bot for PR #${{ github.event.issue.number }} in johanzander/bess-manager.
Required reading:
- docs/agents/rules.md — hard constraints
- .github/claude-bot.md — review checklist
Process:
1. Read the PR diff:
gh pr diff ${{ github.event.issue.number }}
gh pr view ${{ github.event.issue.number }} --json title,body,files,headRefName,baseRefName
2. Identify the linked issue (if any) and read its analysis.
3. Walk through the review checklist in `.github/claude-bot.md`.
**Submit EXACTLY ONE review per run — the summary in step 4.**
This is a hard constraint, not a style preference.
`scripts/request-pr-review.sh` waits for your verdict, and any
extra submitted review is indistinguishable by state from a
real `COMMENT` verdict. That ambiguity left PR #615 approved
but stuck in draft overnight, and a stray "test permission
check" review was submitted to PR #622 while probing what was
available.
So: never call `gh pr review` except once, in step 4. Never
call it to probe permissions — it submits.
Prefer inline comments on the specific lines, via `gh api`:
gh api repos/johanzander/bess-manager/pulls/${{ github.event.issue.number }}/comments \
-f body='...' -f commit_id='<head sha>' -f path='<file>' -F line=<n>
`gh api` may be unavailable to you — it is permission-gated in
this repo, and past runs could not use it. If it fails, DO NOT
fall back to `gh pr review` for notes. Fold the findings into
the step 4 summary instead, each with an explicit `file:line`
and the real code quoted. A complete summary review is a fine
outcome; a second submitted review is not.
4. End with a single summary review using `gh pr review`:
- APPROVE — no blockers, only nits or none
- REQUEST_CHANGES — at least one rule violation or correctness bug
- COMMENT — questions/observations only
**Submitting this review is mandatory in every case,
including when you find nothing wrong.** Finishing the run
without calling `gh pr review` is a failed run, not a clean
one. Silence is indistinguishable from a crash to everything
downstream, and it has a concrete cost: GitHub keeps showing
the LAST explicit verdict, so a prior REQUEST_CHANGES goes on
blocking the merge no matter how many clean runs follow, and
the review can never be cleared by re-running. If the diff is
clean, say so in one line and APPROVE.
5. The summary must include:
- Whether the fix matches the linked issue's root-cause
- Whether the test added would catch a regression
- Whether the change is minimal (no scope creep)
- Specific rule violations (file:line) if any
Hard constraints:
- DO NOT push commits, modify the branch, or change the PR
draft status.
- Quote real code in findings. Don't paraphrase.
- Be specific. "This could be cleaner" is not a useful comment.