Используйте этот чек-лист готовности Flutter-релиза, чтобы подготовить подпись, flavors, краш-репортинг, тексты разрешений и ресурсы для магазина — и сделать первую отправку спокойной и полной.

«Готово к релизу» — это не «приложение запускается на моём телефоне». Это значит, что вы можете сгенерировать production-сборку, установить её на чистое устройство и отправить в магазин без сюрпризов в последний момент.
Чаще всего прямо перед первой отправкой ломается нечто скучное, но болезненное: потерянные ключи подписи, случайно загруженная debug-сборка, краши без полезных логов, запросы разрешений, которые выглядят подозрительно, или ресурсы для магазина, не соответствующие приложению (неправильные иконки, старые скриншоты, отсутствующий текст приватности).
Для первой отправки Flutter-приложения «готовность к релизу» сводится к четырём результатам:
Это руководство фокусируется на обязательном для первой отправки: подпись, flavors, краш-репортинг, тексты и тайминг разрешений и ресурсы для стор-листинга. Это не полноценный план QA, аудит производительности или юридическая проверка.
Запланируйте хотя бы несколько сессий, сфокусированных на задачах. Одиночный разработчик часто закрывает это за 1–2 дня. В команде назначьте явных владельцев (подпись/сборки, краш-репортинг, листинг в сторе и тексты), чтобы ничего не скапливалось в последний час.
Большинство «последних минут» проблем релиза — это ранние решения, которые вы не приняли. Зафиксируйте несколько базовых вещей сейчас, и всё, что идёт дальше, станет проще.
Начните с идентичности: точное имя приложения, которое видят пользователи, и внутренние идентификаторы магазинов (package name на Android, bundle identifier на iOS). Поздняя смена этих значений может сломать обновления, deep links и историю аналитики. Решите также, как вы будете версионировать релизы, чтобы у каждой сборки был понятный номер и вы не гадали, что сейчас в продакшене.
Затем определите платформенные границы: Android, iOS или обе платформы на первый день, и минимальные версии ОС, соответствующие вашим пользователям. Повышение минимальной версии в последний момент может вынудить менять дизайн или исключить устройства, которые вы считали поддерживаемыми.
Запишите эти решения там, где команда сможет их найти:
Наконец, подтвердите, что аккаунты в магазинах существуют и у вас есть возможность публиковать. Ничто так не тормозит запуск, как ожидание одобрения аккаунта, незаполненные налоговые формы или отсутствие прав на загрузку. Если вы генерируете приложение с помощью платформы вроде Koder.ai или программируете вручную, эти решения всё равно применимы.
Подпись приложения — это доказательство, что обновление действительно от вас. Если подпись настроена неправильно, магазин может отклонить загрузку или вы можете оказаться неспособны выпускать обновления.
На Android подпись обычно означает upload key, хранящийся в keystore-файле (и пароли к нему). На iOS это сертификаты и provisioning profiles, привязанные к Apple Developer аккаунту. Даже если вы собираете приложение через Koder.ai и экспортируете исходники, вам всё равно нужно чёткое владение аккаунтами магазинов и подписи до первой отправки.
Выберите систему-источник правды для каждой платформы, желательно корпоративный аккаунт вместо личного. Установите правила доступа, чтобы вы не зависели от одного ноутбука или человека.
Ведите краткую запись, отвечающую на вопросы:
Потерянный Android-ключ может блокировать будущие обновления для того же package. Сделайте зашифрованную резервную копию в отдельном месте и протестируйте восстановление. Для iOS потеря доступа обычно превращается в боль восстановления аккаунта, поэтому держите несколько доверенных администраторов и документируйте их контакты.
Проверьте подпись на чистой машине (чистый checkout, новый CI-runner или ноутбук коллеги). Если всё работает только на одном компьютере — это неготово.
Flavors предотвращают ситуацию «работает на моём телефоне» → «мы выпустили тестовый сервер». Проще говоря, flavor — это именованная сборка, которая использует разные конфиги без правки файлов перед каждым релизом.
Большинству команд стоит начать с двух flavor’ов: dev (для тестирования) и prod (то, что вы отправляете). Если в команде есть «staging», используйте это название. Путающие имена приводят к ошибочным сборкам и загрузкам.
Зафиксируйте, что именно отличается между flavor’ами. Наиболее частые отличия: идентичность приложения (имя и bundle ID), иконки, API-эндпойнты, флаги функций, настройки аналитики/краш-репортинга и уровень логов.
Держите чувствительные значения вне репозитория, когда можно. Используйте файлы окружения, CI-секреты или переменные времени сборки, чтобы ключи не попали в коммиты.
Перед тем как считать задачу выполненной, соберите каждый flavor, который собираетесь использовать, включая чистую релизную сборку. Отсутствующие конфиги обнаруживаются здесь, а не в день запуска.
Даже чистая сборка может не показать реальные проблемы: редкие устройства, нестабильные сети и краевые сценарии. Краш-репортинг превращает эти сюрпризы в список задач.
Выберите один инструмент для краш-репортинга и подключите его рано. Бренд менее важен, чем то, чтобы каждая релизная сборка присылала полезные отчёты.
Многие «не воспроизводится» случаи связаны с отсутствием символов. Сделайте шаг загрузки следующих артефактов частью релиза:
Если это делается вручную, оно будет пропущено в напряжённую неделю.
Решите, что вам нужно в день релиза: версия приложения/сборка, модель устройства, версия ОС, локаль и последний экран или действие. Если у вас есть аккаунты пользователей, добавьте стабильный анонимный ID пользователя и флаг «вошёл/не вошёл». Избегайте персональных данных в логах.
Также фиксируйте нефатальные ошибки. Во Flutter многие проблемы проявляются как исключения, которые не крашат приложение (ошибки парсинга, таймауты, неожиданные null). Отправляйте их как non-fatal события с коротким сообщением и несколькими ключ-значение полями.
Протестируйте это до релиза: соберите staging-сборку, вызовите форсированный краш (через debug-меню или секретный жест) и убедитесь, что вы видите читаемый стек-трейс с правильной версией и контекстом.
Запросы разрешений — быстрый способ потерять доверие при первом запуске. До релиза перечислите все разрешения, которые может запрашивать приложение, фичу, ради которой оно нужно, и что пользователь получает взамен. Если вы не можете объяснить это одним коротким предложением, скорее всего, не стоит запрашивать разрешение.
Держите текст простой и конкретный. «Нам нужен доступ к вашим фотографиям» слабее, чем «Разрешите доступ к фото, чтобы прикрепить чек к расходу». Избегайте технических слов типа «storage», если вы не объясняете, что это значит в момент запроса.
Просите только тогда, когда пользователь инициирует связанную операцию. Не запрашивайте доступ к Фотографиям при старте приложения. Просите, когда пользователь нажимает «Добавить фото», после короткого экрана с объяснением.
Если пользователь отвечает «нет», приложение всё равно должно оставаться удобным. Продумайте альтернативы заранее: держите фичу видимой, объясняйте, что заблокировано, предлагайте обходной путь и сохраняйте прогресс, чтобы пользователь не терял работу. Если выбран «Больше не спрашивать», аккуратно направьте пользователя в Настройки.
Проверьте платформенно-специфичные тексты. iOS требует понятных usage descriptions в Info.plist. Android — правильных записей в манифесте и иногда короткого объяснения внутри приложения. Отсутствие или расплывчатость этих текстов может задержать ревью или отпугнуть пользователей.
Это лёгкий прогон, призванный поймать проблемы, которые проявляются только в реальной релизной сборке. Держите его в пределах часа.
Напишите простой скрипт, который может выполнить любой, даже без дев-инструментов. Правило: тестируйте то, что делают пользователи, а не то, что могут посмотреть разработчики.
Запустите его минимум на одном небольшом телефоне и одном крупном устройстве (а лучше ещё и на старой версии ОС):
После прогона принудительно закройте приложение и запустите снова, чтобы подтвердить, что старт чистый и приложение не зависит от «тёплого» состояния.
Если что-то падает, зафиксируйте точный экран, последнее действие и на каком размере экрана воспроизводится. Часто этого достаточно для быстрого исправления.
Много стресса при запуске приходит от страницы в магазине, а не от кода. Обращайтесь с листингом как с частью релиза — тогда не будет последней минуты с дизайнерскими запросами, отсутствием ответов по приватности и хаосом со скриншотами.
Соберите то, что почти наверняка понадобится: иконку приложения, скриншоты, короткое подзаголовок, более длинное описание и платформенно-специфичные графики. Промо-видео — опционально и имеет смысл только если вы будете поддерживать его в актуальном состоянии.
Для скриншотов заранее выберите размеры устройств и придерживайтесь их. Держите последовательность (онбординг, основной экран, ключевая функция, настройки, апгрейд), чтобы обновления не превращались в хаос.
Пишите описание по-человечески: одно ясное предложение о том, что делает приложение, затем несколько коротких строк про выгоды и прямое замечание о подписках или аккаунтах, если они есть. Не обещайте того, что не поддерживаете.
Также заранее соберите ответы по приватности и использованию данных. Вас попросят о tracking, типах собираемых данных и разрешениях. Если приложение запрашивает локацию, контакты или фото — объясните, зачем это нужно, простыми словами.
Если держать ресурсы организованными, обновления становятся рутинной задачей. Простая структура достаточна (иконка, скриншоты по типам устройств, тексты, заметки по приватности и релиз-ноты).
Dry-run — пройти весь поток отправки в магазин как будто вы вот-вот выпустите релиз, но не нажимать Publish. Это превращает догадки в реальные ответы.
Выберите сборку, которую готовы загрузить (даже если не собираетесь её выпускать). Загрузите её, заполните формы и сохраните черновик. Цель — найти недостающую информацию, пока ещё есть время.
Проверьте:
Запланируйте «что если первый релиз плохой». Решите, как откатываться (держите предыдущий подписанный артефакт), как выпускать хотфикс и что станет триггером для приостановки rollout (всплеск крашей, проблемы со входом).
Также решите, как собирать раннюю обратную связь в первые 48 часов. Небольшой канал для группы, почта поддержки, которую вы действительно мониторите, и in-app «Отправить отзыв» помогут поймать очевидные проблемы до появления однозвёздочных отзывов.
Большинство задержек происходит потому, что сборка, которую вы тестировали, не совпадает с той, что вы отправляете. Debug или profile могут выглядеть идеально, а release-сборка падает на реальном устройстве из-за минификации, других значений конфигурации или отсутствующих runtime-разрешений.
Ещё одна потеря времени — смешивание dev и prod-настроек: отправка staging-URL, неверный ключ аналитики или тестовые платёжные настройки. Обращайтесь с production как с отдельной средой и проверяйте именно релизный артефакт.
Эти ловушки регулярно бьют по командам:
Представьте пятничную загрузку: рецензент открывает приложение, нажимает фичу, которая запрашивает доступ, и текст спорный. Вы исправляете текст, но ключ подписи лежит у коллеги, который офлайн. Это два предотвратимых дня.
Используйте его за день до сборки под магазин. Он намеренно короткий. Если какой-то пункт “может быть”, остановитесь и исправьте перед тем, как тратить время на формы магазина.
Если вы собираете через платформу, которая может экспортировать исходники, например Koder.ai (koder.ai), добавьте ещё одну проверку: подтвердите, что экспортированный проект производит ту же подписанную релиз-сборку, которую вы собираетесь загрузить.
Малая команда из трёх человек готовит первое Flutter-приложение в магазины: разработчик, дизайнер и PM на частичной занятости. Они относятся к первой отправке как к репетиции.
В понедельник разработчик генерирует релизную сборку и понимает, что ключ подписи лежит на ноутбуке, который собираются очистить. Они исправляют это в тот же день: переносят ключ в общий, контролируемый хранилище, документируют владение и подтверждают, что CI может подписывать сборки.
Во вторник PM вслух читает все подсказки разрешений. Одна из них выделяется: текст разрешения на фото говорит «обязательно», тогда как приложение использует фото только для опционального аватара. Они переписывают текст, объясняющий выгоду, и перемещают запрос на момент нажатия «Добавить фото».
В четверг они делают полный dry-run отправки с финальными скриншотами, релиз-нотами и production-сборкой. Магазин отмечает несоответствие между описанием и надписью подписки в приложении. Поскольку это dry-run, они правят формулировку и повторно сохраняют черновик до дня релиза.
Они держат простой план на следующий раз:
Первый запуск учит вас, как выглядит настоящая «готовность». Зафиксируйте это, пока опыт свеж.
Назначьте явных владельцев. Даже в небольшой команде «все» часто означает «никто», и важные задачи соскальзывают:
Превратите то, что вы сделали, в повторяемый чек-лист и шаблон релиз-нот: команды команду, команды команду, команды... (опишите команды, команды, команды), команды, команды. Сохраните команды, команды — и получайте удовольствие от более спокойных релизов.
Запланируйте 20-минутный пост-релизный разбор в течение недели. Фокус — на исправлениях, а не на поиске виноватых:
Если вы собираете через Koder.ai, Planning Mode поможет отслеживать задачи релиза в одном месте, а snapshots дадут известное рабочее состояние перед правками в последний момент.
Release-ready означает, что вы можете получить подписанную production (release) сборку, установить её на чистое устройство и отправить в магазин без правок в последний момент.
Практический минимум:
Создайте release-сборку, затем установите её на устройство, на котором никогда не было вашего приложения.
Проверьте:
Если вы тестировали только debug/profile — считайте, что вы не проверяли то, что собираетесь выпустить.
Обращайтесь с подписывающими компонентами как с продакшен-учетными данными:
Если ключ существует только на одном ноутбуке — вы в одном несчастном случае от блокировки обновлений.
Привязывайте подпись к Apple Developer-аккаунту с понятным доступом админов.
Сделайте это заранее:
Начните с двух flavor’ов: dev и prod.
Типичные отличия:
Цель — избежать правки файлов вручную прямо перед релизом.
Не держите секреты в репозитории.
Хорошие практики:
Это предотвращает случайную отправку staging-эндпойнтов или тестовых платёжных настроек.
Выберите один инструмент для краш-репортинга и интегрируйте его в релизный процесс.
Минимальная конфигурация:
Протестируйте через форсированный краш в staging/release-сборке и убедитесь, что отчет пригоден для отладки.
Просите разрешение только тогда, когда пользователь собирается воспользоваться фичей.
Хороший паттерн:
Невразумительные подсказки и ранняя липкость запросов — частая причина недоверия и задержек при ревью.
Быстрый «smoke test» релизной сборки, который может выполнить любой:
Фиксируйте: последний экран, действие, модель устройства и повторяемость.
Сделайте dry-run отправки в магазин и сохраните черновик.
Проверьте, что готовы:
Также заранее продумайте план отката или hotfix до нажатия Publish.