Publish the Android APK as a build artefact
Build and test / Desktop (Linux) (push) Failing after 1h12m6s
Build and test / Layer separation (push) Successful in 41s
Traceability / Requirement traces (push) Successful in 23s
🐳 Android image / Build and push (push) Successful in 10m59s
Build and test / android-image (push) Successful in 11m2s
Build and test / Android (aarch64) (push) Failing after 22m52s

The android job proved the app links for aarch64 and then threw the
result away. There was no APK anywhere in CI and no upload step in the
repo at all, so a green run left nothing anybody could install -- the
artefact list was empty by construction, not by failure.

It now assembles the APK with the script package.sh uses and uploads it.
The .so comes from the build the API-level check already ran; -o only
adds a copy of it where the packaging step looks, so this costs one copy
rather than a second twenty-minute cross-compile.

The signing key is the part worth being careful about. KEYSTORE points at
a mktemp directory rather than its default under target-android, because
that directory is precisely what actions/cache saves and restores -- the
default would have written a private key into the build cache and kept it
there. Nothing but the .apk is uploaded. A fresh debug key each run is
the right trade for an artefact meant to reach a test device: the only
thing a stable key buys is installing over a previous build without
uninstalling first, and a key that survives in cache storage to buy it is
a bad exchange.

if-no-files-found: error because the failure being guarded against is a
green run with an empty artefact list, which reads as success right up
until somebody goes looking for the file.

Debug-signed, arm64-v8a only -- the ABI the job already builds. Neither
is a release story; this is a build you can install.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 23:38:20 +02:00
co-authored by Claude Opus 5
parent 5741ec5e00
commit 834b219c3f
+37 -1
View File
@@ -223,7 +223,8 @@ jobs:
# It is also the honest artefact to check: the .so this names is the
# one that ships in the APK, so the API level verified here is the
# API level a device will refuse to install against.
cargo ndk -t arm64-v8a build -p darkroom-android --release
cargo ndk -t arm64-v8a -o target-android/jniLibs \
build -p darkroom-android --release
MIN_API=$(sed -n 's/^ARG MIN_API=\([0-9]*\).*/\1/p' docker/android/Dockerfile)
# Empty on both sides would compare equal and pass, so neither side
# is allowed to be the result of a failed parse.
@@ -244,6 +245,41 @@ jobs:
exit 1
fi
# The APK itself, so a run leaves something installable behind rather
# than only the knowledge that it would have linked. The assembly is
# `docker/android/assemble-apk.sh`, shared with `package.sh` so the file
# a device gets from `package.sh --install` and the file published here
# are built by the same code — see that script's header.
#
# `KEYSTORE` deliberately points at a throwaway directory instead of its
# default under `target-android`: that directory is what `actions/cache`
# restores and saves, and a signing key has no business in a build cache
# or in anything this job uploads. A fresh debug key per run is the right
# trade for an artefact whose purpose is getting the app onto a test
# device; nothing upgrades in place over it, which is the one thing a
# stable key would buy.
- name: Package the APK
env:
CARGO_TARGET_DIR: target-android
run: |
set -e
KEYDIR="$(mktemp -d)"
trap 'rm -rf "$KEYDIR"' EXIT
REPO="$PWD" \
TARGET_DIR="$PWD/target-android" \
KEYSTORE="$KEYDIR/debug.keystore" \
bash docker/android/assemble-apk.sh
# `if-no-files-found: error` because the failure this guards against is
# a green run with an empty artefact list, which reads as success until
# somebody goes looking for the file.
- name: Upload the APK
uses: actions/upload-artifact@v4
with:
name: darkroom-arm64-v8a-apk
path: target-android/apk/darkroom.apk
if-no-files-found: error
layering:
runs-on: linux/amd64
name: Layer separation