Files
openidea/scripts/release-prepare.test.ts
T
l0ng-ai 37f0897eb7 chore(release): prepare the release commit with one command (#1672)
pnpm release:prepare <version> sets the app version in Cargo.toml, package.json and tauri.conf.json, refreshes Cargo.lock's workspace entries, and copies wit/*.wit over the plugin API snapshot when wit/ declares a newer API. The release workflow refused a tag with a stale snapshot, but the copy itself was a manual step.
2026-11-06 10:30:56 +08:00

85 lines
3.1 KiB
TypeScript

// @vitest-environment node
import { afterEach, describe, expect, it } from "vitest";
import { mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
SNAPSHOT,
apiVersion,
cargoVersion,
parseVersion,
setCargoVersion,
setJsonVersion,
syncApiSnapshot,
} from "./release-prepare.ts";
const dirs: string[] = [];
afterEach(() => dirs.splice(0).forEach((dir) => rmSync(dir, { recursive: true, force: true })));
function repo(wit: Record<string, string>, snapshot: Record<string, string>): string {
const root = mkdtempSync(join(tmpdir(), "release-prepare-"));
dirs.push(root);
for (const [dir, files] of [
["wit", wit],
[SNAPSHOT, snapshot],
] as const) {
mkdirSync(join(root, dir), { recursive: true });
for (const [name, text] of Object.entries(files)) writeFileSync(join(root, dir, name), text);
}
return root;
}
const pkg = (version: string) => `package openidea:plugin@${version};\n`;
describe("versions", () => {
it("accepts x.y.z with or without a leading v", () => {
expect(parseVersion("0.1.38")).toBe("0.1.38");
expect(parseVersion("v0.1.38")).toBe("0.1.38");
expect(() => parseVersion("0.1")).toThrow();
expect(() => parseVersion(undefined)).toThrow();
});
it("changes only the workspace version in Cargo.toml", () => {
const toml = [
"[workspace]",
'members = ["crates/*"]',
"",
"[workspace.package]",
'authors = ["a"]',
'version = "0.1.37"',
'edition = "2024"',
"",
"[workspace.dependencies]",
'foo = { version = "0.1.37" }',
"",
].join("\n");
expect(cargoVersion(toml)).toBe("0.1.37");
const next = setCargoVersion(toml, "0.1.38");
expect(cargoVersion(next)).toBe("0.1.38");
expect(next).toContain('foo = { version = "0.1.37" }');
expect(next.split("\n")).toHaveLength(toml.split("\n").length);
});
it("keeps a JSON file's formatting", () => {
const json = '{\n "name": "openidea",\n "version": "0.1.37",\n "private": true\n}\n';
expect(setJsonVersion(json, "0.1.38")).toBe(json.replace("0.1.37", "0.1.38"));
});
});
describe("plugin API snapshot", () => {
it("copies wit/ over the snapshot when the API version moved, dropping stale files", () => {
const root = repo(
{ "plugin.wit": pkg("1.2.0"), "indexing.wit": pkg("1.2.0") },
{ "plugin.wit": pkg("1.1.0"), "old.wit": pkg("1.1.0"), "README.md": "kept" },
);
expect(syncApiSnapshot(root)).toEqual({ from: "1.1.0", to: "1.2.0", copied: true });
expect(readdirSync(join(root, SNAPSHOT)).sort()).toEqual(["README.md", "indexing.wit", "plugin.wit"]);
expect(apiVersion(readFileSync(join(root, SNAPSHOT, "plugin.wit"), "utf8"))).toBe("1.2.0");
});
it("leaves the snapshot alone when the API is unchanged", () => {
const root = repo({ "plugin.wit": pkg("1.1.0") + "// edited\n" }, { "plugin.wit": pkg("1.1.0") });
expect(syncApiSnapshot(root)).toEqual({ from: "1.1.0", to: "1.1.0", copied: false });
expect(readFileSync(join(root, SNAPSHOT, "plugin.wit"), "utf8")).toBe(pkg("1.1.0"));
});
});