mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-21 04:10:47 +02:00
88 lines
2.8 KiB
JavaScript
88 lines
2.8 KiB
JavaScript
#!/usr/bin/env node
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
|
|
const [directory, repository = process.env.GITHUB_REPOSITORY, version = "2.0.0"] = process.argv.slice(2);
|
|
if (!directory || !repository) {
|
|
console.error("Usage: create-runtime-release-manifest.mjs <artifact-dir> <owner/repo> [version]");
|
|
process.exit(2);
|
|
}
|
|
|
|
const targets = [
|
|
"darwin-arm64",
|
|
"darwin-x64",
|
|
"linux-arm64",
|
|
"linux-x64",
|
|
"windows-arm64",
|
|
"windows-x64",
|
|
];
|
|
const componentDependencies = {
|
|
core: [],
|
|
"browser-code": ["core"],
|
|
"browser-headless": ["browser-code"],
|
|
"browser-visible": ["browser-code"],
|
|
design: ["core"],
|
|
diagram: ["browser-headless"],
|
|
pdf: ["diagram"],
|
|
ios: ["core"],
|
|
};
|
|
const capabilityComponents = {
|
|
browser: ["browser-code", "browser-headless"],
|
|
"browser-visible": ["browser-code", "browser-visible"],
|
|
design: ["design"],
|
|
diagram: ["diagram"],
|
|
pdf: ["pdf"],
|
|
ios: ["ios"],
|
|
};
|
|
const commonComponents = ["core", "browser-code", "browser-headless", "browser-visible", "design", "diagram", "pdf"];
|
|
const release = `https://github.com/${repository}/releases/download/v${version}`;
|
|
const certificateIdentity = `https://github.com/${repository}/.github/workflows/release-artifacts.yml@refs/tags/v${version}`;
|
|
const targetRecords = {};
|
|
|
|
for (const target of targets) {
|
|
const ids = [...commonComponents, ...(target.startsWith("darwin-") ? ["ios"] : [])];
|
|
const components = {};
|
|
for (const component of ids) {
|
|
const name = `gstack-runtime-${version}-${target}-${component}.tar.gz`;
|
|
const archive = path.join(directory, name);
|
|
const bundle = `${archive}.sigstore.json`;
|
|
const digestFile = `${archive}.sha256`;
|
|
const [stat, digest, bundleStat] = await Promise.all([
|
|
fs.stat(archive),
|
|
fs.readFile(digestFile, "utf8"),
|
|
fs.stat(bundle),
|
|
]);
|
|
const sha256 = digest.trim().split(/\s+/)[0];
|
|
if (!stat.isFile() || stat.size <= 0 || stat.size > 2 * 1024 * 1024 * 1024) {
|
|
throw new Error(`Invalid artifact size for ${name}: ${stat.size}`);
|
|
}
|
|
if (!bundleStat.isFile() || bundleStat.size <= 0) throw new Error(`Missing Sigstore bundle for ${name}`);
|
|
if (!/^[a-f0-9]{64}$/.test(sha256)) throw new Error(`Invalid SHA-256 for ${name}`);
|
|
components[component] = {
|
|
url: `${release}/${name}`,
|
|
sha256,
|
|
bytes: stat.size,
|
|
format: "tar.gz",
|
|
root: "gstack",
|
|
cosignBundleUrl: `${release}/${name}.sigstore.json`,
|
|
certificateIdentity,
|
|
certificateOidcIssuer: "https://token.actions.githubusercontent.com",
|
|
};
|
|
}
|
|
targetRecords[target] = { components };
|
|
}
|
|
|
|
const manifest = {
|
|
schemaVersion: 2,
|
|
version,
|
|
skillApi: "2.0",
|
|
capabilityComponents,
|
|
componentDependencies,
|
|
targets: targetRecords,
|
|
};
|
|
await fs.writeFile(
|
|
path.join(directory, "gstack-runtime-manifest.json"),
|
|
`${JSON.stringify(manifest, null, 2)}\n`,
|
|
{ flag: "wx", mode: 0o644 },
|
|
);
|