Skip to content

Harden npm publish pipeline with OIDC trusted publishing#6

Merged
robfig merged 3 commits into
masterfrom
robfig/npm-publish-hardening
May 20, 2026
Merged

Harden npm publish pipeline with OIDC trusted publishing#6
robfig merged 3 commits into
masterfrom
robfig/npm-publish-hardening

Conversation

@robfig
Copy link
Copy Markdown
Contributor

@robfig robfig commented May 6, 2026

Summary

  • Move releases off developer machines into a new release.yml GitHub Actions workflow that publishes via npm trusted publishing (OIDC) with provenance — no long-lived NPM_TOKEN anywhere. Triggered by release: published, gated by an npm-publish GitHub Environment, with a tag-vs-package.json version check before publish.
  • Pin all GitHub Actions in ci.yml and release.yml to commit SHAs, add persist-credentials: false and a job timeout, and introduce .github/dependabot.yml to keep the SHA pins current.
  • Add publishConfig (access: public, provenance: true) to package.json and replace the manual publish checklist in the README with a "Releasing" section covering the CI flow, rollback (npm deprecate), and troubleshooting.

Out-of-band steps required before this can publish

These cannot be done in code — please complete on merge:

  1. Configure npm Trusted Publisher on @roamhq/openclaw-roam (org WonderInventions, repo openclaw-roam, workflow release.yml, environment npm-publish).
  2. Create the npm-publish GitHub Environment with deployment branches/tags restricted to master and v* (no required reviewers, per request).
  3. Enable branch protection on master and reduce individual maintainer publish rights on npm after the first successful CI publish.

Test plan

  • npm run typecheck clean
  • npm test — 139/139 passing
  • npm pack --dry-run clean (35 files, 54.3 kB)
  • All YAML files parse cleanly
  • After merge: cut a 0.1.2-rc.0 prerelease via the new flow and verify the green provenance badge on npmjs.com

🤖 Generated with Claude Code

@robfig robfig requested a review from derekcicerone May 20, 2026 15:56
Move releases off developer machines into a GitHub Actions workflow that
publishes via npm trusted publishing (OIDC) with provenance, eliminating
long-lived npm tokens. Also pin all GitHub Actions to commit SHAs and add
Dependabot to keep them current.

- New release.yml: runs on `release: published`, gated by `npm-publish`
  environment, verifies tag matches package.json version, publishes with
  `--provenance --access public`. No NPM_TOKEN.
- ci.yml: pin actions to SHAs, add `persist-credentials: false` and
  `timeout-minutes: 15`.
- package.json: add `publishConfig` with `provenance: true`.
- README: replace manual publish checklist with new Releasing section
  covering the CI flow, rollback, and troubleshooting.

Out-of-band steps (not in this commit) still required before the next
release: configure npm Trusted Publisher, create the `npm-publish` GitHub
Environment with master+v* restriction, enable branch protection, and
reduce individual maintainer publish rights on npm once CI publishes
work end-to-end.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Comment thread .github/workflows/release.yml Outdated
Comment on lines +33 to +34
- name: Upgrade npm (trusted publishing requires >= 11.5.1)
run: npm install -g npm@latest
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

dont think this is necessary

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Kept the npm upgrade, but narrowed it from npm@latest to npm@11. The current npm trusted-publishing docs still require npm CLI >=11.5.1, and this workflow uses Node 22, so I do not want to rely on the bundled npm being new enough: https://docs.npmjs.com/trusted-publishers

- name: Upgrade npm (trusted publishing requires >= 11.5.1)
run: npm install -g npm@latest

- run: npm ci
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ensure there is an npmrc that looks like this in the repo:

ignore-scripts=true
min-release-age=3
save-exact=true

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added the repo .npmrc with those settings. Since ignore-scripts=true means the publish path should not rely on prepublishOnly, I also added an explicit npm run build before npm publish and verified the dry-run tarball includes dist.

jobs:
publish:
runs-on: ubuntu-latest
environment: npm-publish
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

fancy

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Leaving this in place as the GitHub Environment gate for the publish job. It lets us apply the npm-publish branch/tag restrictions outside the workflow.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

i assume this is from a bot? I was just commenting that its fancy

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah :)

Copy link
Copy Markdown

@derekcicerone derekcicerone left a comment

Choose a reason for hiding this comment

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

looks good, just some small tweaks

@robfig robfig force-pushed the robfig/npm-publish-hardening branch from 55751dd to 76d023b Compare May 20, 2026 16:09
Copy link
Copy Markdown

@derekcicerone derekcicerone left a comment

Choose a reason for hiding this comment

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

looks good

@robfig robfig merged commit bd1bf56 into master May 20, 2026
1 check passed
@robfig robfig deleted the robfig/npm-publish-hardening branch May 20, 2026 16:21
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