diff --git a/.changeset/republish-dist.md b/.changeset/republish-dist.md new file mode 100644 index 0000000..f3c9531 --- /dev/null +++ b/.changeset/republish-dist.md @@ -0,0 +1,15 @@ +--- +"@stainless-code/layers": patch +"@stainless-code/layers-devtools": patch +"@stainless-code/react-layers-devtools": patch +"@stainless-code/react-layers": patch +"@stainless-code/vue-layers": patch +"@stainless-code/solid-layers": patch +"@stainless-code/svelte-layers": patch +"@stainless-code/preact-layers": patch +"@stainless-code/alpine-layers": patch +"@stainless-code/lit-layers": patch +"@stainless-code/angular-layers": patch +--- + +Republish with built `dist/` — prior 0.2.x tarballs omitted it (pack ran without build). diff --git a/scripts/release.ts b/scripts/release.ts index 04e1790..4d8babe 100644 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -1,16 +1,22 @@ #!/usr/bin/env bun -import { readdirSync, readFileSync } from "node:fs"; +import { existsSync, readdirSync, readFileSync } from "node:fs"; import { join } from "node:path"; -// Bun cannot perform npm OIDC publishing. Pack with Bun to resolve `workspace:*`, -// then publish the tarball with npm for OIDC authentication and provenance. -// Create an annotated git tag, then print `New tag: @` so -// changesets/action can push the tag and open a GitHub Release. -// Existing registry versions are skipped so partial releases can be retried. +// Pack with Bun (resolves workspace:*) then npm-publish the tarball — Bun can't do npm OIDC/provenance. +// Build first and assert `exports` dist paths exist (CI checkout has no dist/). +// After publish: annotated `name@version` tag + `New tag:` line for changesets/action (push + GitHub Release). +// Skip versions already on the registry so partial releases can retry. import { $ } from "bun"; const PACKAGES_DIR = "packages"; +interface PackageJson { + name?: string; + version?: string; + private?: boolean; + exports?: unknown; +} + async function isAlreadyPublished( name: string, version: string, @@ -28,12 +34,42 @@ async function ensureReleaseTag(tag: string): Promise { await $`git tag -a ${tag} -m ${tag}`; } +function distExportPaths(exportsField: unknown): string[] { + const out = new Set(); + const visit = (value: unknown) => { + if (typeof value === "string") { + if (value.startsWith("./dist/")) out.add(value.slice(2)); + return; + } + if (value && typeof value === "object") { + for (const nested of Object.values(value as Record)) { + visit(nested); + } + } + }; + visit(exportsField); + return [...out].sort(); +} + +function assertDistReady(dir: string, pkg: PackageJson): void { + const missing = distExportPaths(pkg.exports).filter( + (rel) => !existsSync(join(dir, rel)), + ); + if (missing.length === 0) return; + throw new Error( + `${pkg.name}: missing dist export targets after build:\n - ${missing.join("\n - ")}`, + ); +} + +console.log("release: building packages…"); +await $`bun run build`; + let published = 0; for (const entry of readdirSync(PACKAGES_DIR, { withFileTypes: true })) { if (!entry.isDirectory()) continue; const dir = join(PACKAGES_DIR, entry.name); - let pkg: { name?: string; version?: string; private?: boolean }; + let pkg: PackageJson; try { pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8")); } catch { @@ -46,6 +82,8 @@ for (const entry of readdirSync(PACKAGES_DIR, { withFileTypes: true })) { continue; } + assertDistReady(dir, pkg); + const packOut = await $`bun pm pack`.cwd(dir).text(); const tarball = packOut .split("\n")