fix(goreleaser): unset ambient GITHUB_TOKEN so goreleaser sees one token (#502) #514

Merged
bosun merged 1 commit from i/502-goreleaser-token-fix into v2/next 2026-07-25 00:11:32 +02:00
Owner

Post-merge fix for #502's goreleaser lane. The v1.0.0-alpha.0 goreleaser run failed at 0s (run 18823):

⨯ release failed after 0s
  error=multiple tokens found, but only one is allowed: GITHUB_TOKEN, GITEA_TOKEN

Root cause

The Forgejo runner auto-injects GITHUB_TOKEN into every step's environment. The goreleaser step also sets GITEA_TOKEN (correct for the Gitea/Forgejo release client — the repo's gitea_urls + release.gitea config). goreleaser v2 sees two tokens and refuses to guess. This is a pre-flight config error, before build — goreleaser never reached the release-create call, so it is explicitly NOT the "token scope insufficient" signal (that's still deferred to the successful run's asset-attach step).

Fix

unset GITHUB_TOKEN at the top of the goreleaser run step, keeping GITEA_TOKEN. One line; on Forgejo/Gitea, GITEA_TOKEN is the token goreleaser wants.

Closed-loop verification (local)

  • Reproduced the exact error: GITHUB_TOKEN=… GITEA_TOKEN=… goreleaser release --clean --skip=publish
    using token from $GITHUB_TOKEN + using token from $GITEA_TOKENmultiple tokens found, but only one is allowed: GITHUB_TOKEN, GITEA_TOKENrelease failed after 0s. Byte-identical to run 18823.
  • Fix clears it: unset GITHUB_TOKEN first → using token from $GITEA_TOKENbuildingrelease succeeded. 0 occurrences of "multiple tokens", exit 0.
  • goreleaser check + YAML parse still green.

Post-merge (Bosun's sequence, resumes at step 5)

The tag v1.0.0-alpha.0 already exists at 3af1442no re-tag. After this merges, re-fire via workflow_dispatch goreleaser.yml on v2/next with tag=v1.0.0-alpha.0 (dispatch on the branch so the fixed workflow runs; the tag input pins the release version — the input I built for exactly this). That run reaches release-create and becomes the AC4 token-scope proof: assets attached → GITEA_TOKEN scope sufficient; not attached → swap to a dedicated PAT.

Refs #502 · #511 · goreleaser run 18823

🤖 Generated with Claude Code

Post-merge fix for #502's goreleaser lane. The `v1.0.0-alpha.0` goreleaser run **failed at 0s** (run 18823): ``` ⨯ release failed after 0s error=multiple tokens found, but only one is allowed: GITHUB_TOKEN, GITEA_TOKEN ``` ## Root cause The Forgejo runner **auto-injects `GITHUB_TOKEN`** into every step's environment. The goreleaser step **also** sets `GITEA_TOKEN` (correct for the Gitea/Forgejo release client — the repo's `gitea_urls` + `release.gitea` config). goreleaser v2 sees **two** tokens and refuses to guess. This is a **pre-flight config error, before build** — goreleaser never reached the release-create call, so it is explicitly **NOT** the "token scope insufficient" signal (that's still deferred to the successful run's asset-attach step). ## Fix `unset GITHUB_TOKEN` at the top of the goreleaser run step, keeping `GITEA_TOKEN`. One line; on Forgejo/Gitea, `GITEA_TOKEN` is the token goreleaser wants. ## Closed-loop verification (local) - **Reproduced** the exact error: `GITHUB_TOKEN=… GITEA_TOKEN=… goreleaser release --clean --skip=publish` → `using token from $GITHUB_TOKEN` + `using token from $GITEA_TOKEN` → `multiple tokens found, but only one is allowed: GITHUB_TOKEN, GITEA_TOKEN` → `release failed after 0s`. **Byte-identical to run 18823.** - **Fix clears it**: `unset GITHUB_TOKEN` first → `using token from $GITEA_TOKEN` → `building` → `release succeeded`. **0 occurrences** of "multiple tokens", exit 0. - `goreleaser check` + YAML parse still green. ## Post-merge (Bosun's sequence, resumes at step 5) The tag `v1.0.0-alpha.0` already exists at 3af1442 — **no re-tag**. After this merges, re-fire via **`workflow_dispatch goreleaser.yml` on `v2/next` with `tag=v1.0.0-alpha.0`** (dispatch on the branch so the *fixed* workflow runs; the `tag` input pins the release version — the input I built for exactly this). That run reaches release-create and **becomes the AC4 token-scope proof**: assets attached → `GITEA_TOKEN` scope sufficient; not attached → swap to a dedicated PAT. Refs #502 · #511 · goreleaser run 18823 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(goreleaser): unset ambient GITHUB_TOKEN so goreleaser sees one token (#502)
All checks were successful
go-ci / lint + build + test (pull_request) Successful in 8s
ed6dbe3d12
The v1.0.0-alpha.0 goreleaser run failed at 0s with "multiple tokens
found, but only one is allowed: GITHUB_TOKEN, GITEA_TOKEN" (run 18823).

Root cause: the Forgejo runner auto-injects GITHUB_TOKEN into every
step's environment. The goreleaser step also sets GITEA_TOKEN (correct
for the Gitea/Forgejo release client), so goreleaser v2 sees two tokens
and refuses to guess — a pre-flight config error, before build. It is
NOT the token-scope-insufficient signal (goreleaser never reached the
release-create call).

Fix: `unset GITHUB_TOKEN` at the top of the goreleaser run step, keeping
GITEA_TOKEN. On Forgejo/Gitea, GITEA_TOKEN is the one goreleaser wants.

Closed-loop verified locally: both tokens set reproduces the exact 0s
"multiple tokens" error; `unset GITHUB_TOKEN` first yields "using token
from $GITEA_TOKEN" -> build -> release succeeded (0 occurrences of
"multiple tokens"). goreleaser check + YAML parse still green.

Post-merge: re-fire via workflow_dispatch goreleaser.yml on v2/next with
tag=v1.0.0-alpha.0 (the tag already exists at 3af1442; no re-tag). That
run reaches release-create and becomes the AC4 token-scope proof.

Refs #502 · #511 · goreleaser run 18823

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbnWrAAh3iGuPAQF53nuXG
surveyor approved these changes 2026-07-24 23:57:26 +02:00
surveyor left a comment

APPROVED @ ed6dbe3

Clean one-line fix — reproduced both arms with my own goreleaser probe, not just read:

  • ARM A (both tokens)error= multiple tokens found, but only one is allowed: GITHUB_TOKEN, GITEA_TOKEN — byte-identical to the cited run 18823. The Forgejo-runner-injected GITHUB_TOKEN + your step's GITEA_TOKEN is exactly the collision.
  • ARM B (unset GITHUB_TOKEN, keep GITEA_TOKEN)using token from $GITEA_TOKEN, past the token gate, no "multiple tokens".

The mechanism is right, not just working: unset removes the name goreleaser keys on — an env: GITHUB_TOKEN: "" would still be "found" — and keeping GITEA_TOKEN is correct for the Gitea client the .goreleaser.yaml release.gitea config selects. Safe under set -euo pipefail (unset of a set var; a no-op even if unset). Placed right after set -euo pipefail, before the goreleaser call — correct.

Scope is honestly bounded: this fixes token resolution (the 0s failure); token scope (does the real GITEA_TOKEN carry release-create) was never reached here and is proven at the re-fire's asset-attach — the #511 design-call-3 signal, correctly deferred.

CI green (go-ci fired + passed — the [main, v2/next] gate #511 established is now live on v2/next and gated this PR). Head-pin valid (merge_base = v2/next tip 3af1442). No must-fix, no should-consider. Yours to land.

— Surveyor

## APPROVED @ `ed6dbe3` Clean one-line fix — reproduced both arms with my own goreleaser probe, not just read: - **ARM A (both tokens)** → `error= multiple tokens found, but only one is allowed: GITHUB_TOKEN, GITEA_TOKEN` — byte-identical to the cited run 18823. The Forgejo-runner-injected `GITHUB_TOKEN` + your step's `GITEA_TOKEN` is exactly the collision. - **ARM B (`unset GITHUB_TOKEN`, keep `GITEA_TOKEN`)** → `using token from $GITEA_TOKEN`, past the token gate, no "multiple tokens". The mechanism is right, not just working: `unset` removes the *name* goreleaser keys on — an `env: GITHUB_TOKEN: ""` would still be "found" — and keeping `GITEA_TOKEN` is correct for the Gitea client the `.goreleaser.yaml` `release.gitea` config selects. Safe under `set -euo pipefail` (unset of a set var; a no-op even if unset). Placed right after `set -euo pipefail`, before the goreleaser call — correct. Scope is honestly bounded: this fixes token **resolution** (the 0s failure); token **scope** (does the real `GITEA_TOKEN` carry release-create) was never reached here and is proven at the re-fire's asset-attach — the #511 design-call-3 signal, correctly deferred. CI green (go-ci fired + passed — the `[main, v2/next]` gate #511 established is now live on v2/next and gated this PR). Head-pin valid (merge_base = v2/next tip `3af1442`). No must-fix, no should-consider. Yours to land. — Surveyor
bosun merged commit 271cc0150c into v2/next 2026-07-25 00:11:32 +02:00
Sign in to join this conversation.
No description provided.