fix(ci): de reviewpoort valt niet meer om op een schone review #3634
Workflow file for this run
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, synchronize, ready_for_review, reopened] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # A cross-repo PR gets no secrets, so CLAUDE_CODE_OAUTH_TOKEN is empty there and | |
| # the action can only fail. Skip instead, and let review-gate report that. | |
| # Compare full_name rather than reading `head.repo.fork`: inside a fork of this | |
| # repo its own PRs are not cross-repo and do have secrets. | |
| claude-review: | |
| if: >- | |
| ${{ !github.event.pull_request.draft && | |
| github.event.pull_request.head.repo.full_name == github.repository && | |
| github.event.pull_request.user.login != 'dependabot[bot]' }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: read | |
| id-token: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 1 | |
| - name: Clean up stale review comments | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| PR=${{ github.event.pull_request.number }} | |
| REPO=${{ github.repository }} | |
| # Dismiss all previous claude[bot] reviews | |
| gh api "repos/${REPO}/pulls/${PR}/reviews" \ | |
| --paginate --jq '.[] | select(.user.login == "claude[bot]" and (.state == "CHANGES_REQUESTED" or .state == "COMMENTED")) | .id' \ | |
| | while read -r review_id; do | |
| gh api -X PUT "repos/${REPO}/pulls/${PR}/reviews/${review_id}/dismissals" \ | |
| -f message="Superseded by new review" -f event="DISMISS" 2>/dev/null || true | |
| done | |
| # Delete all previous claude[bot] inline review comments | |
| gh api "repos/${REPO}/pulls/${PR}/comments" \ | |
| --paginate --jq '.[] | select(.user.login == "claude[bot]") | .id' \ | |
| | while read -r comment_id; do | |
| gh api -X DELETE "repos/${REPO}/pulls/comments/${comment_id}" 2>/dev/null || true | |
| done | |
| # Delete all previous claude[bot] issue comments (sticky comment is managed by the action) | |
| gh api "repos/${REPO}/issues/${PR}/comments" \ | |
| --paginate --jq '.[] | select(.user.login == "claude[bot]") | .id' \ | |
| | while read -r comment_id; do | |
| gh api -X DELETE "repos/${REPO}/issues/comments/${comment_id}" 2>/dev/null || true | |
| done | |
| - name: Run Claude Code Review | |
| id: claude-review | |
| uses: anthropics/claude-code-action@be7b93b1907a4abad570368f3c74b6fe3807510b # v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| use_sticky_comment: true | |
| claude_args: "--allowedTools Bash,Read,Glob,Grep" | |
| prompt: | | |
| Review PR #${{ github.event.pull_request.number }} in ${{ github.repository }}. | |
| Read `REVIEW.md` for the project context, review dimensions, severity scale, and | |
| skip rules. Follow those guidelines strictly. | |
| ## CRITICAL SCOPE RULE | |
| **ONLY review lines that were actually added or modified in this PR's diff.** | |
| You MUST NOT comment on: | |
| - Pre-existing code that was not changed in this PR | |
| - Context lines shown in the diff that were not added/modified (lines without + prefix) | |
| - Issues in unchanged files or unchanged sections of changed files | |
| - Pre-existing patterns, naming, style, or technical debt in surrounding code | |
| You may read full files for context to understand the changes, but every single | |
| finding you report MUST point to a line that was added or modified in the diff. | |
| If a line was not changed by this PR, it is OUT OF SCOPE, no matter how wrong it looks. | |
| Before submitting each finding, verify: "Was this line actually changed in the PR diff?" | |
| If the answer is no, drop the finding. | |
| Skip dimensions that have no findings. Be precise and actionable — no "consider" | |
| or "you might want to" comments. | |
| ## Output format | |
| Structure your review as a single comment with sections for each dimension that has | |
| findings. Use this severity scale: | |
| - 🔴 **Critical** — wrong legal outcome, data loss, runtime crash, security vulnerability | |
| - 🟠 **Significant** — likely bug, broken reference, missing edge case, lost jobs | |
| - 🟡 **Minor** — code quality, style, non-blocking improvement | |
| Also leave inline comments on specific lines where possible. | |
| If there are no issues, say so briefly. Do not pad the review with praise or filler. | |
| # Het bewijs waar review-gate op afgaat. `execution_file` wijst naar het | |
| # uitvoerbestand van Claude en wordt pas gezet nadat de CLI gedraaid heeft; | |
| # stapt de actie er eerder uit — de workflow-validation-skip, wanneer dit | |
| # bestand afwijkt van de versie op de default branch — dan blijft die | |
| # output leeg en wordt deze stap overgeslagen. De poort leest de uitkomst | |
| # van deze stap uit de jobs van déze run, dus het bewijs is per constructie | |
| # run-gebonden, en het bestaat ook wanneer de review nul bevindingen had. | |
| # Hernoem deze stap niet zonder `PROOF_STEP` in review-gate mee te nemen. | |
| - name: Record that the review ran | |
| if: steps.claude-review.outputs.execution_file != '' | |
| env: | |
| EXECUTION_FILE: ${{ steps.claude-review.outputs.execution_file }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| echo "De review-actie is uitgevoerd; uitvoerbestand: ${EXECUTION_FILE}" | |
| { | |
| echo "### Claude review uitgevoerd" | |
| echo | |
| echo "De review-actie heeft gedraaid voor commit \`${HEAD_SHA}\`." | |
| echo "Nul bevindingen is hier een geldige uitkomst; deze stap zegt alleen dat er gereviewd is." | |
| } >>"$GITHUB_STEP_SUMMARY" | |
| # The merge gate. Unlike claude-review this job has no `if:` — it must run and | |
| # report on every PR, cross-repo and dependabot included, because a required | |
| # check that never reports blocks such a PR forever. | |
| review-gate: | |
| name: Claude review completed | |
| runs-on: ubuntu-latest | |
| # Ruim boven de ~10 minuten die de review kost, zodat een trage run niet | |
| # onterecht rood wordt; het script stopt zelf eerder met een duidelijke melding. | |
| timeout-minutes: 40 | |
| permissions: | |
| actions: read | |
| contents: read | |
| pull-requests: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 1 | |
| # De poort mag niet draaien op de versie van zichzelf die in de PR staat: | |
| # een PR die het script naar `exit 0` verandert zou anders per definitie | |
| # groen zijn. Draai daarom de versie van de base-branch, en blokkeer als | |
| # die niet te krijgen is — terugvallen op de PR-versie is precies de | |
| # bypass die deze stap moet dichten. | |
| - name: Take the gate script from the base branch | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| GATE: script/await-claude-review.sh | |
| run: | | |
| set -uo pipefail | |
| fail() { | |
| echo "::error title=Claude review gate::$1" | |
| exit 1 | |
| } | |
| git fetch --depth=1 origin "$BASE_SHA" || | |
| fail "base-commit ${BASE_SHA} is niet op te halen, dus de versie van de poort is niet vast te stellen. Draai deze job opnieuw." | |
| git cat-file -e "${BASE_SHA}:${GATE}" 2>/dev/null || | |
| fail "${GATE} bestaat niet op de base-branch (${BASE_SHA}). De poort kan dan niet voor zichzelf instaan; deze PR moet met de hand gereviewd worden." | |
| git checkout "$BASE_SHA" -- "$GATE" || | |
| fail "${GATE} is niet uit ${BASE_SHA} te checkouten, dus de poort zou de versie uit deze PR draaien. Draai deze job opnieuw." | |
| echo "Poort draait de versie van ${BASE_SHA}." | |
| - name: Wait for the Claude review of this commit | |
| # Alleen de coördinaten van deze run. Wat de poort als feit behandelt — | |
| # fork, draft, auteur, de versie van dit workflowbestand — haalt zij zelf | |
| # op, want dit env-blok staat in de PR die gereviewd wordt. | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| REPO: ${{ github.repository }} | |
| RUN_ID: ${{ github.run_id }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| MAX_WAIT_SECONDS: '2100' | |
| POLL_SECONDS: '20' | |
| run: script/await-claude-review.sh |