anthropics / anthropics/claude-code-action
Tag mode: setupBranch() fetches before configureGitAuth(), so persist-credentials:false breaks every mention on a private repo
- Vorherrschende Sprache
- TypeScript
- Sterne
- 8.9k
- Forks
- 2.1k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
### Summary
In **tag mode**, `setupBranch()` runs `git fetch` *before* `configureGitAuth()`. On a private repository checked out with `actions/checkout`'s `persist-credentials: false`, there is no credential for that fetch, so the action dies in setup — after it has already posted its "Claude Code is working…" tracking comment, which then never resolves.
The result is a permanently pending comment on the PR and no review, for every mention.
### Repro
Workflow (private repo):
```yaml
on:
issue_comment: { types: [created] }
jobs:
claude:
runs-on: ubuntu-latest
permissions: { contents: read, pull-requests: write, issues: write }
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 1
persist-credentials: false # <- the trigger
- uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# no `prompt:` -> tag mode
```
Comment `@claude review this` on an open same-repo PR.
```
Action failed with error: Command failed: git fetch origin --depth=20
```
### Cause (v1)
- `src/modes/detector.ts` — a comment event with no `prompt` input and a matched trigger phrase resolves to **`"tag"`**.
- `src/modes/tag/index.ts` — posts the tracking comment, then calls `setupBranch(...)` at **line 67**; `configureGitAuth(...)` is called only afterwards, at **lines 84 / 97**.
- `src/github/operations/branch.ts:212` — for an open, same-repo PR: `execGit(["fetch", "origin", ...depthArgs, branchName])`, unconditionally. There is no check for whether the requested ref is already present in the working copy.
So the ordering is: **tracking comment → unauthenticated fetch → (never reached) git auth.**
Agent mode is unaffected: `src/modes/agent/index.ts` never calls `setupBranch`, and reads branch state from `GITHUB_HEAD_REF` / `GITHUB_REF_NAME` instead. That is why a `workflow_dispatch`-triggered workflow using the identical checkout config works fine — it takes a different code path, not a safer configuration.
### Why `persist-credentials: false` is not simply user error
`actions/checkout` writes the job token into `.git/config` as an `http.extraheader`. A workflow that runs an agent with file-read tools over the checkout is handing that agent its own token — so `persist-credentials: false` is the correct hardening for exactly this action's use case, not an exotic choice. Right now that hardening is incompatible with tag mode.
Pinning `actions/checkout`'s `ref:` to the PR head does **not** work around it: `setupBranch` fetches by branch name regardless of what is already checked out. (Verified — that was our first attempted fix.)
### Suggested fixes, roughly in order of preference
1. **Configure git auth before `setupBranch()`**, so the fetch it performs is authenticated. Smallest change, fixes the ordering bug directly.
2. **Skip the fetch when the requested ref is already checked out** — cheap, and a speedup for every consumer that pins `ref:`.
3. Failing either, **fail before posting the tracking comment**, so a setup crash does not leave a permanently pending "Claude Code is working…" on the PR. The dangling comment is arguably the worse half of this bug: it reads as "still running" forever.
### Environment
`anthropics/claude-code-action@v1`, `actions/checkout@v7`, `ubuntu-latest`, private repository, tag mode (no `prompt:` input).
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.