Skip to content

Distribution: CLI releases, install scripts, npm packages#22

Open
koomen wants to merge 2 commits into
mainfrom
distribution-infra
Open

Distribution: CLI releases, install scripts, npm packages#22
koomen wants to merge 2 commits into
mainfrom
distribution-infra

Conversation

@koomen

@koomen koomen commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Implements notes/distribution-plan.md end to end (every item except the first real release, which happens after merge per RELEASING.md).

What's here

  • Version plumbingbun scripts/set-version.ts X.Y.Z stamps root + all workspaces; lockstep is enforced in bun run ci; CHANGELOG.md feeds release notes.
  • CLI releasescli/build.js --all-targets cross-compiles darwin/linux × arm64/x64 (verified locally: all four binaries build and package); release.yml triggers on v* tags, runs the same one gate, asserts tag == version, and creates the GitHub Release with archives + checksums.txt.
  • install.sh / install.md — POSIX, checksum-verified, ~/.local/bin, never sudo; latest-version discovery reads asset names from checksums.txt so no GitHub API call. Hermetically tested in ci (local HTTP fixture, fake uname for platform mapping) plus a serving test pinning .shtext/plain and raw .md round-tripping.
  • npm packages (built JS + .d.ts, per the decision-2 flip) — the five packages tsc-emit to dist/ and stage publish-shaped tarballs; ci packs them, imports every package under plain Node from the real tarballs, and typechecks a NodeNext consumer. scripts/publish-packages.ts publishes from a clean tagged checkout in dependency order.

Discovered work (details in the plan note)

Publishing forced structural fixes the plan hadn't named: cross-package imports moved from relative ../../../shared paths to @scratchwork/* specifiers; publishable packages use explicit .ts import extensions (rewriteRelativeImportExtensions, with a d.ts post-process); the Bun-only svg text import became a generated module; and the server tooling workspace dissolved into server/core/src/deploy/ (proc.ts ported from Bun.spawn to node:child_process so deploys run under plain Node).

⚠️ Two calls to veto

  1. License: MIT — the repo had no LICENSE and npm packages need one. Added MIT at root, © Peter Koomen. Swap it before the first publish if you want something else.
  2. Effect-boundary allowlist grew by twoserver/core/src/deploy/{env,proc}.ts (pre-existing plain-Promise deploy tooling that moved into lint scope; rationale inline). An Effect-native rewrite of the deploy tooling chain would let the baseline shrink again.

Invariants: verified per AGENTS.md (report in the session) — auth/adapters/routes untouched beyond mechanical import-specifier rewrites; full bun run ci green.

🤖 Generated with Claude Code

Pete Koomen and others added 2 commits July 21, 2026 08:13
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase 1 — version plumbing: scripts/set-version.ts stamps the lockstep
version across root + all workspaces; scripts/check-versions.ts enforces it
in the gate; CHANGELOG.md seeds the release-notes flow.

Phase 2 — CLI releases: cli/build.js --all-targets cross-compiles the four
release targets; scripts/package-release.ts produces tar.gz archives +
checksums.txt; .github/workflows/release.yml (tag v*) runs the same one gate,
asserts tag == lockstep version, and publishes the GitHub Release with the
CHANGELOG section as notes.

Phase 3 — install entry points: docs/install.sh (POSIX, checksum-verified,
~/.local/bin, no sudo; discovers the latest version from checksums.txt so no
GitHub API call) and docs/install.md (agent-readable manual steps).
scripts/check-install-sh.ts drives the full install loop against a local HTTP
fixture in ci; a shared serving test pins .sh-as-text/plain and raw .md
round-tripping.

Phase 4 — npm packages: the five publishable packages (shared, server-core,
server-deploy-{aws,cloudflare,local}) build to dist/ (tsc ESM +
declarations) and stage publish-shaped tarballs; scripts/check-npm-pack.ts
verifies tarball shape, imports every package under plain Node (Bun for
deploy-local), and typechecks a NodeNext consumer — all hermetically in ci.
scripts/publish-packages.ts publishes from a clean tagged checkout.

Discovered prerequisites shipped along the way: cross-package imports moved
from relative ../../../shared paths to @scratchwork/* specifiers with real
workspace deps; relative imports in publishable packages carry .ts extensions
for rewriteRelativeImportExtensions (d.ts specifiers post-processed); the
Bun-only svg text import became a generated module (freshness-checked); the
server tooling workspace dissolved into server/core/src/deploy/ with proc.ts
ported to node:child_process so deploys run under plain Node; MIT LICENSE
added (packages can't publish without one — flag if you want a different
license).

Phase 5 — RELEASING.md documents the loop end to end. The first real release
(v0.2.0) is the remaining unchecked plan item.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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