ci: use Claude App token for same-repo PRs, fallback for forks (#634)
This commit is contained in:
@@ -77,7 +77,10 @@ Mark task 3 as in_progress.
|
||||
|
||||
Check if CodeRabbit, Greptile, and Claude have posted or are generating reviews.
|
||||
|
||||
**Bot usernames:** `coderabbitai`, `greptile-apps[bot]`, `claude[bot]`
|
||||
**Bot usernames** (`gh pr view --json comments` uses GraphQL and returns `author.login` **without** the `[bot]` suffix; `gh api /.../reviews` and `/.../issues/<n>/comments` use REST and return `user.login` **with** the suffix — filters below use whichever form the invoked endpoint returns):
|
||||
- CodeRabbit: `coderabbitai[bot]`
|
||||
- Greptile: `greptile-apps[bot]`
|
||||
- Claude: `claude[bot]` on same-repo PRs (posts a real review with inline comments via the Claude GitHub App), or `github-actions[bot]` on fork PRs (posts findings as issue comments via `GITHUB_TOKEN`; identify by body markers — tracker starts with `**Claude finished `, findings comment starts with `## Code Review`).
|
||||
|
||||
**CodeRabbit — stop waiting if:**
|
||||
- A comment contains `<!-- rate limited by coderabbit.ai -->` — rate-limited, won't review.
|
||||
@@ -86,8 +89,9 @@ Check if CodeRabbit, Greptile, and Claude have posted or are generating reviews.
|
||||
**Greptile — stop waiting if:**
|
||||
- A review from `greptile-apps[bot]` exists (posts via the GitHub review API, not issue comments).
|
||||
|
||||
**Claude — stop waiting if:**
|
||||
- A review from `claude[bot]` exists (posts via the GitHub review API with inline review comments).
|
||||
**Claude — stop waiting if any of these holds:**
|
||||
- A review from `claude[bot]` exists (same-repo PR, App-authenticated path — has inline review comments).
|
||||
- An issue comment from `github-actions[bot]` whose body starts with `**Claude finished ` or `## Code Review` exists (fork PR, `GITHUB_TOKEN` fallback path — findings are issue comments, no GitHub Review object).
|
||||
- The `claude-review` check in `gh pr checks` has completed (regardless of conclusion).
|
||||
|
||||
**Keep polling if:**
|
||||
@@ -99,8 +103,10 @@ Poll every **30 seconds**, cap at **10 minutes**. Fetch both issue comments and
|
||||
gh pr view <number> --json comments --jq '.comments[] | select(.author.login == "coderabbitai") | {author: .author.login, body: .body}'
|
||||
# Greptile posts reviews (with inline review comments)
|
||||
gh api repos/:owner/:repo/pulls/<number>/reviews --jq '.[] | select(.user.login == "greptile-apps[bot]") | {user: .user.login, state: .state}'
|
||||
# Claude posts reviews (with inline review comments)
|
||||
# Claude — same-repo PRs: App-authenticated review + inline comments
|
||||
gh api repos/:owner/:repo/pulls/<number>/reviews --jq '.[] | select(.user.login == "claude[bot]") | {user: .user.login, state: .state}'
|
||||
# Claude — fork PRs: issue comments from github-actions[bot] (match by body marker)
|
||||
gh pr view <number> --json comments --jq '.comments[] | select(.author.login == "github-actions" and ((.body | startswith("**Claude finished ")) or (.body | startswith("## Code Review")))) | {author: .author.login, body_start: (.body[0:80])}'
|
||||
```
|
||||
|
||||
Mark task 3 as completed.
|
||||
|
||||
@@ -36,15 +36,42 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Run Claude Code Review
|
||||
id: claude-review
|
||||
- name: Run Claude Code Review (same-repo, App token for inline comments)
|
||||
id: claude-review-app
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
# No github_token: the action performs the OIDC -> installation-token
|
||||
# exchange via the Claude GitHub App, which authors comments as
|
||||
# claude[bot] and can post a real GitHub Review with inline threads.
|
||||
track_progress: true
|
||||
allowed_bots: "*"
|
||||
prompt: |
|
||||
REPO: ${{ github.repository }}
|
||||
PR NUMBER: ${{ github.event.pull_request.number }}
|
||||
|
||||
Follow the instructions in `.agents/skills/code-review/SKILL.md` to review this PR.
|
||||
The PR branch is already checked out in the current working directory.
|
||||
|
||||
Use `gh pr comment` for the findings report (step 4 output format).
|
||||
Use `mcp__github_inline_comment__create_inline_comment` (with `confirmed: true`) for inline findings.
|
||||
Only post GitHub comments - don't output review text as messages.
|
||||
|
||||
claude_args: |
|
||||
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
|
||||
|
||||
- name: Run Claude Code Review (fork fallback, GITHUB_TOKEN)
|
||||
id: claude-review-fork
|
||||
if: github.event.pull_request.head.repo.full_name != github.repository
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
# Skip the Claude GitHub App's OIDC -> installation-token exchange,
|
||||
# which 401s on pull_request_target from forks. GITHUB_TOKEN inherits
|
||||
# pull-requests: write from the permissions block above, which is
|
||||
# enough for the action to post review comments.
|
||||
# enough for the action to post review comments. Author will be
|
||||
# github-actions[bot] on this path.
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
track_progress: true
|
||||
allowed_bots: "*"
|
||||
|
||||
Reference in New Issue
Block a user