Skip to content

Commit 5f02db2

Browse files
therealalephclaude
andcommitted
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>
1 parent 8e5be57 commit 5f02db2

2 files changed

Lines changed: 66 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,21 +375,56 @@ jobs:
375375
chmod +x ./gradlew
376376
./gradlew :app:assembleRelease --no-daemon --stacktrace
377377
378-
- name: Rename APK with version
378+
- name: Rename APKs with version
379379
working-directory: android
380380
run: |
381381
VER="${GITHUB_REF#refs/tags/v}"
382-
SRC="app/build/outputs/apk/release/app-release.apk"
383-
if [ ! -f "$SRC" ]; then
384-
# Some AGP versions name it differently when the release config
385-
# can't be auto-signed. Catch that up front with a clear error
386-
# instead of a silent missing-artifact later.
387-
echo "::error::expected $SRC to exist; actual outputs:"
382+
mkdir -p ../dist
383+
384+
# With splits.abi enabled in build.gradle.kts (issue #136), AGP
385+
# emits:
386+
# app-universal-release.apk — all 4 ABIs bundled (~50 MB)
387+
# app-arm64-v8a-release.apk — modern 64-bit ARM (~15 MB)
388+
# app-armeabi-v7a-release.apk — older 32-bit ARM
389+
# app-x86_64-release.apk — emulator on Intel Macs / Chromebook
390+
# app-x86-release.apk — legacy 32-bit Intel emulator
391+
#
392+
# We publish all of them so users behind narrow / flaky
393+
# censorship tunnels can grab the per-ABI APK that matches
394+
# their device (~15 MB) instead of the ~50 MB universal.
395+
# Universal stays named `mhrv-rs-android-universal-v*.apk` so
396+
# existing download links and Telegram mirrors keep working.
397+
declare -A ABI_TO_OUTNAME=(
398+
["universal"]="mhrv-rs-android-universal-v${VER}.apk"
399+
["arm64-v8a"]="mhrv-rs-android-arm64-v8a-v${VER}.apk"
400+
["armeabi-v7a"]="mhrv-rs-android-armeabi-v7a-v${VER}.apk"
401+
["x86_64"]="mhrv-rs-android-x86_64-v${VER}.apk"
402+
["x86"]="mhrv-rs-android-x86-v${VER}.apk"
403+
)
404+
405+
missing=0
406+
for abi in "${!ABI_TO_OUTNAME[@]}"; do
407+
SRC="app/build/outputs/apk/release/app-${abi}-release.apk"
408+
if [ -f "$SRC" ]; then
409+
cp "$SRC" "../dist/${ABI_TO_OUTNAME[$abi]}"
410+
ls -la "../dist/${ABI_TO_OUTNAME[$abi]}"
411+
else
412+
echo "::warning::missing expected APK: $SRC"
413+
missing=$((missing + 1))
414+
fi
415+
done
416+
417+
# Require at least the universal — if that's missing something
418+
# is genuinely broken and we should fail loud rather than ship
419+
# a partial release.
420+
if [ ! -f "../dist/mhrv-rs-android-universal-v${VER}.apk" ]; then
421+
echo "::error::universal APK missing; actual outputs:"
388422
find app/build/outputs/apk -type f -name '*.apk' -print
389423
exit 1
390424
fi
391-
mkdir -p ../dist
392-
cp "$SRC" "../dist/mhrv-rs-android-universal-v${VER}.apk"
425+
if [ "$missing" -gt 0 ]; then
426+
echo "::warning::$missing per-ABI APK(s) missing; continuing with universal + whatever built"
427+
fi
393428
394429
- uses: actions/upload-artifact@v4
395430
with:

android/app/build.gradle.kts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ android {
6666
}
6767
}
6868

69+
// Per-ABI APK splits in addition to the universal APK.
70+
//
71+
// Issue #136: GitHub Releases is filtered from inside IR, and the
72+
// universal APK (~50 MB, all four ABIs bundled) is the bottleneck —
73+
// users on slow or unstable censorship-tunnel paths often can't
74+
// pull down 50 MB reliably. Per-ABI APKs are ~15 MB each (only one
75+
// copy of libmhrv_rs.so + libtun2proxy.so instead of four), which
76+
// is small enough to succeed where the universal fails.
77+
//
78+
// Keeping the universal APK too (`isUniversalApk = true`) because
79+
// existing download paths / docs / Telegram mirrors all reference
80+
// the universal name — removing it would break every link in the
81+
// wild. The per-ABI outputs are additive.
82+
splits {
83+
abi {
84+
isEnable = true
85+
reset()
86+
include("arm64-v8a", "armeabi-v7a", "x86_64", "x86")
87+
isUniversalApk = true
88+
}
89+
}
90+
6991
compileOptions {
7092
sourceCompatibility = JavaVersion.VERSION_17
7193
targetCompatibility = JavaVersion.VERSION_17

0 commit comments

Comments
 (0)