소스 검색

fix(ci): unbreak the issue-triage bot, which answered nothing

Since 2026-07-20 every `issues` run reported success while posting no
comment at all - #6094 through #6103 carry zero replies. The cause is
the sandbox, not the prompt or the model.

`handle-issue` and `handle-pr-review` pass allowed_non_write_users,
which is what lets the bot run for reporters who have no write access.
claude-code-action reacts to that input by turning subprocess isolation
on and installing bubblewrap, and that sandbox cannot start on the
runner: every Bash call dies during setup, before the command itself
runs, with

    bwrap: Can't create file at /home/.mcp.json: Permission denied

`gh` is reachable only through Bash, so the triage investigated the
issue, wrote its reply to /tmp/comment.md, and could never post it.
The action itself did not crash, so the job stayed green.

Opt both jobs out with CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=0. The scrub is
a best-effort wipe of secrets from subprocess environments, not an
access control; what actually bounds these jobs is unchanged - a
contents: read token that cannot push, and a Bash allowlist holding
only specific `gh issue`, `gh label`, `gh search` and `gh release`
subcommands. Code changes stay confined to handle-pr-fix and mention,
which only trusted actors and the owner can trigger.

Add a step to each job that fails the run when no bot comment landed on
the issue or pull request, so the next silent breakage shows up red
instead of green, and lower retention-days to the repository maximum of
7 so the artifact upload stops warning.
Sanaei 12 시간 전
부모
커밋
1358f65bec
1개의 변경된 파일34개의 추가작업 그리고 9개의 파일을 삭제
  1. 34 9
      .github/workflows/claude-bot.yml

+ 34 - 9
.github/workflows/claude-bot.yml

@@ -1,12 +1,5 @@
 name: Claude Bot
 
-# Each prompt: / claude_args: value below interpolates ${{ }}, so GitHub parses
-# the whole block scalar as ONE expression and caps it at 21000 characters.
-# Going over does not fail a job - the entire workflow stops parsing and
-# vanishes from Actions, with the run reported only as a workflow file issue.
-# Keep every prompt well under the cap; put shared context in CLAUDE.md and
-# docs/architecture.md, which are in the checkout, instead of pasting it here.
-
 on:
   issues:
     types: [opened]
@@ -29,6 +22,8 @@ jobs:
       contents: read
       issues: write
       id-token: write
+    env:
+      CLAUDE_CODE_SUBPROCESS_ENV_SCRUB: "0"
     steps:
       - uses: actions/checkout@v7
         with:
@@ -324,12 +319,26 @@ jobs:
         if: always()
         env:
           NODE_OPTIONS: ""
-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@v7
         with:
           name: claude-issue-${{ github.event.issue.number }}
           path: ${{ runner.temp }}/claude-execution-output.json
           if-no-files-found: ignore
-          retention-days: 14
+          retention-days: 7
+      - name: Fail if the triage posted no reply
+        if: always()
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          REPO: ${{ github.repository }}
+          ISSUE: ${{ github.event.issue.number }}
+        run: |
+          set -euo pipefail
+          bot_comments=$(gh api "repos/${REPO}/issues/${ISSUE}/comments" --paginate \
+            --jq '[.[] | select(.user.type == "Bot")] | length')
+          if [ "$bot_comments" = "0" ]; then
+            echo "::error::The triage run ended without commenting on #${ISSUE}. Read the uploaded transcript before re-running."
+            exit 1
+          fi
 
   handle-pr-fix:
     if: github.event_name == 'pull_request_target' && contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.pull_request.author_association)
@@ -546,6 +555,8 @@ jobs:
       contents: read
       pull-requests: write
       id-token: write
+    env:
+      CLAUDE_CODE_SUBPROCESS_ENV_SCRUB: "0"
     steps:
       - uses: actions/checkout@v7
         with:
@@ -840,6 +851,20 @@ jobs:
               and confirm your comment is there. If it is not, the command was
               rejected: fix it and post again. Never end the run believing you
               posted a review when you did not.
+      - name: Fail if the review was never posted
+        if: always()
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          REPO: ${{ github.repository }}
+          PR: ${{ github.event.pull_request.number }}
+        run: |
+          set -euo pipefail
+          bot_comments=$(gh api "repos/${REPO}/issues/${PR}/comments" --paginate \
+            --jq '[.[] | select(.user.type == "Bot")] | length')
+          if [ "$bot_comments" = "0" ]; then
+            echo "::error::The review run ended without commenting on #${PR}."
+            exit 1
+          fi
 
   mention:
     if: github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && github.event.comment.user.login == github.repository_owner