feat(release): npm trusted publishing (OIDC); flake dev shell with ziglint - #17
Merged
Merged
Conversation
…glint npm publishing has been broken for two releases. v0.2.11 (2026-02-01) and v0.3.0 (today) both failed with a registry 404 — npm's way of saying the token is not authorized — while the tag, the GitHub release, and the manifests all looked correct. NPM_TOKEN was set 2025-11-28. A long-lived secret that expires silently is the failure mode; rotating it would just reset the clock. Trusted publishing removes the secret entirely: the publish job declares `id-token: write`, npm exchanges that short-lived workflow-scoped GitHub identity for publish rights, and each package names alleneubank/linear-cli + release.yml as its trusted publisher. The workflow FILENAME is part of the trust relationship — renaming it breaks publishing until every package's config is updated. It has to be `npm publish`: bun cannot present an OIDC identity (oven-sh/bun#22423, open since 2025-09) and fails with "missing authentication". bunfig.toml existed only to hand bun the token, so it goes with it. No NPM_TOKEN fallback is left behind — a fallback would re-arm exactly the failure mode this removes. Publishing from a public repo also gets provenance attestations for free. Also adds flake.nix, which is what makes `zig build lint` runnable: the step shells out to `ziglint` and dies with FileNotFound when it is absent, which is why it never ran anywhere. The shell pins zig_0_16 (0.16.0, matching CI — the toolchain is not interchangeable) plus ziglint and the jq both release scripts parse manifests with. Verified: `nix flake check` passes; `nix develop -c` reports zig 0.16.0, ziglint 0.5.3, jq 1.8.2; `zig build lint` now executes (it reports 14 pre-existing findings, left alone here); both workflows parse; the version gate and `zig fmt --check` still pass. The npmjs.com side (five packages) is configured separately in the web UI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
npm publishing has been broken for two releases and nothing surfaced it:
404 Not Foundfrom the registryA 404 on publish is npm's way of saying the token is not authorized.
NPM_TOKENwas set 2025-11-28. Everything else about both releases looked green — tag, GitHub release, manifests — so npm quietly stayed on 0.2.11 while the repo moved on. Rotating the token would just reset the clock on the same failure.What
Trusted publishing (OIDC) removes the secret. The
publishjob declaresid-token: write, npm exchanges that short-lived workflow-scoped GitHub identity for publish rights, and each of the five packages namesalleneubank/linear-cli+release.ymlas its trusted publisher on npmjs.com.Two things worth knowing:
release.ymlbreaks publishing until every package's config is updated. Noted inCLAUDE.mdand in the job's comments.npm publish, notbun publish. bun cannot present an OIDC identity (oven-sh/bun#22423, open since 2025-09) and fails withmissing authentication.bunfig.tomlexisted only to hand bun the token, so it goes too. NoNPM_TOKENfallback is left behind — a fallback would re-arm the exact failure mode this removes.Publishing from a public repo with OIDC also produces provenance attestations automatically.
flake.nix
zig build linthas never been runnable: it shells out toziglint, which is not installed anywhere, so it dies withFileNotFound— that is why the step is in neither CI nor any local run. The dev shell pinszig_0_16(0.16.0, matching CI; the toolchain is not interchangeable), plusziglintand thejqboth release scripts parse manifests with.zig build lintnow executes and reports 14 pre-existing findings (11x Z030deinit should set self.* = undefined, 2x Z010, 1x Z020; 8 of them in test files). Left alone in this PR — they are advisory and not a release gate.Verification
nix flake check— passesnix develop -c— zig 0.16.0, ziglint 0.5.3, jq 1.8.2zig build lint— executes (previouslyFileNotFound)scripts/check-versions.sh --expect 0.3.0andzig fmt --checkpass