DOWNLOAD_IOMATEX_APP/DEVELOPERS.md

138 lines
6.0 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.

# IOMATEX Android release guide
Этот репозиторий — публичный канал обновлений Android-приложения. Клиент читает
`latest.json`, сравнивает `build_number` с установленным `versionCode` и
показывает обновление только при строго большем значении.
## Неизменяемые правила
1. Каждая новая версия обязана увеличивать `build_number` в `pubspec.yaml`.
2. Все production APK подписываются только постоянным ключом
`iomatex-release`.
3. Keystore, пароль и `android/key.properties` никогда не добавляются в Git.
4. SHA-1 сертификата APK должен быть
`9C:0B:AA:72:12:C0:B9:84:12:10:CB:13:0A:92:20:89:5D:D8:27:EC`.
5. `latest.json`, APK, SHA-256 и размер обязаны описывать один и тот же файл.
6. Старые release-каталоги не изменяются и не удаляются.
7. Откат выполняется только новой сборкой с большим `build_number`. Уменьшение
номера не предложит пользователям обновление.
## Контракт latest.json
Обязательные для приложения поля:
```json
{
"version": "5.3.2",
"build_number": 4433,
"apk_url": "https://git.it-screen.com/.../IOMATEX.apk",
"sha256": "64 lowercase hex characters",
"size_bytes": 82910903,
"release_notes": {
"en": "English release notes",
"ru": "Русское описание"
}
}
```
## Фоновое обновление
Начиная с `5.3.4+4435`, direct-distribution сборка не открывает APK в
браузере. После явного нажатия пользователем кнопки обновления:
1. Foreground data-sync service IOMATEX скачивает APK в фоне и показывает
постоянное системное уведомление с прогрессом. Системный `DownloadManager`
не используется из-за зависания его очереди на части Android-устройств.
2. Клиент проверяет `size_bytes` и `sha256` из manifest.
3. Native Android-слой проверяет package name и совпадение сертификата
с установленным IOMATEX.
4. Только после этих проверок кнопка `Install update` передаёт APK
системному установщику.
Проверка `latest.json` выполняется при запуске, каждые 15 минут во время
активной сессии и сразу после возврата приложения из фона.
Этот канал нельзя включать в будущей Google Play сборке: Play-версия
должна обновляться только через Google Play и не запрашивать
`REQUEST_INSTALL_PACKAGES`.
Поля `build`, `platform`, `architecture`, `file` и `published_at` сохраняются
для людей и обратной совместимости внешних инструментов.
## Подготовка версии
1. В `IOMATEX_APP/pubspec.yaml` увеличить обе части версии:
```yaml
version: 5.3.3+4434
```
2. Убедиться, что локально существуют игнорируемые Git файлы:
```text
android/app/iomatex-release.jks
android/key.properties
```
3. Запустить анализ и тесты:
```bash
flutter analyze
flutter test
```
4. Собрать production APK:
```bash
flutter build apk --release
```
5. Проверить сертификат APK через Android SDK `apksigner`:
```bash
apksigner verify --verbose --print-certs \
build/app/outputs/flutter-apk/app-release.apk
```
SHA-1 signer должен точно совпасть с production SHA-1 из правил выше.
## Публикация
1. Создать неизменяемый каталог `releases/<version>-<build>/`.
2. Скопировать APK с понятным именем, включающим версию и build.
3. Получить метаданные:
```bash
sha256sum releases/<version>-<build>/IOMATEX-*.apk
stat -c '%s' releases/<version>-<build>/IOMATEX-*.apk
```
4. Обновить все поля `latest.json`, включая абсолютный публичный `apk_url`.
5. Проверить JSON:
```bash
jq . latest.json
```
6. Commit APK и manifest вместе, затем push в `main`. Manifest нельзя
публиковать раньше APK: клиент сразу начнёт показывать новый release.
7. После push проверить публичные ответы:
```bash
curl -fL https://git.it-screen.com/An-J/DOWNLOAD_IOMATEX_APP/raw/branch/main/latest.json
curl -fIL '<apk_url из manifest>'
```
8. Скачать APK по публичной ссылке, повторно проверить SHA-256 и установить на
тестовое устройство поверх предыдущей production-версии.
## CI/CD
Для автоматической сборки хранить keystore как protected file variable, а
пароли — как protected masked variables. Job должен восстановить
`android/app/iomatex-release.jks`, сформировать `android/key.properties`,
собрать APK, проверить signer SHA-1 и только затем публиковать release.
Не запускайте release job из недоверенных веток или pull request. Постоянный
keystore должен иметь минимум две независимые зашифрованные резервные копии.