Эта статья делает одно
- Строит ментальную модель Flutter iOS CI = Уровень управления + Уровень выполнения + Уровень кэша.
- Предоставляет матрицу решений macos-latest vs. самостоятельный — ответ за 5 минут.
- Распределяет детальную реализацию по 5 тематическим статьям — прямой доступ по вашей проблеме.
Трёхуровневая CI-модель
Прежде чем рассматривать конкретные инструменты, установим одно уравнение — оно определяет, какой уровень нужно изменить:
Flutter iOS CI =
Уровень управления (GitHub Actions: триггеры · согласования · Secrets)
+ Уровень выполнения (Mac mini M4 : нативная iOS-сборка · подпись · согласованность среды)
+ Уровень кэша (Локальный SSD : персистентное хранение зависимостей и артефактов)
Три следствия, определяющие все решения этой серии:
- Уровень управления не выполняет код. Оптимизация YAML workflow не ускоряет сборки. Сокращение времени сборки требует замены уровня выполнения.
- Уровень выполнения определяет воспроизводимость. Версия Xcode в общем пуле (
macos-latest) следует обновлениям GitHub; на самостоятельной машине версию фиксируете вы. - Уровень кэша определяет скорость. Преимущество в скорости самостоятельного раннера — не от CPU, а от того, что локальный SSD заменяет загрузку/скачивание удалённого кэша при каждом задании.
Почему Flutter iOS CI нужен выделенный уровень выполнения macOS
Flutter может обрабатывать Android-сборки и юнит-тесты на Linux, но iOS-сборки и релизы в App Store возможны только на macOS — жёсткое ограничение цепочки инструментов Apple, а не Flutter.
Поэтому каждая Flutter-команда сталкивается с архитектурным выбором: где выполнять iOS-ветку? Три типичные проблемы, которые заставляют уходить от macos-latest:
- Стоимость: GitHub-хостируемые macOS-раннеры значительно дороже по минутному тарифу, чем Linux. Холодные iOS-сборки занимают 20–30 минут; счёт быстро растёт с частотой сборок.
- Согласованность среды: Версия Xcode в хостируемых образах следует обновлениям GitHub — её нельзя зафиксировать. «Локально проходит, CI падает» становится повторяющейся стоимостью отладки.
- Скорость сборки: iOS-зависимости объёмны. Хостируемые раннеры повторно загружают кэш при каждом задании. Самостоятельная машина с локальным SSD устраняет это узкое место в корне.
«Вернуть уровень выполнения macOS в контролируемые границы» — вот центральное архитектурное решение. Уровень управления остаётся в GitHub (триггеры PR, ревью-шлюзы, управление Secrets); только уровень выполнения заменяется на выделенный Mac mini M4.
Официальные ссылки: Документация GitHub self-hosted runners · Руководство Flutter CD
Обзор архитектуры
Отобразите весь пайплайн на трёхуровневую модель — при возникновении проблемы сначала определите уровень, затем переходите к соответствующей тематической статье:
| Уровень | Отвечает за | Не отвечает за | Признаки сбоя |
|---|---|---|---|
| Уровень управления | Правила триггеров, границы прав, инъекция Secrets, загрузка артефактов | Не выполняет код сборки | Задание не запускается / ошибка прав / сбой PR-шлюза |
| Уровень выполнения | Нативная iOS-сборка, фиксированная версия Xcode, цепочка подписи | Не управляет логикой триггеров и источником Secrets | Дрейф среды / сбой подписи / раннер офлайн |
| Уровень кэша | Персистентность зависимостей и артефактов между заданиями | Не определяет триггеры и среду выполнения | Горячая ≈ холодной сборке / предупреждение диска / случайные сбои |
Любой сбой Flutter iOS CI относится к одной из этих трёх строк. Правильно определив уровень, путь к решению становится очевидным.
Матрица решений: когда миграция оправдана?
Самостоятельный хостинг — не ответ по умолчанию. Эта матрица позволяет принять решение за 5 минут командного ревью:
| Сигнал | Оставить macos-latest | Мигрировать на самостоятельный |
|---|---|---|
| Частота сборок | < 40 iOS-сборок в месяц | > 40/месяц или несколько раз в день |
| Стабильность среды | Нет чувствительности к минорным версиям Xcode | Нужна фиксация версии Xcode / SDK |
| Скорость сборки | Горячая сборка < 8 мин приемлема | Горячая сборка стабильно > 8 мин, замедляет итерации |
| Пайплайн релизов | Подпись App Store не требуется | Есть пайплайн App Store / TestFlight |
| Готовность к эксплуатации | Приоритет нулевых операций | Готовы обменять ежемесячное окно обслуживания на контроль |
Эмпирическое правило: 3 и более сигналов «мигрировать» — самостоятельный хостинг обычно окупается за 2–4 недели (аренда машины vs. сэкономленные минуты хостируемого macOS).
Тематическая серия: прямой доступ по болевой точке
Эта статья охватывает только понимание архитектуры и решение о миграции. Каждый уровень выполнения имеет собственную тематическую статью:
| Тема | Центральный вопрос | Уровень | Ссылка |
|---|---|---|---|
| ① Настройка Runner | Как поддерживать Mac mini онлайн, планируемым и безопасно изолированным | Выполнение | Скоро |
| ② Трёхуровневая модель кэша | Почему iOS-сборки не ускоряются и как использовать локальный SSD | Кэш | Скоро |
| ③ Подпись и релиз | Как завершить подпись iOS и загрузку в App Store в автоматическом CI | Выполнение | Скоро |
| ④ Проектирование Workflow | Как структурировать разделение Android/iOS, фильтрацию путей и параллелизм | Управление | Скоро |
| ⑤ Эксплуатация и стабильность | Почему CI падает, как восстановить раннер после отказа, управление диском | Выполнение + Кэш | Скоро |
Выбор точки входа по сценарию
- Начать с нуля: Эта статья для определения архитектурного направления → ① «Настройка Runner» для запуска машины → ② «Модель кэша» для оптимизации скорости → ③ «Подпись» для подключения пайплайна релизов.
- Runner есть, но iOS-сборка медленная: Переходите напрямую к ② «Трёхуровневая модель кэша».
- Подпись или TestFlight заблокированы: Переходите к ③ «Подпись и релиз».
- Runner офлайн / сборки падают случайно: Переходите к ⑤ «Эксплуатация и стабильность».
- Миграция с Bitrise или другого облачного CI: Таблица сравнения стоимости миграции — в Руководство по выбору: Bitrise vs. самостоятельный облачный Mac.
Нужен Mac mini для этой архитектуры?
kvmboot предоставляет выделенные Mac mini M4 (16 ГБ / 24 ГБ) для тенантов через SSH/VNC с посуточной, понедельной или помесячной оплатой. Уровень управления остаётся в GitHub; заменяется только уровень выполнения. По трёхуровневой модели этой статьи типичная схема: День 0 — провизионирование, День 1 — подключение CI-пайплайна, День 2 — проверка подписи — с согласованной версией Xcode с первой сборки.
Характеристики и тарифы: Посмотреть тарифы · Варианты конфигурации