Skip to content

ci: add Claude Code review workflow#712

Merged
lklimek merged 8 commits into
v1.0-devfrom
ci/claude-code-review
Mar 10, 2026
Merged

ci: add Claude Code review workflow#712
lklimek merged 8 commits into
v1.0-devfrom
ci/claude-code-review

Conversation

@lklimek
Copy link
Copy Markdown
Contributor

@lklimek lklimek commented Mar 10, 2026

Summary

  • Adds automated code review workflow triggered by claudius-review PR label
  • Uses --agent claudius:claudius with grumpy-review and check-pr-comments skills via GitHub MCP
  • Review flow: check existing threads → resolve fixed ones → fresh review → post MEDIUM+ findings → remove label → approve if clean
  • Label is always removed after review (human-triggered each time)
  • Defaults to Opus model, configurable via CLAUDE_MODEL repo variable
  • Fails the job when CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK secret is missing (intentional — visible failure, not silent skip)

Prerequisites

  1. CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK secret configured (already exists)
  2. Create claudius-review label in GitHub → Issues → Labels

Test plan

  • Add claudius-review label to a test PR → verify workflow triggers and produces review comments
  • Push new commits to labeled PR → verify workflow re-runs on synchronize
  • Address all review comments, re-label → verify threads get resolved and PR is approved
  • Remove secret temporarily → verify workflow fails with warning (red, not green)
  • Verify workflow does NOT trigger on unlabeled PRs or draft PRs
  • Verify only MEDIUM+ findings are posted as inline comments

Non-functional CI change — no manual test scenario file needed.

🤖 Generated with Claude Code · Co-authored by Claudius the Magnificent

Summary by CodeRabbit

  • Chores
    • Implemented automated code review workflow for pull requests to streamline the review process and maintain code quality standards.

Adds a GitHub Actions workflow that triggers automated code review
when a "claude review" label is applied to a PR. Uses the claudius
grumpy-review and check-pr-comments skills via MCP-first approach.

- Triggers on label application and subsequent pushes
- Checks/resolves previously addressed review threads
- Approves and removes label when all comments resolved
- Falls back to opus model when CLAUDE_MODEL var is not set
- Skips gracefully when OAuth token is not configured

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 10, 2026

Warning

Rate limit exceeded

@lklimek has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0b21b1fa-c370-499e-8ac3-d9e134cb13a6

📥 Commits

Reviewing files that changed from the base of the PR and between f468951 and 7c648fc.

📒 Files selected for processing (1)
  • .github/workflows/claude-code-review.yml
📝 Walkthrough

Walkthrough

Adds a new GitHub Actions workflow that triggers Claude-based automated code reviews on pull_request label or synchronize events, validates an OAuth secret, checks out the repo, configures git, and runs an anthropics/claude-code-action with a multi-step prompt to comment, label, or approve PRs.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow
.github/workflows/claude-code-review.yml
Adds a new workflow "Claude (label: claudius-review)" triggered on PR label/synchronize. Implements concurrency, conditional run for non-draft PRs, secret presence validation (CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK), repo checkout, git HTTPS config, and invokes anthropics/claude-code-action@v1 with CLAUDE_MODEL and claude_args plus a multi-step review prompt.

Sequence Diagram(s)

sequenceDiagram
    participant GitHub as GitHub Actions
    participant Secrets as Secrets Store
    participant Repo as Repository
    participant CLAUDE as Claude Action/Service

    Note over GitHub: PR labeled or synchronized
    GitHub->>Secrets: check `CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK`
    alt secret missing
        GitHub->>GitHub: warn & exit
    else secret present
        GitHub->>Repo: checkout (depth:1)
        GitHub->>Repo: configure git HTTPS
        GitHub->>CLAUDE: invoke anthropics/claude-code-action (CLAUDE_MODEL, claude_args, prompt)
        CLAUDE-->>GitHub: review comments, suggested actions
        GitHub->>Repo: post inline comments, remove label, approve if resolved
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped into CI with a curious cheer,
Claude sniffed the diffs and whispered in my ear,
Secrets checked, prompts prepared, comments on the way,
Labels tugged, approvals hummed, the branches sway,
Cheery thumps — the meadow's PRs are clear!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'ci: add Claude Code review workflow' directly and clearly describes the main change: adding a new CI workflow for Claude-based code reviews.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ci/claude-code-review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/claude-code-review.yml:
- Around line 29-35: The "Check for OAuth token" step currently exits with code
1 when the HAS_TOKEN check fails, which turns the advertised skip into a job
failure; update the run block so missing CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK only
emits the warning and does not fail the job (e.g., replace "exit 1" with a
non-failing exit like "exit 0" or simply remove the exit so the step ends
successfully), keeping the env variable HAS_TOKEN and the same warning message
intact.
- Around line 22-25: The workflow's permissions block is missing the issues:
write permission needed to remove PR labels; update the permissions map to
include issues: write alongside contents: read, pull-requests: write, and
id-token: write so the action that removes the "claude review" label can
succeed; specifically add the key issues: write under the existing permissions
section so GitHub's label removal API calls have the required scope.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8f4c172a-9739-40db-8686-3ec846f6b981

📥 Commits

Reviewing files that changed from the base of the PR and between dfb328a and 15200e4.

📒 Files selected for processing (1)
  • .github/workflows/claude-code-review.yml

Comment thread .github/workflows/claude-code-review.yml
Comment thread .github/workflows/claude-code-review.yml
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
.github/workflows/claude-code-review.yml (2)

22-25: ⚠️ Potential issue | 🟠 Major

Add issues: write before asking Claude to remove labels.

The prompt on Lines 62-63 tells the agent to remove the claudius-review label, but GitHub’s label-removal API is covered by Issues write permission, not just pull-requests: write. Without it, that step will fail. (docs.github.com)

Suggested change
     permissions:
       contents: read
+      issues: write
       pull-requests: write
       id-token: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 22 - 25, The
workflow's permissions block currently lists "contents: read", "pull-requests:
write", and "id-token: write" but is missing the Issues permission required to
remove labels; add a new entry "issues: write" alongside those entries (i.e.,
under the same top-level permissions mapping that contains permissions:,
contents: read, pull-requests: write, id-token: write) so the step that
instructs the agent to remove the "claudius-review" label can call the Issues
label API successfully.

29-48: ⚠️ Potential issue | 🟠 Major

Make the missing-secret path a real skip.

Line 35 still fails the job, so the “warning and skip” path leaves the PR red. Also, if this becomes a non-failing exit without gating later steps, checkout and the Claude action will still run with no OAuth token.

Suggested change
       - name: Check for OAuth token
+        id: token-check
         env:
           HAS_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK != '' }}
         run: |
+          echo "has_token=$HAS_TOKEN" >> "$GITHUB_OUTPUT"
           if [ "$HAS_TOKEN" != "true" ]; then
             echo "::warning::CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK secret not configured — skipping review."
-            exit 1
+            exit 0
           fi

       - name: Checkout repository
+        if: steps.token-check.outputs.has_token == 'true'
         uses: actions/checkout@v6
         with:
           fetch-depth: 1

       - name: Configure git to use HTTPS instead of SSH
+        if: steps.token-check.outputs.has_token == 'true'
         run: git config --global url."https://github.com/".insteadOf "git@github.com:"

       - name: Run Claude Code Review
+        if: steps.token-check.outputs.has_token == 'true'
         id: claude-review
         uses: anthropics/claude-code-action@v1
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 29 - 48, The "Check
for OAuth token" step uses HAS_TOKEN but exits non‑zero, so it still fails the
job; change that step to exit 0 on missing token (or set a step output like
token_present=false) and then guard the downstream steps ("Checkout repository"
and the step with id claude-review / Run Claude Code Review) with an if
condition that runs them only when HAS_TOKEN (or the step output token_present)
is true so the workflow truly skips the checkout and claude action when the
secret is not configured.
🧹 Nitpick comments (2)
.github/workflows/claude-code-review.yml (2)

26-27: Consider pinning the default model instead of using the floating opus alias.

Claude Code treats opus as an alias for the latest Opus model, so this workflow’s review and approval behavior can change without any repo diff. A fixed model ID is safer for CI reproducibility. (docs.claude.com)

Suggested change
     env:
-      CLAUDE_MODEL: ${{ vars.CLAUDE_MODEL || 'opus' }}
+      CLAUDE_MODEL: ${{ vars.CLAUDE_MODEL || 'claude-opus-4-6' }}

Also applies to: 66-67

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 26 - 27, The workflow
currently sets CLAUDE_MODEL to the floating alias 'opus' (env: CLAUDE_MODEL: ${{
vars.CLAUDE_MODEL || 'opus' }}), which can change behavior; update it to a fixed
model ID string (e.g., replace 'opus' with the specific Opus model identifier
you want pinned) and apply the same change where CLAUDE_MODEL is set again later
in the file so CI uses a reproducible model instead of the alias.

4-18: Confirm fork PRs are intentionally out of scope.

On pull_request workflows, GitHub does not pass repository secrets to runs from forks, and forked PRs get a read-only GITHUB_TOKEN. That means this job cannot use CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK or mutate PR state for external contributors. If reviews are supposed to work on fork PRs too, this needs a different event/auth design; otherwise I’d document the same-repo-only limitation. (docs.github.com)

Also applies to: 29-31

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml around lines 4 - 18, The workflow
currently triggers on pull_request and uses secrets
(CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK) and mutable PR actions in the review job named
"review", but GitHub does not provide secrets or a writable GITHUB_TOKEN to runs
triggered from forked PRs; update the workflow to either (A) explicitly
restrict/clarify to same-repo PRs by documenting the limitation near the
pull_request trigger/description and ensuring the "review" job only runs for
same-repo contributors, or (B) change the trigger/auth pattern to
pull_request_target (or another approved approach) so the job runs with
repository secrets and a write-capable token for PRs, and update any logic that
assumes secrets exist (including uses of CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK and the
label 'claudius-review'); apply the same change/documentation to the referenced
block (lines 29-31) as well.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @.github/workflows/claude-code-review.yml:
- Around line 22-25: The workflow's permissions block currently lists "contents:
read", "pull-requests: write", and "id-token: write" but is missing the Issues
permission required to remove labels; add a new entry "issues: write" alongside
those entries (i.e., under the same top-level permissions mapping that contains
permissions:, contents: read, pull-requests: write, id-token: write) so the step
that instructs the agent to remove the "claudius-review" label can call the
Issues label API successfully.
- Around line 29-48: The "Check for OAuth token" step uses HAS_TOKEN but exits
non‑zero, so it still fails the job; change that step to exit 0 on missing token
(or set a step output like token_present=false) and then guard the downstream
steps ("Checkout repository" and the step with id claude-review / Run Claude
Code Review) with an if condition that runs them only when HAS_TOKEN (or the
step output token_present) is true so the workflow truly skips the checkout and
claude action when the secret is not configured.

---

Nitpick comments:
In @.github/workflows/claude-code-review.yml:
- Around line 26-27: The workflow currently sets CLAUDE_MODEL to the floating
alias 'opus' (env: CLAUDE_MODEL: ${{ vars.CLAUDE_MODEL || 'opus' }}), which can
change behavior; update it to a fixed model ID string (e.g., replace 'opus' with
the specific Opus model identifier you want pinned) and apply the same change
where CLAUDE_MODEL is set again later in the file so CI uses a reproducible
model instead of the alias.
- Around line 4-18: The workflow currently triggers on pull_request and uses
secrets (CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK) and mutable PR actions in the review
job named "review", but GitHub does not provide secrets or a writable
GITHUB_TOKEN to runs triggered from forked PRs; update the workflow to either
(A) explicitly restrict/clarify to same-repo PRs by documenting the limitation
near the pull_request trigger/description and ensuring the "review" job only
runs for same-repo contributors, or (B) change the trigger/auth pattern to
pull_request_target (or another approved approach) so the job runs with
repository secrets and a write-capable token for PRs, and update any logic that
assumes secrets exist (including uses of CLAUDE_CODE_OAUTH_TOKEN_LKLIMEK and the
label 'claudius-review'); apply the same change/documentation to the referenced
block (lines 29-31) as well.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 224ba4a9-4c8a-478f-95c3-94e1393a9b24

📥 Commits

Reviewing files that changed from the base of the PR and between 15200e4 and 1ddbd76.

📒 Files selected for processing (1)
  • .github/workflows/claude-code-review.yml

lklimek and others added 2 commits March 10, 2026 14:42
- Workflow name: "Claude (label: claudius-review)"
- Uses --agent claudius:claudius to run as Claudius directly
- Persona instructions in prompt for PR comment tone

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add issues: write permission for label removal (CMT-001)
- Reorder flow: check existing → resolve fixed → fresh review → post MEDIUM+ → remove label → approve if clean
- Always remove claudius-review label (human-triggered each time)
- Approve only when no unresolved comments remain after full flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new GitHub Actions workflow to run automated Claude-based PR reviews when a claudius-review label is applied, integrating the “claudius” agent/skills and optionally approving the PR when no medium+ findings remain.

Changes:

  • Introduces a label-triggered (labeled, synchronize) review workflow gated on claudius-review and non-draft PRs.
  • Runs anthropics/claude-code-action@v1 with a custom prompt/agent configuration and a configurable model via CLAUDE_MODEL.
  • Adds an explicit “fail loud” check when the required OAuth token secret is missing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/claude-code-review.yml
Comment thread .github/workflows/claude-code-review.yml Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/claude-code-review.yml:
- Around line 57-70: The workflow currently only removes the "claudius-review"
label inside the Claude review step, so failures/timeouts leave the label stuck;
add a separate cleanup step that runs after the Claude action to always remove
the label (use if: always()), e.g. a step named like
"cleanup-remove-claudius-review-label" that invokes actions/github-script or an
equivalent handler to remove label "claudius-review" on the PR, and place it
after the Claude/claudius review step so it runs unconditionally even when the
review job fails or times out.
- Around line 39-54: The workflow uses mutable references and an unpinned
marketplace URL—replace mutable action refs and the marketplace reference with
immutable pins: change uses: actions/checkout@v6 and uses:
anthropics/claude-code-action@v1 to specific commit SHAs or immutable tags, and
stop passing plugin_marketplaces="https://github.com/lklimek/agents.git"
directly; instead vendor the marketplace JSON into the repo and reference it via
a local path or point plugin_marketplaces to a marketplace repo/tag@SHA that
contains marketplace.json with each plugin entry pinned to exact commit SHAs
(and update the plugins input accordingly), ensuring the Run Claude Code Review
step (id: claude-review) no longer relies on mutable refs or an unpinned remote
URL.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 22ef8f58-eda7-40b6-925b-5e05ede8abee

📥 Commits

Reviewing files that changed from the base of the PR and between 1ddbd76 and f468951.

📒 Files selected for processing (1)
  • .github/workflows/claude-code-review.yml

Comment thread .github/workflows/claude-code-review.yml
Comment thread .github/workflows/claude-code-review.yml Outdated
Label removal was inside the Claude prompt, so timeouts or failures
would leave it stuck and retrigger on every push. Now handled by a
dedicated step with if: always().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
lklimek and others added 2 commits March 10, 2026 15:16
Keep claudius-review label on failure/timeout so subsequent pushes
retrigger the review automatically until it completes successfully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lklimek lklimek enabled auto-merge (squash) March 10, 2026 14:27
@lklimek lklimek merged commit 838336b into v1.0-dev Mar 10, 2026
6 checks passed
@lklimek lklimek deleted the ci/claude-code-review branch March 10, 2026 14:33
@lklimek lklimek review requested due to automatic review settings March 23, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants