Skip to content

ci: publish to npm when a release is published - #304

Merged
ralyodio merged 1 commit into
mainfrom
ci/npm-publish-on-release
Aug 5, 2026
Merged

ci: publish to npm when a release is published#304
ralyodio merged 1 commit into
mainfrom
ci/npm-publish-on-release

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds .github/workflows/publish.yml, which publishes to npm on a published GitHub release.

npm is moshcode's second channel — the first is curl … install.sh | sh — and that is exactly why it cannot be manual. A channel that updates only when someone remembers serves an old version forever, silently, to everyone who found the package instead of the install script. v0.24.0 was published by hand; nothing would have published v0.25.0.

Guards

npm will not let a version be replaced, so the job is deliberately cautious:

guard why
tests run first on the exact tree about to be packed
release tag must equal package.json version a tag/version mismatch would publish the wrong tree under a version nobody can reuse
skip if already on the registry re-running a release that failed transiently is harmless instead of an E403
missing NPM_TOKEN fails with a plain message rather than a bare 401 partway through a release

Publishes with --provenance, signed by a short-lived OIDC token (id-token: write) rather than anything stored in the repo. The repo is public, so provenance is available.

Required before it can work

⚠️ Add a repository secret NPM_TOKEN — an npm automation token (the kind that publishes without a 2FA prompt). There are currently no repository secrets set. Until it exists the job fails with an explicit message naming the missing secret.

Verification

  • YAML parses; 11 steps, triggers release: [published] and workflow_dispatch
  • setup steps mirror the existing test.yml exactly, including the packageManager/pnpm pinning caveat
  • the skip-if-published guard checked against the live registry: moshcode@0.24.0 → skip, moshcode@0.25.0 → proceed
  • publishing v0.24.0 by hand earlier confirmed the tarball itself installs and runs from the registry

🤖 Generated with Claude Code

npm is moshcode's second distribution channel — the first is
`curl … install.sh | sh` — and that is exactly why it cannot be a manual step.
A channel that updates only when someone remembers is one that serves an old
version forever, silently, to everyone who found the package instead of the
install script. 0.24.0 was published by hand; nothing would have published
0.25.0.

The GitHub release is the trigger, so there is no second thing to remember.

Three guards, because npm will not let a version be replaced:

- the tests run first, on the exact tree about to be packed
- a release tag that disagrees with package.json fails rather than publishing
  the wrong tree under a version nobody can reuse
- a version already on the registry is skipped, so re-running a release that
  failed on something transient is harmless rather than an E403

Publishes with provenance, signed by a short-lived OIDC token rather than
anything stored in the repo.

Needs a repository secret NPM_TOKEN — an npm automation token. Until that is
set the job fails with a message saying so, rather than a bare 401.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

92 finding(s)

HIGH/CRITICAL: 50 | MEDIUM: 42

Severity Rule Location
HIGH manifest-typosquat apps/pwa/package.json:19
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:45
HIGH secret-generic-credential apps/pwa/test/apikey-bearer-scheme.test.mjs:30
HIGH secret-generic-credential apps/pwa/test/apikey-mask.test.mjs:38
HIGH secret-generic-credential apps/pwa/test/apikey-reveal.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/approvals-context.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/approvals-credits.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/approvals-notify.test.mjs:26
HIGH secret-generic-credential apps/pwa/test/approvals-resolve-race.test.mjs:20
HIGH secret-generic-credential apps/pwa/test/auth-form-email.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/auth-form-email.test.mjs:33
HIGH secret-generic-credential apps/pwa/test/auth-page-error.test.mjs:36
HIGH secret-generic-credential apps/pwa/test/cli-device-token.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/cli-pages-balance.test.mjs:32
HIGH secret-generic-credential apps/pwa/test/cli-token.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/credits-pack.test.mjs:51
HIGH secret-generic-credential apps/pwa/test/credits-webhook-event-match.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/credits-webhook.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/csrf-input-escaping.test.mjs:31
HIGH secret-generic-credential apps/pwa/test/csrf-input-escaping.test.mjs:101
HIGH secret-generic-credential apps/pwa/test/logout-csrf.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/moshpit-api-key.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-bulk-claim.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-claim-full-name.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/moshpit-crawlable.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-ending-page.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-pins.test.mjs:22
HIGH secret-generic-credential apps/pwa/test/moshpit-pit-page.test.mjs:33
HIGH secret-generic-credential apps/pwa/test/moshpit-records-page.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-records.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-registry.test.mjs:20
HIGH secret-generic-credential apps/pwa/test/moshpit-related-endings.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-sales.test.mjs:16
HIGH secret-generic-credential apps/pwa/test/moshpit-search.test.mjs:74
HIGH secret-generic-credential apps/pwa/test/moshpit-terms.test.mjs:19
HIGH secret-generic-credential apps/pwa/test/moshpit-tlds-pagination.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/passkey-register-duplicate.test.mjs:38
HIGH secret-generic-credential apps/pwa/test/require-auth-next.test.mjs:31
HIGH secret-generic-credential apps/pwa/test/require-auth-next.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/sessions-output-seq.test.mjs:30
HIGH secret-generic-credential apps/pwa/test/sessions-paste.test.mjs:24
HIGH secret-generic-credential apps/pwa/test/sessions-stream-replay.test.mjs:34
HIGH secret-generic-credential apps/pwa/test/sessions.test.mjs:24
HIGH secret-generic-credential apps/pwa/test/signature.test.mjs:6
HIGH secret-generic-credential test/auth.test.mjs:13
HIGH secret-generic-credential test/auth.test.mjs:63
HIGH secret-generic-credential test/console-cookie-malformed.test.mjs:15
HIGH secret-generic-credential test/console.test.mjs:12
HIGH secret-generic-credential test/mirror.test.mjs:37
HIGH secret-generic-credential test/mirror.test.mjs:77

…and 42 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit a0d3145 into main Aug 5, 2026
4 checks passed
@ralyodio
ralyodio deleted the ci/npm-publish-on-release branch August 5, 2026 09:48
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.

1 participant