ReviewOS

craft-native/craft

fix(release): build and validate every npm workspace before publishing

#288
Closed glennmichael123 opened this 10 days ago ·
10 days ago

Release blocker

The current npm release job installs dependencies and immediately runs pantry publish --npm --access public; it never builds all publishable workspaces. Only craft-native has a prepublishOnly build hook, so the v0.0.92 registry artifacts for six secondary packages were published without dist/:

  • @craft-native/android: 2 missing targets (dist/index.js, dist/index.d.ts)
  • @craft-native/ios: 3 missing targets (dist/index.js, dist/index.d.ts, dist/cli.js)
  • @craft-native/react: all 3 distinct dist entry files missing
  • @craft-native/svelte: all 3 dist entry files plus its declared source entry missing
  • @craft-native/ts-maps: all 8 declared dist subpath files missing
  • @craft-native/vue: all 3 distinct dist entry files missing

craft-native and create-craft are the only v0.0.92 tarballs whose declared file targets are present. Across the eight published manifests, 32 manifest references (23 distinct physical paths) are absent.

Reproduction

npm pack craft-native@0.0.92 create-craft@0.0.92 \
  @craft-native/android@0.0.92 @craft-native/ios@0.0.92 \
  @craft-native/react@0.0.92 @craft-native/svelte@0.0.92 \
  @craft-native/ts-maps@0.0.92 @craft-native/vue@0.0.92

tar -tzf craft-native-react-0.0.92.tgz
tar -tzf craft-native-ts-maps-0.0.92.tgz

The React tarball contains only package metadata/docs/license; the ts-maps tarball contains source but no dist. Equivalent omissions affect the other four packages above.

Root cause

.github/workflows/release.yml npm job currently does:

  1. bun install
  2. pantry publish --npm --access public

It does not run package builds or verify:packages. The root SDK survives because packages/typescript/package.json alone defines prepublishOnly: bun run build.

Expected

  • Build every publishable npm workspace before publishing (including ts-maps, which is currently absent from root build:all).
  • Pack each workspace and fail if any declared main, module, types, bin, or concrete exports target is absent.
  • Run an import/type-resolution smoke test against the packed artifacts before registry mutation.
  • Republish corrected packages under a new version; npm 0.0.92 is already immutable.

Separate package-local defects remain after a build and are tracked in #286 (mobile declarations) and #287 (Svelte source export). Found during the release-readiness audit alongside #272.

10 days ago

The existing verification explains why CI stayed green:

  • scripts/verify-packages.ts only enumerates packages/typescript, packages/create-craft, and packages/ts-maps; it omits Android, iOS, React, Svelte, and Vue.
  • It checks files in the workspace, not the output of bun pm pack/the registry tarball, so stale or pre-existing dist directories can satisfy it even when the release job publishes from a fresh checkout without building.
  • scripts/verify-builds.ts checks several local dist files, but the npm job runs neither builds nor either verifier before pantry publish.
  • Root build:all itself omits packages/ts-maps.

The regression gate should therefore validate freshly packed tarballs after explicit builds, not only workspace paths.

10 days ago

Regression-window check: the same six packages in npm 0.0.91 have the same missing-build shape (Android/iOS ship templates but no dist; React/Svelte/Vue ship only metadata/docs/license; ts-maps ships source but no dist). The registry break therefore affects at least 0.0.91–0.0.92 and was not introduced by the scoped changes merged today.

10 days ago

The exact React registry cutoff is now confirmed: 0.0.74 contains its full dist tree, while 0.0.75 and every sampled/newer release through 0.0.92 contain only metadata/docs/license. The repository npm job itself is materially identical across the v0.0.74→v0.0.75 diff; the only workflow change was signing-credential handling, while Pantry setup still referenced mutable @main. That makes an external Pantry action/CLI behavior change between those runs a plausible trigger, but the durable fix remains explicit repository-owned builds plus packed-artifact validation before publish.

10 days ago

Verified the corrected publish path in v0.0.98. The release npm job succeeded after Test package regressions, Build and verify every npm artifact, Scan packed npm artifacts and production dependencies, and Publish scanned npm archives: https://github.com/craft-native/craft/actions/runs/36445986425 . I independently downloaded the published registry tarballs for all eight public packages (craft-native, create-craft, and the android, ios, react, svelte, ts-maps, vue packages). Their packed manifests all report 0.0.98, and all 35 declared main/module/types/bin/svelte/concrete exports targets are present. In a separate temporary consumer using the downloaded archives, all 13 package and subpath imports executed and resolved under strict TypeScript/bundler settings. The create-craft CLI also ran with --help after supplying its declared @stacksjs/clapp dependency. The v0.0.92 registry artifacts remain immutable, but v0.0.98 republishes corrected archives; closing this release blocker.

Sign in to comment on this issue.