Build the Android APK on main and serve it for phone install #34
Labels
No labels
agent
agent:ci
agent:done
agent:failed
agent:needs-input
agent:refined
agent:refining
agent:running
agent:skip
autonomous
driven
local
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jeroen/cartopolis#34
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The Android app has been buildable since 2026-08-08 and installable by nobody.
crates/viberfox_android/build-apk.shneeds an NDK, an SDK root, a JDK andcargo-ndk; none of those are on a phone, anddocs/notes/android-build.mdrecorded a deliberate decision to have no APK job (the signing key would have
to be a real secret to be worth anything). So the artifact existed and the
install path did not — the only way to get the app onto a device was to run the
script by hand on a machine that had all four, then reach the phone somehow.
Two facts make the "no APK job" reasoning weaker than it looked:
app to the certificate that signed it and refuses an update signed by another
(
INSTALL_FAILED_UPDATE_INCOMPATIBLE). A key regenerated per CI run — which iswhat
build-apk.sh:159's built-in debug keystore is in a fresh container —turns every deploy into an uninstall/reinstall.
deploy-web.ymlalready publishes into/data/viberfox/site, which Caddy has mounted andfile_server'd.Approach
A new
.forgejo/workflows/deploy-android.yml, shaped likedeploy-web.ymlandseparate from
ci.ymlfor the same reason: this one links the whole Bevy stackagainst a runner with capacity 2, and the android lane in
ci.ymlmust stay afast
cargo checkon every push.main, plusworkflow_dispatch./data/viberfox/site/apk/→ https://viberfox.garage44.eu/apk/,with a small landing page (commit, date, size, sha256, download button).
stays at exactly one APK. That is the whole retention policy: the runner host
is at 76% with a 24 GB Actions cache on it.
deploy-web.yml'srsync --deletegrows--exclude '/apk/'; without it thenext web deploy silently removes the APK.
build-apk.shlearnsANDROID_KEY/ANDROID_CERT(apksigner--key/--cert)and strips the packaged
.socopy withllvm-strip --strip-unneeded./data/viberfox/android-key/(
.pk8+.x509.pem— openssl can produce that pair andkeytoolcannot,which keeps a JDK off the host), mounted read-only into the job, plus that
path in the runner's
valid_volumesand ano-cache+ APK content-type headerin the Caddyfile.
Acceptance criteria
deploy-android.ymlruns on pushes tomainand on manual dispatch..sha256and oneindex.html,under names that do not vary between builds.
over the previous one without an uninstall.
android_mainis anexported dynamic symbol, that there is no
classes.dex, and that nothingneeds
libc++_shared.so— the strip is the step that would otherwiseproduce an APK that builds, signs, installs and does not start.
trace (the runner drops an unlisted volume with a warning in its log and
nothing in the job's).
the packaging path is only exercised by the job itself.
itself: nothing has ever run on a device (
docs/notes/android-build.md,"Verification status").
Verification
bash -n crates/viberfox_android/build-apk.sh, plus eachrun:block extractedfrom the workflow YAML and syntax-checked — both done. The publish step was
dry-run against a temp root, so the landing page and the atomic rename are
exercised;
curl -sI https://viberfox.garage44.eu/apk/confirms the Caddyheaders on a placeholder page.
Everything past that needs the job: merge to
main(or dispatch on the branch)and watch the run. It cannot be verified in the agent container, which has no
NDK, no SDK and no JDK — and a full
android-releaselink is ~28 minutes cold.Device install is a workstation/phone check, not a CI one.
Out of scope
the phone remain unusable — that trade is unchanged and documented.
versionCodebump perbuild;
AndroidManifest.xmlstays atversionCode="1".arm64-v8aonly; nox86_64emulator build in CI.viberfox-ci:latest. The better end state, same asfor the NDK, but that image lives in another repo.
Branch:
feat/34-build-android-apk-mainPicked up as part of #44, which found why this never worked: CI ran
cargo fmt --checkas the first step of thecheckjob, so an unformatted merge ended the job before the Android lane ran — and behind it sat a real compile break (the APK is built--no-default-features, which dropssolo, which makes twosession.rsenum variants dead, andunused = "deny"makes dead code an error).deploy-android.ymlhas failed on every push tomainsince it landed.Both are fixed on
feat/44-native-release-polish, andcargo check -p viberfox_android --target aarch64-linux-androidnow passes for the first time. Leaving this open until the deploy actually runs onmainandhttps://viberfox.garage44.eu/apk/serves a verified 200.