fix/e2e runtime java #1202
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Claude Code | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, ready_for_review, reopened] | |
| issue_comment: | |
| types: [created] | |
| pull_request_review_comment: | |
| types: [created] | |
| issues: | |
| types: [opened, assigned] | |
| pull_request_review: | |
| types: [submitted] | |
| jobs: | |
| # Automatic PR review (can fix linting issues and push) | |
| # Blocked for fork PRs to prevent malicious code execution | |
| pr-review: | |
| if: | | |
| github.event_name == 'pull_request' && | |
| github.actor != 'claude[bot]' && | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: read | |
| id-token: write | |
| actions: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.pull_request.head.ref }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v6 | |
| - name: Install dependencies | |
| run: | | |
| uv venv --seed | |
| uv sync | |
| - name: Run Claude Code | |
| id: claude | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| use_foundry: "true" | |
| use_sticky_comment: true | |
| allowed_bots: "claude[bot],codeflash-ai[bot]" | |
| prompt: | | |
| REPO: ${{ github.repository }} | |
| PR NUMBER: ${{ github.event.pull_request.number }} | |
| EVENT: ${{ github.event.action }} | |
| ## STEP 1: Run prek and mypy checks, fix issues | |
| First, run these checks on files changed in this PR: | |
| 1. `uv run prek run --from-ref origin/main` - linting/formatting issues | |
| 2. `uv run mypy <changed_files>` - type checking issues | |
| If there are prek issues: | |
| - 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 | |
| - For issues that prek cannot auto-fix, do NOT attempt to fix them manually — report them as remaining issues in your summary | |
| If there are mypy issues: | |
| - Fix type annotation issues (missing return types, Optional/None unions, import errors for type hints, incorrect types) | |
| - Do NOT add `type: ignore` comments - always fix the root cause | |
| After fixing issues: | |
| - Stage the fixed files with `git add` | |
| - Commit with message "style: auto-fix linting issues" or "fix: resolve mypy type errors" as appropriate | |
| - Push the changes with `git push` | |
| IMPORTANT - Verification after fixing: | |
| - After committing fixes, run `uv run prek run --from-ref origin/main` ONE MORE TIME to verify all issues are resolved | |
| - If errors remain, either fix them or report them honestly as unfixed in your summary | |
| - NEVER claim issues are fixed without verifying. If you cannot fix an issue, say so | |
| Do NOT attempt to fix: | |
| - Type errors that require logic changes or refactoring | |
| - Complex generic type issues | |
| - Anything that could change runtime behavior | |
| ## STEP 2: Review the PR | |
| ${{ 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.' }} | |
| Review this PR focusing ONLY on: | |
| 1. Critical bugs or logic errors | |
| 2. Security vulnerabilities | |
| 3. Breaking API changes | |
| 4. Test failures (methods with typos that wont run) | |
| IMPORTANT: | |
| - 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. | |
| - 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. | |
| - Only create NEW inline comments for HIGH-PRIORITY issues found in changed files. | |
| - Limit to 5-7 NEW comments maximum per review. | |
| - Use CLAUDE.md for project-specific guidance. | |
| - Use `mcp__github_inline_comment__create_inline_comment` sparingly for critical code issues only. | |
| ## STEP 3: Coverage analysis | |
| Analyze test coverage for changed files: | |
| 1. Get the list of Python files changed in this PR (excluding tests): | |
| `git diff --name-only origin/main...HEAD -- '*.py' | grep -v test` | |
| 2. Run tests with coverage on the PR branch: | |
| `uv run coverage run -m pytest tests/ -q --tb=no` | |
| `uv run coverage json -o coverage-pr.json` | |
| 3. Get coverage for changed files only: | |
| `uv run coverage report --include="<changed_files_comma_separated>"` | |
| 4. Compare with main branch coverage: | |
| - Checkout main: `git checkout origin/main` | |
| - Run coverage: `uv run coverage run -m pytest tests/ -q --tb=no && uv run coverage json -o coverage-main.json` | |
| - Checkout back: `git checkout -` | |
| 5. Analyze the diff to identify: | |
| - NEW FILES: Files that don't exist on main (require good test coverage) | |
| - MODIFIED FILES: Files with changes (changes must be covered by tests) | |
| 6. Report in PR comment with a markdown table: | |
| - Coverage % for each changed file (PR vs main) | |
| - Overall coverage change | |
| - For NEW files: Flag if coverage is below 75% | |
| - For MODIFIED files: Flag if the changed lines are not covered by tests | |
| - Flag if overall coverage decreased | |
| Coverage requirements: | |
| - New implementations/files: Must have ≥75% test coverage | |
| - Modified code: Changed lines should be exercised by existing or new tests | |
| - No coverage regressions: Overall coverage should not decrease | |
| ## STEP 4: Post ONE consolidated summary comment | |
| CRITICAL: You must post exactly ONE summary comment containing ALL results (pre-commit, review, coverage). | |
| DO NOT post multiple separate comments. Use this format: | |
| ``` | |
| ## PR Review Summary | |
| ### Prek Checks | |
| [status and any fixes made] | |
| ### Code Review | |
| [critical issues found, if any] | |
| ### Test Coverage | |
| [coverage table and analysis] | |
| --- | |
| *Last updated: <timestamp>* | |
| ``` | |
| To ensure only ONE comment exists: | |
| 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` | |
| 2. If found, UPDATE it: `gh api --method PATCH repos/${{ github.repository }}/issues/comments/<ID> -f body="<content>"` | |
| 3. If not found, CREATE: `gh pr comment ${{ github.event.pull_request.number }} --body "<content>"` | |
| 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/{}` | |
| ## STEP 5: Merge pending codeflash optimization PRs | |
| Check for open optimization PRs from codeflash and merge if CI passes: | |
| 1. List open PRs from codeflash bot: | |
| `gh pr list --author "codeflash-ai[bot]" --state open --json number,title,headRefName` | |
| 2. For each optimization PR: | |
| - Check if CI is passing: `gh pr checks <number>` | |
| - If all checks pass, merge it: `gh pr merge <number> --squash --delete-branch` | |
| claude_args: '--model claude-opus-4-6 --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"' | |
| additional_permissions: | | |
| actions: read | |
| env: | |
| ANTHROPIC_FOUNDRY_API_KEY: ${{ secrets.AZURE_ANTHROPIC_API_KEY }} | |
| ANTHROPIC_FOUNDRY_BASE_URL: ${{ secrets.AZURE_ANTHROPIC_ENDPOINT }} | |
| # @claude mentions (can edit and push) - restricted to maintainers only | |
| claude-mention: | |
| if: | | |
| ( | |
| github.event_name == 'issue_comment' && | |
| contains(github.event.comment.body, '@claude') && | |
| (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review_comment' && | |
| contains(github.event.comment.body, '@claude') && | |
| (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR') && | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review' && | |
| contains(github.event.review.body, '@claude') && | |
| (github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'COLLABORATOR') && | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) || | |
| ( | |
| github.event_name == 'issues' && | |
| (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && | |
| (github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'COLLABORATOR') | |
| ) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: read | |
| id-token: write | |
| actions: read | |
| steps: | |
| - name: Get PR head ref | |
| id: pr-ref | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| # For issue_comment events, we need to fetch the PR info | |
| if [ "${{ github.event_name }}" = "issue_comment" ]; then | |
| PR_REF=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }} --jq '.head.ref') | |
| echo "ref=$PR_REF" >> $GITHUB_OUTPUT | |
| else | |
| echo "ref=${{ github.event.pull_request.head.ref || github.head_ref }}" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ steps.pr-ref.outputs.ref }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v6 | |
| - name: Install dependencies | |
| run: | | |
| uv venv --seed | |
| uv sync | |
| - name: Run Claude Code | |
| id: claude | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| use_foundry: "true" | |
| claude_args: '--model claude-opus-4-6 --allowedTools "Read,Edit,Write,Glob,Grep,Bash(git status*),Bash(git diff*),Bash(git add *),Bash(git commit *),Bash(git push*),Bash(git log*),Bash(git merge*),Bash(git fetch*),Bash(git checkout*),Bash(git branch*),Bash(uv run prek *),Bash(prek *),Bash(uv run ruff *),Bash(uv run pytest *),Bash(uv run mypy *),Bash(uv run coverage *),Bash(gh pr comment*),Bash(gh pr view*),Bash(gh pr diff*),Bash(gh pr merge*),Bash(gh pr close*)"' | |
| additional_permissions: | | |
| actions: read | |
| env: | |
| ANTHROPIC_FOUNDRY_API_KEY: ${{ secrets.AZURE_ANTHROPIC_API_KEY }} | |
| ANTHROPIC_FOUNDRY_BASE_URL: ${{ secrets.AZURE_ANTHROPIC_ENDPOINT }} |