Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .changeset/republish-dist.md
Original file line number Diff line number Diff line change
@@ -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).
52 changes: 45 additions & 7 deletions scripts/release.ts
Original file line number Diff line number Diff line change
@@ -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: <name>@<version>` 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,
Expand All @@ -28,12 +34,42 @@ async function ensureReleaseTag(tag: string): Promise<void> {
await $`git tag -a ${tag} -m ${tag}`;
}

function distExportPaths(exportsField: unknown): string[] {
const out = new Set<string>();
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<string, unknown>)) {
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 {
Expand All @@ -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")
Expand Down
Loading