feat: add package-first release flow
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(scriptDir, "..");
|
||||
const uiPackagePath = path.join(repoRoot, "packages", "ui", "package.json");
|
||||
const tokensPackagePath = path.join(repoRoot, "packages", "tokens", "package.json");
|
||||
|
||||
function parseArgs(argv) {
|
||||
const options = {
|
||||
before: null,
|
||||
field: null
|
||||
};
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const current = argv[index];
|
||||
|
||||
if (current === "--before" || current === "--field") {
|
||||
const next = argv[index + 1];
|
||||
|
||||
if (!next) {
|
||||
throw new Error(`Expected a value after ${current}.`);
|
||||
}
|
||||
|
||||
if (current === "--before") {
|
||||
options.before = next;
|
||||
} else {
|
||||
options.field = next;
|
||||
}
|
||||
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new Error(`Unknown argument: ${current}`);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function readVersion(filePath) {
|
||||
return JSON.parse(fs.readFileSync(filePath, "utf8")).version;
|
||||
}
|
||||
|
||||
function readVersionAtRef(ref, filePath) {
|
||||
if (!ref || /^0{40}$/.test(ref)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const content = execFileSync("git", ["show", `${ref}:${path.relative(repoRoot, filePath)}`], {
|
||||
cwd: repoRoot,
|
||||
encoding: "utf8"
|
||||
});
|
||||
return JSON.parse(content).version;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getReleaseMetadata(beforeRef) {
|
||||
const uiVersion = readVersion(uiPackagePath);
|
||||
const tokensVersion = readVersion(tokensPackagePath);
|
||||
|
||||
if (uiVersion !== tokensVersion) {
|
||||
throw new Error(
|
||||
`Expected @ai-ui/ui and @ai-ui/tokens to share a version. Received ${uiVersion} and ${tokensVersion}.`
|
||||
);
|
||||
}
|
||||
|
||||
const previousUiVersion = readVersionAtRef(beforeRef, uiPackagePath);
|
||||
const previousTokensVersion = readVersionAtRef(beforeRef, tokensPackagePath);
|
||||
const changed =
|
||||
previousUiVersion === null ||
|
||||
previousTokensVersion === null ||
|
||||
previousUiVersion !== uiVersion ||
|
||||
previousTokensVersion !== tokensVersion;
|
||||
|
||||
return {
|
||||
changed,
|
||||
tag: `cadence-ui-v${uiVersion}`,
|
||||
version: uiVersion
|
||||
};
|
||||
}
|
||||
|
||||
const options = parseArgs(process.argv.slice(2));
|
||||
const metadata = getReleaseMetadata(options.before);
|
||||
|
||||
if (options.field) {
|
||||
if (!(options.field in metadata)) {
|
||||
throw new Error(`Unknown field "${options.field}".`);
|
||||
}
|
||||
|
||||
process.stdout.write(String(metadata[options.field]));
|
||||
} else {
|
||||
process.stdout.write(`${JSON.stringify(metadata, null, 2)}\n`);
|
||||
}
|
||||
Reference in New Issue
Block a user