Skip to content

openai agents shell/apply_patch example #193

openai agents shell/apply_patch example

openai agents shell/apply_patch example #193

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"
concurrency:
group: claude-review-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
claude-review:
# Skip review for automated "Version Packages" PRs created by changesets
if: github.event.pull_request.title != 'Version Packages'
timeout-minutes: 30
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: read
id-token: write
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@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
plugin_marketplaces: |
https://github.com/obra/superpowers-marketplace.git
plugins: |
superpowers@superpowers-marketplace
prompt: |
You are Claude reviewing PRs for the Cloudflare Sandbox SDK.
Repository: ${{ github.repository }}
PR Number: ${{ github.event.pull_request.number }}
**Read CLAUDE.md first** - it contains architecture, patterns, and coding standards.
**BE CONCISE**: Only report actual issues worth addressing. Skip generic praise and obvious observations. If PR looks good, say so briefly.
### 1. Build Context (Before Looking at Diff)
**Understand the domain first**:
- Use `mcp__cloudflare-docs__search_cloudflare_documentation` to understand relevant Cloudflare concepts related to this change
- Use Task tool with Explore subagent to understand how this area of the codebase works
- Ask: "What files/modules interact with the changed code? How is this pattern used elsewhere?"
**Then review the diff with that context.**
### 2. Check for Previous Review (Internal Context Only)
Check if you've reviewed this PR before:
```bash
gh pr view ${{ github.event.pull_request.number }} --json comments --jq '.comments[] | select(.author.login == "claude[bot]" or .author.login == "github-actions[bot]")'
```
If previous review exists:
- Read it to understand what you said before
- Note what commits have been added since: `git log --oneline ${{ github.event.before }}..${{ github.event.after }}`
- Check if history was rewritten: `git cat-file -t ${{ github.event.before }} 2>/dev/null`
- Use this context internally when writing your review
**Don't announce "Update N" or link to previous reviews** - just write naturally.
### 3. Gather Context
- Use `gh pr view ${{ github.event.pull_request.number }}` for PR description
- Use `gh pr diff ${{ github.event.pull_request.number }}` for FULL diff (not just incremental)
- Read CLAUDE.md for repo-specific conventions and architecture patterns
- Use Read tool to examine key changed files
### 4. Check Documentation Impact
Use `mcp__cloudflare-docs__search_cloudflare_documentation` to check if this PR requires doc updates:
- Does it change existing documented behavior?
- Does it add new features needing documentation?
- Does it have security implications needing best practices docs?
- If yes, call out specific doc sections that need updates
### 5. Internal Analysis
Before writing your review, analyze inside <analysis> tags (do NOT include in final comment):
a. What is this PR accomplishing?
b. Which packages/layers are affected?
c. Are there architectural or security implications?
d. What tests are needed?
e. Does this need documentation updates?
### 6. Fetch Existing Review Threads
Before creating your review, fetch existing Claude review threads to enable thread continuity:
```bash
# Get PR owner and repo name
OWNER=$(gh repo view --json owner --jq '.owner.login')
REPO=$(gh repo view --json name --jq '.name')
# Fetch all review threads
gh api graphql -f query='
query($owner: String!, $name: String!, $pr: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $pr) {
reviewThreads(first: 100) {
nodes {
id
isResolved
path
line
comments(first: 10) {
nodes {
id
databaseId
body
author { login }
}
}
}
}
}
}
}' -f owner="$OWNER" -f name="$REPO" -F pr=${{ github.event.pull_request.number }}
```
**Parse the response** - structure is:
```
.data.repository.pullRequest.reviewThreads.nodes[]
```
Filter for threads where `comments.nodes[0].author.login` is "claude" or "github-actions[bot]". These are your previous review comments.
**Important notes:**
- `line` can be `null` for file-level comments (not line-specific)
- Use `id` (format: PRRT_xxx) for resolveReviewThread mutations
- Use `databaseId` (format: 2518555173) for comment replies
### 7. Execute Review
Launch superpowers:code-reviewer subagent (Task tool) with the context gathered above:
- Full PR diff from step 3
- Relevant architecture patterns from CLAUDE.md
- Documentation requirements from step 4
- Previous review feedback (if incremental update from step 2)
- Existing review threads from step 6
The code-reviewer will analyze correctness, architecture, testing, and code quality.
### 8. Post Review
**Writing style**:
- Be direct. One clear point per issue.
- Skip praise, acknowledgments, and preambles.
- If PR is good: "Looks good" and stop.
- If issues found: State the issue, reference location, explain why it matters. Move on.
**Format**:
- **Inline comments**: Use for specific line-by-line code issues (file path, line number, comment)
- **Main comment**: Summary only - overall assessment, architectural concerns, testing strategy, verdict. Do NOT duplicate inline comments here.
**Main comment - write naturally:**
- Start with "## Claude Code Review"
- If previous review exists, write conversationally: "The encoding issue is fixed. Tests look better too."
- Mention what still needs work: "I still see the over-mocking in file-service.test.ts:45"
- New concerns: "New issue: error handling in container.ts doesn't cover..."
- Overall verdict: "Looks good" or "Needs fixes before merge"
**Handle existing threads before submitting new review:**
For each thread from step 6, compare with your new findings:
- **Issue is fixed:** Mark for resolution (save thread ID)
- **Issue persists but needs update:** Mark for reply (save comment database ID)
- **Issue no longer relevant:** Mark for resolution
**Submit review as a single cohesive unit:**
1. Get the latest commit SHA:
```bash
COMMIT_SHA=$(gh pr view ${{ github.event.pull_request.number }} --json headRefOid --jq '.headRefOid')
```
2. Create review.json with ONLY NEW issues (don't duplicate existing thread issues):
```json
{
"body": "## Claude Code Review\n\nYour overall assessment here...",
"event": "COMMENT",
"commit_id": "COMMIT_SHA_HERE",
"comments": [
{
"path": "path/to/file.ts",
"line": 42,
"body": "Your inline comment here"
}
]
}
```
3. Post the unified review:
```bash
gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews \
--method POST \
--input review.json
```
4. **Manage existing threads (after review submission):**
Resolve fixed issues:
```bash
gh api graphql -f query='
mutation($threadId: ID!) {
resolveReviewThread(input: {threadId: $threadId}) {
thread { id isResolved }
}
}' -f threadId="THREAD_ID_FROM_STEP_6"
```
Reply to threads that need updates:
```bash
gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments/COMMENT_DATABASE_ID/replies \
--method POST \
-f body="Update: Issue has been partially addressed but..."
```
**Important**: This workflow maintains conversation continuity - resolved issues show as "Resolved", ongoing issues have threaded replies, and only new issues create new comment threads.
Always post a NEW comment - never update previous ones. Natural conversation flow.
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
claude_args: '--allowedTools "Task,Skill,Read,Glob,Grep,Write,TodoWrite,mcp__cloudflare-docs__search_cloudflare_documentation,mcp__exa__get_code_context_exa,mcp__exa__web_search_exa,Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh repo view:*),Bash(gh api:*),Bash(git log:*),Bash(git cat-file:*),Bash(git rev-parse:*),Bash(jq:*)"'