1+ # Managed by eqdmc/.github — do not edit. Changes overwritten on next sync.
12name : " Agent: Review PR"
23
34on :
45 pull_request :
56 types : [opened, synchronize, reopened, labeled]
67
7- concurrency :
8- group : agent-review-${{ github.event.pull_request.number }}
9- cancel-in-progress : true
10-
118jobs :
12- gate :
13- if : contains(github.event.pull_request.labels.*.name, 'agent-work')
14- runs-on : ubuntu-latest
15- permissions :
16- pull-requests : read
17- outputs :
18- proceed : ${{ steps.check.outputs.proceed }}
19- pr : ${{ steps.check.outputs.pr }}
20- steps :
21- - name : Check PR state
22- id : check
23- env :
24- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
25- PR : ${{ github.event.pull_request.number }}
26- run : |
27- set -euo pipefail
28- reviews=$(gh pr view "$PR" \
29- -R "${{ github.repository }}" \
30- --json reviews --jq '[.reviews[] | select(.authorAssociation != "NONE")] | length')
31- if [ "$reviews" -gt 0 ]; then
32- echo "PR already has reviews, skipping agent review"
33- echo "proceed=false" >> "$GITHUB_OUTPUT"
34- exit 0
35- fi
36-
37- labels=$(gh pr view "$PR" -R "${{ github.repository }}" \
38- --json labels --jq '.labels[].name' | tr '\n' ',')
39- if echo "$labels" | grep -qE '(^|,)review:agent-complete(,|$)'; then
40- echo "PR already reviewed by agent, skipping"
41- echo "proceed=false" >> "$GITHUB_OUTPUT"
42- exit 0
43- fi
44-
45- echo "proceed=true" >> "$GITHUB_OUTPUT"
46- echo "pr=$PR" >> "$GITHUB_OUTPUT"
47-
489 review :
49- needs : gate
50- if : needs.gate.outputs.proceed == 'true'
51- runs-on : ubuntu-latest
52- timeout-minutes : 15
53- permissions :
54- contents : read
55- pull-requests : write
56- issues : write
57-
58- steps :
59- - name : Checkout repository
60- uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
61- with :
62- fetch-depth : 0
63- ref : ${{ github.event.pull_request.head.sha }}
64-
65- - name : Review PR with OpenCode
66- uses : anomalyco/opencode/github@77fc88c8ade8e5a620ebbe1197f3a572d29ae91a # latest
67- env :
68- ANTHROPIC_API_KEY : ${{ secrets.ANTHROPIC_API_KEY }}
69- GITHUB_TOKEN : ${{ secrets.ORG_CONFIG_TOKEN }}
70- GH_TOKEN : ${{ secrets.ORG_CONFIG_TOKEN }}
71- with :
72- model : anthropic/claude-haiku-4-5-20251001
73- use_github_token : " true"
74- prompt : |
75- You are an independent reviewer for PR #${{ needs.gate.outputs.pr }} on ${{ github.repository }}.
76-
77- You are a DIFFERENT agent from whoever wrote this PR.
78- Do not defer to their decisions. Read the diff with fresh eyes.
79-
80- Procedure:
81- 1. Fetch the PR diff: `gh pr diff ${{ needs.gate.outputs.pr }} -R ${{ github.repository }}`
82- 2. Fetch the parent issue(s) referenced via `Closes #N` in the PR body.
83- 3. For each parent issue, fetch its acceptance checklist.
84- 4. Check each checklist item against the diff. Unchecked items = blocking.
85- 5. Apply the 4-pass review: security, correctness, architecture, quality.
86- 6. Compose a SINGLE review comment in Conventional Comments format.
87-
88- Scope: review CODE CHANGES only. Do NOT flag branch naming,
89- PR title format, label presence, or other metadata — those are
90- enforced by pr-metadata-check (a separate CI workflow). If the
91- only issues are metadata, verdict is Pass.
92-
93- Output contract:
94- - POST a PR comment via `gh pr comment ${{ needs.gate.outputs.pr }} -R ${{ github.repository }} --body "..."`.
95- - If you find ANY blocking issues, also:
96- 1. Convert PR to draft: `gh pr ready ${{ needs.gate.outputs.pr }} --undo -R ${{ github.repository }}`
97- 2. Add label: `gh pr edit ${{ needs.gate.outputs.pr }} --add-label "review:agent-failed" -R ${{ github.repository }}`
98- - If ALL checks pass (no blocking issues):
99- 1. Add label: `gh pr edit ${{ needs.gate.outputs.pr }} --add-label "review:agent-complete" -R ${{ github.repository }}`
100-
101- Hard constraints:
102- - DO NOT fix anything yourself. File findings only.
103- - DO NOT merge anything. Merges are human-only.
104- - DO NOT edit any files. Read-only review.
105- - DO NOT approve via GitHub review events (APPROVE / REQUEST_CHANGES).
106-
107- Format (Conventional Comments):
108- - `issue (blocking): path/file.py:42 — <subject>` for bugs/security
109- - `suggestion (non-blocking): …` for improvements
110- - `question (blocking): …` for clarification needed
111- - `nitpick (non-blocking): …` for style
112- - `praise: …` for things done well
113- - End with:
114- **Summary:** N blocking, N non-blocking, N praise
115- **Verdict:** Pass | Pass with suggestions | Needs changes | Needs discussion
10+ if : contains(github.event.pull_request.labels.*.name, 'agent-work')
11+ uses : eqdmc/.github/.github/workflows/_agent-review-pr.yml@main
12+ with :
13+ pr-number : ${{ github.event.pull_request.number }}
14+ secrets : inherit
0 commit comments