Files
ctms/frontend/scripts/desktop-release-policy.mjs
T
Cheng Zhou c23a5d6a22
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
build(desktop): allow controlled unsigned v0.1.0 release
2026-07-17 10:52:20 +08:00

87 lines
3.2 KiB
JavaScript

import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import { fileURLToPath } from "node:url";
const frontendDir = fileURLToPath(new URL("../", import.meta.url));
export const desktopReleasePolicyPath = resolve(frontendDir, "desktop-release-policy.json");
const semverPattern = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
const validatePolicy = (policy) => {
const failures = [];
const assert = (condition, message) => {
if (!condition) failures.push(message);
};
assert(policy?.schemaVersion === 1, "desktop release policy schemaVersion must be 1.");
assert(
policy?.defaultPlatformSigningMode === "signed",
"desktop release policy must default platform signing to signed.",
);
assert(policy?.updaterSigningRequired === true, "desktop release policy must always require updater signing.");
assert(
Array.isArray(policy?.unsignedPlatformExceptions),
"desktop release policy unsignedPlatformExceptions must be an array.",
);
const versions = new Set();
for (const exception of policy?.unsignedPlatformExceptions || []) {
const prefix = `unsigned platform exception ${exception?.version || "<missing>"}`;
assert(semverPattern.test(exception?.version || ""), `${prefix} must use an exact X.Y.Z version.`);
assert(!versions.has(exception?.version), `${prefix} is duplicated.`);
versions.add(exception?.version);
assert(exception?.status === "approved", `${prefix} must have status approved.`);
assert(exception?.macos === "ad-hoc", `${prefix} must constrain macOS to ad-hoc signing.`);
assert(exception?.windows === "unsigned", `${prefix} must constrain Windows to unsigned.`);
assert(exception?.distribution === "controlled", `${prefix} must constrain distribution to controlled.`);
assert(/^\d{4}-\d{2}-\d{2}$/.test(exception?.approvedOn || ""), `${prefix} must record an approval date.`);
assert(
typeof exception?.reason === "string" && exception.reason.trim().length >= 30,
`${prefix} must record a substantive reason.`,
);
}
if (failures.length > 0) {
throw new Error(failures.join("\n"));
}
};
export const loadDesktopReleasePolicy = async () => {
const policy = JSON.parse(await readFile(desktopReleasePolicyPath, "utf8"));
validatePolicy(policy);
return policy;
};
export const resolveDesktopReleasePolicy = (version, policy) => {
if (!semverPattern.test(version || "")) {
throw new Error(`Desktop release version must use exact X.Y.Z semver; found ${version || "<missing>"}.`);
}
const exception = policy.unsignedPlatformExceptions.find(
(candidate) => candidate.version === version && candidate.status === "approved",
);
if (!exception) {
return {
version,
platformSigningMode: "signed",
macosSigning: "apple-developer",
windowsSigning: "authenticode",
artifactLabel: "SIGNED-PLATFORM",
distribution: "formal",
warningRequired: false,
};
}
return {
version,
platformSigningMode: "unsigned-exception",
macosSigning: exception.macos,
windowsSigning: exception.windows,
artifactLabel: "UNSIGNED-PLATFORM",
distribution: exception.distribution,
warningRequired: true,
exception,
};
};