Урок по треку Архитектура мобильных приложений 6 мин

CI/CD, фича-флаги и релизы мобильных приложений

Пайплайн сборки, подпись, тесты на CI, фича-флаги, поэтапные релизы, принудительное обновление и откат.

Главное отличие мобильных релизов от веба: их нельзя откатить мгновенно. Сборка проходит ревью магазина, пользователи обновляются днями, старые версии живут месяцами. Отсюда весь набор практик ниже.

CI для каждого пулреквеста

  • Сборка затронутых модулей.
  • Линтеры и статический анализ: SwiftLint, detekt, ktlint, Android Lint, flutter analyze, ESLint.
  • Юнит-тесты, snapshot-тесты дизайн-системы.
  • Проверка размера сборки.
  • Цель: 10-15 минут. Полные UI-тесты на нескольких устройствах ночью.

Ускорение: кеш зависимостей и результатов сборки, разделение по модулям, параллельные задачи.

Релизный пайплайн

тег или отсечка → версия и номер сборки → сборка и подпись
→ загрузка dSYM / маппинга R8 в крэш-аналитику
→ TestFlight и внутренний трек Google Play → регресс
→ ревью магазина → поэтапная раскатка → 100% или пауза

Инструменты: fastlane, Gradle Play Publisher, Xcode Cloud, GitHub Actions, GitLab CI, Bitrise.

Подпись: ключи и сертификаты в секретах CI, а не в репозитории. На Android Play App Signing хранит ключ подписи приложения у Google, а команда использует ключ загрузки, который можно сменить при утечке. На iOS API-ключ App Store Connect и общее хранилище сертификатов.

Релизный поезд

Релизы выходят по расписанию (раз в одну-две недели). Что готово к отсечке и закрыто флагами, уезжает; остальное едет следующим поездом. Маленькие регулярные релизы менее рискованны.

Фича-флаги

Типы:

  • релизный: прятать незавершённую фичу в основной ветке;
  • kill switch: мгновенно выключить проблемную функцию;
  • эксперимент: A/B-группы;
  • постепенное включение: растущая доля пользователей;
  • конфигурационный: лимиты, тексты, параметры без релиза.

Гигиена: у флага владелец и срок удаления, значения по умолчанию безопасны офлайн, флаги кешируются при старте, старые флаги удаляются.

Поэтапная раскатка

Google Play staged rollout: долю задаёте сами, раскатку можно остановить. App Store phased release: 7 дней по фиксированному графику, можно приостановить. На каждом этапе смотрят crash-free users и sessions, ANR rate, бизнес-метрики и отзывы, сравнивая с прошлым релизом.

Хотфикс

Остановить раскатку, выключить фичу флагом или поменять серверную конфигурацию, собрать исправление от релизной ветки, запросить ускоренное ревью, перенести фикс в основную ветку.

Совместимость версий

В продакшене одновременно живут 5-10 версий приложения. Поэтому:

  • API меняется аддитивно, ломающие изменения через новую версию эндпоинта;
  • клиент устойчив к неизвестным полям, значениям enum и типам блоков;
  • поведение настраивается удалённым конфигом;
  • минимальная поддерживаемая версия и принудительное обновление только для опасных случаев (уязвимость, сломанный протокол), с мягким предупреждением заранее;
  • контрактные тесты между клиентом и сервером.

Server-driven UI позволяет менять экраны (витрины, главные страницы) без релиза, но усложняет совместимость и отладку, а менять суть функциональности в обход ревью правила магазинов не позволяют.

Что спросят на собесе

  • Как устроен ваш CI/CD для мобильного приложения?
  • Зачем фича-флаги и какие они бывают?
  • Как работает поэтапная раскатка и по каким метрикам решать?
  • Что делать с критическим багом в релизе?
  • Как поддерживать совместимость бэкенда со старыми версиями приложения?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.