Акция

Flutter + GitHub Actions + Mac mini самостоятельный Runner: архитектура iOS CI

CI Flutter · Self-hosted Runner
2026-06-05 ~8 мин

Flutter iOS CI — это не «заменить ubuntu-latest на macos-latest». Это архитектурное решение трёх уровней: уровень управления остаётся в GitHub, уровень выполнения работает на Mac mini M4, уровень кэша находится на локальном SSD. Эта статья делает три вещи: устанавливает модель, предоставляет матрицу решений для миграции и направляет к тематическим статьям в зависимости от вашей болевой точки.

Эта статья делает одно

  1. Строит ментальную модель Flutter iOS CI = Уровень управления + Уровень выполнения + Уровень кэша.
  2. Предоставляет матрицу решений macos-latest vs. самостоятельный — ответ за 5 минут.
  3. Распределяет детальную реализацию по 5 тематическим статьям — прямой доступ по вашей проблеме.
Архитектура Flutter GitHub Actions и Mac mini самостоятельный Runner CI
Кросс-платформенный CI Flutter: уровень управления в GitHub, iOS-сборка выполняется на самостоятельном Runner Mac mini.

Трёхуровневая CI-модель

Прежде чем рассматривать конкретные инструменты, установим одно уравнение — оно определяет, какой уровень нужно изменить:

Flutter iOS CI =
  Уровень управления (GitHub Actions: триггеры · согласования · Secrets)
+ Уровень выполнения (Mac mini M4  : нативная iOS-сборка · подпись · согласованность среды)
+ Уровень кэша      (Локальный SSD : персистентное хранение зависимостей и артефактов)

Три следствия, определяющие все решения этой серии:

  1. Уровень управления не выполняет код. Оптимизация YAML workflow не ускоряет сборки. Сокращение времени сборки требует замены уровня выполнения.
  2. Уровень выполнения определяет воспроизводимость. Версия Xcode в общем пуле (macos-latest) следует обновлениям GitHub; на самостоятельной машине версию фиксируете вы.
  3. Уровень кэша определяет скорость. Преимущество в скорости самостоятельного раннера — не от 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 с первой сборки.

Характеристики и тарифы: Посмотреть тарифы · Варианты конфигурации