Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Claude Code Review

on:
pull_request:
types: [opened, synchronize]
# Optional: Only run on specific file changes
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"

jobs:
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Fix YAML lint nits: trailing spaces and extra blank line.

There are trailing spaces on several lines and an extra blank line at the end. Clean them up to keep CI lint quiet.

You can auto-fix with:

-# (remove trailing spaces on the noted lines and drop the extra blank line at EOF)

Or run: yamllint .github/workflows/claude-code-review.yml locally and apply its suggestions.

Also applies to: 27-27, 51-51, 56-56, 64-64, 67-67, 70-70, 73-73, 78-79


🏁 Script executed:

#!/bin/bash
# Verify formatting issues reported by yamllint
yamllint .github/workflows/claude-code-review.yml || true

Length of output: 1327


Fix YAML lint errors in .github/workflows/claude-code-review.yml

The workflow file currently fails yamllint with multiple errors. Please address the following to keep CI green:

• Add the document start marker

  • Line 1: missing --- at top of file
    • Replace non-boolean values with true/false
  • Line 3: truthy value should be one of [false, true]
    • Remove trailing spaces
  • Lines 20, 27, 51, 56, 64, 70, 73
    • Ensure lines do not exceed 80 characters
  • Line 40 (96 chars), 54 (115 chars), 61 (81 chars), 62 (84 chars), 67 (94 chars), 68 (150 chars), 69 (109 chars), 72 (90 chars)
    • Remove the extra blank line at end of file
  • Line 78: too many blank lines (empty‐lines)

You can locally verify and auto-fix many of these with:

yamllint .github/workflows/claude-code-review.yml

…then trim trailing spaces, wrap or shorten long lines, add --- at the top, and replace any non-boolean values accordingly.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 20-20: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
.github/workflows/claude-code-review.yml lines 1-78: fix yamllint issues by
adding a document start marker `---` at the top (line 1), replace any
non-boolean truthy values with explicit true/false (line 3), remove trailing
spaces on lines 20, 27, 51, 56, 64, 70, 73, wrap or shorten lines that exceed 80
characters (lines 40, 54, 61, 62, 67, 68, 69, 72) so they stay <=80 chars, and
remove the extra blank line at the end of file (line 78); run `yamllint
.github/workflows/claude-code-review.yml`, trim trailing whitespace, break long
strings into shorter lines or use YAML folded scalars where appropriate, and
ensure the file ends with a single newline.

runs-on: ubuntu-latest
Comment on lines +14 to +21

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Gate runs on forked PRs or document that forks won’t be auto-reviewed.

Secrets aren’t available to forked PRs on pull_request events, so this job will fail for external contributors. Either restrict execution to same-repo PRs or switch to a more complex pull_request_target pattern (with strict safety constraints).

Apply this diff to only run for same-repo PRs:

   claude-review:
-    # Optional: Filter by PR author
+    # Run only for PRs originating from this repository (secrets are unavailable to forks)
+    if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
+    # Optional: Filter by PR author

If you intend to support forks, I can propose a safe pull_request_target variant that avoids executing untrusted code while still reviewing diffs.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
runs-on: ubuntu-latest
claude-review:
# Run only for PRs originating from this repository (secrets are unavailable to forks)
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
runs-on: ubuntu-latest
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 20-20: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
.github/workflows/claude-code-review.yml lines 14-21: the job will run on forked
PRs where secrets are unavailable and will fail for external contributors;
update the workflow to only run for same-repo pull requests (e.g., add an
if-condition that checks the PR is not from a fork or that
github.event.pull_request.head.repo.full_name == github.repository) or, if you
need fork support, switch to a safe pull_request_target pattern that explicitly
limits steps which use repo secrets and only runs untrusted code in a read-only
review sandbox; apply one of these changes so the job no longer attempts to use
secrets on forked PRs.

permissions:
contents: read
pull-requests: read
issues: read
id-token: write
Comment on lines +22 to +26

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Action cannot comment with read-only permissions; remove unnecessary id-token.

The job likely needs to create or update PR comments. With pull-requests: read and issues: read, it will be unable to post feedback. Also, id-token: write is unnecessary here and should be dropped to keep least privilege.

Apply this diff:

     permissions:
-      contents: read
-      pull-requests: read
-      issues: read
-      id-token: write
+      contents: read
+      pull-requests: write
+      issues: write
+      # id-token not required; remove to reduce privilege
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
permissions:
contents: read
pull-requests: write
issues: write
# id-token not required; remove to reduce privilege
🤖 Prompt for AI Agents
.github/workflows/claude-code-review.yml lines 22-26: the workflow currently
grants pull-requests: read and id-token: write which prevents the action from
posting PR comments and unnecessarily elevates privileges; change pull-requests
to write so the job can create/update PR comments and remove the id-token: write
entry entirely to follow least-privilege principles.


steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@beta
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

Comment on lines +34 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm secret name and required inputs match the action’s docs.

The input is claude_code_oauth_token. Ensure this is the expected input and your repository secret name matches exactly.

If the action accepts GITHUB_TOKEN for commenting, we can further reduce explicit secrets here.


🌐 Web query:

For anthropics/claude-code-action, what is the exact input name for the required token/secret and what scopes are needed? Is it `claude_code_oauth_token`?

💡 Result:

The required input name for the secret/token in anthropics/claude-code-action is api_key, and the secret itself should be set as ANTHROPIC_API_KEY in your GitHub repository or organization secrets[10][4]. The value expected is your raw Anthropic API key, typically beginning with sk-ant-api... and not prefixed with "Bearer"[2][5].

Input/Secret Name:

  • The GitHub Actions input is:
    api_key: ${{ secrets.ANTHROPIC_API_KEY }}[10]
  • The secret must be named ANTHROPIC_API_KEY in your GitHub secrets[4]

There is no reference in any documentation or SDK code to a secret named claude_code_oauth_token for this action. That is not a valid or required input name for the main Claude Code GitHub Action[2][4][10].

Required OAuth Scopes:

  • The API key itself, created in the Anthropic Console, only requires that it is a valid Claude Code API key, which means your Anthropic account must have sufficient billing/setup and the key must not be expired[1][7].
  • No additional custom OAuth scopes must be set on the Anthropic side—just ensure the API key has access to Claude Code models[3][5].
  • In GitHub, to use repository secrets in Actions, you need read access to secrets and standard "actions" workflow permissions.

Summary Table

Input to Action Value
api_key: ${{ secrets.ANTHROPIC_API_KEY }}
Secret in GitHub ANTHROPIC_API_KEY
Secret value Anthropic API Key raw string (not bearer)
Not used/recognized claude_code_oauth_token
Required Anthropic scopes Access to Claude Code APIs (API key)

Relevant documentation supports only ANTHROPIC_API_KEY as the input name and secret for the action[10][4][7].

Citations:


Update Claude Code Action Input and Secret Name

The anthropics/claude-code-action expects its OAuth key under the input name api_key and the GitHub secret must be named ANTHROPIC_API_KEY. The currently used claude_code_oauth_token input is not recognized by the action and will cause the workflow to fail.

Please update your workflow snippet as follows:

   - name: Run Claude Code Review
     id: claude-review
     uses: anthropics/claude-code-action@beta
     with:
-      claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
+      api_key:               ${{ secrets.ANTHROPIC_API_KEY }}

• Rename your repository (or organization) secret from CLAUDE_CODE_OAUTH_TOKEN to ANTHROPIC_API_KEY.
• Ensure the secret value is your raw Anthropic API key (e.g. sk-ant-api…) without any Bearer prefix.

Let me know if you need further assistance in adjusting scopes or permissions.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@beta
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@beta
with:
api_key: ${{ secrets.ANTHROPIC_API_KEY }}
🤖 Prompt for AI Agents
In .github/workflows/claude-code-review.yml around lines 34 to 39, the workflow
uses the wrong input name and secret for the anthropics action; change the
action input from claude_code_oauth_token to api_key and update the referenced
secret from CLAUDE_CODE_OAUTH_TOKEN to ANTHROPIC_API_KEY, then create/rename the
repository secret ANTHROPIC_API_KEY to contain the raw Anthropic API key (no
"Bearer" prefix).

# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1)
# model: "claude-opus-4-1-20250805"

# Direct prompt for automated review (no @claude mention needed)
direct_prompt: |
Please review this pull request and provide feedback on:
- Code quality and best practices
- Potential bugs or issues
- Performance considerations
- Security concerns
- Test coverage

Be constructive and helpful in your feedback.

# Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
# use_sticky_comment: true

# Optional: Customize review based on file types
# direct_prompt: |
# Review this PR focusing on:
# - For TypeScript files: Type safety and proper interface usage
# - For API endpoints: Security, input validation, and error handling
# - For React components: Performance, accessibility, and best practices
# - For tests: Coverage, edge cases, and test quality

# Optional: Different prompts for different authors
# direct_prompt: |
# ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
# 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
# 'Please provide a thorough code review focusing on our coding standards and best practices.' }}

# Optional: Add specific tools for running tests or linting
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"

# Optional: Skip review for certain conditions
# if: |
# !contains(github.event.pull_request.title, '[skip-review]') &&
# !contains(github.event.pull_request.title, '[WIP]')

64 changes: 64 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
Comment on lines +15 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Anyone can currently trigger runs by typing @claude; enforce “writers only.”

The PR description says only users with write access can trigger this workflow, but the condition doesn’t enforce that. Add association checks and guard against null bodies.

Apply this diff:

-    if: |
-      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
-      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
-      (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
-      (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
+    if: |
+      (
+        github.event_name == 'issue_comment' &&
+        (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR') &&
+        github.event.comment.body != '' &&
+        contains(github.event.comment.body, '@claude')
+      ) ||
+      (
+        github.event_name == 'pull_request_review_comment' &&
+        (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR') &&
+        github.event.comment.body != '' &&
+        contains(github.event.comment.body, '@claude')
+      ) ||
+      (
+        github.event_name == 'pull_request_review' &&
+        (github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'COLLABORATOR') &&
+        github.event.review.body != '' &&
+        contains(github.event.review.body, '@claude')
+      ) ||
+      (
+        github.event_name == 'issues' &&
+        (github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'COLLABORATOR') &&
+        (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))
+      )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
if: |
(
github.event_name == 'issue_comment' &&
(github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR') &&
github.event.comment.body != '' &&
contains(github.event.comment.body, '@claude')
) ||
(
github.event_name == 'pull_request_review_comment' &&
(github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR') &&
github.event.comment.body != '' &&
contains(github.event.comment.body, '@claude')
) ||
(
github.event_name == 'pull_request_review' &&
(github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'COLLABORATOR') &&
github.event.review.body != '' &&
contains(github.event.review.body, '@claude')
) ||
(
github.event_name == 'issues' &&
(github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'COLLABORATOR') &&
(contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))
)
runs-on: ubuntu-latest
🤖 Prompt for AI Agents
.github/workflows/claude.yml lines 15-20: the workflow condition currently
triggers on any '@claude' mention and doesn't check the author's repository
association or protect against null comment/review/issue bodies; update the
composite if to require the appropriate author_association for each event (e.g.,
comment.author_association for issue_comment and pull_request_review_comment,
review.author_association or review.user.author_association for
pull_request_review, and issue.user_association for issues) to be a trusted
value like 'OWNER'|'MEMBER'|'COLLABORATOR' (or equivalent org-level roles you
require), and also guard each contains(...) check with a null-safe test (only
call contains when the body/title exists) so the workflow only runs when a
writer-level actor actually mentioned '@claude' and no null bodies cause errors.

permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
Comment on lines +21 to +27

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Grant minimal write permissions for comments; remove id-token.

To post replies or status back, the job needs pull-requests: write and issues: write. id-token: write is not required here.

Apply this diff:

     permissions:
-      contents: read
-      pull-requests: read
-      issues: read
-      id-token: write
-      actions: read # Required for Claude to read CI results on PRs
+      contents: read
+      pull-requests: write
+      issues: write
+      actions: read # Required for Claude to read CI results on PRs
+      # id-token not required; remove to reduce privilege
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
permissions:
contents: read
pull-requests: write
issues: write
actions: read # Required for Claude to read CI results on PRs
# id-token not required; remove to reduce privilege
steps:
🤖 Prompt for AI Agents
In .github/workflows/claude.yml around lines 21 to 27, the workflow currently
grants id-token: write and only read access for pull-requests and issues; update
permissions to remove id-token: write and grant minimal write permissions by
changing pull-requests: read to pull-requests: write and issues: read to issues:
write so the job can post replies/status without unnecessary id-token scope.

- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Fix YAML lint nits: trailing spaces and the extra blank line.

Remove trailing spaces on the noted lines and the extra blank line at the end.

You can verify locally with:

Also applies to: 45-45, 48-48, 51-51, 54-54, 60-60, 64-65


🏁 Script executed:

#!/bin/bash
yamllint .github/workflows/claude.yml || true

Length of output: 1267


Address all yamllint violations in .github/workflows/claude.yml

When running yamllint .github/workflows/claude.yml, the following issues were reported:

• Line 1: warning – missing document start (---)
• Line 3: warning – truthy value should be one of [false, true]
• Lines 16, 17, 18, 19, 39, 43, 53, 55: error – line too long (> 80 characters)
• Line 26: warning – too few spaces before comment (expected 2)
• Lines 42, 45, 48, 51, 54, 60: error – trailing spaces
• Line 64: error – too many blank lines at end of file

Please:

  • Add --- at the top of the file.
  • Replace any truthy values (e.g. yes, on) with true or false.
  • Wrap or shorten long lines to ≤ 80 characters.
  • Ensure comments have at least two spaces before #.
  • Remove all trailing spaces on the noted lines.
  • Delete the extra blank line at the end of the file.

You can re-verify locally with:

yamllint .github/workflows/claude.yml || true
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 42-42: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
In .github/workflows/claude.yml around lines 1-64: add a YAML document start
`---` at the top (line 1), replace any non-boolean truthy values like `yes`/`on`
with `true` or `false` (line 3), wrap or shorten lines exceeding 80 characters
(lines 16–19, 39, 43, 53, 55) so each is <=80 chars, ensure comments have at
least two spaces before `#` (line 26), remove trailing whitespace on lines 42,
45, 48, 51, 54, 60, and delete the extra blank lines at EOF (line 64);
afterwards run `yamllint .github/workflows/claude.yml` to confirm all violations
are resolved.

# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1)
# model: "claude-opus-4-1-20250805"

# Optional: Customize the trigger phrase (default: @claude)
# trigger_phrase: "/claude"

# Optional: Trigger when specific user is assigned to an issue
# assignee_trigger: "claude-bot"

# Optional: Allow Claude to run specific commands
# allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"

# Optional: Add custom instructions for Claude to customize its behavior for your project
# custom_instructions: |
# Follow our coding standards
# Ensure all new code has tests
# Use TypeScript for new files

# Optional: Custom environment variables for Claude
# claude_env: |
# NODE_ENV: test

Loading