Lift the APK assembly out of package.sh so CI can run it too
package.sh does two things: it decides how the host reaches the image, and it assembles an APK once inside it. Only the first half is host-specific. CI already runs in that image, so the second half was about to be copied into a workflow step -- two copies of aapt2/zipalign/apksigner ordering, drifting apart at whatever rate the toolchain moves. So it moves to docker/android/assemble-apk.sh, which assumes it is inside the image and takes its paths from the environment, because the callers disagree about them: the container mounts the repo at /work, the runner checks it out wherever it likes. Every default reproduces what package.sh did, so the host path is unchanged. Two things stop being hard-coded on the way. The build-tools version and the compile SDK are resolved from what is installed rather than written out as 36.0.0 and android-36 -- the versions are Dockerfile ARGs, and a second copy is a second thing to miss when they move. --min-sdk-version now comes from that same ARG instead of a literal 28, which is the number the API-level check in CI already reads. The intermediates are removed at the end. They were harmless in a cache directory nobody looks at; beside a published artefact they are four more files for a glob to pick up by mistake. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -63,90 +63,15 @@ SO="${CACHE}/target/jniLibs/${ABI}/libdarkroom.so"
|
||||
# ---------------------------------------------------------------------------
|
||||
# 2. Assemble the APK inside the container, where the SDK lives.
|
||||
#
|
||||
# Everything below runs in one container invocation: aapt2 link produces a base
|
||||
# APK with the manifest, then the .so and Slint's dex are added as stored
|
||||
# entries, then zipalign and apksigner finish it. The .so is stored rather than
|
||||
# deflated so Android can mmap it directly (extractNativeLibs=false territory);
|
||||
# for a 37 MB library that also keeps install times sane.
|
||||
# The assembly itself is assemble-apk.sh, which runs in the image and is shared
|
||||
# with CI — see its header. Only the mount layout is decided here: the repo is
|
||||
# at /work and the cache's target directory at /work/target-android, so every
|
||||
# default in that script already points at the right place.
|
||||
# ---------------------------------------------------------------------------
|
||||
echo "==> packaging APK"
|
||||
"${HERE}/build.sh" bash -euo pipefail -c '
|
||||
SDK=/opt/android-sdk
|
||||
BT="${SDK}/build-tools/36.0.0"
|
||||
ABI="'"${ABI}"'"
|
||||
RT="'"${RUST_TARGET}"'"
|
||||
OUT=/work/target-android/apk
|
||||
rm -rf "${OUT}" && mkdir -p "${OUT}/staging/lib/${ABI}"
|
||||
|
||||
# Slint compiles a Java helper (SlintAndroidJavaHelper) in its build script
|
||||
# and dexes it. The build-dir hash changes whenever its inputs change, so
|
||||
# find it rather than hard-coding a path; the newest wins if stale
|
||||
# directories from earlier builds are still around.
|
||||
DEX="$(find "/work/target-android/${RT}/release/build" \
|
||||
-path "*i-slint-backend-android-activity*/out/classes.dex" \
|
||||
-printf "%T@ %p\n" 2>/dev/null | sort -rn | head -1 | cut -d" " -f2-)"
|
||||
if [[ -z "${DEX}" ]]; then
|
||||
echo "error: Slint classes.dex not found — did the backend build?" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo " dex: ${DEX}"
|
||||
|
||||
# A debug keystore, created once and kept in the cache. Debug-signed only:
|
||||
# this exists to get the app onto a test device, not to release it.
|
||||
KS=/work/target-android/debug.keystore
|
||||
if [[ ! -f "${KS}" ]]; then
|
||||
echo " generating debug keystore"
|
||||
keytool -genkeypair -keystore "${KS}" -alias androiddebugkey \
|
||||
-storepass android -keypass android \
|
||||
-keyalg RSA -keysize 2048 -validity 10950 \
|
||||
-dname "CN=Android Debug,O=Android,C=US" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# The launcher icon is the only resource the app has, but resources go
|
||||
# through aapt2 in two steps regardless: compile turns the source tree into
|
||||
# an intermediate archive of flat files, link folds that into the APK and
|
||||
# builds the resources.arsc table that @mipmap/ic_launcher in the manifest
|
||||
# resolves against. Skipping compile and handing link the directory does
|
||||
# not work — link only reads compiled input.
|
||||
"${BT}/aapt2" compile \
|
||||
--dir /work/apps/darkroom-android/android/res \
|
||||
-o "${OUT}/res.zip"
|
||||
|
||||
# aapt2 link needs the compile SDK to resolve android: attributes, and
|
||||
# --min-sdk-version is what ends up in the manifest the device reads.
|
||||
"${BT}/aapt2" link \
|
||||
-I "${SDK}/platforms/android-36/android.jar" \
|
||||
--manifest /work/apps/darkroom-android/android/AndroidManifest.xml \
|
||||
-R "${OUT}/res.zip" \
|
||||
--min-sdk-version 28 \
|
||||
--target-sdk-version 36 \
|
||||
--version-name "'"${VERSION_NAME}"'" \
|
||||
--version-code "'"${VERSION_CODE}"'" \
|
||||
-o "${OUT}/base.apk" \
|
||||
--auto-add-overlay
|
||||
|
||||
cp "/work/target-android/jniLibs/${ABI}/libdarkroom.so" \
|
||||
"${OUT}/staging/lib/${ABI}/libdarkroom.so"
|
||||
cp "${DEX}" "${OUT}/staging/classes.dex"
|
||||
|
||||
# -0 "" stores without compression; see the note above about mmap.
|
||||
cd "${OUT}/staging"
|
||||
cp "${OUT}/base.apk" "${OUT}/unaligned.apk"
|
||||
zip -q -0 -X "${OUT}/unaligned.apk" "lib/${ABI}/libdarkroom.so"
|
||||
zip -q -X "${OUT}/unaligned.apk" classes.dex
|
||||
|
||||
# zipalign before signing: apksigner preserves alignment, the reverse order
|
||||
# invalidates the signature.
|
||||
"${BT}/zipalign" -p -f 4 "${OUT}/unaligned.apk" "${OUT}/darkroom.apk"
|
||||
"${BT}/apksigner" sign \
|
||||
--ks "${KS}" --ks-pass pass:android --key-pass pass:android \
|
||||
--min-sdk-version 28 \
|
||||
"${OUT}/darkroom.apk"
|
||||
"${BT}/apksigner" verify --print-certs "${OUT}/darkroom.apk" | head -2
|
||||
'
|
||||
|
||||
echo "==> ${APK}"
|
||||
ls -la "${APK}"
|
||||
"${HERE}/build.sh" env \
|
||||
ABI="${ABI}" RUST_TARGET="${RUST_TARGET}" \
|
||||
/work/docker/android/assemble-apk.sh
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 3. Install from the host.
|
||||
|
||||
Reference in New Issue
Block a user