android: publish per-ABI APKs in addition to universal (fix #136)

GitHub Releases is filtered from inside IR, and the 50 MB universal APK
is a bottleneck for users on slow/unstable censorship-tunnel paths that
can't reliably pull that much data. Per-ABI APKs are ~18–23 MB each —
small enough to succeed where the universal fails.

Build changes:
- android/app/build.gradle.kts: enabled `splits { abi { ... } }` with
  `isUniversalApk = true`, producing five release APKs:
    app-universal-release.apk     ~53 MB  (all 4 ABIs)
    app-arm64-v8a-release.apk     ~21 MB  (95%+ of modern devices)
    app-armeabi-v7a-release.apk   ~18 MB  (older 32-bit ARM)
    app-x86_64-release.apk        ~23 MB  (emulators, Chromebooks)
    app-x86-release.apk           ~22 MB  (legacy 32-bit Intel)
  abiFilters is retained for the universal build; splits.abi layers on
  per-ABI outputs without removing it.

- .github/workflows/release.yml: rename step now copies all 5 APKs to
  dist/ under versioned names (mhrv-rs-android-{abi}-v{VER}.apk),
  logs a warning if any per-ABI APK is missing, and hard-fails only if
  the universal is missing. Universal keeps its existing download path
  and filename so Telegram mirrors / previous-version update prompts
  keep working.

The release + telegram aggregation jobs downstream don't need changes —
they already use `files: dist/*` and `mhrv-rs-android-universal` artifact
name respectively.

Local build verified: clean assembleRelease produces all 5 APKs with the
expected size ratios (arm64-v8a is 41% the universal size).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
therealaleph
2026-04-24 22:26:44 +03:00
parent 7c102b4f63
commit cc04558437
2 changed files with 66 additions and 9 deletions
+44 -9
View File
@@ -375,21 +375,56 @@ jobs:
chmod +x ./gradlew chmod +x ./gradlew
./gradlew :app:assembleRelease --no-daemon --stacktrace ./gradlew :app:assembleRelease --no-daemon --stacktrace
- name: Rename APK with version - name: Rename APKs with version
working-directory: android working-directory: android
run: | run: |
VER="${GITHUB_REF#refs/tags/v}" VER="${GITHUB_REF#refs/tags/v}"
SRC="app/build/outputs/apk/release/app-release.apk" mkdir -p ../dist
if [ ! -f "$SRC" ]; then
# Some AGP versions name it differently when the release config # With splits.abi enabled in build.gradle.kts (issue #136), AGP
# can't be auto-signed. Catch that up front with a clear error # emits:
# instead of a silent missing-artifact later. # app-universal-release.apk — all 4 ABIs bundled (~50 MB)
echo "::error::expected $SRC to exist; actual outputs:" # app-arm64-v8a-release.apk — modern 64-bit ARM (~15 MB)
# app-armeabi-v7a-release.apk — older 32-bit ARM
# app-x86_64-release.apk — emulator on Intel Macs / Chromebook
# app-x86-release.apk — legacy 32-bit Intel emulator
#
# We publish all of them so users behind narrow / flaky
# censorship tunnels can grab the per-ABI APK that matches
# their device (~15 MB) instead of the ~50 MB universal.
# Universal stays named `mhrv-rs-android-universal-v*.apk` so
# existing download links and Telegram mirrors keep working.
declare -A ABI_TO_OUTNAME=(
["universal"]="mhrv-rs-android-universal-v${VER}.apk"
["arm64-v8a"]="mhrv-rs-android-arm64-v8a-v${VER}.apk"
["armeabi-v7a"]="mhrv-rs-android-armeabi-v7a-v${VER}.apk"
["x86_64"]="mhrv-rs-android-x86_64-v${VER}.apk"
["x86"]="mhrv-rs-android-x86-v${VER}.apk"
)
missing=0
for abi in "${!ABI_TO_OUTNAME[@]}"; do
SRC="app/build/outputs/apk/release/app-${abi}-release.apk"
if [ -f "$SRC" ]; then
cp "$SRC" "../dist/${ABI_TO_OUTNAME[$abi]}"
ls -la "../dist/${ABI_TO_OUTNAME[$abi]}"
else
echo "::warning::missing expected APK: $SRC"
missing=$((missing + 1))
fi
done
# Require at least the universal — if that's missing something
# is genuinely broken and we should fail loud rather than ship
# a partial release.
if [ ! -f "../dist/mhrv-rs-android-universal-v${VER}.apk" ]; then
echo "::error::universal APK missing; actual outputs:"
find app/build/outputs/apk -type f -name '*.apk' -print find app/build/outputs/apk -type f -name '*.apk' -print
exit 1 exit 1
fi fi
mkdir -p ../dist if [ "$missing" -gt 0 ]; then
cp "$SRC" "../dist/mhrv-rs-android-universal-v${VER}.apk" echo "::warning::$missing per-ABI APK(s) missing; continuing with universal + whatever built"
fi
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
+22
View File
@@ -66,6 +66,28 @@ android {
} }
} }
// Per-ABI APK splits in addition to the universal APK.
//
// Issue #136: GitHub Releases is filtered from inside IR, and the
// universal APK (~50 MB, all four ABIs bundled) is the bottleneck —
// users on slow or unstable censorship-tunnel paths often can't
// pull down 50 MB reliably. Per-ABI APKs are ~15 MB each (only one
// copy of libmhrv_rs.so + libtun2proxy.so instead of four), which
// is small enough to succeed where the universal fails.
//
// Keeping the universal APK too (`isUniversalApk = true`) because
// existing download paths / docs / Telegram mirrors all reference
// the universal name — removing it would break every link in the
// wild. The per-ABI outputs are additive.
splits {
abi {
isEnable = true
reset()
include("arm64-v8a", "armeabi-v7a", "x86_64", "x86")
isUniversalApk = true
}
}
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17