CampgroundTickets/runner/README.md
Hank 3583c2e15f CI: cache Android SDK/NDK, Gradle, and npm across APK builds
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>
2026-07-08 16:26:06 +00:00

2.9 KiB
Raw Blame History

Forgejo Actions runner (APK builds)

Run this on the roomy server (where Forgejo lives / where there's disk for the ~34 GB Android SDK), not on the app host — the Android build needs several GB of scratch space that the small app host doesn't have.

Deploy

  1. Copy this runner/ directory to the roomy server (or clone the repo there).
  2. In Forgejo → Beartaria/CampgroundTicketsSettings → Actions → Runners → Create new runner, copy the registration token.
  3. Create .env from the example and fill it in:
    cp .env.example .env
    # REGISTRATION_TOKEN=<the token from Forgejo>
    # DOCKER_GID=<output of: stat -c %g /var/run/docker.sock on THIS server>
    
  4. Start it:
    mkdir -p data && sudo chown -R 1000:1000 data
    docker compose up -d
    docker compose logs -f     # expect "declared successfully" then "poller launched"
    

The runner advertises the docker label; the build workflow (.forgejo/workflows/build-apk.yml) runs jobs in a node:22-bookworm container and installs the Android SDK itself.

Build an APK

  1. One-time: generate a keystore with ../scripts/gen-keystore.sh and add the four ANDROID_* secrets to the repo (see the main README → APK builds).
  2. Push a tag: git tag v0.1.0 && git push origin v0.1.0.
  3. The runner builds camp-scan-v0.1.0.apk and attaches it to a Forgejo release; Obtainium picks it up.

Build caching (fast repeat builds)

The first APK build takes ~1h (downloads Gradle + the ~2GB Android NDK, resolves all Maven deps, compiles native modules). After that it should drop to a few minutes because three persistent Docker volumes are reused across runs:

Volume Holds
camptickets-android-sdk/opt/android-sdk SDK, NDK, CMake
camptickets-gradle/root/.gradle Gradle dist, Maven deps, local build cache
camptickets-npm/root/.npm npm download cache

For this to work the runner must allow these volumes via config.yaml (container.valid_volumes) — deploy-runner.sh writes that config, pre-creates the volumes, and starts the daemon with --config /data/config.yaml. If you set the runner up by hand, copy config.yaml next to the compose file and add --config /data/config.yaml to the daemon command.

To force a clean rebuild, remove the volumes: docker volume rm camptickets-android-sdk camptickets-gradle camptickets-npm.

Notes

  • The runner I initially registered on the app host has been removed. If Forgejo still lists an offline camptickets-runner, delete it from Settings → Actions → Runners.
  • DOCKER_GID must match the roomy server's docker socket group, or the runner can't reach the Docker daemon.
  • After updating to a caching-enabled runner, re-run deploy-runner.sh (or docker compose up -d in the runner dir) so the new config.yaml + volumes take effect, then push a fresh tag.