Skip to content

ci: add Claudius PR Review workflow#3347

Open
lklimek wants to merge 6 commits intov3.1-devfrom
chore/claudius-review-workflow
Open

ci: add Claudius PR Review workflow#3347
lklimek wants to merge 6 commits intov3.1-devfrom
chore/claudius-review-workflow

Conversation

@lklimek
Copy link
Contributor

@lklimek lklimek commented Mar 16, 2026

Issue being fixed or feature implemented

Adds automated AI-powered PR review via Claudius, triggered by label or comment.

What was done?

Added .github/workflows/claudius-review.yml that invokes lklimek/claudius-review-action@main.

Triggers:

  • Label: adding claudius-review label to a non-draft PR
  • Synchronize: pushing to a labeled non-draft PR
  • Comment: posting /review on any PR (including drafts)

Configuration:

  • Uses OAuth token (CLAUDE_CODE_OAUTH_TOKEN secret) for authentication
  • Claude model: opus
  • Comment trigger restricted to trusted users (OWNER, MEMBER, COLLABORATOR)
  • Concurrency: one review per PR, cancel-in-progress

The composite action handles:

  • Repository checkout
  • Claude Code invocation with review skills
  • Review report upload as artifact with link comment
  • claudius-review label removal on success

How Has This Been Tested?

Workflow YAML validated with Python yaml parser. Will be tested on first triggered PR after merge.

Breaking Changes

None.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

🤖 Co-authored by Claudius the Magnificent AI Agent

Summary by CodeRabbit

  • Chores
    • Enhanced automated code review workflow to streamline the PR review process and improve code quality.

Adds GitHub Actions workflow that triggers claudius-review-action
on `claudius-review` label or `/claudius:review` PR comment.

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

coderabbitai bot commented Mar 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 06fbbff7-9e62-4561-a102-7bbd8e44c2d1

📥 Commits

Reviewing files that changed from the base of the PR and between 5b5d153 and e77497f.

📒 Files selected for processing (1)
  • .github/workflows/claudius-review.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/claudius-review.yml

📝 Walkthrough

Walkthrough

Adds a new GitHub Actions workflow "Claudius PR Review" that triggers on pull_request_target (labeled, synchronize) and issue_comment (created), conditionally runs when PR is labeled claudius-review or an /review comment is made by privileged collaborators, and invokes the claudius-review action with configured inputs and permissions.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow
.github/workflows/claudius-review.yml
New workflow "Claudius PR Review". Triggers: pull_request_target (labeled, synchronize) and issue_comment (created). Adds concurrency per PR/issue, permissions (contents: read, pull-requests: write, issues: write), conditional job execution based on label or comment with author association checks, and runs lklimek/claudius-review-action@main with inputs (CLAUDE_CODE_OAUTH_TOKEN, github_token, claude_model: "opus", trigger_label: "claudius-review").

Sequence Diagram(s)

sequenceDiagram
  participant GitHub as GitHub Events
  participant Runner as Actions Runner
  participant Claudius as Claudius Action
  participant ClaudeAPI as Claude API

  GitHub->>Runner: pull_request_target (labeled/synchronize) or issue_comment(created)
  Runner->>Runner: evaluate concurrency & permissions
  Runner->>Runner: check conditions (label == "claudius-review" OR comment contains "/review" && author is OWNER/MEMBER/COLLAB)
  alt Conditions met
    Runner->>Claudius: invoke lklimek/claudius-review-action with inputs
    Claudius->>ClaudeAPI: submit code + prompts (CLAUDE_CODE_OAUTH_TOKEN, model "opus")
    ClaudeAPI-->>Claudius: review results
    Claudius-->>Runner: post review (uses github_token to write PR/comments)
    Runner-->>GitHub: create/update PR review/comments
  else Conditions not met
    Runner-->>GitHub: no-op
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A rabbit hops in CI's light,
Labels and comments spark the night,
Claudius listens, Claude replies,
Reviews arrive like springtime skies —
Hooray for smart checks, quick and bright! ✨

🚥 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 Claudius PR Review workflow' accurately and concisely summarizes the main change: adding a new GitHub Actions workflow for automated AI-powered PR review.
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 chore/claudius-review-workflow
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.

Add a .trivyignore file to your project to customize which findings Trivy reports.

@github-actions github-actions bot added this to the v3.1.0 milestone Mar 16, 2026
@lklimek
Copy link
Contributor Author

lklimek commented Mar 16, 2026

/claudius:review

@lklimek lklimek marked this pull request as ready for review March 16, 2026 09:23
@lklimek
Copy link
Contributor Author

lklimek commented Mar 16, 2026

/claudius:review

Copy link
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/claudius-review.yml:
- Around line 25-27: The issue: the issue_comment branch of the if in the
workflow allows any commenter to trigger /claudius:review; restrict it to
trusted commenters by adding an author association check. Update the existing if
expression (the multi-line conditional block) to require
github.event.comment.body contains '/claudius:review' AND that
github.event.comment.author_association is one of trusted values (e.g.,
'OWNER','MEMBER','COLLABORATOR','CONTRIBUTOR','MAINTAINER') using comparisons or
contains/startsWith logic with an array literal; use
github.event.comment.author_association in the condition so only those trusted
associations can trigger the workflow.
- Line 29: The workflow is using a mutable ref "uses:
lklimek/claudius-review-action@main" which is a supply-chain risk; replace the
"@main" ref with the action's immutable full commit SHA (e.g.,
"@<full-commit-sha>") for lklimek/claudius-review-action, updating the "uses"
line accordingly; fetch and verify the intended commit SHA from the action
repository (or vendor a known-good SHA) and use that exact 40-character commit
hash in the workflow so the action execution is pinned to a fixed commit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 30db46a6-8178-435c-87fc-0f610371cf45

📥 Commits

Reviewing files that changed from the base of the PR and between 7b3aa20 and 5b5d153.

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

lklimek and others added 2 commits March 16, 2026 10:28
- Use claude_code_oauth_token instead of anthropic_api_key
- Skip label/synchronize triggers on draft PRs
- Comment trigger (/claudius:review) still works on drafts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Only OWNER, MEMBER, and COLLABORATOR can trigger review via comment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lklimek lklimek requested a review from Copilot March 16, 2026 09:33
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
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 the “Claudius” automated PR review action when explicitly triggered via label or slash-command comment.

Changes:

  • Introduces .github/workflows/claudius-review.yml workflow for PR review automation
  • Triggers on pull_request_target (label + synchronize) and issue_comment (/claudius:review) with concurrency control
  • Grants workflow permissions needed to post PR/issue comments and supplies required tokens/secrets to the action

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

Comment on lines +3 to +8
on:
pull_request_target:
types:
- labeled
- synchronize
issue_comment:
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'claudius-review') && github.event.pull_request.draft == false) ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/review') && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association))
steps:
- uses: lklimek/claudius-review-action@main
@lklimek lklimek added the claudius-review Trigger automated review label Mar 16, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

This PR adds a CI workflow for AI-powered PR review using pull_request_target, which grants access to repository secrets even for fork PRs. The workflow has reasonable gating (label requirement, collaborator-only comment trigger, draft-PR filtering), but has one blocking security issue — the action is referenced by a mutable branch (@main) rather than a pinned commit SHA — and several logic/hardening suggestions.

Reviewed commit: e77497f

🔴 1 blocking | 🟡 3 suggestion(s) | 💬 1 nitpick(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `.github/workflows/claudius-review.yml`:
- [BLOCKING] lines 31-34: Action pinned to mutable branch, not commit SHA
  `lklimek/claudius-review-action@main` references a mutable branch. This action receives `CLAUDE_CODE_OAUTH_TOKEN` and `GITHUB_TOKEN` and runs in a `pull_request_target` context, which grants access to base-repo secrets even for fork PRs. If the upstream action repository is compromised or force-pushed, an attacker gains access to these credentials and can write to any PR in this repo.

GitHub's security hardening guide recommends pinning third-party actions to a full-length commit SHA. This is especially critical here because: (1) the action is from a personal account, not a verified org, (2) it runs in a `pull_request_target` context with elevated trust, and (3) it receives secrets. This repo already follows SHA-pinning in `milestone.yml` (`actions/github-script@f28e40c7...`), making `@main` an outlier.
- [SUGGESTION] lines 27-29: `labeled` trigger re-runs review when unrelated labels are added
  The condition checks `contains(github.event.pull_request.labels.*.name, 'claudius-review')` for all `pull_request_target` events, without distinguishing between `labeled` and `synchronize` actions. When the `labeled` event fires, `github.event.pull_request.labels` contains *all* current labels on the PR, not just the newly added one. So if `claudius-review` was added earlier and someone later adds an unrelated label (e.g., `bug`), the `labeled` event fires, the condition is satisfied, and the review workflow runs again unnecessarily.

The fix is to check `github.event.label.name == 'claudius-review'` specifically for the `labeled` action, while keeping the `contains()` check for `synchronize` events.
- [SUGGESTION] lines 4-7: `synchronize` + `pull_request_target` + `cancel-in-progress` enables TOCTOU risk on labeled PRs
  The `synchronize` trigger fires when new commits are pushed to a PR. Combined with `pull_request_target` and `cancel-in-progress: true`, this creates a potential time-of-check/time-of-use scenario: (1) a collaborator reviews code and adds the `claudius-review` label, (2) the review starts, (3) the contributor pushes new commits before the run finishes, (4) `cancel-in-progress` cancels the in-flight run and starts a new one with the label still present, (5) the new run reviews the updated (potentially malicious) code.

The practical risk depends on the action's internals — `pull_request_target` checks out the base branch by default, but the action may check out the PR head for review purposes. If the action does check out PR code, the attacker-controlled CLAUDE.md or `.claude/` files could influence Claude Code's behavior.

Consider removing `synchronize` from the triggers and requiring explicit re-labeling for each review cycle, or verifying that the action does not check out untrusted code.
- [SUGGESTION] line 29: Loose substring match on `/review` comment trigger
  `contains(github.event.comment.body, '/review')` matches `/review` as a substring anywhere in the comment. Comments like "please don't /review this yet" or URLs containing `/review` will trigger the workflow. While the collaborator-association gate limits who can trigger it, unintentional triggers still waste CI resources and may post unwanted review comments.

Using `startsWith()` would provide a more precise match. Note that `startsWith` trims leading whitespace in some GitHub expression contexts, so `/review` on its own line at the start of a comment would still work.

Comment on lines +31 to +34
- uses: lklimek/claudius-review-action@main
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
Copy link
Collaborator

Choose a reason for hiding this comment

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

🔴 Blocking: Action pinned to mutable branch, not commit SHA

lklimek/claudius-review-action@main references a mutable branch. This action receives CLAUDE_CODE_OAUTH_TOKEN and GITHUB_TOKEN and runs in a pull_request_target context, which grants access to base-repo secrets even for fork PRs. If the upstream action repository is compromised or force-pushed, an attacker gains access to these credentials and can write to any PR in this repo.

GitHub's security hardening guide recommends pinning third-party actions to a full-length commit SHA. This is especially critical here because: (1) the action is from a personal account, not a verified org, (2) it runs in a pull_request_target context with elevated trust, and (3) it receives secrets. This repo already follows SHA-pinning in milestone.yml (actions/github-script@f28e40c7...), making @main an outlier.

Suggested change
- uses: lklimek/claudius-review-action@main
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- uses: lklimek/claudius-review-action@<full-40-char-commit-sha> # pin to audited commit

source: ['claude', 'codex']

🤖 Fix this with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `.github/workflows/claudius-review.yml`:
- [BLOCKING] lines 31-34: Action pinned to mutable branch, not commit SHA
  `lklimek/claudius-review-action@main` references a mutable branch. This action receives `CLAUDE_CODE_OAUTH_TOKEN` and `GITHUB_TOKEN` and runs in a `pull_request_target` context, which grants access to base-repo secrets even for fork PRs. If the upstream action repository is compromised or force-pushed, an attacker gains access to these credentials and can write to any PR in this repo.

GitHub's security hardening guide recommends pinning third-party actions to a full-length commit SHA. This is especially critical here because: (1) the action is from a personal account, not a verified org, (2) it runs in a `pull_request_target` context with elevated trust, and (3) it receives secrets. This repo already follows SHA-pinning in `milestone.yml` (`actions/github-script@f28e40c7...`), making `@main` an outlier.

Comment on lines +27 to +29
if: |
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'claudius-review') && github.event.pull_request.draft == false) ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/review') && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association))
Copy link
Collaborator

Choose a reason for hiding this comment

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

🟡 Suggestion: labeled trigger re-runs review when unrelated labels are added

The condition checks contains(github.event.pull_request.labels.*.name, 'claudius-review') for all pull_request_target events, without distinguishing between labeled and synchronize actions. When the labeled event fires, github.event.pull_request.labels contains all current labels on the PR, not just the newly added one. So if claudius-review was added earlier and someone later adds an unrelated label (e.g., bug), the labeled event fires, the condition is satisfied, and the review workflow runs again unnecessarily.

The fix is to check github.event.label.name == 'claudius-review' specifically for the labeled action, while keeping the contains() check for synchronize events.

Suggested change
if: |
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'claudius-review') && github.event.pull_request.draft == false) ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/review') && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association))
if: |
(github.event_name == 'pull_request_target' && github.event.pull_request.draft == false && (
(github.event.action == 'labeled' && github.event.label.name == 'claudius-review') ||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'claudius-review'))
)) ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/review') && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association))

source: ['codex']

🤖 Fix this with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `.github/workflows/claudius-review.yml`:
- [SUGGESTION] lines 27-29: `labeled` trigger re-runs review when unrelated labels are added
  The condition checks `contains(github.event.pull_request.labels.*.name, 'claudius-review')` for all `pull_request_target` events, without distinguishing between `labeled` and `synchronize` actions. When the `labeled` event fires, `github.event.pull_request.labels` contains *all* current labels on the PR, not just the newly added one. So if `claudius-review` was added earlier and someone later adds an unrelated label (e.g., `bug`), the `labeled` event fires, the condition is satisfied, and the review workflow runs again unnecessarily.

The fix is to check `github.event.label.name == 'claudius-review'` specifically for the `labeled` action, while keeping the `contains()` check for `synchronize` events.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claudius-review Trigger automated review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants