Build the Android app on our own Gitea runner
Pushing a v* tag builds the normal and FOSS APKs, signed with the upload key, and attaches them to a Gitea release; a manual run on a branch uploads a test build to the repo's packages. Everything runs on the Gitea server: a builder image with the Android SDK, an act_runner registered only for this repo, and plain shell steps (no third-party actions). The build itself is apps/mobile/scripts/build-android.sh, the same script for hand builds. Setup steps are in docs/ANDROID-CI.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build both release APKs into an output folder:
|
||||
# musicshare-<version>.apk the normal app (with Google's barcode scanner)
|
||||
# musicshare-<version>-foss.apk no closed-source code (MUSICSHARE_FOSS=1), as F-Droid builds it
|
||||
#
|
||||
# apps/mobile/scripts/build-android.sh [out-dir] (default: apps/mobile/dist)
|
||||
#
|
||||
# Both are signed with the upload key when it's configured (see plugins/withReleaseSigning.js;
|
||||
# in CI it comes from ORG_GRADLE_PROJECT_MUSICSHARE_UPLOAD_* variables). Set REQUIRE_SIGNED=1 to
|
||||
# fail rather than produce unsigned APKs. ABIS picks the CPU types (default: phones, 32 and 64 bit).
|
||||
# Regenerates apps/mobile/android each time (prebuild --clean).
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
OUT=$(realpath -m "${1:-dist}")
|
||||
VERSION=$(node -p "require('./app.json').expo.version")
|
||||
ABIS=${ABIS:-armeabi-v7a,arm64-v8a}
|
||||
BUILD_TOOLS=$(ls -d "$ANDROID_HOME"/build-tools/*/ | sort -V | tail -1)
|
||||
mkdir -p "$OUT"
|
||||
|
||||
say() { printf '\n==> %s\n' "$*"; }
|
||||
|
||||
build() {
|
||||
local suffix=$1 foss=$2
|
||||
say "Building musicshare-$VERSION$suffix.apk"
|
||||
MUSICSHARE_FOSS=$foss CI=1 npx expo prebuild --platform android --clean --no-install
|
||||
(cd android && ./gradlew :app:assembleRelease -PreactNativeArchitectures="$ABIS" --console=plain)
|
||||
local apk
|
||||
apk=$(ls android/app/build/outputs/apk/release/*.apk | head -1)
|
||||
|
||||
if "$BUILD_TOOLS/apksigner" verify "$apk" > /dev/null 2>&1; then
|
||||
"$BUILD_TOOLS/apksigner" verify --print-certs "$apk" | grep 'SHA-256 digest'
|
||||
elif [ "${REQUIRE_SIGNED:-0}" = 1 ]; then
|
||||
echo "The APK isn't signed: is the upload key configured?" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "Unsigned (no upload key configured)."
|
||||
fi
|
||||
|
||||
if [ "$foss" = 1 ]; then
|
||||
# Nothing from Google's closed-source libraries may be inside.
|
||||
local tmp count
|
||||
tmp=$(mktemp -d)
|
||||
unzip -q "$apk" 'classes*.dex' -d "$tmp"
|
||||
count=$(for f in "$tmp"/classes*.dex; do "$BUILD_TOOLS/dexdump" "$f" 2>/dev/null | grep 'Class descriptor'; done | grep -cE 'Lcom/google/(mlkit|android/gms)/' || true)
|
||||
rm -rf "$tmp"
|
||||
if [ "$count" != 0 ]; then
|
||||
echo "The FOSS build contains $count ML Kit / Play Services classes." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "No ML Kit / Play Services classes."
|
||||
fi
|
||||
cp "$apk" "$OUT/musicshare-$VERSION$suffix.apk"
|
||||
}
|
||||
|
||||
build "" 0
|
||||
build "-foss" 1
|
||||
(cd "$OUT" && sha256sum musicshare-"$VERSION"*.apk > SHA256SUMS && cat SHA256SUMS)
|
||||
Reference in New Issue
Block a user