farmcontrol-ui/scripts/pre-build.mjs
Tom Butcher e1051499f9
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
Add installer icons for Windows and macOS
- Introduced a new installer icon in ICO format and a complete iconset for macOS, enhancing the visual branding of the installer.
- Updated Windows installer scripts to reference the new icon files, ensuring they are included in the installation package.
- Implemented a script to prepare the installer icons from a source image, streamlining the icon generation process for different platforms.
2026-08-02 23:35:37 +01:00

147 lines
4.0 KiB
JavaScript

import { existsSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath, pathToFileURL } from "node:url";
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const buildEnv = process.env.ELECTROBUN_BUILD_ENV || "dev";
const requiredFiles = [
"src/bun/index.js",
"electrobun.config.ts",
"package.json",
];
for (const relativePath of requiredFiles) {
const filePath = path.join(rootDir, relativePath);
if (!existsSync(filePath)) {
console.error(`pre-build: required file not found: ${relativePath}`);
process.exit(1);
}
}
if (buildEnv === "stable" && process.env.ELECTROBUN_OS === "macos") {
const codesignVars = [
"ELECTROBUN_DEVELOPER_ID",
"ELECTROBUN_APPLEID",
"ELECTROBUN_APPLEIDPASS",
"ELECTROBUN_TEAMID",
];
const missing = codesignVars.filter((name) => !process.env[name]);
if (missing.length > 0) {
console.warn(
`pre-build: stable macOS build without code signing credentials (${missing.join(", ")}); Electrobun will skip signing.`,
);
}
}
const buildMacosEffects = spawnSync(
"bun",
[path.join(rootDir, "scripts/build-macos-effects.mjs")],
{ cwd: rootDir, stdio: "inherit", env: process.env },
);
if (buildMacosEffects.status !== 0) {
process.exit(buildMacosEffects.status ?? 1);
}
if (process.platform === "darwin") {
const { validateMacosEffectsDylib, outFile } = await import(
pathToFileURL(
path.join(rootDir, "scripts/build-macos-effects.mjs"),
).href
);
if (!validateMacosEffectsDylib({ dylibPath: outFile })) {
console.error(
"pre-build: macOS window effects dylib is missing or invalid; blur and traffic lights will not work in packaged builds.",
);
process.exit(1);
}
}
const prepareIcons = spawnSync(
"bun",
[
path.join(rootDir, "scripts/prepare-app-icons.mjs"),
"assets/logos/farmcontrolicon.png",
],
{ cwd: rootDir, stdio: "inherit", env: process.env },
);
if (prepareIcons.status !== 0) {
process.exit(prepareIcons.status ?? 1);
}
const prepareInstallerIcons = spawnSync(
"bun",
[path.join(rootDir, "scripts/prepare-installer-icons.mjs")],
{ cwd: rootDir, stdio: "inherit", env: process.env },
);
if (prepareInstallerIcons.status !== 0) {
process.exit(prepareInstallerIcons.status ?? 1);
}
const windowsIconPath = path.join(rootDir, "assets/icon.ico");
if (!existsSync(windowsIconPath)) {
console.error(
"pre-build: assets/icon.ico not found after prepare-app-icons (required for build.win.icon)",
);
process.exit(1);
}
const writeBuildInfo = spawnSync(
"bun",
[path.join(rootDir, "scripts/write-build-info.mjs")],
{ cwd: rootDir, stdio: "inherit", env: process.env },
);
if (writeBuildInfo.status !== 0) {
process.exit(writeBuildInfo.status ?? 1);
}
if (buildEnv === "dev") {
console.log(
"pre-build: dev environment — skipping production renderer build (use dev:renderer for Vite)",
);
// Electrobun still copies dist/mainview into the app bundle; provide a stub so
// dev builds don't warn when Vite serves the renderer instead.
const stubDir = path.join(rootDir, "dist/mainview");
mkdirSync(stubDir, { recursive: true });
writeFileSync(
path.join(stubDir, "index.html"),
"<!doctype html><html><body>Dev mode — start Vite with <code>bun run dev:renderer</code>.</body></html>",
);
console.log(`pre-build: validation passed (${buildEnv})`);
process.exit(0);
}
const buildRenderer = spawnSync(
"bun",
[path.join(rootDir, "scripts/build-renderer.mjs")],
{
cwd: rootDir,
stdio: "inherit",
env: {
...process.env,
NODE_ENV: "production",
},
},
);
if (buildRenderer.status !== 0) {
process.exit(buildRenderer.status ?? 1);
}
const rendererIndex = path.join(rootDir, "dist/mainview/index.html");
if (!existsSync(rendererIndex)) {
console.error(`pre-build: renderer output not found: dist/mainview/index.html`);
process.exit(1);
}
console.log(`pre-build: validation and renderer build passed (${buildEnv})`);