chore(deps): bump husky-rs from 0.1.5 to 0.3.3 #1191
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 Review | |
| on: | |
| pull_request: | |
| types: [opened, reopened, ready_for_review] | |
| issue_comment: | |
| types: [created] | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: "PR number to review" | |
| required: true | |
| type: number | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| id-token: write | |
| actions: read | |
| jobs: | |
| pre-check: | |
| name: Pre-Check | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_review: ${{ steps.check.outputs.should_review }} | |
| pr_number: ${{ steps.check.outputs.pr_number }} | |
| steps: | |
| - name: Determine if review should run | |
| id: check | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| let prNumber; | |
| let shouldReview = false; | |
| if (context.eventName === 'workflow_dispatch') { | |
| prNumber = context.payload.inputs.pr_number; | |
| shouldReview = true; | |
| } else if (context.eventName === 'issue_comment') { | |
| const comment = context.payload.comment.body; | |
| if (!comment.includes('@claude-review')) { | |
| core.setOutput('should_review', 'false'); | |
| return; | |
| } | |
| prNumber = context.payload.issue.number; | |
| shouldReview = true; | |
| } else { | |
| prNumber = context.payload.pull_request.number; | |
| const pr = context.payload.pull_request; | |
| if (pr.draft) { | |
| core.info('Skipping draft PR'); | |
| core.setOutput('should_review', 'false'); | |
| return; | |
| } | |
| const skipBots = ['dependabot[bot]', 'renovate[bot]']; | |
| if (pr.user.type === 'Bot' && skipBots.includes(pr.user.login)) { | |
| core.info(`Skipping dependency bot PR from ${pr.user.login}`); | |
| core.setOutput('should_review', 'false'); | |
| return; | |
| } | |
| shouldReview = true; | |
| } | |
| if (shouldReview) { | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber | |
| }); | |
| const { data: files } = await github.rest.pulls.listFiles({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber, | |
| per_page: 100 | |
| }); | |
| core.info(`PR has ${files.length} files and ${pr.additions + pr.deletions} changed lines`); | |
| } | |
| core.setOutput('should_review', String(shouldReview)); | |
| core.setOutput('pr_number', String(prNumber)); | |
| review: | |
| name: AI Code Review | |
| needs: pre-check | |
| if: needs.pre-check.outputs.should_review == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| id-token: write | |
| actions: read | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev | |
| - name: Run Claude Code Review | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| allowed_bots: "claude[bot]" | |
| track_progress: true | |
| prompt: | | |
| REPO: ${{ github.repository }} | |
| PR NUMBER: ${{ needs.pre-check.outputs.pr_number }} | |
| You are reviewing a PR for GoudEngine, a Rust game engine with C# and Python SDKs. | |
| Read the root AGENTS.md for full project context. | |
| Perform a 7-phase review: | |
| ## Phase 1: Context Gathering | |
| - Read AGENTS.md for project conventions | |
| - Identify which layers are touched (Core, FFI, SDK, Examples) | |
| - Note the PR type (feature, fix, refactor, etc.) | |
| ## Phase 2: Architecture Validation | |
| - Verify dependency flow is downward only (libs -> engine -> ffi -> sdks -> examples) | |
| - Check that no logic is implemented in SDKs (Rust-first principle) | |
| - Verify no raw OpenGL calls outside graphics/backend module | |
| - Check file sizes (flag files exceeding 500 lines) | |
| ## Phase 3: Anti-Pattern Scan | |
| Check for these blockers: | |
| - Missing #[no_mangle] or #[repr(C)] on FFI exports | |
| - unsafe blocks without // SAFETY: comments | |
| - FFI changes without corresponding C# AND Python SDK updates | |
| - todo!() or unimplemented!() in production code | |
| - unwrap()/expect() in library code (should use Result) | |
| - Duplicated logic between Rust and SDK layers | |
| ## Phase 4: Quality Assessment | |
| - Code clarity and naming conventions | |
| - Error handling completeness | |
| - Test coverage for new code | |
| - Documentation on public APIs | |
| ## Phase 5: Security Review (if FFI/unsafe changes) | |
| - Null pointer checks on all FFI pointer parameters | |
| - Memory ownership documented (who allocates, who frees) | |
| - Buffer bounds validation | |
| - No use-after-free potential | |
| ## Phase 6: Scope Verification | |
| - Changes match the PR description | |
| - No unrelated changes smuggled in | |
| - Version bump included if needed | |
| ## Phase 7: Review Output | |
| Produce a structured review with: | |
| - Verdict: APPROVED | CHANGES REQUESTED | BLOCKED | |
| - BLOCKERS table (must fix before merge) | |
| - WARNINGS table (should fix, non-blocking) | |
| - Positive callouts (good patterns observed) | |
| Provide detailed feedback using inline comments for specific issues. | |
| Use top-level comments for general observations. | |
| claude_args: | | |
| --allowedTools "Bash(cargo check:*),Bash(cargo fmt:*),Bash(cargo clippy:*),Bash(cargo test:*),Bash(cargo deny:*),Bash(wc -l:*),Bash(rg:*),Read,Glob,Grep" | |
| agent-feedback: | |
| name: Agent Feedback Loop | |
| needs: [pre-check, review] | |
| if: >- | |
| vars.AGENT_REVIEW_FEEDBACK_ENABLED == 'true' && | |
| needs.pre-check.outputs.should_review == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| issues: write | |
| steps: | |
| - name: Generate App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v3 | |
| with: | |
| app-id: ${{ secrets.AGENT_APP_ID }} | |
| private-key: ${{ secrets.AGENT_APP_PRIVATE_KEY }} | |
| - name: Trigger agent feedback if needed | |
| uses: actions/github-script@v9 | |
| with: | |
| github-token: ${{ steps.app-token.outputs.token }} | |
| script: | | |
| const prNumber = ${{ needs.pre-check.outputs.pr_number }}; | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber | |
| }); | |
| // Only trigger feedback for agent-created PRs (branch starts with agent/) | |
| const isAgentPR = pr.head.ref.startsWith('agent/'); | |
| if (!isAgentPR) { | |
| core.info('Not an agent PR, skipping feedback loop'); | |
| return; | |
| } | |
| // Count existing review rounds to prevent infinite loops | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber | |
| }); | |
| const reviewRounds = comments.filter(c => | |
| c.body.includes('<!-- agent-review-round') | |
| ).length; | |
| if (reviewRounds >= 2) { | |
| core.info(`Already completed ${reviewRounds} review rounds, leaving for human review`); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body: `<!-- agent-review-round: ${reviewRounds + 1} -->\n\nThis agent PR has completed ${reviewRounds} automated review rounds. Remaining issues require human review.` | |
| }); | |
| return; | |
| } | |
| const round = reviewRounds + 1; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body: `<!-- agent-review-round: ${round} -->\n\n@goudengine-agent The automated code review above has completed (round ${round}/2). Please address any issues found in the review and push fixes to this PR.` | |
| }); | |
| core.info(`Posted agent feedback trigger (round ${round})`); |