// Build the Android APK (plan step 4). // // node scripts/build-apk.mjs debug → debug APK (WebView debuggable, auto-signed) // node scripts/build-apk.mjs release → release APK signed with ~/.xenia keystore, // also copied to public/downloads/ for the web build // // Assumes `npm run build:native` already ran (the npm scripts chain it). The APK // is copied to waiter_pwa/releases/xenia-waiter-(-debug).apk. import { execFileSync } from 'node:child_process' import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' const variant = process.argv[2] === 'release' ? 'release' : 'debug' const root = join(dirname(fileURLToPath(import.meta.url)), '..') const androidDir = join(root, 'android') const gradleFile = readFileSync(join(androidDir, 'app', 'build.gradle'), 'utf8') const versionName = gradleFile.match(/versionName\s+"([^"]+)"/)?.[1] ?? '0.0.0' const versionCode = gradleFile.match(/versionCode\s+(\d+)/)?.[1] ?? '0' if (variant === 'release') { const props = process.env.XENIA_KEYSTORE_PROPS || join(process.env.USERPROFILE || process.env.HOME || '', '.xenia', 'keystore.properties') if (!existsSync(props)) { console.error(`No keystore properties at ${props} — refusing to build an unsigned release APK.`) process.exit(1) } } // Full path: cmd.exe doesn't look in the working directory for gradlew.bat const gradlew = join(androidDir, process.platform === 'win32' ? 'gradlew.bat' : 'gradlew') const task = variant === 'release' ? 'assembleRelease' : 'assembleDebug' console.log(`> gradlew ${task} (versionName ${versionName}, versionCode ${versionCode})`) execFileSync(gradlew, [task, '--console=plain'], { cwd: androidDir, stdio: 'inherit', shell: process.platform === 'win32' }) const built = join(androidDir, 'app', 'build', 'outputs', 'apk', variant, `app-${variant}.apk`) const outDir = join(root, 'releases') mkdirSync(outDir, { recursive: true }) const out = join(outDir, `xenia-waiter-${versionName}${variant === 'debug' ? '-debug' : ''}.apk`) copyFileSync(built, out) console.log(`\nAPK: ${out}`) // Release APKs are also bundled into the web build, so every venue server hands // out the app at http:///downloads/xenia-waiter.apk (the browser-mode // install banner links there). Build the Docker images AFTER this step. if (variant === 'release') { const downloads = join(root, 'public', 'downloads') mkdirSync(downloads, { recursive: true }) copyFileSync(built, join(downloads, 'xenia-waiter.apk')) console.log('Bundled for venue servers: public/downloads/xenia-waiter.apk') }