anthropics / anthropics/claude-code-action

Tag mode: setupBranch() fetches before configureGitAuth(), so persist-credentials:false breaks every mention on a private repo

Abierto
#1,711 2 comentarios 0 reacciones 0 asignados Ver en GitHub
area:permissions bug duplicate p2
Lenguaje dominante
TypeScript
Estrellas
8.9k
Forks
2.1k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

### 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).

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.