Reusable GitHub Actions workflows for all Gemma Analytics repositories. Add two thin wrapper files to any repo to get Claude-powered code review and an @claude mention responder.
| Workflow | What it does |
|---|---|
claude-review.yml |
Automated code review when a PR is opened or marked ready for review; can also be triggered on demand by commenting @claude review on a PR |
claude.yml |
General-purpose @claude mention handler — answer questions, help with issues, respond to inline review comments |
Both workflows authenticate to Claude via AWS Bedrock (OIDC, no API key stored). GitHub interactions use a GitHub App token (Gemma Claude Assistant) so comments and reactions appear under the bot account rather than a personal token.
Create two files in your repo's .github/workflows/ directory.
name: Claude Code Review
on:
pull_request:
types: [opened, ready_for_review]
issue_comment:
types: [created]
permissions:
id-token: write
contents: read
pull-requests: write
issues: write
jobs:
review:
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '@claude review'))
uses: Gemma-Analytics/.github/.github/workflows/claude-review.yml@main
with:
additional_instructions: |
- Any repo-specific rules Claude should check (one per line)
- e.g. Foreign keys use on_delete=PROTECT
- e.g. No secrets committed
secrets: inheritname: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
permissions:
id-token: write
contents: write
pull-requests: write
issues: write
jobs:
claude:
if: |
(github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@claude') &&
!startsWith(github.event.comment.body, '@claude review')) ||
(github.event_name == 'pull_request_review_comment' &&
contains(github.event.comment.body, '@claude') &&
!startsWith(github.event.comment.body, '@claude review')) ||
(github.event_name == 'issues' && contains(github.event.issue.body, '@claude'))
uses: Gemma-Analytics/.github/.github/workflows/claude.yml@main
secrets: inheritImportant: the negation
!startsWith(..., '@claude review')inclaude.ymlensures that an@claude reviewcomment routes to the review workflow, not the generic responder. Keep both files in sync.
All three secrets must be available in the repo (or inherited from the org). They are already configured at the org level for all Gemma Analytics repositories — no per-repo action is needed.
| Secret | Purpose |
|---|---|
CLAUDE_CODE_ROLE_ARN |
AWS IAM role ARN for OIDC; grants access to Bedrock |
GEMMA_CLAUDE_ASSISTANT_APP_ID |
GitHub App ID for posting comments and reactions as the bot |
GEMMA_CLAUDE_ASSISTANT_APP_PRIVATE_KEY |
GitHub App private key (PEM) |
| Input | Type | Default | Description |
|---|---|---|---|
model |
string | eu.anthropic.claude-sonnet-4-6 |
Bedrock model ID. Change to use a different Claude model (e.g. eu.anthropic.claude-opus-4-7 for harder reviews). |
aws_region |
string | eu-central-1 |
AWS region for Bedrock OIDC. All Gemma infra is in eu-central-1; only change if a repo's workload is in another region. |
additional_instructions |
string | (empty) | Repo-specific review rules appended to the base prompt. Use one bullet per line. Claude checks these on top of the standard review criteria. |
max_turns |
string | 50 |
Maximum agentic turns. Caps cost on large diffs; raised to 50 to support exhaustive category sweeps. |
| Input | Type | Default | Description |
|---|---|---|---|
model |
string | eu.anthropic.claude-sonnet-4-6 |
Bedrock model ID. |
aws_region |
string | eu-central-1 |
AWS region for Bedrock OIDC. |
prompt |
string | (empty) | When empty, the action reads the triggering comment/issue body and handles @claude mentions natively. Pass an explicit prompt only for special routing (rarely needed). |
max_turns |
string | (empty — action default) | When blank, the action uses its built-in default. |
The review is one-shot: auto-fires on PR open and draft→ready; new commits do NOT retrigger it. Re-review requires an explicit @claude review comment. The prompt enforces a 9-category sweep with a mandatory completeness self-check, so all blocking issues are surfaced in the first pass rather than drip-fed across rounds. If you observe repeated drip-feed rounds across multiple PRs, treat that as a prompt regression and flag it.
| Event | Fires? | Notes |
|---|---|---|
| PR opened | Yes | First review on every new PR |
| PR marked ready for review | Yes | Draft → ready transition; ensures draft PRs also get reviewed when they're ready |
| New commit pushed to PR | No | Dropped to avoid re-running on every rebase |
| PR reopened | No | Not wired; add reopened to pull_request.types in your consumer wrapper if needed |
Post @claude review as a PR conversation comment (the main timeline, not inline on a diff line) to trigger a re-review at any time.
@claude review— re-runs the full review@claude review focus on the auth changes— re-reviews with the extra text appended as focus guidance in the prompt- The bot reacts with 👀 to acknowledge within a few seconds
- Concurrency: if you trigger two reviews in quick succession, the first run is cancelled and only the second proceeds
Any comment containing @claude (but not starting with @claude review) routes to the general-purpose responder. Examples:
| Comment | Routes to |
|---|---|
@claude review |
Review workflow |
@claude review focus on security |
Review workflow |
@claude what does this function do? |
Generic responder |
@claude please help me fix this |
Generic responder |
@claude please review this |
Generic responder (does not start with @claude review) |
Tip:
@claude reviewis case-sensitive.@Claude review(capital C) will not trigger the review workflow — it will route to the generic responder.
All consumers in this org pin to @main, meaning any merge to main here is immediately live across all repos. This is intentional for fast iteration.
If you need a stable pin (e.g. for a production-critical repo), reference a tag instead:
uses: Gemma-Analytics/.github/.github/workflows/claude-review.yml@v1Tags are not currently cut automatically — coordinate with the infrastructure team.
- Comment body injection: the
github.event.comment.bodyvalue (user-supplied) is handled via shellenv:variables, never interpolated directly intorun:scripts. This prevents command injection from maliciously crafted comments. - Fork PRs: OIDC credentials and secrets are not available to workflows triggered by PRs from forks. Review will silently fail for fork PRs — this is a known GitHub limitation.
- Bot loops: the
allowed_botssetting in both central workflows permits onlygemma-claude-assistant[bot]andgemmbot. Claude's own review summary comments will not re-trigger another review.