You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Publishing 10.0.0-alpha.3 took four failed attempts and about an hour, none of it caused by the code being wrong. The manual path is the problem, and patching it is not the fix — v10 has beta and stable still to come, on a September deadline.
What actually happened
pnpm release failed — expired npm token.
Re-authed. Failed again — the token had no write access to @react-three/* yet.
Access was granted. Failed again — npm's authz cache had not propagated, and it reports that as a 404 on PUT, which reads identically to "you do not have permission". Three of us concluded the wrong thing from it.
Eventually worked, publishing the three packages by hand.
The debug log shows 2FA completing cleanly and the PUT failing after it, so the browser challenge was never the issue:
40 http fetch GET 200 .../done?authId=*** ← 2FA completed
41 verbose web auth done-check finished
42 http fetch PUT 404 .../@react-three%2ffiber ← rejected here
None of this is reproducible or reviewable. The alphas so far were published from two different people's laptops (krispyaa for alpha.0–2, dennissmolek for alpha.3), with no provenance attestation on any of them.
Meanwhile, the canary job just works
canary.yml has published cleanly on every push to v10 — via GitHub OIDC, no personal token, with provenance:
10.0.0-canary.611635d by GitHub Actions provenance: YES
10.0.0-alpha.2 by krispyaa provenance: none
So the mechanism is already proven in this repo. It is simply not wired to anything but canary.
What drei does
pmndrs/drei has alpha, beta and rc branches, and one release.yml:
on:
push:
branches: ['master', 'beta', 'alpha', 'canary-*', 'rc']jobs:
build-and-release:
needs: test # release cannot run unless tests passpermissions:
id-token: write # provenance
Push to alpha → published under the alpha tag. No tokens, no OTP, no laptop, and needs: test makes it impossible to publish something that did not pass CI.
Proposed
Adopt the same shape. The pieces already exist here:
Trigger: extend a release workflow to alpha / beta / rc branches, modelled on canary.yml, which already has the OIDC trust working.
Tag derivation: scripts/release.js already derives the dist-tag from the version and refuses to touch latest without --allow-latest. Either keep it as the publish step or replace it with semantic-release; the guard rails matter more than the tool.
Open question worth deciding early: semantic-release or the existing script. semantic-release also handles version bumping and changelog generation from commits, which is a larger change to how this repo works. The smaller step is branch-triggered publishing with the current script, keeping hand-written changelogs.
Also worth fixing regardless
scripts/release.js spawns pnpm publish through execFileSync with stdio: 'inherit'. npm's 2FA browser prompt printed but did not appear to block, and publishing by hand is what eventually worked. If any manual path survives, that spawn should hand the TTY through properly — but automating the publish removes the interactive prompt entirely, which is the better answer.
Acceptance
Pushing to a release branch publishes every package under the matching dist-tag, from CI, with provenance, and only after tests pass.
Publishing
10.0.0-alpha.3took four failed attempts and about an hour, none of it caused by the code being wrong. The manual path is the problem, and patching it is not the fix — v10 has beta and stable still to come, on a September deadline.What actually happened
pnpm releasefailed — expired npm token.@react-three/*yet.The debug log shows 2FA completing cleanly and the
PUTfailing after it, so the browser challenge was never the issue:None of this is reproducible or reviewable. The alphas so far were published from two different people's laptops (
krispyaafor alpha.0–2,dennissmolekfor alpha.3), with no provenance attestation on any of them.Meanwhile, the canary job just works
canary.ymlhas published cleanly on every push tov10— via GitHub OIDC, no personal token, with provenance:So the mechanism is already proven in this repo. It is simply not wired to anything but
canary.What drei does
pmndrs/dreihasalpha,betaandrcbranches, and onerelease.yml:with
release.config.jsmapping branch → dist-tag:Push to
alpha→ published under thealphatag. No tokens, no OTP, no laptop, andneeds: testmakes it impossible to publish something that did not pass CI.Proposed
Adopt the same shape. The pieces already exist here:
alpha/beta/rcbranches, modelled oncanary.yml, which already has the OIDC trust working.needs: test, so a publish cannot outrun CI. Worth noting test: stop shadowing React's act with a frame-wait helper #3823 and fix: keep interaction state continuous across instance reconstruction #3824 both merged a commit short of what CI had verified — a release gated on a post-merge run would have caught that.scripts/release.jsalready derives the dist-tag from the version and refuses to touchlatestwithout--allow-latest. Either keep it as the publish step or replace it with semantic-release; the guard rails matter more than the tool.Open question worth deciding early: semantic-release or the existing script. semantic-release also handles version bumping and changelog generation from commits, which is a larger change to how this repo works. The smaller step is branch-triggered publishing with the current script, keeping hand-written changelogs.
Also worth fixing regardless
scripts/release.jsspawnspnpm publishthroughexecFileSyncwithstdio: 'inherit'. npm's 2FA browser prompt printed but did not appear to block, and publishing by hand is what eventually worked. If any manual path survives, that spawn should hand the TTY through properly — but automating the publish removes the interactive prompt entirely, which is the better answer.Acceptance
Pushing to a release branch publishes every package under the matching dist-tag, from CI, with provenance, and only after tests pass.