diff --git a/.github/workflows/claude-review.yml b/.github/workflows/claude-review.yml new file mode 100644 index 0000000..cfa7207 --- /dev/null +++ b/.github/workflows/claude-review.yml @@ -0,0 +1,72 @@ +name: Claude PR Review + +on: + pull_request: + types: [opened, synchronize, ready_for_review] + +concurrency: + group: claude-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + id-token: write + +jobs: + review: + if: >- + github.event.pull_request.draft == false && + github.event.pull_request.head.repo.full_name == github.repository && + github.actor != 'dependabot[bot]' && + !contains(github.event.pull_request.labels.*.name, 'skip-claude-review') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install (for type/lint verification) + run: | + pip install -e ".[pandas]" + pip install ruff pyright + + - uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + prompt: | + You are an expert reviewer for ${{ github.repository }}, the official SharpAPI Python + SDK (published to PyPI), reviewing PR #${{ github.event.pull_request.number }}: + "${{ github.event.pull_request.title }}". + + First read ./REVIEW.md (and ./CLAUDE.md if present) for review rules. Honor them. + + Scope: review ONLY the changes this PR introduces + (`gh pr diff ${{ github.event.pull_request.number }}`). Read surrounding code for + context; do NOT comment on pre-existing code the PR does not touch. + + For each genuine problem, post an inline comment on the exact line via the + mcp__github_inline_comment__create_inline_comment tool (confirmed: true), prefixed: + [Critical] bug, BACKWARD-INCOMPATIBLE public API change, or a type error + [Important] a real problem worth fixing before merge + [Nit] minor/style; skip what `ruff` already enforces + + You MAY run `ruff check` and `pyright` to CONFIRM a lint/type suspicion before + flagging it. Cite file:line; never speculate — if you cannot verify a concern, omit it. + + Focus: backward compatibility of the public API (PyPI is immutable — flag any breaking + change to classes/functions/kwargs), pyright type correctness (no `Any` leakage in + public signatures), correct httpx/pydantic usage, and parity with the documented + SharpAPI surface. + + Finish with ONE concise summary comment (`gh pr comment`): overall verdict, counts by + severity, top 1-3 items. Be terse. If clean, say so — do not invent issues. + claude_args: | + --model claude-sonnet-4-6 + --max-turns 15 + --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(ruff check:*),Bash(pyright:*),Bash(python -m py_compile:*),Read,Grep" + --disallowedTools "WebSearch,Write,Edit" diff --git a/REVIEW.md b/REVIEW.md new file mode 100644 index 0000000..c9648e2 --- /dev/null +++ b/REVIEW.md @@ -0,0 +1,18 @@ +# Review rules — sharpapi-python (official Python SDK) + +Guidance for the automated Claude PR reviewer (`.github/workflows/claude-review.yml`). + +## Severity +- **[Critical]** — bug, a backward-incompatible change to the public API, or a type error. +- **[Important]** — a real problem to fix before merge. +- **[Nit]** — minor/style. Skip what `ruff` already enforces. + +## Always check +- **Backward compatibility** — public classes/functions/kwargs are a published contract (PyPI is immutable). Flag any breaking change. +- **Types** — passes `pyright`; accurate annotations; no `Any` leakage in public signatures. +- **httpx / pydantic** — correct async/sync usage, error handling, model validation. +- **API parity** — the SDK matches the documented SharpAPI surface (endpoints, params, response models). + +## Don't +- Don't flag pre-existing code this PR didn't touch. +- You MAY run `ruff check` / `pyright` to confirm a concern; otherwise don't speculate — cite `file:line` or omit. "LGTM" is valid.