DOWNLOAD_IOMATEX_APP/DEVELOPERS.md

6.4 KiB
Raw Permalink Blame History

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

Обязательные для приложения поля:

{
  "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-устройств. Частичный .part-файл сохраняется; после временной сетевой ошибки сервис выполняет до трёх попыток и продолжает загрузку с помощью HTTP Range. Одновременно разрешён только один процесс загрузки обновления.
  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 увеличить обе части версии:

    version: 5.3.3+4434
    
  2. Убедиться, что локально существуют игнорируемые Git файлы:

    android/app/iomatex-release.jks
    android/key.properties
    
  3. Запустить анализ и тесты:

    flutter analyze
    flutter test
    
  4. Собрать production APK:

    flutter build apk --release
    
  5. Проверить сертификат APK через Android SDK apksigner:

    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. Получить метаданные:

    sha256sum releases/<version>-<build>/IOMATEX-*.apk
    stat -c '%s' releases/<version>-<build>/IOMATEX-*.apk
    
  4. Обновить все поля latest.json, включая абсолютный публичный apk_url.

  5. Проверить JSON:

    jq . latest.json
    
  6. Commit APK и manifest вместе, затем push в main. Manifest нельзя публиковать раньше APK: клиент сразу начнёт показывать новый release.

  7. После push проверить публичные ответы:

    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 должен иметь минимум две независимые зашифрованные резервные копии.