The runner host (~20GB/4-core, shared with Forgejo + databases) OOM-thrashed
because the RN build spawned ~3 Kotlin daemons at -Xmx5376m each. org.gradle.jvmargs
only bounds the Gradle JVM, not the forked Kotlin daemons — so write a
gradle.properties to GRADLE_USER_HOME with kotlin.daemon.jvmargs=-Xmx1536m,
org.gradle.jvmargs=-Xmx1536m, workers.max=2, parallel=false. Combined with the
earlier single-ABI + CMAKE_BUILD_PARALLEL_LEVEL=2 caps, the build no longer
swamps the host.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI: limit Gradle to 2 worker JVMs (org.gradle.workers.max=2, --max-workers=2,
parallel=false), cap native compiler jobs (CMAKE_BUILD_PARALLEL_LEVEL=2), and
build only the arm64-v8a ABI — so the build no longer spawns a JVM/compiler per
core and swamps the host (which also serves Forgejo).
App: the success chime now fires the instant a scan resolves to a valid ticket
(ticket/ice modes), matching Banquet, instead of after the check-in round-trip.
The failure sound is unchanged. Removed the duplicate chime at check-in.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Persist three Docker volumes into the build job (android-sdk, gradle home, npm
cache) and enable the Gradle build cache, so repeat builds skip the ~2GB NDK
download, Maven dependency resolution, and unchanged native/Kotlin compilation
— cutting builds from ~1h to a few minutes after the first run.
The runner must whitelist these volumes via config.yaml (container.valid_volumes);
deploy-runner.sh now writes that config, pre-creates the volumes, and starts the
daemon with --config. Requires re-running deploy-runner.sh on the runner host
before the next tag.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The runner host has no working IPv6 route; Maven Central (AAAA records) was
'Network is unreachable' while IPv4-only CDNs worked. Set
JAVA_TOOL_OPTIONS=-Djava.net.preferIPv4Stack=true so all build JVMs use IPv4.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>