Skip to content

[SDK-720] Publish to npm with trusted publishing - #32

Open
devtools-agent[bot] wants to merge 2 commits into
masterfrom
SDK-720-npm-trusted-publishing
Open

devtools-agent[bot] wants to merge 2 commits into
masterfrom
SDK-720-npm-trusted-publishing

Conversation

@devtools-agent

@devtools-agent devtools-agent Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Linear: SDK-720

What changed

  • .github/workflows/publish.yml (new): runs on release: published with permissions: { id-token: write, contents: read }.
    • Checks out the release tag (github.event.release.tag_name).
    • Node 24 via actions/setup-node@v4 (registry https://registry.npmjs.org), then npm install -g npm@^11.5.1, since trusted publishing needs npm 11.5.1+.
    • Fails with an ::error:: unless package.json's version equals the tag with any leading v removed.
    • npm ci, then npm run build --if-present (rollbar-cli has no build script today, so this is a no-op until one exists).
    • npm test, so every publish is gated on a passing suite. node.js.yml only runs on pushes and PRs to master, so a release cut from a tag on any other commit would otherwise reach npm untested. The coverage output (coverage/, .nyc_output/) is gitignored, so it stays out of the tarball.
    • npm publish --provenance --access public --tag <latest|next>: versions with a pre-release part (e.g. 3.2.0-rc.1) go to next, everything else to latest. No NPM_TOKEN anywhere.
  • package-lock.json is now committed and removed from .gitignore, because npm ci fails without a lockfile. It was generated with npm install --package-lock-only against the current package.json and no dependency versions changed.
  • node.js.yml is unchanged.

Why

This moves releases to npm trusted publishing (OIDC plus provenance) so no long-lived npm token is needed. The matching trusted publisher on npmjs.com must name workflow file publish.yml.

Validation

  • The YAML parses and the trigger and permissions are as specified.
  • Ran the version/dist-tag shell logic on a matrix of inputs: v0.2.1/0.2.1 with 0.2.1 → latest; v3.2.0-rc.1 with 3.2.0-rc.1 → next; any mismatch fails.
  • In a clean copy of the tree: npm ci succeeded, npm run build --if-present was a no-op, npm test passed (36 passing), and npm publish --dry-run --access public --tag next showed rollbar-cli@0.2.1 going to registry.npmjs.org.
  • After adding the test step: with npm 11 (the version the workflow installs) and the repo's ignore-scripts=true, npm test still runs (36 passing), and npm pack --dry-run afterwards includes no coverage/ or .nyc_output/ files.
  • The real OIDC publish can only be tested with an actual GitHub release once the trusted publisher is configured on npmjs.com.

🤖 Generated with Claude Code

Add .github/workflows/publish.yml, which runs on release: published and
publishes to npm via OIDC trusted publishing (no NPM_TOKEN). It checks out
the release tag, fails unless package.json's version matches the tag
(minus a leading v), runs npm ci and the build if one exists, then
npm publish --provenance --access public. Pre-release versions publish
under the next dist-tag.

npm ci needs a lockfile, so package-lock.json is no longer gitignored and
is committed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Sep 29, 2026

Copy link
Copy Markdown

SDK-720

@rollbar-circleci-machine rollbar-circleci-machine left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Agent Review (openai, openai-astra)

Review: publish to npm with trusted publishing

The workflow is small and generally sound:

  • OIDC: permissions are limited to id-token: write and contents: read.
  • Injection: the release tag reaches the shell through env (TAG), not direct ${{ }} interpolation.
  • Dist-tag: it can only be the fixed strings next or latest.
  • Version check: it correctly strips a leading v from the tag.
  • Provenance: repository.url in package.json (git+https://github.com/rollbar/rollbar-cli.git) matches this repo.
  • Lockfile: the new package-lock.json is lockfileVersion 3 and its root entry matches package.json (version 0.2.1, same dependency ranges). All 460 resolved URLs point at https://registry.npmjs.org/, with no private or mirror registries. npm never includes package-lock.json in the published tarball, so committing it doesn't affect consumers.
  • Install scripts: the project .npmrc sets ignore-scripts=true, so npm ci in the publish job won't run dependency install scripts.

One finding (low): the publish job never runs npm test, and the existing CI workflow doesn't cover tag commits well enough to make up for it (see the inline comment).

Outside the changed files (not findings):

  • .github/workflows/node.js.yml:32-35 refers to matrix.node-version, but the matrix only defines node and npm (lines 17-28). So CI never actually tests the Node/npm matrix, only the runner's default Node.
  • The same workflow runs npm install, not npm ci. Now that the lockfile is committed, CI won't catch a package.json change that leaves package-lock.json out of date. The first time that shows up would be the npm ci step here, at release time. Switching CI to npm ci would catch it earlier.
  • package.json has no files field and there's no .npmignore, so the published tarball includes test/ (including the large angular9/react16 fixture builds) and .github/. This is how the package was already being published, but it's worth adding files now that publishing is automated.
  • actions/checkout@v4 and actions/setup-node@v4 are pinned to major tags, not commit SHAs. Consider pinning them, since this job can mint a publish token.

This is a static review only. Nothing was run, and I make no claim about the workflow succeeding end to end.

Comment thread .github/workflows/publish.yml
Gate npm publish on `npm test` so a release cut from a tag that CI never
tested cannot reach npm with a failing suite. Coverage output is gitignored,
so it stays out of the published tarball.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rollbar-circleci-machine

Copy link
Copy Markdown

AI Agent Review (openai, openai-astra)

Review: npm trusted publishing workflow + committed lockfile

No problems found on the changed lines.

What I checked

  • The new publish.yml workflow grants only id-token: write and contents: read (.github/workflows/publish.yml:11-13), which is what trusted publishing needs.
  • Script injection: the release tag reaches the shell through an env var (TAG) rather than being pasted into the run: script (publish.yml:34-37). The only value pasted into npm publish is dist_tag, which the script sets to next or latest itself (publish.yml:42-45,50).
  • Version check: the tag, minus any leading v, must match package.json's version. Versions containing a hyphen (prereleases) are published under next (publish.yml:37-45).
  • --provenance: package.json:33-35 points at git+https://github.com/rollbar/rollbar-cli.git, which matches this repo, as provenance requires.
  • Project .npmrc: it sets ignore-scripts=true (.npmrc:1). That does not stop npm test or npm run build --if-present from running. package.json:8-11 defines no pre*/post*/prepack/prepublishOnly scripts that would be silently skipped.
  • What gets published: npm test writes coverage/ and .nyc_output/. There is no .npmignore, so npm falls back to .gitignore, which still lists both (.gitignore:2-3). They stay out of the tarball.
  • .gitignore change: dropping package-lock.json is what lets npm ci (publish.yml:47) work. npm never puts package-lock.json in a published tarball, so this doesn't change what ships.
  • package-lock.json: lockfile v3. Its root entry matches package.json's dependencies, devDependencies and bin exactly (package-lock.json:7-29). All 460 resolved URLs point at https://registry.npmjs.org/; there are no git, file or third-party sources. The highest engines.node floor is >=18 (node-releases, package-lock.json:3755). axios is locked at the exact 1.15.0 pin (package-lock.json:694-697).

Worth fixing, outside this diff (not reported as findings)

  • The existing CI never picks a Node version: .github/workflows/node.js.yml:35 passes ${{ matrix.node-version }}, but the matrix keys are node and npm (node.js.yml:18-28). So every matrix job runs on the runner's default Node, and the npm versions are never installed. Nothing tests the suite on Node 24, which is the version publish.yml:26 uses for the npm test that gates publishing. The CI also still uses actions/checkout@v2, actions/setup-node@v1 and npm install instead of npm ci.
  • Broken main entry: package.json:29 sets "main": "index.js", but there is no root index.js; the entry lives at src/index.js. This predates the PR.

Optional hardening (a policy choice, not a defect)

  • Who can publish: anyone who can publish a GitHub release can now push a version to npm. To keep a human approval step, add a protected GitHub environment: with required reviewers to the publish job, and name the same environment in the npmjs.com trusted-publisher settings.
  • Pin actions: you could pin actions/checkout and actions/setup-node to commit SHAs instead of @v4.

I couldn't run anything, so I haven't confirmed that the tests pass on Node 24 or that a publish succeeds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants