TGViewer
Flutter Pulse Flutter Pulse @flutterpulse · 1.01K subscribers
Post #3032 302
Миграция Flutter iOS CI/CD на Xcode Cloud: как сэкономить 10x и избавиться от боли с сертификатами 🚀

Долгое время iOS-сборки в GitHub Actions были «черной дырой» бюджета: минута на macOS-раннере съедает 10 минут квоты (или стоит в 10 раз дороже Linux). Старый пайплайн на 90 строк YAML требовал ручного управления 6 секретами, профилями и ключами — хрупко, больно и дорого. 😭

Решение — переезд на Xcode Cloud. И это гейм-чейнджер: 25 часов compute-времени в месяц уже входят в стандартную подписку Apple Developer Program ($99/год). Релиз теперь стоит 0 минут GitHub Actions и всего ~6 минут оплачиваемого времени Apple. 💸

Главные плюсы, за которые стоит сказать «спасибо»:
✅ Managed Signing — Apple сама управляет подписью. Никаких keychain, base64, правок pbxproj и секретов в репозитории.
✅ Доставка в TestFlight настраивается галочкой в UI, без API-ключей.
✅ Кастомизация через три shell-скрипта в папке ci_scripts (post-clone, pre-xcodebuild, post-xcodebuild): ставим Flutter, проверяем версию в теге vs pubspec.yaml, генерируем Generated.xcconfig, шлём уведомления в Telegram. 🤖

Есть и минус: конфигурация уходит из Git в веб-интерфейс App Store Connect (No code-as-config). Лечится обязательным ранбуком (документацией с датой) в репозитории, иначе пайплайн превращается в «фольклор». 📝

Триггеры разделили префиксами тегов: ios/v* — Xcode Cloud, android/v* — GitHub Actions. Обычный v* ничего не запускает — защита от случайных затрат. 🛡

Путь первого успешного билда пролегал через 7 кругов ада за 6 коммитов (ни одна ошибка не была виной дизайна миграции!):
1️⃣ Права доступа к репо — помогло переключение на «New Primary Repository».
2️⃣ Устаревший Flutter тянул старый intl (на Android замаскировалось).
3️⃣ Swift Package Manager требует закоммиченный Package.resolved — пришлось откатиться на CocoaPods.
4️⃣ Ошибка «specs repository is too out-of-date» — ложный след.
5️⃣ Настоящая причина — конфликт Ruby: системный 2.6 не видел xcodeproj из Homebrew. Лечится gem install --user-install xcodeproj. 💎
6️⃣ Двойной pod install (flutter build --config-only уже делает это сам).
7️⃣ Застарелый Podfile.lock (4 месяца!) — версии нативных SDK расходились с pubspec.lock. Локально тоже было сломано! 🤯

💡 Главный урок: CI, который не запускаешь регулярно, не находит ошибки. Ошибка CocoaPods «too out-of-date» почти всегда вводит в заблуждение — смотрите логи выше!

📊 Итоговые замеры:
⏱️ Wall-clock: 10 мин (оценка 15).
⚡️ Compute-time: 6 мин (оценка 15).
📈 Экономия: было ~45 мин GH Actions → стало 0. Запас релизов в месяц вырос с ~100 до ~250. Xcode Cloud тарифицирует CPU-время, а не ожидание сети!

Читать здесь: полная статья на Хабре

FlutterPulse — канал о мире Flutter!

#flutter #dart #flutterpulse #flutterpulsehabr #ci_cd #xcodecloud #iosdev
More from @flutterpulse
  1. Sep 30, 2026Как теплотехник в 50 лет стер границу между КИПиА и IT: пишем универсальный Android‑SCADA…
  2. Sep 30, 2026Обновлённые пакеты за последние 24 часа Bones_API 1.17.0 Фреймворк для создания API-бэкенд…
  3. Sep 30, 2026photo post
  4. Sep 29, 2026👣 Как встроить Unity игру во Flutter приложение Flutter — это король интерфейсов, навигац…
  5. Sep 29, 2026Обзор пакетов на тему Machine Learning, OCR & Computer Vision google_mlkit_commons 0.13.0…
  6. Sep 29, 2026Добавляем 3D в игру на Flame, не переписывая её 3D-графика в 2D-играх без переписывания ко…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →