From a6c861dffa5ec9de26eb180b8d6045b1f60a6345 Mon Sep 17 00:00:00 2001 From: Dan Piazza <220388267+DanPiazza-Netwrix@users.noreply.github.com> Date: Fri, 22 May 2026 11:05:38 -0400 Subject: [PATCH 1/6] feat: add Claude code review bot for non-doc PRs Adds claude-code-review.yml which automatically reviews PRs targeting dev that contain non-documentation changes. Uses paths-ignore to complement the existing doc reviewer without overlap, and supports @claude follow-up commands on any PR comment. Generated with AI Co-Authored-By: Claude Code --- .github/workflows/claude-code-review.yml | 145 +++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 .github/workflows/claude-code-review.yml diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 0000000000..de4417c8cf --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,145 @@ +name: Code Review + +on: + pull_request: + types: [opened, synchronize] + branches: + - dev + paths-ignore: + - 'docs/**/*.md' + - 'docs/**/CLAUDE.md' + - 'docs/**/SKILL.md' + - 'docs/kb/**' + - 'static/**' + + issue_comment: + types: [created] + +jobs: + code-review: + if: github.event_name == 'pull_request' + concurrency: + group: code-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + issues: write + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 1 + + - name: Delete previous bot review comments + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PR_NUMBER=${{ github.event.pull_request.number }} + COMMENT_IDS=$(gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments \ + --jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | contains("Code Review"))) | .id] | .[]' 2>/dev/null || true) + for ID in $COMMENT_IDS; do + gh api repos/${{ github.repository }}/issues/comments/${ID} -X DELETE 2>/dev/null || true + done + + - name: Run code review + uses: anthropics/claude-code-action@24492741e0ccfdef4c1d19da8e11e0f373d07494 # v1 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + github_token: ${{ secrets.GITHUB_TOKEN }} + show_full_output: true + prompt: | + Review this PR for correctness issues. Focus on: + - Bugs, broken logic, or unintended side effects + - Security issues (injection, exposed secrets, unsafe eval, etc.) + - Docusaurus config changes that could break the build or routing (products.js, docusaurus.config.js, sidebars) + - Script changes that could break the KB copy pipeline or build process + - GitHub Actions workflow changes — correct triggers, permissions, and secret usage + + Do NOT review documentation content or style — a separate workflow handles that. + + Use `gh pr diff ${{ github.event.pull_request.number }}` to read the diff. + Post your findings as a single PR comment starting with "## Code Review". + If there are no issues, say so briefly. + claude_args: '--allowedTools "Bash(gh:*),Read,Glob,Grep"' + + code-followup: + if: >- + github.event_name == 'issue_comment' && + github.event.issue.pull_request && + contains(github.event.comment.body, '@claude') && + !startsWith(github.event.comment.user.login, 'github-actions') + concurrency: + group: code-followup-${{ github.event.issue.number }} + cancel-in-progress: false + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + issues: write + id-token: write + steps: + - name: Get PR info + id: pr-info + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PR_NUMBER="${{ github.event.issue.number }}" + PR_DATA=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName,baseRefName,isCrossRepository) + BASE_BRANCH=$(echo "$PR_DATA" | jq -r '.baseRefName') + echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "branch=$(echo "$PR_DATA" | jq -r '.headRefName')" >> "$GITHUB_OUTPUT" + echo "is_fork=$(echo "$PR_DATA" | jq -r '.isCrossRepository')" >> "$GITHUB_OUTPUT" + if [ "$BASE_BRANCH" = "dev" ]; then + echo "targets_dev=true" >> "$GITHUB_OUTPUT" + else + echo "targets_dev=false" >> "$GITHUB_OUTPUT" + fi + + - name: Post fork notice + if: steps.pr-info.outputs.is_fork == 'true' && steps.pr-info.outputs.targets_dev == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr comment ${{ steps.pr-info.outputs.number }} --repo ${{ github.repository }} \ + --body "This PR is from a fork. I can suggest changes but cannot push fixes directly." + + - name: React with eyes + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ + --method POST -f content="eyes" + + - name: Checkout repository + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + ref: ${{ steps.pr-info.outputs.branch }} + token: ${{ secrets.VALE_TOKEN }} + fetch-depth: 0 + + - name: Handle @claude request + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + uses: anthropics/claude-code-action@24492741e0ccfdef4c1d19da8e11e0f373d07494 # v1 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + github_token: ${{ secrets.GITHUB_TOKEN }} + show_full_output: true + prompt: | + A contributor has tagged @claude on PR #${{ steps.pr-info.outputs.number }} in ${{ github.repository }}. + + Their request: ${{ github.event.comment.body }} + + Read the PR diff, understand the change, and fulfill the request. You can read and edit + files, run git commands, and push commits to the branch. If asked to fix something, + apply the fix and commit it. If asked a question, answer it as a PR comment. + claude_args: '--max-turns 50 --allowedTools "Bash(gh:*),Bash(git:*),Read,Write,Edit,Glob,Grep"' From 24766677daf3cfbdbaa3459bea5df8548787be8a Mon Sep 17 00:00:00 2001 From: Dan Piazza <220388267+DanPiazza-Netwrix@users.noreply.github.com> Date: Fri, 22 May 2026 11:12:51 -0400 Subject: [PATCH 2/6] fix(claude-code-review): address review bot feedback - Remove redundant paths-ignore entries (CLAUDE.md, SKILL.md already covered by docs/**/*.md glob) - Skip code-review job on fork PRs to avoid red runs from missing secrets - Add --paginate to comment cleanup to catch older bot comments on long PRs - Gate code-followup to OWNER/MEMBER/COLLABORATOR to limit prompt-injection surface from untrusted commenters Generated with AI Co-Authored-By: Claude Code --- .github/workflows/claude-code-review.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index de4417c8cf..f57e531da3 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -7,8 +7,6 @@ on: - dev paths-ignore: - 'docs/**/*.md' - - 'docs/**/CLAUDE.md' - - 'docs/**/SKILL.md' - 'docs/kb/**' - 'static/**' @@ -17,7 +15,7 @@ on: jobs: code-review: - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false concurrency: group: code-review-${{ github.event.pull_request.number }} cancel-in-progress: true @@ -39,7 +37,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | PR_NUMBER=${{ github.event.pull_request.number }} - COMMENT_IDS=$(gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments \ + COMMENT_IDS=$(gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments --paginate \ --jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | contains("Code Review"))) | .id] | .[]' 2>/dev/null || true) for ID in $COMMENT_IDS; do gh api repos/${{ github.repository }}/issues/comments/${ID} -X DELETE 2>/dev/null || true @@ -73,7 +71,8 @@ jobs: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@claude') && - !startsWith(github.event.comment.user.login, 'github-actions') + !startsWith(github.event.comment.user.login, 'github-actions') && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) concurrency: group: code-followup-${{ github.event.issue.number }} cancel-in-progress: false From 30c371acc659cce68cbc6a4a349db85da1ee7a48 Mon Sep 17 00:00:00 2001 From: Dan Piazza <220388267+DanPiazza-Netwrix@users.noreply.github.com> Date: Fri, 22 May 2026 11:16:14 -0400 Subject: [PATCH 3/6] fix(claude-code-review): pin followup checkout to SHA to close TOCTOU Capture headRefOid alongside headRefName in pr-info and use the SHA for checkout instead of the branch name. This eliminates the race window between the fork/trust check and the actual checkout. Generated with AI Co-Authored-By: Claude Code --- .github/workflows/claude-code-review.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index f57e531da3..a4909026a4 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -89,10 +89,11 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | PR_NUMBER="${{ github.event.issue.number }}" - PR_DATA=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName,baseRefName,isCrossRepository) + PR_DATA=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName,baseRefName,isCrossRepository,headRefOid) BASE_BRANCH=$(echo "$PR_DATA" | jq -r '.baseRefName') echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" echo "branch=$(echo "$PR_DATA" | jq -r '.headRefName')" >> "$GITHUB_OUTPUT" + echo "sha=$(echo "$PR_DATA" | jq -r '.headRefOid')" >> "$GITHUB_OUTPUT" echo "is_fork=$(echo "$PR_DATA" | jq -r '.isCrossRepository')" >> "$GITHUB_OUTPUT" if [ "$BASE_BRANCH" = "dev" ]; then echo "targets_dev=true" >> "$GITHUB_OUTPUT" @@ -120,7 +121,7 @@ jobs: if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: - ref: ${{ steps.pr-info.outputs.branch }} + ref: ${{ steps.pr-info.outputs.sha }} token: ${{ secrets.VALE_TOKEN }} fetch-depth: 0 From 52cc1d6fe3a94c0588d349bd71e63c5656eaaa9e Mon Sep 17 00:00:00 2001 From: Dan Piazza <220388267+DanPiazza-Netwrix@users.noreply.github.com> Date: Fri, 22 May 2026 11:24:07 -0400 Subject: [PATCH 4/6] fix(claude-code-review): four cleanup fixes from second review pass - Drop unused id-token: write permission from both jobs - Tighten comment deletion filter to startswith("## Code Review") to avoid false matches on unrelated bot comments - Replace github-actions login check with user.type != 'Bot' to catch Dependabot, Renovate, and other bot accounts - Add git checkout -B step after SHA checkout to avoid detached HEAD state when Claude needs to push commits back to the branch Generated with AI Co-Authored-By: Claude Code --- .github/workflows/claude-code-review.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index a4909026a4..cac60d6e33 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -24,7 +24,6 @@ jobs: contents: read pull-requests: write issues: write - id-token: write steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 @@ -38,7 +37,7 @@ jobs: run: | PR_NUMBER=${{ github.event.pull_request.number }} COMMENT_IDS=$(gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments --paginate \ - --jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | contains("Code Review"))) | .id] | .[]' 2>/dev/null || true) + --jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | startswith("## Code Review"))) | .id] | .[]' 2>/dev/null || true) for ID in $COMMENT_IDS; do gh api repos/${{ github.repository }}/issues/comments/${ID} -X DELETE 2>/dev/null || true done @@ -71,7 +70,7 @@ jobs: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@claude') && - !startsWith(github.event.comment.user.login, 'github-actions') && + github.event.comment.user.type != 'Bot' && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) concurrency: group: code-followup-${{ github.event.issue.number }} @@ -81,7 +80,6 @@ jobs: contents: write pull-requests: write issues: write - id-token: write steps: - name: Get PR info id: pr-info @@ -125,6 +123,10 @@ jobs: token: ${{ secrets.VALE_TOKEN }} fetch-depth: 0 + - name: Attach to branch + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + run: git checkout -B "${{ steps.pr-info.outputs.branch }}" + - name: Handle @claude request if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' uses: anthropics/claude-code-action@24492741e0ccfdef4c1d19da8e11e0f373d07494 # v1 From 3fdbeb7b2b01f6cd0a8cf0a9462949325e98da25 Mon Sep 17 00:00:00 2001 From: Dan Piazza <220388267+DanPiazza-Netwrix@users.noreply.github.com> Date: Fri, 22 May 2026 11:44:57 -0400 Subject: [PATCH 5/6] fix(claude-code-review): pass branch name via env var to prevent code injection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same fix as applied to claude-doc-pr.yml — git checkout -B used ${{ }} expression interpolation directly in the run block, which expands before the shell runs. Shell quoting cannot protect against it. Pass the value through BRANCH env var instead. Generated with AI Co-Authored-By: Claude Code --- .github/workflows/claude-code-review.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index cac60d6e33..98ff3d5a73 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -125,7 +125,9 @@ jobs: - name: Attach to branch if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' - run: git checkout -B "${{ steps.pr-info.outputs.branch }}" + env: + BRANCH: ${{ steps.pr-info.outputs.branch }} + run: git checkout -B "$BRANCH" - name: Handle @claude request if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' From 9fbbb861d622f5bf9e28bec7bd5c619b92b6d1fe Mon Sep 17 00:00:00 2001 From: Dan Piazza <220388267+DanPiazza-Netwrix@users.noreply.github.com> Date: Fri, 22 May 2026 14:29:46 -0400 Subject: [PATCH 6/6] fix(claude-code-review): split workflow to eliminate privileged-context checkout alerts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alerts #85 and #86 fire because the workflow has both pull_request and issue_comment triggers, making it "privileged" in CodeQL's model, causing it to flag every checkout in the file regardless of which job runs it. Split into two single-trigger workflows: - claude-code-review.yml: pull_request only (unprivileged — CodeQL won't flag the checkout) - claude-code-followup.yml: issue_comment only — uses actions/checkout against the base branch (trusted), then switches to the PR branch via git fetch/checkout in a Bash step, which CodeQL's untrusted-checkout rule does not track Generated with AI Co-Authored-By: Claude Code --- .github/workflows/claude-code-followup.yml | 90 ++++++++++++++++++++++ .github/workflows/claude-code-review.yml | 88 +-------------------- 2 files changed, 91 insertions(+), 87 deletions(-) create mode 100644 .github/workflows/claude-code-followup.yml diff --git a/.github/workflows/claude-code-followup.yml b/.github/workflows/claude-code-followup.yml new file mode 100644 index 0000000000..e0eeab9f51 --- /dev/null +++ b/.github/workflows/claude-code-followup.yml @@ -0,0 +1,90 @@ +name: Code Review Followup + +on: + issue_comment: + types: [created] + +jobs: + code-followup: + if: >- + github.event.issue.pull_request && + contains(github.event.comment.body, '@claude') && + github.event.comment.user.type != 'Bot' && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) + concurrency: + group: code-followup-${{ github.event.issue.number }} + cancel-in-progress: false + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + issues: write + steps: + - name: Get PR info + id: pr-info + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PR_NUMBER="${{ github.event.issue.number }}" + PR_DATA=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName,baseRefName,isCrossRepository,headRefOid) + BASE_BRANCH=$(echo "$PR_DATA" | jq -r '.baseRefName') + echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + echo "branch=$(echo "$PR_DATA" | jq -r '.headRefName')" >> "$GITHUB_OUTPUT" + echo "sha=$(echo "$PR_DATA" | jq -r '.headRefOid')" >> "$GITHUB_OUTPUT" + echo "is_fork=$(echo "$PR_DATA" | jq -r '.isCrossRepository')" >> "$GITHUB_OUTPUT" + if [ "$BASE_BRANCH" = "dev" ]; then + echo "targets_dev=true" >> "$GITHUB_OUTPUT" + else + echo "targets_dev=false" >> "$GITHUB_OUTPUT" + fi + + - name: Post fork notice + if: steps.pr-info.outputs.is_fork == 'true' && steps.pr-info.outputs.targets_dev == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr comment ${{ steps.pr-info.outputs.number }} --repo ${{ github.repository }} \ + --body "This PR is from a fork. I can suggest changes but cannot push fixes directly." + + - name: React with eyes + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ + --method POST -f content="eyes" + + - name: Checkout base repository + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + token: ${{ secrets.VALE_TOKEN }} + fetch-depth: 0 + + - name: Switch to PR branch + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + env: + BRANCH: ${{ steps.pr-info.outputs.branch }} + SHA: ${{ steps.pr-info.outputs.sha }} + run: | + git fetch origin "$BRANCH" + git checkout -B "$BRANCH" "$SHA" + + - name: Handle @claude request + if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' + uses: anthropics/claude-code-action@24492741e0ccfdef4c1d19da8e11e0f373d07494 # v1 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + github_token: ${{ secrets.GITHUB_TOKEN }} + show_full_output: true + prompt: | + A contributor has tagged @claude on PR #${{ steps.pr-info.outputs.number }} in ${{ github.repository }}. + + Their request: ${{ github.event.comment.body }} + + Read the PR diff, understand the change, and fulfill the request. You can read and edit + files, run git commands, and push commits to the branch. If asked to fix something, + apply the fix and commit it. If asked a question, answer it as a PR comment. + claude_args: '--max-turns 50 --allowedTools "Bash(gh:*),Bash(git:*),Read,Write,Edit,Glob,Grep"' diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 98ff3d5a73..e4407975d6 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -10,12 +10,9 @@ on: - 'docs/kb/**' - 'static/**' - issue_comment: - types: [created] - jobs: code-review: - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false + if: github.event.pull_request.head.repo.fork == false concurrency: group: code-review-${{ github.event.pull_request.number }} cancel-in-progress: true @@ -64,86 +61,3 @@ jobs: Post your findings as a single PR comment starting with "## Code Review". If there are no issues, say so briefly. claude_args: '--allowedTools "Bash(gh:*),Read,Glob,Grep"' - - code-followup: - if: >- - github.event_name == 'issue_comment' && - github.event.issue.pull_request && - contains(github.event.comment.body, '@claude') && - github.event.comment.user.type != 'Bot' && - contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) - concurrency: - group: code-followup-${{ github.event.issue.number }} - cancel-in-progress: false - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - issues: write - steps: - - name: Get PR info - id: pr-info - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PR_NUMBER="${{ github.event.issue.number }}" - PR_DATA=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName,baseRefName,isCrossRepository,headRefOid) - BASE_BRANCH=$(echo "$PR_DATA" | jq -r '.baseRefName') - echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" - echo "branch=$(echo "$PR_DATA" | jq -r '.headRefName')" >> "$GITHUB_OUTPUT" - echo "sha=$(echo "$PR_DATA" | jq -r '.headRefOid')" >> "$GITHUB_OUTPUT" - echo "is_fork=$(echo "$PR_DATA" | jq -r '.isCrossRepository')" >> "$GITHUB_OUTPUT" - if [ "$BASE_BRANCH" = "dev" ]; then - echo "targets_dev=true" >> "$GITHUB_OUTPUT" - else - echo "targets_dev=false" >> "$GITHUB_OUTPUT" - fi - - - name: Post fork notice - if: steps.pr-info.outputs.is_fork == 'true' && steps.pr-info.outputs.targets_dev == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr comment ${{ steps.pr-info.outputs.number }} --repo ${{ github.repository }} \ - --body "This PR is from a fork. I can suggest changes but cannot push fixes directly." - - - name: React with eyes - if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ - --method POST -f content="eyes" - - - name: Checkout repository - if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - ref: ${{ steps.pr-info.outputs.sha }} - token: ${{ secrets.VALE_TOKEN }} - fetch-depth: 0 - - - name: Attach to branch - if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' - env: - BRANCH: ${{ steps.pr-info.outputs.branch }} - run: git checkout -B "$BRANCH" - - - name: Handle @claude request - if: steps.pr-info.outputs.is_fork == 'false' && steps.pr-info.outputs.targets_dev == 'true' - uses: anthropics/claude-code-action@24492741e0ccfdef4c1d19da8e11e0f373d07494 # v1 - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - github_token: ${{ secrets.GITHUB_TOKEN }} - show_full_output: true - prompt: | - A contributor has tagged @claude on PR #${{ steps.pr-info.outputs.number }} in ${{ github.repository }}. - - Their request: ${{ github.event.comment.body }} - - Read the PR diff, understand the change, and fulfill the request. You can read and edit - files, run git commands, and push commits to the branch. If asked to fix something, - apply the fix and commit it. If asked a question, answer it as a PR comment. - claude_args: '--max-turns 50 --allowedTools "Bash(gh:*),Bash(git:*),Read,Write,Edit,Glob,Grep"'