Enhance macOS build process and configuration
Some checks reported errors
farmcontrol/farmcontrol-server/pipeline/head Something is wrong with the build of this commit
Some checks reported errors
farmcontrol/farmcontrol-server/pipeline/head Something is wrong with the build of this commit
- Updated electrobun.config.ts to conditionally enable code signing and notarization based on developer ID presence. - Refactored Jenkinsfile to support separate macOS builds for x64 and arm64 architectures. - Added new scripts for ensuring core dependencies and patching Electrobun source for cross-architecture compatibility. - Enhanced build-macos.mjs to improve architecture detection and build order, ensuring robust handling of macOS builds. - Updated package.json to include a post-install script for patching Electrobun source files.
This commit is contained in:
parent
7bbe717823
commit
575a2d1d20
7
Jenkinsfile
vendored
7
Jenkinsfile
vendored
@ -122,6 +122,10 @@ def buildOnLabel(label, buildCommand) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def buildMacOnLabel(label, targetArch) {
|
||||||
|
return buildOnLabel(label, "ELECTROBUN_TARGET_ARCH=${targetArch} bun run build:app:mac")
|
||||||
|
}
|
||||||
|
|
||||||
def setBuildNameFromPackageVersion() {
|
def setBuildNameFromPackageVersion() {
|
||||||
node('ubuntu') {
|
node('ubuntu') {
|
||||||
stage('Set Build Name') {
|
stage('Set Build Name') {
|
||||||
@ -145,7 +149,8 @@ try {
|
|||||||
|
|
||||||
parallel(
|
parallel(
|
||||||
'Windows Build': buildOnLabel('windows', 'bun run build:app'),
|
'Windows Build': buildOnLabel('windows', 'bun run build:app'),
|
||||||
'MacOS Build': buildOnLabel('macos', 'bun run build:app:mac'),
|
'MacOS x64 Build': buildMacOnLabel('macos', 'x64'),
|
||||||
|
'MacOS arm64 Build': buildMacOnLabel('macos-arm64', 'arm64'),
|
||||||
'Ubuntu Build': { buildLinux() }
|
'Ubuntu Build': { buildLinux() }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { readFileSync } from "node:fs";
|
|||||||
const packageJson = JSON.parse(readFileSync("./package.json", "utf8"));
|
const packageJson = JSON.parse(readFileSync("./package.json", "utf8"));
|
||||||
const buildEnv = process.env.ELECTROBUN_BUILD_ENV || "dev";
|
const buildEnv = process.env.ELECTROBUN_BUILD_ENV || "dev";
|
||||||
const isStable = buildEnv === "stable";
|
const isStable = buildEnv === "stable";
|
||||||
|
const canCodesign = Boolean(process.env.ELECTROBUN_DEVELOPER_ID);
|
||||||
|
|
||||||
const nativeExternals = [
|
const nativeExternals = [
|
||||||
"canvas",
|
"canvas",
|
||||||
@ -41,8 +42,8 @@ export default {
|
|||||||
watchIgnore: ["dist/**", "build/**", "app_dist/**"],
|
watchIgnore: ["dist/**", "build/**", "app_dist/**"],
|
||||||
mac: {
|
mac: {
|
||||||
bundleCEF: false,
|
bundleCEF: false,
|
||||||
codesign: isStable,
|
codesign: isStable && canCodesign,
|
||||||
notarize: isStable,
|
notarize: isStable && canCodesign,
|
||||||
},
|
},
|
||||||
linux: {
|
linux: {
|
||||||
bundleCEF: false,
|
bundleCEF: false,
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
"dev:renderer": "vite src/app --port 5287 --no-open",
|
"dev:renderer": "vite src/app --port 5287 --no-open",
|
||||||
"build:app": "electrobun build --env=stable",
|
"build:app": "electrobun build --env=stable",
|
||||||
"build:app:mac": "bun scripts/build-macos.mjs",
|
"build:app:mac": "bun scripts/build-macos.mjs",
|
||||||
|
"postinstall": "bun scripts/patch-electrobun-src.mjs",
|
||||||
"build:linux": "bun scripts/build-linux.mjs",
|
"build:linux": "bun scripts/build-linux.mjs",
|
||||||
"clean": "bun scripts/clean-build.mjs"
|
"clean": "bun scripts/clean-build.mjs"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -46,6 +46,10 @@ Commands:
|
|||||||
|
|
||||||
- Desktop app (current platform): `bun run build:app`
|
- Desktop app (current platform): `bun run build:app`
|
||||||
- macOS universal (arm64 + x64): `bun run build:app:mac`
|
- macOS universal (arm64 + x64): `bun run build:app:mac`
|
||||||
|
- macOS single arch: `ELECTROBUN_TARGET_ARCH=arm64 bun run build:app:mac`
|
||||||
|
- macOS arm64 on Intel: cross-builds via patched Electrobun CLI (`ELECTROBUN_TARGET_ARCH=arm64`)
|
||||||
|
|
||||||
|
Universal macOS builds use split CI agents (`macos` for x64, `macos-arm64` for arm64). Locally on Intel, arm64 builds work via `ELECTROBUN_TARGET_ARCH=arm64`. On Apple Silicon, x64 uses Rosetta (`arch -x86_64`).
|
||||||
- Linux headless packages: `bun run build:linux`
|
- Linux headless packages: `bun run build:linux`
|
||||||
- Clean build outputs: `bun run clean`
|
- Clean build outputs: `bun run clean`
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
import { spawnSync } from "node:child_process";
|
import { spawnSync } from "node:child_process";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
import { getReleaseArch } from "./release-artifact-utils.mjs";
|
||||||
|
|
||||||
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||||
const hostArch = process.arch === "arm64" ? "arm64" : "x64";
|
const hostArch = getReleaseArch(process.arch);
|
||||||
const targetArchs = ["arm64", "x64"];
|
const targetArchs = process.env.ELECTROBUN_TARGET_ARCH
|
||||||
|
? [getReleaseArch(process.env.ELECTROBUN_TARGET_ARCH)]
|
||||||
|
: ["arm64", "x64"];
|
||||||
|
|
||||||
|
function canRunUnderArch(archFlag) {
|
||||||
|
const result = spawnSync("arch", [archFlag, "true"], {
|
||||||
|
encoding: "utf8",
|
||||||
|
stdio: ["ignore", "pipe", "pipe"],
|
||||||
|
});
|
||||||
|
return result.status === 0;
|
||||||
|
}
|
||||||
|
|
||||||
function run(command, args, options = {}) {
|
function run(command, args, options = {}) {
|
||||||
const result = spawnSync(command, args, {
|
const result = spawnSync(command, args, {
|
||||||
@ -19,37 +30,82 @@ function run(command, args, options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getElectrobunInvocation(targetArch) {
|
function buildElectrobunEnv(targetArch) {
|
||||||
const electrobunArgs = ["electrobun", "build", "--env=stable"];
|
return {
|
||||||
const env = {
|
|
||||||
...process.env,
|
...process.env,
|
||||||
|
ELECTROBUN_BUILD_ENV: "stable",
|
||||||
|
ELECTROBUN_OS: "macos",
|
||||||
ELECTROBUN_ARCH: targetArch,
|
ELECTROBUN_ARCH: targetArch,
|
||||||
|
ELECTROBUN_FORCE_ARCH: targetArch,
|
||||||
|
ELECTROBUN_TARGET_ARCH: targetArch,
|
||||||
|
NODE_ENV: "production",
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInvocation(targetArch) {
|
||||||
|
const env = buildElectrobunEnv(targetArch);
|
||||||
|
const runScript = path.join(rootDir, "scripts/run-electrobun-build.mjs");
|
||||||
|
|
||||||
if (targetArch === hostArch) {
|
if (targetArch === hostArch) {
|
||||||
return { command: "bun", args: electrobunArgs, env };
|
return { command: "bun", args: [runScript], env };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hostArch === "arm64" && targetArch === "x64") {
|
// Apple Silicon can build x64 under Rosetta; Electrobun sees an x64 host.
|
||||||
return { command: "arch", args: ["-x86_64", "bun", ...electrobunArgs], env };
|
if (targetArch === "x64" && hostArch === "arm64" && canRunUnderArch("-x86_64")) {
|
||||||
|
return {
|
||||||
|
command: "arch",
|
||||||
|
args: ["-x86_64", "bun", runScript],
|
||||||
|
env,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hostArch === "x64" && targetArch === "arm64") {
|
// Intel (and any host) can cross-build arm64 via the patched Electrobun Bun CLI.
|
||||||
return { command: "arch", args: ["-arm64", "bun", ...electrobunArgs], env };
|
if (targetArch === "arm64" && hostArch === "x64") {
|
||||||
|
return { command: "bun", args: [runScript], env };
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const targetArch of targetArchs) {
|
const orderedTargets = [...targetArchs].sort((a, b) => {
|
||||||
const invocation = getElectrobunInvocation(targetArch);
|
if (a === hostArch) return -1;
|
||||||
|
if (b === hostArch) return 1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Host architecture: ${hostArch}`);
|
||||||
|
console.log(`Build order: ${orderedTargets.join(", ")}`);
|
||||||
|
|
||||||
|
let builtCount = 0;
|
||||||
|
|
||||||
|
for (const targetArch of orderedTargets) {
|
||||||
|
const invocation = getInvocation(targetArch);
|
||||||
if (!invocation) {
|
if (!invocation) {
|
||||||
console.warn(
|
console.error(
|
||||||
`Skipping macOS ${targetArch} build: unsupported cross-compile from ${hostArch}.`,
|
`Cannot build macOS ${targetArch} from host ${hostArch}.`,
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`\n=== Building macOS ${targetArch} ===\n`);
|
console.log(`\n=== Building macOS ${targetArch} (host ${hostArch}) ===`);
|
||||||
|
console.log(
|
||||||
|
`ELECTROBUN_BUILD_ENV=stable ELECTROBUN_OS=macos ELECTROBUN_ARCH=${targetArch}\n`,
|
||||||
|
);
|
||||||
|
|
||||||
run(invocation.command, invocation.args, { env: invocation.env });
|
run(invocation.command, invocation.args, { env: invocation.env });
|
||||||
|
builtCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (builtCount === 0) {
|
||||||
|
console.error("No macOS architectures were built.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builtCount < targetArchs.length) {
|
||||||
|
console.error(
|
||||||
|
`Built ${builtCount}/${targetArchs.length} macOS architectures.`,
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\nBuilt macOS architectures: ${orderedTargets.join(", ")}`);
|
||||||
|
|||||||
123
scripts/ensure-electrobun-core.mjs
Normal file
123
scripts/ensure-electrobun-core.mjs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import {
|
||||||
|
createWriteStream,
|
||||||
|
existsSync,
|
||||||
|
mkdirSync,
|
||||||
|
readdirSync,
|
||||||
|
unlinkSync,
|
||||||
|
} from "node:fs";
|
||||||
|
import { spawnSync } from "node:child_process";
|
||||||
|
import path from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { getReleaseArch } from "./release-artifact-utils.mjs";
|
||||||
|
|
||||||
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||||
|
const electrobunDir = path.join(rootDir, "node_modules/electrobun");
|
||||||
|
const electrobunVersion = JSON.parse(
|
||||||
|
await Bun.file(path.join(electrobunDir, "package.json")).text(),
|
||||||
|
).version;
|
||||||
|
|
||||||
|
function getPlatformPaths(targetOS, targetArch) {
|
||||||
|
const binExt = targetOS === "win" ? ".exe" : "";
|
||||||
|
const platformDistDir = path.join(
|
||||||
|
electrobunDir,
|
||||||
|
`dist-${targetOS}-${targetArch}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
platformDistDir,
|
||||||
|
bunBinary: path.join(platformDistDir, "bun") + binExt,
|
||||||
|
bsdiff: path.join(platformDistDir, "bsdiff") + binExt,
|
||||||
|
bspatch: path.join(platformDistDir, "bspatch") + binExt,
|
||||||
|
launcher: path.join(platformDistDir, "launcher") + binExt,
|
||||||
|
nativeWrapperMacos: path.join(platformDistDir, "libNativeWrapper.dylib"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadFile(url, destination) {
|
||||||
|
const response = await fetch(url);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to download ${url}: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdirSync(path.dirname(destination), { recursive: true });
|
||||||
|
const fileStream = createWriteStream(destination);
|
||||||
|
const reader = response.body?.getReader();
|
||||||
|
if (!reader) {
|
||||||
|
throw new Error(`No response body for ${url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done) break;
|
||||||
|
fileStream.write(Buffer.from(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
fileStream.end((error) => (error ? reject(error) : resolve()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractTarGz(tarPath, destination) {
|
||||||
|
mkdirSync(destination, { recursive: true });
|
||||||
|
const result = spawnSync("tar", ["-xzf", tarPath, "-C", destination], {
|
||||||
|
stdio: "inherit",
|
||||||
|
});
|
||||||
|
if (result.status !== 0) {
|
||||||
|
throw new Error(`tar extraction failed for ${tarPath}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ensureCoreDependencies(targetOS, targetArch) {
|
||||||
|
const paths = getPlatformPaths(targetOS, targetArch);
|
||||||
|
const required = [
|
||||||
|
paths.bunBinary,
|
||||||
|
paths.bsdiff,
|
||||||
|
paths.bspatch,
|
||||||
|
paths.launcher,
|
||||||
|
paths.nativeWrapperMacos,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (required.every((filePath) => existsSync(filePath))) {
|
||||||
|
console.log(`ensure-electrobun-core: ${targetOS}-${targetArch} already present`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const platformName =
|
||||||
|
targetOS === "macos" ? "darwin" : targetOS === "win" ? "win" : "linux";
|
||||||
|
const url = `https://github.com/blackboardsh/electrobun/releases/download/v${electrobunVersion}/electrobun-core-${platformName}-${targetArch}.tar.gz`;
|
||||||
|
const tempFile = path.join(
|
||||||
|
electrobunDir,
|
||||||
|
`core-${targetOS}-${targetArch}-temp.tar.gz`,
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`ensure-electrobun-core: downloading ${targetOS}-${targetArch}`);
|
||||||
|
console.log(url);
|
||||||
|
|
||||||
|
await downloadFile(url, tempFile);
|
||||||
|
extractTarGz(tempFile, paths.platformDistDir);
|
||||||
|
|
||||||
|
if (existsSync(tempFile)) {
|
||||||
|
unlinkSync(tempFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
const missing = required.filter((filePath) => !existsSync(filePath));
|
||||||
|
if (missing.length > 0) {
|
||||||
|
const extracted = existsSync(paths.platformDistDir)
|
||||||
|
? readdirSync(paths.platformDistDir)
|
||||||
|
: [];
|
||||||
|
throw new Error(
|
||||||
|
`Missing ${targetOS}-${targetArch} binaries after extract: ${missing.join(", ")}; extracted=${extracted.join(", ")}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`ensure-electrobun-core: ${targetOS}-${targetArch} ready`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetOS = "macos";
|
||||||
|
const targetArch = getReleaseArch(
|
||||||
|
process.env.ELECTROBUN_TARGET_ARCH ||
|
||||||
|
process.env.ELECTROBUN_FORCE_ARCH ||
|
||||||
|
process.arch,
|
||||||
|
);
|
||||||
|
|
||||||
|
await ensureCoreDependencies(targetOS, targetArch);
|
||||||
159
scripts/patch-electrobun-src.mjs
Normal file
159
scripts/patch-electrobun-src.mjs
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
import {
|
||||||
|
cpSync,
|
||||||
|
existsSync,
|
||||||
|
mkdirSync,
|
||||||
|
readFileSync,
|
||||||
|
writeFileSync,
|
||||||
|
} from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||||
|
const electrobunDir = path.join(rootDir, "node_modules/electrobun");
|
||||||
|
const sharedSrcDir = path.join(electrobunDir, "src/shared");
|
||||||
|
const sharedDistDir = path.join(electrobunDir, "dist/api/shared");
|
||||||
|
|
||||||
|
if (!existsSync(sharedDistDir)) {
|
||||||
|
console.error("patch-electrobun-src: electrobun dist/api/shared not found");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdirSync(sharedSrcDir, { recursive: true });
|
||||||
|
|
||||||
|
for (const fileName of [
|
||||||
|
"cef-version.ts",
|
||||||
|
"bun-version.ts",
|
||||||
|
"electrobun-version.ts",
|
||||||
|
"naming.ts",
|
||||||
|
"rpc.ts",
|
||||||
|
]) {
|
||||||
|
const source = path.join(sharedDistDir, fileName);
|
||||||
|
const destination = path.join(sharedSrcDir, fileName);
|
||||||
|
if (existsSync(source)) {
|
||||||
|
cpSync(source, destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const platformPatch = `import { platform, arch } from "os";
|
||||||
|
|
||||||
|
export type SupportedOS = "macos" | "win" | "linux";
|
||||||
|
export type SupportedArch = "arm64" | "x64";
|
||||||
|
|
||||||
|
const platformName = platform();
|
||||||
|
const archName = arch();
|
||||||
|
|
||||||
|
export const OS: SupportedOS = (() => {
|
||||||
|
switch (platformName) {
|
||||||
|
case "win32":
|
||||||
|
return "win";
|
||||||
|
case "darwin":
|
||||||
|
return "macos";
|
||||||
|
case "linux":
|
||||||
|
return "linux";
|
||||||
|
default:
|
||||||
|
throw new Error(\`Unsupported platform: \${platformName}\`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
function normalizeForcedArch(value) {
|
||||||
|
if (value === "arm64" || value === "aarch64") {
|
||||||
|
return "arm64";
|
||||||
|
}
|
||||||
|
if (value === "x64" || value === "amd64") {
|
||||||
|
return "x64";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ARCH: SupportedArch = (() => {
|
||||||
|
const forcedArch = normalizeForcedArch(
|
||||||
|
process.env.ELECTROBUN_FORCE_ARCH || process.env.ELECTROBUN_TARGET_ARCH,
|
||||||
|
);
|
||||||
|
if (forcedArch) {
|
||||||
|
return forcedArch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OS === "win") {
|
||||||
|
return "x64";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (archName) {
|
||||||
|
case "arm64":
|
||||||
|
return "arm64";
|
||||||
|
case "x64":
|
||||||
|
return "x64";
|
||||||
|
default:
|
||||||
|
throw new Error(\`Unsupported architecture: \${archName}\`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
export const HOST_ARCH: SupportedArch = (() => {
|
||||||
|
if (OS === "win") {
|
||||||
|
return "x64";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (archName) {
|
||||||
|
case "arm64":
|
||||||
|
return "arm64";
|
||||||
|
case "x64":
|
||||||
|
return "x64";
|
||||||
|
default:
|
||||||
|
throw new Error(\`Unsupported architecture: \${archName}\`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
export function getPlatformOS(): SupportedOS {
|
||||||
|
return OS;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPlatformArch(): SupportedArch {
|
||||||
|
return ARCH;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
writeFileSync(path.join(sharedSrcDir, "platform.ts"), platformPatch);
|
||||||
|
|
||||||
|
const templatesDir = path.join(electrobunDir, "src/cli/templates");
|
||||||
|
mkdirSync(templatesDir, { recursive: true });
|
||||||
|
writeFileSync(
|
||||||
|
path.join(templatesDir, "embedded.ts"),
|
||||||
|
`export function getTemplateNames() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTemplate(name: string) {
|
||||||
|
throw new Error(\`Template not available in patched electrobun CLI: \${name}\`);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const cliPath = path.join(electrobunDir, "src/cli/index.ts");
|
||||||
|
let cliSource = readFileSync(cliPath, "utf8");
|
||||||
|
if (!cliSource.includes("HOST_ARCH")) {
|
||||||
|
cliSource = cliSource.replace(
|
||||||
|
'import { OS, ARCH } from "../shared/platform";',
|
||||||
|
'import { OS, ARCH, HOST_ARCH } from "../shared/platform";',
|
||||||
|
);
|
||||||
|
cliSource = cliSource.replace(
|
||||||
|
"const hostPaths = getPlatformPaths(OS, ARCH);",
|
||||||
|
"const hostPaths = getPlatformPaths(OS, HOST_ARCH);",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!cliSource.includes("toolPaths")) {
|
||||||
|
cliSource = cliSource.replace(
|
||||||
|
"const targetPaths = getPlatformPaths(currentTarget.os, currentTarget.arch);",
|
||||||
|
"const targetPaths = getPlatformPaths(currentTarget.os, currentTarget.arch);\n\t\tconst toolPaths = getPlatformPaths(currentTarget.os, ARCH !== HOST_ARCH ? HOST_ARCH : ARCH);",
|
||||||
|
);
|
||||||
|
cliSource = cliSource.replaceAll("const zstdPath = targetPaths.ZSTD;", "const zstdPath = toolPaths.ZSTD;");
|
||||||
|
cliSource = cliSource.replaceAll("const bsdiffpath = targetPaths.BSDIFF;", "const bsdiffpath = toolPaths.BSDIFF;");
|
||||||
|
cliSource = cliSource.replace(
|
||||||
|
"zigAsarCli = join(targetPaths.BSPATCH).replace(\"bspatch\", \"zig-asar\");",
|
||||||
|
"zigAsarCli = join(toolPaths.BSPATCH).replace(\"bspatch\", \"zig-asar\");",
|
||||||
|
);
|
||||||
|
writeFileSync(cliPath, cliSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
const markerPath = path.join(electrobunDir, ".farmcontrol-electrobun-patched");
|
||||||
|
writeFileSync(markerPath, `patched-at=${new Date().toISOString()}\n`);
|
||||||
|
|
||||||
|
console.log("patch-electrobun-src: electrobun src/shared ready for cross-arch builds");
|
||||||
75
scripts/run-electrobun-build.mjs
Normal file
75
scripts/run-electrobun-build.mjs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { spawnSync } from "node:child_process";
|
||||||
|
import path from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { getReleaseArch } from "./release-artifact-utils.mjs";
|
||||||
|
|
||||||
|
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||||
|
const electrobunCli = path.join(
|
||||||
|
rootDir,
|
||||||
|
"node_modules/electrobun/src/cli/index.ts",
|
||||||
|
);
|
||||||
|
|
||||||
|
const buildEnv = process.env.ELECTROBUN_BUILD_ENV || "stable";
|
||||||
|
const targetArch = getReleaseArch(
|
||||||
|
process.env.ELECTROBUN_TARGET_ARCH ||
|
||||||
|
process.env.ELECTROBUN_FORCE_ARCH ||
|
||||||
|
process.arch,
|
||||||
|
);
|
||||||
|
|
||||||
|
const patchResult = spawnSync("bun", [path.join(rootDir, "scripts/patch-electrobun-src.mjs")], {
|
||||||
|
cwd: rootDir,
|
||||||
|
stdio: "inherit",
|
||||||
|
env: process.env,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (patchResult.status !== 0) {
|
||||||
|
process.exit(patchResult.status ?? 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ensureCoreEnv = {
|
||||||
|
...process.env,
|
||||||
|
ELECTROBUN_TARGET_ARCH: targetArch,
|
||||||
|
ELECTROBUN_FORCE_ARCH: targetArch,
|
||||||
|
};
|
||||||
|
|
||||||
|
const ensureCoreResult = spawnSync(
|
||||||
|
"bun",
|
||||||
|
[path.join(rootDir, "scripts/ensure-electrobun-core.mjs")],
|
||||||
|
{
|
||||||
|
cwd: rootDir,
|
||||||
|
stdio: "inherit",
|
||||||
|
env: ensureCoreEnv,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ensureCoreResult.status !== 0) {
|
||||||
|
process.exit(ensureCoreResult.status ?? 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const env = {
|
||||||
|
...process.env,
|
||||||
|
ELECTROBUN_BUILD_ENV: buildEnv,
|
||||||
|
ELECTROBUN_OS: "macos",
|
||||||
|
ELECTROBUN_ARCH: targetArch,
|
||||||
|
ELECTROBUN_FORCE_ARCH: targetArch,
|
||||||
|
ELECTROBUN_TARGET_ARCH: targetArch,
|
||||||
|
NODE_ENV: process.env.NODE_ENV || "production",
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`run-electrobun-build: env=${buildEnv} os=macos arch=${targetArch} (host ${getReleaseArch(process.arch)})`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = spawnSync(
|
||||||
|
"bun",
|
||||||
|
[electrobunCli, "build", `--env=${buildEnv}`],
|
||||||
|
{
|
||||||
|
cwd: rootDir,
|
||||||
|
stdio: "inherit",
|
||||||
|
env,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.status !== 0) {
|
||||||
|
process.exit(result.status ?? 1);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user