Skip to content

feat(repo): add the build and release lane entry scripts - #3

Merged
John-David Dalton (jdalton) merged 1 commit into
mainfrom
feat/build-release-lane
Jul 29, 2026
Merged

feat(repo): add the build and release lane entry scripts#3
John-David Dalton (jdalton) merged 1 commit into
mainfrom
feat/build-release-lane

Conversation

@jdalton

@jdalton John-David Dalton (jdalton) commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Defect

The 2026-07-28 fleet code-as-law audit flagged a docs/reality gap in this repo:

  • README/CLAUDE.md claim node-smol owns "source patches, builtins, SEA packaging, platform artifacts, and release assembly", and the README Install section tells users to run gh release download --repo SocketDev/node-smol — but the repo has zero releases and zero repo-owned build/release scripts (only docker/repo/node-smol-base.Dockerfile + the prebake workflow; scripts/repo/ held only the cascaded bootstrap). An agent asked to build or release node-smol had nothing to run.
  • CLAUDE.md asserted .gitmodules carries ref+sha256: pins, while the actual .gitmodules is branch = main + shallow = true with no sha256: (stuie publishes no release tags — the file says so itself).

What this adds

  • scripts/repo/build.mts — a real, runnable build entry for what exists today:
    • --target base (default) bakes the compile-environment image(s) declared in .config/repo/socket-wheelhouse.json docker.prebakes via docker buildx build, mirroring .github/workflows/prebake-publish.yml (same config, same argv shape). Local default builds the host platform and --loads it; --push builds the declared platform matrix (precondition stated: docker login ghcr.io with packages:write; the workflow dispatch stays the canonical publisher).
    • --dry-run prints the exact commands plus their preconditions (argv built by the same function the real run uses, so the plan cannot drift).
    • --target binary fails loud with a precise inventory of what is missing and where the sources are: the builder was never extracted from socket-btm — its extraction manifest (.config/repo/node-smol-rust-extraction.json) marks packages/node-smol-builder and packages/npm as destined for node-smol with removalStatus: "removed"; the pre-drop tree is socket-btm@55f8f23a packages/node-smol-builder. No fantasy steps.
  • scripts/repo/release.mts — release assembly from a built output dir (default build/release/, or --dir). Dry-run is the default; it prints per-asset SHA-256 digests and the exact gh release create --draft command. --publish verifies gh auth, verifies no release exists for the tag (verify-before-publish), writes checksums.txt, and cuts a draft; undrafting (gh release edit <tag> --draft=false) remains a separate deliberate act. Fails loud on a missing/empty asset dir, pointing at the missing binary lane.
  • scripts/repo/paths.mts — repo-tier path anchor inheriting scripts/fleet/paths.mts (1 path, 1 reference). The Dockerfile path is deliberately resolved from socket-wheelhouse.json, not duplicated.
  • package.jsonbuild:repo + release script entries (build is owned by the fleet hook-bundle build, so the repo lane gets a segmented name).
  • README — Install section now states there are no releases yet and points at scripts/repo/build.mts for source builds.
  • CLAUDE.md — the .gitmodules pinning claim now describes the actual pin shape (branch = main + shallow = true, no sha256:) with a TODO naming the intended ref+sha256: contract.

Validation

  • pnpm run lint, pnpm run format:check, pnpm run type — green.
  • pnpm run check — green except dispatch-table-is-current, which is red on the pristine tree too (pre-existing, unrelated to this diff).
  • Exercised: build.mts --dry-run (plan prints), --dry-run --push (full matrix plan), --target binary (fails loud, exit 1), release.mts dry-run against a scratch asset dir (digests + plan) and against the empty default dir (fails loud, exit 1), bad-tag and unknown-target error paths.

What remains (follow-ups, deliberately not in this PR)

  • ref+sha256: submodule pins (blocked on stuie shipping a taggable release; gen/gitmodules-hash --set is the intended tool).
  • Porting the actual binary builder from socket-btm@55f8f23a packages/node-smol-builder (Node source pin, patch series, additions/builtins, SEA packaging, strip/compress) and wiring --target binary to it.
  • A real platform artifact matrix and the first release cut through release.mts.

Note

Low Risk
New local/operator tooling and documentation honesty; no changes to auth, fleet hooks, or production CI behavior beyond wiring npm scripts to new entrypoints.

Overview
Adds repo-owned build and release entrypoints so agents and contributors can run what exists today instead of relying on docs that implied full binary/release workflows with zero scripts and zero GitHub releases.

scripts/repo/build.mts defaults to --target base: it reads docker.prebakes from .config/repo/socket-wheelhouse.json and runs the same docker buildx build shape as the prebake-publish workflow (host platform --load locally; optional --push / --platforms). --dry-run prints the exact plan; --target binary exits with a detailed inventory of what was never ported from socket-btm rather than stubbing steps.

scripts/repo/release.mts stages assets from build/release/ (or --dir), computes SHA-256 digests and checksums.txt, and by default dry-runs the gh release create --draft command; --publish verifies gh auth and that the tag does not already exist before cutting a draft. Empty or missing asset dirs fail loud.

scripts/repo/paths.mts extends fleet paths with BUILD_DIR / RELEASE_ASSETS_DIR without duplicating Dockerfile paths from wheelhouse config. package.json adds build:repo and release scripts.

README states there are no releases yet and documents the build/release scripts instead of implying gh release download works today. CLAUDE.md corrects .gitmodules pinning to the actual branch + shallow shape and notes the future ref+sha256: contract.

Reviewed by Cursor Bugbot for commit df1b557. Configure here.

The repo docs claimed ownership of source patches, builtins, SEA
packaging, platform artifacts, and release assembly, and the README
pointed installers at gh release download, but the repo had zero
releases and zero repo-owned build/release scripts - an agent asked to
build or release node-smol had nothing to run. Flagged by the
2026-07-28 fleet code-as-law audit.

What this adds:

- scripts/repo/build.mts: real entry for what is buildable today. The
  default base target bakes the compile-environment image(s) declared
  in .config/repo/socket-wheelhouse.json docker.prebakes via docker
  buildx, mirroring the prebake-publish workflow; local runs load the
  host platform, --push covers the declared matrix. --dry-run prints
  the exact commands with preconditions. --target binary fails loud,
  naming exactly what was never ported from socket-btm (the pre-drop
  tree is socket-btm@55f8f23a packages/node-smol-builder) instead of
  pretending a lane exists.
- scripts/repo/release.mts: release assembly from a built output dir.
  Dry-run is the default; --publish computes SHA-256 checksums, writes
  checksums.txt, verifies no release exists for the tag, and cuts a
  DRAFT via gh release create --draft. Undrafting stays a separate
  deliberate act. Fails loud on an empty asset dir.
- scripts/repo/paths.mts: repo-tier path anchor inheriting the fleet
  paths module.
- package.json: build:repo and release script entries (build is owned
  by the fleet hook-bundle build, so the repo lane gets a segmented
  name).
- README: the Install section now states there are no releases yet and
  points at scripts/repo/build.mts for source builds.
- CLAUDE.md: the .gitmodules pinning claim now describes the actual
  pin shape (branch = main + shallow = true, no sha256) with a TODO
  for the intended ref+sha256 contract; the sha256 pin itself is
  follow-up work, not part of this change.
@jdalton
John-David Dalton (jdalton) merged commit 598a543 into main Jul 29, 2026
9 checks passed
@jdalton
John-David Dalton (jdalton) deleted the feat/build-release-lane branch July 29, 2026 00:24

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit df1b557. Configure here.

Comment thread scripts/repo/release.mts
return `${digests
.map(entry => `${entry.digest} ${path.basename(entry.file)}`)
.join('\n')}\n`
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nested assets lose unique names

Medium Severity

The release.mts script collects assets recursively, but checksums.txt and gh release create use only the file's basename. This causes collisions for assets with identical names in different subdirectories, leading to ambiguous checksums and failed or clobbered GitHub release uploads.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit df1b557. Configure here.

Comment thread scripts/repo/build.mts
platformsOverride: values.platforms,
push: values.push,
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cover runs docker bake as build

High Severity

Placing the docker prebake entry at scripts/repo/build.mts makes the fleet cover runner treat it as the source-map build entry. pnpm run cover now spawns this script with no flags, so it tries a real docker buildx bake (or fails without Docker) instead of instrumenting sources directly as before.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit df1b557. Configure here.

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