diff --git a/Jenkinsfile b/Jenkinsfile index bf36b99..7da6a5e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -36,6 +36,23 @@ def writeBuildMetadata() { } } +def releaseBaseUrl = + "https://dist.farmcontrol.app/jenkins/farmcontrol/farmcontrol-server" + +def runBuild(buildCommand) { + withEnv([ + "VITE_BUILD_NUMBER=${env.BUILD_NUMBER ?: 'dev'}", + 'NODE_ENV=production', + "ELECTROBUN_RELEASE_BASE_URL=${releaseBaseUrl}", + ]) { + if (isUnix()) { + sh buildCommand + } else { + bat buildCommand + } + } +} + def buildLinux() { node('ubuntu') { try { @@ -70,9 +87,6 @@ def buildLinux() { } } -def releaseBaseUrl = - "https://dist.farmcontrol.app/jenkins/farmcontrol/farmcontrol-server" - def buildOnLabel(label, buildCommand) { return { node(label) { @@ -98,11 +112,7 @@ def buildOnLabel(label, buildCommand) { } stage("Build (${label})") { - if (isUnix()) { - sh "VITE_BUILD_NUMBER=${env.BUILD_NUMBER} NODE_ENV=production ELECTROBUN_RELEASE_BASE_URL=${releaseBaseUrl} ${buildCommand}" - } else { - bat "set VITE_BUILD_NUMBER=${env.BUILD_NUMBER} && set NODE_ENV=production && set ELECTROBUN_RELEASE_BASE_URL=${releaseBaseUrl} && ${buildCommand}" - } + runBuild(buildCommand) } } diff --git a/package.json b/package.json index 7e1219a..790e973 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "build:linux": "bun run cleanBuild && bun run build:server && bun run build:linux-binary && bun run build:linux-packages", "build:linux-binary": "bun scripts/build-linux-binary.mjs", "build:linux-packages": "bash scripts/build-linux-packages.sh", - "cleanBuild": "rm -rf build dist" + "cleanBuild": "bun scripts/clean-build.mjs" }, "author": "Tom Butcher", "license": "ISC", diff --git a/scripts/build-macos.mjs b/scripts/build-macos.mjs index 35613b2..7d9774a 100644 --- a/scripts/build-macos.mjs +++ b/scripts/build-macos.mjs @@ -3,6 +3,7 @@ import { fileURLToPath } from "node:url"; import path from "node:path"; const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +const hostArch = process.arch === "arm64" ? "arm64" : "x64"; const targetArchs = ["arm64", "x64"]; function run(command, args, options = {}) { @@ -18,15 +19,39 @@ function run(command, args, options = {}) { } } +function getElectrobunInvocation(targetArch) { + const electrobunArgs = ["electrobun", "build", "--env=stable"]; + const env = { + ...process.env, + ELECTROBUN_ARCH: targetArch, + }; + + if (targetArch === hostArch) { + return { command: "bun", args: electrobunArgs, env }; + } + + if (hostArch === "arm64" && targetArch === "x64") { + return { command: "arch", args: ["-x86_64", "bun", ...electrobunArgs], env }; + } + + if (hostArch === "x64" && targetArch === "arm64") { + return { command: "arch", args: ["-arm64", "bun", ...electrobunArgs], env }; + } + + return null; +} + run("bun", ["run", "build"]); for (const targetArch of targetArchs) { - console.log(`\n=== Building macOS ${targetArch} ===\n`); + const invocation = getElectrobunInvocation(targetArch); + if (!invocation) { + console.warn( + `Skipping macOS ${targetArch} build: unsupported cross-compile from ${hostArch}.`, + ); + continue; + } - run("bun", ["electrobun", "build", "--env=stable"], { - env: { - ...process.env, - ELECTROBUN_ARCH: targetArch, - }, - }); + console.log(`\n=== Building macOS ${targetArch} ===\n`); + run(invocation.command, invocation.args, { env: invocation.env }); } diff --git a/scripts/clean-build.mjs b/scripts/clean-build.mjs new file mode 100644 index 0000000..967ee6e --- /dev/null +++ b/scripts/clean-build.mjs @@ -0,0 +1,9 @@ +import { rmSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); + +for (const dir of ["build", "dist"]) { + rmSync(path.join(rootDir, dir), { recursive: true, force: true }); +}