Skip to content

Commit c73dfeb

Browse files
authored
feat: enable Claude PR review (#463)
Add the two-stage Claude PR-review caller workflows, matching the integration already enabled in aws-deadline/deadline-cloud (#1195): - claude_pr_review_collect.yml: Stage 1, runs on pull_request and exists only to fire the workflow_run event that starts the review stage. It produces no data the review stage trusts. - claude_pr_review.yml: Stage 2, triggered by the collect workflow's completion. Runs from the default branch with this repo's secrets, so a fork PR cannot alter review behavior, permissions, or credentials. All review logic (Bedrock auth, the pinned action, the restricted tool surface, the read-only PR-head checkout, and per-run limits) lives in the reusable workflow in aws-deadline/.github; these are thin callers that forward the workflow_run identifiers and the role-ARN secret. Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
1 parent fc2ad73 commit c73dfeb

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Stage 2 caller for the Claude PR-review integration: the "review" workflow.
2+
#
3+
# Triggered by completion of the Stage-1 "collect" workflow. Because the trigger
4+
# is workflow_run, GitHub runs this file from the default branch (never a fork's
5+
# copy) and with this repo's secrets -- so a fork PR cannot alter the review
6+
# behavior, permissions, or credential setup.
7+
#
8+
# All the review logic (Bedrock auth, the pinned action, the restricted tool
9+
# surface, the read-only PR-head checkout, and per-run limits) lives in the
10+
# reusable workflow in aws-deadline/.github. This caller only forwards the
11+
# workflow_run identifiers and the role-ARN secret.
12+
name: Claude PR Review
13+
14+
on:
15+
workflow_run:
16+
workflows: ["Claude PR Review (collect)"]
17+
types:
18+
- completed
19+
20+
# Cancel a superseded review when the PR is pushed again, keyed on the trusted head repo + branch from the workflow_run payload (no pull_request.number here).
21+
concurrency:
22+
group: claude-pr-review-${{ github.event.workflow_run.head_repository.full_name }}-${{ github.event.workflow_run.head_branch }}
23+
cancel-in-progress: true
24+
25+
# Least privilege. The reusable workflow re-declares the same scopes on its job;
26+
# these are the ceiling for the called workflow.
27+
permissions:
28+
contents: read
29+
pull-requests: write
30+
issues: write
31+
id-token: write
32+
33+
jobs:
34+
review:
35+
# Only run if Stage 1 succeeded, and only for runs triggered by a
36+
# pull_request. The collect workflow listens on pull_request alone today, but
37+
# gating on the event here is defense in depth: if another trigger
38+
# (workflow_dispatch, schedule, ...) is ever added to the collect workflow,
39+
# this prevents a review from firing -- with the base repo's secrets and a
40+
# fork-controlled head_sha -- from a non-PR context.
41+
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' }}
42+
uses: aws-deadline/.github/.github/workflows/reusable_claude_pr_review.yml@mainline
43+
permissions:
44+
contents: read
45+
pull-requests: write
46+
issues: write
47+
id-token: write
48+
with:
49+
# Head repo and head SHA come from the server-populated workflow_run event
50+
# payload, which a fork cannot forge. The review stage resolves the PR
51+
# number and base SHA from these, so nothing fork-controlled is trusted.
52+
head_repository: ${{ github.event.workflow_run.head_repository.full_name }}
53+
head_sha: ${{ github.event.workflow_run.head_sha }}
54+
secrets:
55+
# OIDC role that can mint a Bedrock bearer token.
56+
bedrock_role_arn: ${{ secrets.AWS_CLAUDE_PR_REVIEW_ROLE }}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Stage 1 trigger for the Claude PR-review integration: the "collect" workflow.
2+
#
3+
# Runs on pull_request. For PRs from forks GitHub provides no secrets and a
4+
# read-only GITHUB_TOKEN. This stage does no work and records nothing -- it
5+
# exists only so that its completion fires the workflow_run event that starts
6+
# the review stage (claude_pr_review.yml).
7+
#
8+
# Crucially, this stage produces NO data that the review stage trusts. The
9+
# review stage derives the PR number, head SHA, and base SHA entirely from the
10+
# server-populated workflow_run event payload (which a fork cannot forge), so a
11+
# fork's copy of this file cannot influence what gets reviewed or where comments
12+
# are posted.
13+
#
14+
# This is a thin caller -- the (now no-op) collect job lives in the reusable
15+
# workflow in aws-deadline/.github.
16+
name: Claude PR Review (collect)
17+
18+
on:
19+
pull_request:
20+
types: [opened, synchronize]
21+
22+
# Cancel an in-flight collect run when the PR is updated again.
23+
concurrency:
24+
group: claude-pr-review-collect-${{ github.event.pull_request.number }}
25+
cancel-in-progress: true
26+
27+
# No permissions needed: this stage only exists to fire the workflow_run event.
28+
permissions: {}
29+
30+
jobs:
31+
collect:
32+
uses: aws-deadline/.github/.github/workflows/reusable_claude_pr_review_collect.yml@mainline

0 commit comments

Comments
 (0)