Skip to content

Commit ab1a535

Browse files
authored
Merge pull request #1718 from codeflash-ai/fix-claude-workflow
fix: rewrite Claude Code PR review prompt
2 parents aed7161 + 29d0d2c commit ab1a535

1 file changed

Lines changed: 84 additions & 100 deletions

File tree

.github/workflows/claude.yml

Lines changed: 84 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -56,132 +56,116 @@ jobs:
5656
use_sticky_comment: true
5757
allowed_bots: "claude[bot],codeflash-ai[bot]"
5858
prompt: |
59-
REPO: ${{ github.repository }}
60-
PR NUMBER: ${{ github.event.pull_request.number }}
61-
EVENT: ${{ github.event.action }}
59+
<context>
60+
repo: ${{ github.repository }}
61+
pr_number: ${{ github.event.pull_request.number }}
62+
event: ${{ github.event.action }}
63+
is_re_review: ${{ github.event.action == 'synchronize' }}
64+
</context>
6265
63-
## STEP 1: Run prek and mypy checks, fix issues
66+
<commitment>
67+
Execute these steps in order. If a step has no work, state that and continue to the next step.
68+
Post all review findings in a single summary comment only — never as inline PR review comments.
69+
</commitment>
6470
65-
First, run these checks on files changed in this PR:
66-
1. `uv run prek run --from-ref origin/main` - linting/formatting issues
67-
2. `uv run mypy <changed_files>` - type checking issues
71+
<step name="lint_and_typecheck">
72+
Run checks on files changed in this PR and auto-fix what you can.
6873
69-
If there are prek issues:
70-
- For SAFE auto-fixable issues (formatting, import sorting, trailing whitespace, etc.), run `uv run prek run --from-ref origin/main` again to auto-fix them
71-
- For issues that prek cannot auto-fix, do NOT attempt to fix them manually — report them as remaining issues in your summary
74+
1. Run `uv run prek run --from-ref origin/main` to check linting/formatting.
75+
If there are auto-fixable issues, run it again to fix them.
76+
Report any issues prek cannot auto-fix in your summary.
7277
73-
If there are mypy issues:
74-
- Fix type annotation issues (missing return types, Optional/None unions, import errors for type hints, incorrect types)
75-
- Do NOT add `type: ignore` comments - always fix the root cause
78+
2. Run `uv run mypy <changed_files>` to check types.
79+
Fix type annotation issues (missing return types, Optional unions, import errors).
80+
Always fix the root cause instead of adding `type: ignore` comments.
81+
Leave alone: type errors requiring logic changes, complex generics, anything changing runtime behavior.
7682
77-
After fixing issues:
78-
- Stage the fixed files with `git add`
79-
- Commit with message "style: auto-fix linting issues" or "fix: resolve mypy type errors" as appropriate
80-
- Push the changes with `git push`
83+
3. After fixes: stage with `git add`, commit ("style: auto-fix linting issues" or "fix: resolve mypy type errors"), push.
8184
82-
IMPORTANT - Verification after fixing:
83-
- After committing fixes, run `uv run prek run --from-ref origin/main` ONE MORE TIME to verify all issues are resolved
84-
- If errors remain, either fix them or report them honestly as unfixed in your summary
85-
- NEVER claim issues are fixed without verifying. If you cannot fix an issue, say so
85+
4. Verify by running `uv run prek run --from-ref origin/main` one more time. Report honestly if issues remain.
86+
</step>
8687
87-
Do NOT attempt to fix:
88-
- Type errors that require logic changes or refactoring
89-
- Complex generic type issues
90-
- Anything that could change runtime behavior
88+
<step name="resolve_stale_threads">
89+
Before reviewing, resolve any stale review threads from previous runs.
9190
92-
## STEP 2: Review the PR
91+
1. Fetch unresolved threads you created:
92+
`gh api graphql -f query='{ repository(owner: "${{ github.repository_owner }}", name: "${{ github.event.repository.name }}") { pullRequest(number: ${{ github.event.pull_request.number }}) { reviewThreads(first: 100) { nodes { id isResolved path comments(first: 1) { nodes { body author { login } } } } } } } }' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | select(.comments.nodes[0].author.login == "claude") | {id: .id, path: .path, body: .comments.nodes[0].body}'`
9393
94-
${{ github.event.action == 'synchronize' && 'This is a RE-REVIEW after new commits. First, get the list of changed files in this latest push using `gh pr diff`. Review ONLY the changed files. Check ALL existing review comments and resolve ones that are now fixed.' || 'This is the INITIAL REVIEW.' }}
94+
2. For each unresolved thread:
95+
a. Read the file at that path to check if the issue still exists
96+
b. If fixed → resolve it: `gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: "<THREAD_ID>"}) { thread { isResolved } } }'`
97+
c. If still present → leave it
9598
96-
Review this PR focusing ONLY on:
97-
1. Critical bugs or logic errors
99+
Read the actual code before deciding. If there are no unresolved threads, skip to the next step.
100+
</step>
101+
102+
<step name="review">
103+
Review the diff (`gh pr diff ${{ github.event.pull_request.number }}`) for:
104+
1. Bugs that will crash at runtime
98105
2. Security vulnerabilities
99106
3. Breaking API changes
100-
4. Test failures (methods with typos that wont run)
101-
5. Stale documentation — if files or directories were moved, renamed, or deleted, check that `.claude/rules/`, `CLAUDE.md`, and `AGENTS.md` don't reference paths that no longer exist
102-
6. New language support — if new language modules are added under `languages/`, check that `.github/workflows/duplicate-code-detector.yml` includes the new language in its file filters, search patterns, and cross-module checks
103-
104-
IMPORTANT:
105-
- First check existing review comments using `gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments`. For each existing comment, check if the issue still exists in the current code.
106-
- If an issue is fixed, use `gh api --method PATCH repos/${{ github.repository }}/pulls/comments/COMMENT_ID -f body="✅ Fixed in latest commit"` to resolve it.
107-
- Only create NEW inline comments for HIGH-PRIORITY issues found in changed files.
108-
- Limit to 5-7 NEW comments maximum per review.
109-
- Use CLAUDE.md for project-specific guidance.
110-
- Use `mcp__github_inline_comment__create_inline_comment` sparingly for critical code issues only.
111107
112-
## STEP 3: Coverage analysis
108+
Ignore style issues, type hints, and log message wording.
109+
Record findings for the summary comment. Refer to CLAUDE.md for project conventions.
110+
</step>
113111
112+
<step name="coverage">
114113
Analyze test coverage for changed files:
115114
116-
1. Get the list of Python files changed in this PR (excluding tests):
117-
`git diff --name-only origin/main...HEAD -- '*.py' | grep -v test`
118-
119-
2. Run tests with coverage on the PR branch:
120-
`uv run coverage run -m pytest tests/ -q --tb=no`
121-
`uv run coverage json -o coverage-pr.json`
122-
123-
3. Get coverage for changed files only:
124-
`uv run coverage report --include="<changed_files_comma_separated>"`
125-
126-
4. Compare with main branch coverage:
127-
- Checkout main: `git checkout origin/main`
128-
- Run coverage: `uv run coverage run -m pytest tests/ -q --tb=no && uv run coverage json -o coverage-main.json`
129-
- Checkout back: `git checkout -`
115+
1. Get changed Python files (excluding tests): `git diff --name-only origin/main...HEAD -- '*.py' | grep -v test`
116+
2. Run coverage on PR branch: `uv run coverage run -m pytest tests/ -q --tb=no` then `uv run coverage json -o coverage-pr.json`
117+
3. Get per-file coverage: `uv run coverage report --include="<changed_files>"`
118+
4. Compare with main: checkout main, run coverage, checkout back
119+
5. Flag: new files below 75%, decreased coverage, untested changed lines
120+
</step>
130121
131-
5. Analyze the diff to identify:
132-
- NEW FILES: Files that don't exist on main (require good test coverage)
133-
- MODIFIED FILES: Files with changes (changes must be covered by tests)
122+
<step name="summary_comment">
123+
Post exactly one summary comment containing all results from previous steps.
134124
135-
6. Report in PR comment with a markdown table:
136-
- Coverage % for each changed file (PR vs main)
137-
- Overall coverage change
138-
- For NEW files: Flag if coverage is below 75%
139-
- For MODIFIED files: Flag if the changed lines are not covered by tests
140-
- Flag if overall coverage decreased
141-
142-
Coverage requirements:
143-
- New implementations/files: Must have ≥75% test coverage
144-
- Modified code: Changed lines should be exercised by existing or new tests
145-
- No coverage regressions: Overall coverage should not decrease
146-
147-
## STEP 4: Post ONE consolidated summary comment
148-
149-
CRITICAL: You must post exactly ONE summary comment containing ALL results (pre-commit, review, coverage).
150-
DO NOT post multiple separate comments. Use this format:
125+
To ensure one comment: find an existing claude[bot] comment and update it, or create one if none exists.
126+
Delete any duplicate claude[bot] comments.
151127
152128
```
153-
## PR Review Summary
129+
gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments --jq '.[] | select(.user.login == "claude[bot]") | .id' | head -1
130+
```
154131
132+
Format:
133+
## PR Review Summary
155134
### Prek Checks
156-
[status and any fixes made]
157-
158135
### Code Review
159-
[critical issues found, if any]
160-
161136
### Test Coverage
162-
[coverage table and analysis]
163-
164137
---
165138
*Last updated: <timestamp>*
166-
```
167-
168-
To ensure only ONE comment exists:
169-
1. Find existing claude[bot] comment: `gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments --jq '.[] | select(.user.login == "claude[bot]") | .id' | head -1`
170-
2. If found, UPDATE it: `gh api --method PATCH repos/${{ github.repository }}/issues/comments/<ID> -f body="<content>"`
171-
3. If not found, CREATE: `gh pr comment ${{ github.event.pull_request.number }} --body "<content>"`
172-
4. Delete any OTHER claude[bot] comments to clean up duplicates: `gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments --jq '.[] | select(.user.login == "claude[bot]") | .id' | tail -n +2 | xargs -I {} gh api --method DELETE repos/${{ github.repository }}/issues/comments/{}`
173-
174-
## STEP 5: Merge pending codeflash optimization PRs
175-
176-
Check for open optimization PRs from codeflash and merge if CI passes:
177-
178-
1. List open PRs from codeflash bot:
179-
`gh pr list --author "codeflash-ai[bot]" --state open --json number,title,headRefName`
180-
181-
2. For each optimization PR:
182-
- Check if CI is passing: `gh pr checks <number>`
183-
- If all checks pass, merge it: `gh pr merge <number> --squash --delete-branch`
184-
claude_args: '--model us.anthropic.claude-opus-4-6-v1 --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*),Bash(gh pr checks:*),Bash(gh pr merge:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh api:*),Bash(uv run prek *),Bash(uv run mypy *),Bash(uv run coverage *),Bash(uv run pytest *),Bash(git status*),Bash(git add *),Bash(git commit *),Bash(git push*),Bash(git diff *),Bash(git checkout *),Read,Glob,Grep,Edit"'
139+
</step>
140+
141+
<step name="simplify">
142+
Run /simplify to review recently changed code for reuse, quality, and efficiency opportunities.
143+
If improvements are found, commit with "refactor: simplify <description>" and push.
144+
Only make behavior-preserving changes.
145+
</step>
146+
147+
<step name="merge_optimization_prs">
148+
Check for open PRs from codeflash-ai[bot]:
149+
`gh pr list --author "codeflash-ai[bot]" --state open --json number,title,headRefName,createdAt,mergeable`
150+
151+
For each PR:
152+
- If CI passes and the PR is mergeable → merge with `--squash --delete-branch`
153+
- Close the PR as stale if ANY of these apply:
154+
- Older than 7 days
155+
- Has merge conflicts (mergeable state is "CONFLICTING")
156+
- CI is failing
157+
- The optimized function no longer exists in the target file (check the diff)
158+
Close with: `gh pr close <number> --comment "Closing stale optimization PR." --delete-branch`
159+
</step>
160+
161+
<verification>
162+
Before finishing, confirm:
163+
- All steps were attempted (even if some had no work)
164+
- Stale review threads were checked and resolved where appropriate
165+
- All findings are in a single summary comment (no inline review comments were created)
166+
- If fixes were made, they were verified with prek
167+
</verification>
168+
claude_args: '--model us.anthropic.claude-opus-4-6-v1 --allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*),Bash(gh pr checks:*),Bash(gh pr merge:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh api:*),Bash(uv run prek *),Bash(uv run mypy *),Bash(uv run coverage *),Bash(uv run pytest *),Bash(git status*),Bash(git add *),Bash(git commit *),Bash(git push*),Bash(git diff *),Bash(git checkout *),Read,Glob,Grep,Edit,Skill"'
185169
additional_permissions: |
186170
actions: read
187171

0 commit comments

Comments
 (0)