Skip to content

build: publish npm prereleases from tags with trusted publishing - #293

Open
gnidan wants to merge 9 commits into
mainfrom
build-npm-prerelease
Open

gnidan wants to merge 9 commits into
mainfrom
build-npm-prerelease

Conversation

@gnidan

@gnidan gnidan commented Sep 14, 2026

Copy link
Copy Markdown
Member

What ships: the seven public packages get files limited to dist/ (minus .tsbuildinfo), engines, a full repository entry, a LICENSE copy, and a README; conformance becomes private; bugc's CLI now runs from dist/bin/bugc.js with a node shebang.

What changes for developers: each public package builds from a new tsconfig.build.json that excludes tests, via a single clean build script that prepare calls; root yarn build is now lerna run build --no-private; pointers' test cases move to test/; the React packages copy their stylesheets into dist/.

How publishing works: yarn lerna version prerelease --no-push --no-commit-hooks bumps and tags locally, a manual git push --atomic origin main --follow-tags lands them, and publish.yml publishes every package tagged at HEAD with the npm CLI under trusted publishing. A tarball allow-list runs in CI on Node 20 and 22 and again before each publish.

First release: trusted publishers are configured on the two packages that already exist; the five new ones need one local publish, after which CI handles everything.

@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://ethdebug.github.io/format/pr-preview/pr-293/

Built to branch gh-pages at 2026-09-15 18:30 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@gnidan
gnidan force-pushed the build-npm-prerelease branch from abf9ee0 to bf8f4bb Compare September 15, 2026 17:39
Give the seven public packages the fields npm and its consumers need:
`files` limited to `dist` (minus the incremental build info),
`engines`, a full `repository` entry with `directory`, a LICENSE copy,
and a README that states the supported TypeScript resolution modes
(node16, nodenext, bundler).

Declare the runtime dependencies that were only devDependencies or an
optional peer: pointers on format, evm on pointers, bugc on
ethereum-cryptography. Each of those packages failed to import when
installed alone.

Run bugc's CLI from `dist/bin/bugc.js` with a node shebang; the source
shebang needed tsx, which consumers do not have.

Mark conformance private: it is a test harness, not a library.
`src/test-cases.ts` imported the `test/` helpers, so it could not stay
in the shipped tree once `test/` is excluded from the build. It lives
in `test/` now; the integration test, the example runner, and the four
docs pages that embed it follow.
Each public package gets a `tsconfig.build.json` that includes only
`src/` (plus `bin/` for bugc), excludes tests, turns off declaration
maps, and restates its project references against the sibling build
configs: references are not inherited through `extends`, and
`tsc --build` needs them to build dependencies first.

One `build` script per package does the generation step, wipes
`dist/`, and compiles; `prepare` calls it, so a fresh install and a
publish produce the same clean output. Root `build` runs the package
builds in dependency order through Lerna, skipping the private
packages; root `test` runs vitest once.

A root `nx.json` makes Lerna resolve the workspace root inside a git
worktree instead of the shallowest ancestor that contains nx.

format's `watch` no longer starts with the clean build, which raced
the other watchers.
tsc does not copy CSS, so the React packages' stylesheets were absent
from anything built from `dist/`. The build now copies `src/**/*.css`
into `dist/src/`, bugc-react exports the new path, and the playground
imports it.
`checkPackList` accepts only `package.json`, README, LICENSE,
`dist/src/**` and `dist/bin/**`, and rejects anything that looks like
a test or build info. `packList` runs `npm pack --dry-run --json` and
reads the last JSON array, because a package's `prepare` script prints
before it. Tests live in a root `bin` vitest project.
`publish-tagged.ts` reads the Lerna tags that point at HEAD, maps them
to public workspaces, checks each tag against the manifest version,
and publishes in dependency order with
`npm publish --access public --tag latest`. The explicit tag is
required: npm 11 refuses to publish a prerelease version without one.
Provenance is requested only under GitHub Actions.

Before each publish the script asks the registry for the package's
versions and skips one that is already there, so a re-run after a
partial failure is safe; any other registry error aborts the run. It
also checks the pack list, prints published, skipped and failed
summaries, and warns about a tag that names no workspace.

Lerna's own publish command is not used: it cannot exchange the GitHub
OIDC token for npm credentials.
`check-tarballs.ts` runs the allow-list check on every public package.
`smoke-tarballs.ts` goes further: it packs each package, installs it
alone in a temporary directory with only its sibling tarballs, imports
it, and runs bugc's CLI. The allow-list sees file names only; the
smoke test is what catches a runtime dependency declared as a
devDependency, which the workspace's hoisted node_modules and the
registry's stale 0.1.0-0 builds would otherwise hide.
The publish job needs Node 22 for npm 11, so the test suite runs on
both versions. The tarball checks run after the tests.
Lerna pushes the Publish commit and its tags in one atomic push, and
GitHub creates no tag events when more than three tags arrive at once,
so the workflow triggers on pushes to main. A short `check` job looks
for package tags at HEAD and gates the publish job, which installs
npm 11 for trusted publishing, runs the tests, and calls
`publish-tagged.ts`. A manual dispatch defaults to a dry run.
@gnidan
gnidan force-pushed the build-npm-prerelease branch from a4b9021 to 3a86ef1 Compare September 15, 2026 18:26
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