Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

scripts/release/index.test.ts

Raw
import {
	mkdirSync,
	mkdtempSync,
	readFileSync,
	rmSync,
	writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
	deliverGit,
	digestTree,
	npmPackFiles,
	snapshot,
	verifiedReceipt,
} from "./index.ts";

const roots: string[] = [];
function repo(publish = true): { root: string; dist: string; release: string } {
	const root = mkdtempSync(join(tmpdir(), "pi-ext-release-test-"));
	roots.push(root);
	const ext = join(root, "extensions", "demo");
	const dist = join(root, "dist");
	mkdirSync(ext, { recursive: true });
	writeFileSync(join(root, "package.json"), '{"version":"1.2.3"}\n');
	writeFileSync(
		join(ext, "scenario.mjs"),
		"export async function verify() {}\n",
	);
	writeFileSync(
		join(ext, "package.json"),
		JSON.stringify({
			"pi-ext": publish
				? {
						publish: true,
						publicName: "@owned/demo",
						git: "file:///never-push",
						releaseScenario: "scenario.mjs",
					}
				: {},
		}),
	);
	mkdirSync(join(dist, "demo"), { recursive: true });
	writeFileSync(join(dist, "demo", "index.js"), "export default () => {};\n");
	writeFileSync(
		join(dist, "demo", ".pi-ext-build.json"),
		'{"files":["index.js","package.json"]}\n',
	);
	writeFileSync(
		join(dist, "demo", "package.json"),
		'{"name":"@bugabinga/pi-ext-demo","private":true}\n',
	);
	return { root, dist, release: join(root, "release") };
}
afterEach(() =>
	roots
		.splice(0)
		.forEach((root) => rmSync(root, { recursive: true, force: true })),
);

describe("release snapshots", () => {
	it("fails closed for private extensions", () => {
		const input = repo(false);
		expect(() =>
			snapshot("demo", {
				root: input.root,
				distRoot: input.dist,
				releaseRoot: input.release,
			}),
		).toThrow(/not eligible/u);
	});

	it("hashes CI and verifier before receipt, packs only runtime bytes, and rejects tampering", () => {
		const input = repo();
		const receipt = snapshot("demo", {
			root: input.root,
			distRoot: input.dist,
			releaseRoot: input.release,
		});
		expect(digestTree(receipt.path)).toBe(receipt.digest);
		expect(
			readFileSync(join(receipt.path, ".ci", "standalone.kdl"), "utf8"),
		).toContain('image "node:24-alpine"');
		expect(npmPackFiles(receipt.path)).toEqual(["index.js", "package.json"]);
		expect(
			verifiedReceipt("demo", {
				distRoot: input.dist,
				releaseRoot: input.release,
			}).digest,
		).toBe(receipt.digest);
		writeFileSync(join(input.dist, "demo", "index.js"), "tampered\n");
		expect(() =>
			verifiedReceipt("demo", {
				distRoot: input.dist,
				releaseRoot: input.release,
			}),
		).toThrow(/current dist differs/u);
	});

	it("delivers a root package in an isolated local Git repository", () => {
		const input = repo();
		const receipt = snapshot("demo", {
			root: input.root,
			distRoot: input.dist,
			releaseRoot: input.release,
		});
		expect(receipt.extension).toBe("demo");
		const git = deliverGit("demo", {
			distRoot: input.dist,
			releaseRoot: input.release,
		});
		roots.push(git);
		expect(readFileSync(join(git, "package.json"), "utf8")).toContain(
			"@owned/demo",
		);
		expect(() =>
			readFileSync(join(git, "extensions", "demo", "index.ts"), "utf8"),
		).toThrow();
	});
});