farmcontrol-ui/Jenkinsfile
Tom Butcher 888c0fe38a
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
Enhance build configuration and scripts for multi-platform support
- Updated electrobun.config.ts to include environment-based settings for macOS builds.
- Added new build scripts for Windows and macOS, including support for architecture-specific builds.
- Introduced scripts for cleaning build artifacts, managing dependencies, and ensuring core binaries are present.
- Enhanced Jenkinsfile to integrate new build processes and improve artifact management.
- Added new assets for application icons and installer configurations.
- Implemented NSIS and MSI packaging scripts for Windows installer creation.
- Updated package.json with new scripts for development and build processes, including post-installation tasks.
2026-08-02 00:28:33 +01:00

192 lines
5.3 KiB
Groovy

properties([
buildDiscarder(logRotator(numToKeepStr: '10'))
])
def bunBinDir() {
if (isUnix()) {
return "${env.HOME}/.bun/bin"
}
return "${env.USERPROFILE}/.bun/bin"
}
def withBun(Closure body) {
def sep = isUnix() ? ':' : ';'
withEnv(["PATH=${bunBinDir()}${sep}${env.PATH}"]) {
body()
}
}
def checkBun() {
if (isUnix()) {
sh 'bun -v'
} else {
bat 'bun -v'
}
}
def writeBuildMetadata() {
if (isUnix()) {
sh '''
bun --eval "await Bun.write('src/buildInfo.json', JSON.stringify({ buildNumber: process.env.BUILD_NUMBER || 'dev' }, null, 2) + '\\n')"
'''
} else {
bat '''
bun --eval "await Bun.write('src/buildInfo.json', JSON.stringify({ buildNumber: process.env.BUILD_NUMBER || 'dev' }, null, 2) + '\\n')"
'''
}
}
def runBuild(buildCommand) {
def releaseBaseUrl =
"https://dist.farmcontrol.app/jenkins/farmcontrol/farmcontrol-ui"
withEnv([
"VITE_BUILD_NUMBER=${env.BUILD_NUMBER ?: 'dev'}",
'NODE_ENV=production',
"ELECTROBUN_RELEASE_BASE_URL=${releaseBaseUrl}",
]) {
if (isUnix()) {
sh buildCommand
} else {
bat buildCommand
}
}
}
def deploy() {
node('ubuntu') {
try {
stage('Checkout (Ubuntu)') {
checkout scm
}
stage('Setup Node.js (Ubuntu)') {
nodejs(nodeJSInstallationName: 'Node23') {
sh 'node -v'
sh 'pnpm -v'
}
}
stage('Install Dependencies (Ubuntu)') {
nodejs(nodeJSInstallationName: 'Node23') {
sh 'pnpm install --frozen-lockfile --production=false'
}
}
stage('Build (Ubuntu)') {
nodejs(nodeJSInstallationName: 'Node23') {
sh "VITE_BUILD_NUMBER=${env.BUILD_NUMBER} NODE_ENV=production pnpm build:cloudflare"
}
}
stage('Deploy (Ubuntu)') {
nodejs(nodeJSInstallationName: 'Node23') {
withCredentials([string(credentialsId: 'cloudflare-api-token', variable: 'CLOUDFLARE_API_TOKEN')]) {
sh 'pnpm wrangler pages deploy build --branch main'
}
}
}
} finally {
cleanWs()
}
}
}
def prepareMacBuildWorkspace() {
if (isUnix()) {
sh '''
df -h .
for vol in /Volumes/Farm\\ Control*; do
if [ -d "$vol" ]; then
hdiutil detach "$vol" -force || true
fi
done
rm -rf build/stable-macos-*/.dmg-staging build/stable-macos-*/.finalize-dmg-staging 2>/dev/null || true
'''
}
}
def buildOnLabel(label, buildCommand) {
return {
node(label) {
try {
stage("Checkout (${label})") {
checkout scm
}
withBun {
stage("Check Bun (${label})") {
checkBun()
}
if (label.startsWith('macos')) {
stage("Prepare macOS workspace (${label})") {
prepareMacBuildWorkspace()
}
}
stage("Install Dependencies (${label})") {
if (isUnix()) {
sh 'bun install --frozen-lockfile'
} else {
bat 'bun install --frozen-lockfile'
}
}
stage("Write Build Metadata (${label})") {
writeBuildMetadata()
}
stage("Build (${label})") {
runBuild(buildCommand)
}
}
stage("Archive Artifacts (${label})") {
archiveArtifacts artifacts: 'app_dist/farmcontrol-*', fingerprint: true
}
} finally {
cleanWs()
}
}
}
}
def buildMacOnLabel(label, targetArch) {
return buildOnLabel(label, "ELECTROBUN_TARGET_ARCH=${targetArch} bun run build:app:mac")
}
def setBuildNameFromPackageVersion() {
node('ubuntu') {
stage('Set Build Name') {
checkout scm
withBun {
checkBun()
def version = sh(
script: "bun --eval \"console.log(JSON.parse(await Bun.file('package.json').text()).version)\"",
returnStdout: true
).trim()
def buildName = "v${version}-b${env.BUILD_NUMBER}"
currentBuild.displayName = buildName
echo "Build name set to: ${buildName}"
}
}
}
}
try {
setBuildNameFromPackageVersion()
parallel(
'Windows Build': buildOnLabel('windows', 'bun run build:app'),
'MacOS x64 Build': buildMacOnLabel('macos', 'x64'),
'MacOS arm64 Build': buildMacOnLabel('macos', 'arm64'),
'Ubuntu Deploy': { deploy() }
)
echo 'All parallel stages completed successfully!'
} catch (Exception e) {
echo "Pipeline failed: ${e.message}"
throw e
}