Files
f7cloud_mobile/docs/RELEASE-SIGNING.md
T
b-dev-mobile c259936e82 Этап 0 п.2: универсальный APK 99→53 МБ (abiFilters ARM + resConfigs ru,en)
- defaultConfig.ndk.abiFilters 'arm64-v8a','armeabi-v7a' — без эмуляторных x86/x86_64
- resourceConfigurations += ['ru','en'] — срез ~48 локалей vendor до нужных
- проверено сборкой: assembleRelease 53 МБ, ABI только ARM, подпись v2+v3 OK
- renderscriptSupportModeEnabled в vendor НЕ трогал (риск blur, отдельный пункт)
2026-07-07 17:55:14 +00:00

4.5 KiB

Release-подпись и минификация f7cloud_mobile

TL;DR

assembleRelease теперь собирает подписанный, минифицированный APK. Ключ подписи берётся из окружения; при его отсутствии release подписывается debug-ключом (для локального QA).

Переменные окружения (боевой keystore — вне git, в CI — из secrets)

Переменная Назначение
F7_KEYSTORE_FILE путь к keystore (.jks/.p12)
F7_KEYSTORE_PASSWORD пароль хранилища
F7_KEY_ALIAS алиас ключа
F7_KEY_PASSWORD пароль ключа

Можно задавать и как gradle-property (-PF7_KEYSTORE_FILE=…). Логика — в app/build.gradle (signingConfigs.release): если F7_KEYSTORE_FILE задан и файл существует → подпись боевым ключом (схемы v2+v3, v1 отключён — minSdk 26); иначе → debug-ключ (APK не для распространения).

Генерация боевого keystore (один раз, хранить в секрете и с бэкапом!)

keytool -genkeypair -v \
  -keystore f7cloud-release.p12 -storetype PKCS12 \
  -alias f7cloud -keyalg RSA -keysize 4096 -validity 10000 \
  -dname "CN=F7cloud Mobile, O=F7cloud, C=RU"

⚠️ PKCS12 (дефолт современного keytool): пароль ключа ОБЯЗАН совпадать с паролем хранилища. Отдельный -keypass игнорируется → при сборке KeytoolException: Given final block not properly padded. Поэтому F7_KEY_PASSWORD == F7_KEYSTORE_PASSWORD.

⚠️ Боевой ключ подписи неизменен на весь срок жизни приложения: потеря = невозможность выката обновлений существующим пользователям. Хранить в секрете + офлайн-бэкап.

Локальная сборка (пример)

export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
export ANDROID_HOME=/opt/android-sdk
source /path/to/signing.env      # экспорт четырёх F7_* переменных
./gradlew :app:assembleRelease
# APK: app/build/outputs/apk/release/f7cloud-mobile-v<ver>-<code>-release.apk
# проверка: $ANDROID_HOME/build-tools/36.0.0/apksigner verify --verbose <apk>

Минификация (R8)

Release: minifyEnabled true + shrinkResources true. Keep-правила:

  • app-уровеньapp/proguard-rules.pro (kotlinx.serialization, Firebase, JS-мосты WebView, Coil).
  • vendor-зависимостиvendor/talk-android/app/consumer-rules.pro, подключён через consumerProguardFiles (WebRTC JNI, LoganSquare $$JsonObjectMapper, Dagger, RxJava, Parceler, EventBus, conscrypt + -dontwarn geogson/joda). Vendor — library без своей минификации, поэтому его правила доезжают до R8 приложения ТОЛЬКО через consumer-файл.

При добавлении рефлексивных библиотек: собрать release, при Missing class R8 сгенерирует точные правила в app/build/intermediates/mapping/release/minifyReleaseWithR8/missing_rules.txt — перенести их в соответствующий proguard-файл.

Размер APK

Прогресс сокращения (универсальный APK):

  • ~130 МБ — debug (все 4 ABI, без R8).
  • 99 МБ — release: R8 + shrinkResources (все 4 ABI).
  • 53 МБ — + abiFilters 'arm64-v8a','armeabi-v7a' (без эмуляторных x86/x86_64) + resourceConfigurations += ['ru','en']. Это ТЕКУЩИЙ универсальный APK (пункт 2 этапа 0).

Состав .so в 53-МБ APK: arm64-v8a ~19 МБ + armeabi-v7a ~11 МБ (в основном WebRTC). Настройки — в app/build.gradle (defaultConfig.ndk.abiFilters, resourceConfigurations).

Ещё возможно (НЕ сделано, требует проверки на устройстве): только arm64 (−~11 МБ, теряет 32-битные устройства); отключить renderscriptSupportModeEnabled в vendor (риск для blur-эффектов).