Skip to content
Merged
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
66 changes: 66 additions & 0 deletions .github/workflows/claude-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Claude Comment Response

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]

permissions:
contents: read
pull-requests: write
issues: write
id-token: write
actions: read

concurrency:
group: claude-comment-${{ github.event.issue.number || github.event.pull_request.number }}
cancel-in-progress: false

jobs:
respond:
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[Medium] 缺少 concurrency 控制

pr-review.ymlconcurrency: cancel-in-progress: true,但 claude-comment.yml 没有。如果有人快速发多条 @claude 评论,会同时触发多个 action 实例,可能导致:

  • 重复回复
  • 并发超出 API budget
  • 竞争写同一个 PR comment

建议加上:

concurrency:
  group: claude-comment-${{ github.event.issue.number || github.event.pull_request.number }}
  cancel-in-progress: true

或者如果希望每条 @claude 评论都得到回复(不取消),至少加 cancel-in-progress: false 做队列化。

if: |
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[Info] issue_comment 事件在 fork PR 上的行为

issue_comment 事件的 GITHUB_TOKEN 权限由 base repo 决定(不是 fork),所以 fork PR 的评论也能正常触发。但 actions/checkout@v4 默认 checkout 的是 base repo 的代码,不是 fork 的 PR 分支。

对于 fork PR 的 @claude 请求,Claude 读到的代码可能不包含 PR 的变更。如果需要支持 fork PR,checkout step 需要改为:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
    ref: ${{ github.event.pull_request.head.sha }}

不过 claude-code-action@v1 可能内部已处理此问题,如果只在自有仓库使用可以忽略。

(
github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@claude') &&
github.event.issue.pull_request
) ||
(
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')
)
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
trigger_phrase: "@claude"
track_progress: true
claude_args: |
--model opus
--max-budget-usd 10
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr checks:*),Bash(git log:*),Bash(git blame:*),Bash(git diff:*),Read,Glob,Grep"
prompt: |
REPO: ${{ github.repository }}

You are a helpful AI assistant for this TypeScript/Node.js project.
Read CLAUDE.md first to understand the project architecture and conventions.

When responding:
1. Always read the relevant source files to understand full context before answering.
2. Use `git blame` and `git log` to understand change history when relevant.
3. Provide concrete code examples when suggesting changes.
4. Use `mcp__github_inline_comment__create_inline_comment` for code-specific feedback.
5. Verify issues exist by reading actual code — never speculate.
6. Explain reasoning behind suggestions.
82 changes: 82 additions & 0 deletions .github/workflows/pr-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Claude PR Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]

permissions:
contents: read
pull-requests: write
issues: write
id-token: write
actions: read

concurrency:
group: claude-review-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
review:
if: ${{ !github.event.pull_request.draft }}
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
track_progress: true
claude_args: |
--model opus
--max-budget-usd 10
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr checks:*),Bash(git log:*),Bash(git blame:*),Bash(git diff:*),Read,Glob,Grep"
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[Info] allowedTools 白名单完整性

当前白名单:

mcp__github_inline_comment__create_inline_comment
Bash(gh pr comment:*)
Bash(gh pr diff:*)
Bash(gh pr view:*)
Bash(gh pr checks:*)
Bash(git log:*)
Bash(git blame:*)
Bash(git diff:*)
Read, Glob, Grep

看起来很完整。几个观察:

  • Write / Edit 未列入,意味着 Claude 不能修改代码文件(只能 review,不能 auto-fix)。这是故意的且合理的——review bot 不应该修改代码。
  • Bash(git show:*) 可能会用到(查看特定 commit 内容),但 Read + git diff 基本可以覆盖。
  • Bash(gh api:*) 未列入,限制了 Claude 对 GitHub API 的访问范围。这是好的安全限制。

prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}

You are a senior code reviewer. Your goal is to find real, actionable issues — not to generate noise.

## Setup
1. Read CLAUDE.md to understand the project architecture and conventions.
2. Run `gh pr diff ${{ github.event.pull_request.number }}` to get the full diff.
3. Run `gh pr view ${{ github.event.pull_request.number }}` to understand the PR intent.

## Review Process
For EACH changed file in the diff:
1. Read the FULL source file (not just the diff) to understand context.
2. Use `git blame` on suspicious lines to understand the change history.
3. Trace function calls to verify correctness across module boundaries.

## What to Look For
- **Bugs**: Logic errors, off-by-one, null/undefined access, race conditions, unhandled promise rejections
- **Security**: Injection risks (command, SQL, XSS), secret exposure, unsafe permissions, missing input validation
- **Architecture**: Does the change follow patterns in CLAUDE.md? ESM imports with .js extensions? Proper singleton usage?
- **TypeScript**: Unsafe `any` types, incorrect generics, missing error types, async/await pitfalls
- **Resource leaks**: Unclosed connections, missing event listener cleanup, timer leaks

## Confidence Scoring
For each issue, assign a confidence score (0-100):
- 90-100: Certain this is a real bug or security issue
- 75-89: Highly confident, likely a real problem
- 50-74: Moderate confidence, worth mentioning
- Below 50: Do NOT report — too likely to be a false positive

Only report issues with confidence ≥ 75.

## False Positive Filters — Do NOT report:
- Pre-existing issues not introduced in this PR
- Style preferences or nitpicks
- Issues that linters/formatters will catch
- Missing comments on self-explanatory code
- Hypothetical future problems
- Code that "could be improved" but works correctly

## Output Format
- Use `mcp__github_inline_comment__create_inline_comment` to post comments directly on the relevant code lines.
- Post a summary comment via `gh pr comment` with:
- One-line verdict: ✅ Approved / ⚠️ Issues Found
- If issues found: bulleted list with severity (🔴 critical / 🟡 warning) and confidence score
- Brief overall assessment of the PR quality
Loading