ci: publish to npm via OIDC trusted publishing - #294
Open
shahzaib-sheikh wants to merge 2 commits into
Open
shahzaib-sheikh wants to merge 2 commits into
shahzaib-sheikh wants to merge 2 commits into
Conversation
Drops the NPM_TOKEN dependency from the @bluefin-exchange/pro-sdk publish path in favour of npm trusted publishing (OIDC). Node moves 20 -> 22 (trusted publishing needs >= 22.14.0) and npm is upgraded in-job, since the OIDC flow needs npm >= 11.5.1. Adds a workflow_dispatch path to retry a failed publish without cutting another tag, guarded so it only publishes a commit reachable from origin/main. The ts-release-<version> tag must match ts/sdk/package.json's version, and a version already on npm is refused up front, since there is no token to fall back on and npm versions are immutable. This repo is public, so npm attaches a provenance attestation automatically under trusted publishing; the package.json repository field already matches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
shahzaib-sheikh
requested review from
a team,
alawrenc and
lucasfronza
as code owners
August 27, 2026 10:02
…rkflow npm_publish_prerelease.yaml published the same package from a second workflow file. npm allows one trusted publisher per package, bound to a single workflow filename, so only one of the two could ever have authorised — the other would have failed with ENEEDAUTH once the token was gone. Folds its `ts-pre-release-*` tag trigger into npm_publish.yaml and deletes it. The pre-release prefix is matched before the release prefix, since both begin with "ts-". Node is 24 rather than 22: the pre-release path already built this package on 24, so it is the better-evidenced choice for the release path too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
What
Moves
@bluefin-exchange/pro-sdkoffsecrets.NPM_TOKENonto npm OIDC trusted publishing.Part of the org-wide move off npm tokens (BFE-934), prompted by the 7k SDK publish failures.
Already proven end to end:
@ember-finance/sdk@2.10.4published this way with no token(ember-sdk#84).
Merging is safe; the next release needs npmjs.com config
Publishing only happens on a
ts-release-*/ts-pre-release-*tag, so nothing publishes onmerge. But the next release will fail unless a
@bluefin-exchangenpm org owner adds, on@bluefin-exchange/pro-sdk→ Settings → Trusted publisher:fireflyprotocolpro-sdknpm_publish.yamlnpm publishpublish_to_npm.yamlagainst apublish_to_npm.ymlfile and the publish failed with a bareENEEDAUTH— npm silently declines OIDC and reports having no credentials, with nothing in theerror naming OIDC or the filename. If a release fails that way, align the names rather than
bumping the version; a failed publish burns nothing.
npm_publish_prerelease.yamlis deleted — this is the important bitIt published the same package from a second workflow file. npm allows exactly one trusted
publisher per package, bound to one workflow filename, so only one of the two files could ever
have authorised — whichever wasn't registered would have started failing
ENEEDAUTHthe momentthe shared token went away. Its
ts-pre-release-*trigger is folded intonpm_publish.yaml:ts-release-<version>latestts-pre-release-<version>pre-releaseThe pre-release prefix is matched first, since both prefixes begin with
ts-. Behaviour isotherwise identical to the two separate files.
Changes
permissions: id-token: write;NODE_AUTH_TOKEN/secrets.NPM_TOKENgone from both paths.24. Trusted publishing requires >= 22.14.0; the release path was on 20, but thepre-release path already built this package on 24, so 24 is the better-evidenced choice.
npm install -g npm@latest— OIDC needs npm >= 11.5.1._authTokenline from the npmrc aftersetup-node.registry-urlunconditionally writes
//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}and exports adummy
NODE_AUTH_TOKEN; npm then treats auth as configured and never attempts the OIDCexchange (setup-node#1551,
npm/documentation#1960). Present on the successful ember-sdk run; repos here using
setup-node@v7publish fine without it, so treat it as belt-and-braces on v4/v6 rather than strictly required — it's a no-op when the line is absent.workflow_dispatch(pre-release/latest) to retry a publish without cuttinganother tag.
ts/sdk/package.json's version, the version must not already be on npm, and a dispatch mustname a commit reachable from
origin/main.concurrencygroup so two tag pushes can't race a publish.yarn install --immutable/yarn buildand thets/sdkworking directory are unchanged.Provenance
Unlike the Ember repos (which are private), this repo is public, so npm attaches a
provenance attestation automatically under trusted publishing — a genuine supply-chain win. The
repositoryfield ints/sdk/package.jsonalready matcheshttps://github.com/fireflyprotocol/pro-sdk.git, which provenance requires. I left provenanceat its default rather than forcing it on, so an attestation problem can't fail an otherwise-good
publish.
Note on the current version
ts/sdk/package.jsonis at2.1.0, which is already on npm underpre-release(latestis2.0.0). The new guard refuses to republish an existing version, so taggingts-release-2.1.0today fails with a clear message instead of an opaque npm conflict — the next release needs a
bump.
Verification
YAML parses, no token references remain, and the tag → dist-tag/version parsing is checked
against
ts-release-2.1.0,ts-pre-release-2.1.0,ts-release-1.17.0andts-pre-release-3.0.0-rc.1. The OIDC handshake itself can only be exercised by a real publish,so the next release is the test — the dispatch path exists to retry it without burning a version.