114 lines
4.1 KiB
JavaScript
114 lines
4.1 KiB
JavaScript
import { execFileSync } from "node:child_process";
|
|
import { readFile } from "node:fs/promises";
|
|
import { resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const frontendDir = fileURLToPath(new URL("../", import.meta.url));
|
|
const rootDir = resolve(frontendDir, "..");
|
|
const packageInfo = JSON.parse(await readFile(resolve(frontendDir, "package.json"), "utf8"));
|
|
const failures = [];
|
|
|
|
const allowedChannels = new Set(["dev", "main", "release", "local"]);
|
|
const fullShaPattern = /^[0-9a-f]{40}$/i;
|
|
const semverTag = `v${packageInfo.version}`;
|
|
|
|
const env = process.env;
|
|
const channel = env.VITE_BUILD_CHANNEL || "local";
|
|
const commit = env.VITE_BUILD_COMMIT || "local";
|
|
const isCi = env.CI === "true" || env.GITHUB_ACTIONS === "true";
|
|
const isTagBuild = env.GITHUB_REF_TYPE === "tag";
|
|
const isReleaseBuild = env.RELEASE_BUILD === "true" || isTagBuild || channel === "release";
|
|
const requiresMacosSigning = env.REQUIRE_DESKTOP_SIGNING === "true";
|
|
const requiresWindowsSigning = env.REQUIRE_WINDOWS_SIGNING === "true";
|
|
|
|
const fail = (message) => failures.push(message);
|
|
const assert = (condition, message) => {
|
|
if (!condition) fail(message);
|
|
};
|
|
|
|
const requireEnv = (name) => {
|
|
assert(Boolean(env[name]), `${name} must be configured for signed desktop release builds.`);
|
|
};
|
|
|
|
const gitHead = () => {
|
|
try {
|
|
return execFileSync("git", ["rev-parse", "HEAD"], {
|
|
cwd: rootDir,
|
|
encoding: "utf8",
|
|
stdio: ["ignore", "pipe", "ignore"],
|
|
}).trim();
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
};
|
|
|
|
assert(allowedChannels.has(channel), `VITE_BUILD_CHANNEL must be one of ${[...allowedChannels].join(", ")}.`);
|
|
|
|
if (isCi || isReleaseBuild) {
|
|
assert(channel !== "local", "CI and release builds must inject VITE_BUILD_CHANNEL.");
|
|
assert(fullShaPattern.test(commit), "CI and release builds must inject a full 40-character VITE_BUILD_COMMIT.");
|
|
}
|
|
|
|
if (env.GITHUB_SHA) {
|
|
assert(
|
|
commit === env.GITHUB_SHA || commit === "local",
|
|
"VITE_BUILD_COMMIT must match GITHUB_SHA when GitHub Actions provides a source commit.",
|
|
);
|
|
}
|
|
|
|
if (isReleaseBuild && fullShaPattern.test(commit)) {
|
|
const headSha = gitHead();
|
|
assert(Boolean(headSha), "Release builds must be able to resolve the current Git commit.");
|
|
if (headSha) {
|
|
assert(commit === headSha, "VITE_BUILD_COMMIT must match the current Git HEAD for release builds.");
|
|
}
|
|
}
|
|
|
|
if (isTagBuild) {
|
|
assert(env.GITHUB_REF_NAME === semverTag, `Release tag must be ${semverTag}; found ${env.GITHUB_REF_NAME || "<missing>"}.`);
|
|
assert(channel === "release", "Release tag builds must set VITE_BUILD_CHANNEL=release.");
|
|
}
|
|
|
|
assert(
|
|
!(requiresMacosSigning && requiresWindowsSigning),
|
|
"macOS and Windows signing requirements must be checked in their native jobs.",
|
|
);
|
|
|
|
if (requiresMacosSigning) {
|
|
assert(process.platform === "darwin", "Signed macOS desktop release builds must run on macOS.");
|
|
if (isCi) {
|
|
assert(isTagBuild, "Signed desktop release candidate builds in CI must run from a release tag.");
|
|
}
|
|
requireEnv("TAURI_SIGNING_PRIVATE_KEY");
|
|
requireEnv("TAURI_SIGNING_PRIVATE_KEY_PASSWORD");
|
|
requireEnv("APPLE_ID");
|
|
requireEnv("APPLE_PASSWORD");
|
|
requireEnv("APPLE_TEAM_ID");
|
|
assert(
|
|
Boolean(env.APPLE_CERTIFICATE || env.APPLE_SIGNING_IDENTITY),
|
|
"APPLE_CERTIFICATE or APPLE_SIGNING_IDENTITY must be configured for macOS signing.",
|
|
);
|
|
if (env.APPLE_CERTIFICATE) {
|
|
requireEnv("APPLE_CERTIFICATE_PASSWORD");
|
|
}
|
|
}
|
|
|
|
if (requiresWindowsSigning) {
|
|
assert(process.platform === "win32", "Signed Windows desktop release builds must run on Windows.");
|
|
if (isCi) {
|
|
assert(isTagBuild, "Signed Windows desktop release candidate builds in CI must run from a release tag.");
|
|
}
|
|
requireEnv("TAURI_SIGNING_PRIVATE_KEY");
|
|
requireEnv("TAURI_SIGNING_PRIVATE_KEY_PASSWORD");
|
|
requireEnv("WINDOWS_CERTIFICATE");
|
|
requireEnv("WINDOWS_CERTIFICATE_PASSWORD");
|
|
requireEnv("WINDOWS_TIMESTAMP_URL");
|
|
}
|
|
|
|
if (failures.length > 0) {
|
|
console.error(`Release build environment check failed:\n${failures.map((item) => ` - ${item}`).join("\n")}`);
|
|
process.exitCode = 1;
|
|
} else {
|
|
console.log("Release build environment check passed.");
|
|
}
|