# Forgejo Actions runner (APK builds) Run this **on the roomy server** (where Forgejo lives / where there's disk for the ~3–4 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/CampgroundTickets` → **Settings → Actions → Runners → Create new runner**, copy the **registration token**. 3. Create `.env` from the example and fill it in: ```bash cp .env.example .env # REGISTRATION_TOKEN= # DOCKER_GID= ``` 4. Start it: ```bash 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.