Files
f7cloud_mobile/docs/RELEASE-SIGNING.md
T
b-dev-mobile 67cc851b15 Этап 0 п.1: release собираем и подписан (signingConfig из env + R8-правила)
- signingConfig.release читает F7_KEYSTORE_FILE/PASSWORD, F7_KEY_ALIAS/PASSWORD
  из env или -P; фолбэк на debug-подпись если не заданы. Схемы v2+v3.
- R8: app/proguard-rules.pro (kotlinx.serialization, Firebase, JS-мосты, Coil);
  vendor consumer-rules.pro через consumerProguardFiles (WebRTC/LoganSquare/Dagger/
  RxJava/Parceler/EventBus + dontwarn geogson/joda из missing_rules.txt).
- Проверено на инфре B (JDK 21 + Android SDK 36): assembleRelease BUILD SUCCESSFUL,
  подписанный APK 99 МБ (было ~130 debug), apksigner verify v2+v3 OK.
- Доки: docs/RELEASE-SIGNING.md, docs/AUDIT-2026-07-07.md.
2026-07-07 13:17:20 +00:00

64 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (один раз, хранить в секрете и с бэкапом!)
```bash
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`.
⚠️ Боевой ключ подписи **неизменен на весь срок жизни приложения**: потеря = невозможность
выката обновлений существующим пользователям. Хранить в секрете + офлайн-бэкап.
## Локальная сборка (пример)
```bash
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
R8 + shrinkResources: **~130 МБ (debug) → 99 МБ (release, все 4 ABI)**. Дальнейшее сокращение
до ~3045 МБ — ABI-split/`resConfigs` (пункт 2 этапа 0 плана аудита), пока не сделано.