name: Claude Code Review on: pull_request: types: [opened, synchronize, ready_for_review, reopened] jobs: claude-review: if: ${{ !github.event.pull_request.draft }} runs-on: ubuntu-latest permissions: contents: read pull-requests: write issues: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v7 with: fetch-depth: 0 - name: Run Claude Code Review id: claude-review uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} allowed_bots: 'dependabot[bot],goodolclint-claude[bot],goodolclint-codex[bot]' track_progress: true prompt: | REPO: ${{ github.repository }} PR NUMBER: ${{ github.event.pull_request.number }} Review this pull request for the PSProxmoxVE PowerShell module. Focus areas: 1. **DECISIONS.md compliance** — Check against the architectural decisions (D001-D016). Any violation is a regression. 2. **Code quality** — Cmdlet conventions (sealed, OutputType, ConfirmImpact.High for destructive, VmId ValidateRange), SecureString for passwords, Uri.EscapeDataString on path params, no bare catch blocks, Newtonsoft-only JSON. 3. **API correctness** — Parameter names and enum values must match the PVE OpenAPI spec (see tests/PSProxmoxVE.Core.Tests/Fixtures/ pve-api-enums.pve*.json for valid values per PVE version). 4. **Tests** — New cmdlets should have xUnit service tests and Pester parameter-validation tests. 5. **Security** — No hardcoded credentials, no secrets in logs, TLS verification on by default. Use inline comments for issues tied to specific lines. Skip nitpicks unless they indicate a real problem. You MUST end the review by submitting a formal review verdict with `gh pr review`, because branch protection only recognises a review state — plain PR comments and inline-only comments do not count: - Nothing blocks merge: `gh pr review ${{ github.event.pull_request.number }} --approve --body ""` - Something must change before merge: `gh pr review ${{ github.event.pull_request.number }} --request-changes --body ""` Always pass a non-empty `--body`. If you cannot complete the review for any reason, still submit `gh pr review ${{ github.event.pull_request.number }} --comment --body ""` rather than staying silent. claude_args: | --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr review:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api:*)" - name: Verify formal review was submitted if: always() && steps.claude-review.outputs.execution_file != '' env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} REPO: ${{ github.repository }} run: | # Branch protection requires a formal review state. Plain PR comments # don't count, and inline-only comments create empty-body COMMENTED # reviews that don't count either. formal_count=$(gh api "repos/$REPO/pulls/$PR_NUMBER/reviews" \ --jq '[.[] | select(.user.login == "claude[bot]") | select(.state == "APPROVED" or .state == "CHANGES_REQUESTED" or ((.body // "") | length > 0))] | length') echo "Formal claude[bot] reviews on PR #$PR_NUMBER: $formal_count" if [ "$formal_count" -eq 0 ]; then echo "::error title=No formal review submitted::Claude reviewed the PR but did not call 'gh pr review'. Re-run the workflow or invoke '@claude re-review' on the PR." exit 1 fi