DevOps / CI·CD 30 апреля 2026

2026-04-30 Миграция iOS CI с Intel x86_64 на Apple Silicon ARM64 с xcodebuild на арендованном облачном Mac (HK / JP / KR / SG / US)

Команда инженеров MacXCode 30 апреля 2026 Около 24 мин чтения

Apple по-прежнему поставляет Xcode для Intel, но 2026 — год, когда большинство мобильных команд перестаёт платить облачную надбавку за срезы x86_64, которые уже не уходят в прод. Если очередь всё ещё смотрит на старые Intel Mac mini, а продуктовые бинарники только arm64, вы финансируете дублирующие графы зависимостей и более медленные холодные старты xcodebuild test, чем у конкурентов, уже стандартизировавших Mac mini M4 в Гонконге, Токио, Сеуле, Сингапуре и США. Этот материал от 2026-04-30 — миграционный бриф для release-инженерии: инвентаризация «толстых» бинарников, нормализация ARCHS, пересборка CocoaPods без Intel-only вендоров, двойная полоса достаточно долго, чтобы доверять флейкам, затем переключение маршрута по умолчанию на ARM64 с резервной Intel-полосой для редких CLI. Он дополняет удалённые Archive, параллельные дорожки Xcode, мульти-Xcode матрицы и ограничения Swift 6 strict concurrency, которые иначе ведут себя под параллельной нагрузкой.

Снимок: почему «собирается на моём M3» недостаточно

Ноутбуки скрывают грехи: тёплые кэши модулей, прозрачный Rosetta и человеческое терпение. CI должен выставлять их напоказ за минуты. Три признака, что вы в середине миграции, а не в конце:

  • Ошибки линкера с undefined symbols for architecture arm64, пока lipo -archs всё ещё показывает x86_64 на вендорских фреймворках.
  • Дрейф целей симулятора: intel-эра destinations остались в YAML, хотя Apple убрал образы из новых бандлов Xcode.
  • Лживые метки runner: теги GitHub Actions или Buildkite говорят macos-intel, хотя shell уже arm64 из-за переиспользования имён.
Цифры для отслеживания: цель — не меньше 35 % сокращения времени стены на чистом xcodebuild build после нормализации ARM64 для среднего приложения; заложите 14 календарных дней наблюдения двойной очереди перед удалением Intel-ёмкости.

Инвентаризация бинарников: докажите оставшийся x86_64 до обвинений Swift

Пройдите каждый .framework, .a и предсобранный XCFramework под Carthage/Build, Pods/ или ThirdParty/. Две команды для каждого тикета миграции:

find . \( -name "*.framework" -o -name "*.a" -o -name "*.xcframework" \) -print0 | xargs -0 -I@ sh -c 'echo "@:"; lipo -info "@" 2>/dev/null || file "@"'

Если вендор всё ещё только Intel, открывайте коммерческий тред, а не хак с EXCLUDED_ARCHS=arm64, который тихо тащит Rosetta в прод для инженеров. На арендованных хостах с self-hosted runner централизуйте скрипт инвентаризации в одном infra-репо, чтобы каждый регион запускал один детектор; расхождение между узлами JP и US плодит «зелёно в Токио, красно в Вирджинии».

Матрица runner: ответственность Intel-полосы и ARM-полосы

В переходный период каждая полоса должна нести явные гарантии — не притворяйтесь, что обе CI одинаковы.

Полоса Владеет Не должна владеть
ARM64 основная PR по умолчанию, тесты симулятора, Archive в TestFlight Legacy CLI без arm64, кроме изолированной песочницы
Intel аварийная Вендорские бинарники в ожидании обновления, разовые проверки паритета Долгосрочная подпись; не смешивайте прод-ключи
Дымовая гибридная Скрипты file, проверяющие fat-срезы где нужно Тихая зависимость от Rosetta для целей iOS-приложения

Флаги xcodebuild и настройки сборки как политика

Закодируйте ниже в общих фрагментах xcconfig или экспортах Fastlane: один раз спорите, везде наследуйте.

Настройка Рекомендуемое значение CI ARM64 Заметки
ARCHS arm64 Явное лучше «standard», когда схемы приложения и расширений расходятся.
ONLY_ACTIVE_ARCH NO для CI в духе Release; YES для внутреннего Debug, если принимаете тонкие срезы. Расхождение даёт флейки симулятор против устройства.
EXCLUDED_ARCHS[sdk=iphonesimulator*] Обычно пусто на Apple Silicon Уберите intel-эра исключения, случайно убивающие arm64-симулятор.

Свяжите флаги с закреплённым DEVELOPER_DIR на задачу по руководству по матрице xcode-select: ничто так не путает постмортем, как две версии Xcode, по-разному читающие один проект.

CocoaPods, SwiftPM и бинарные графы, сопротивляющиеся ARM64

Пользователям CocoaPods следует регенерировать Pods/ на arm64-хосте, а не rsync с Intel, чтобы script-фазы компилировались с правильной архитектурой. Командам SwiftPM стоит убедиться, что бинарные цели в Package.resolved действительно содержат arm64-apple-ios, где применимо. Когда фреймворки отстают, временные source-build или pin форка — проценты копятся ежедневно.

Ловушка Rosetta: если uname -m показывает arm64, а file $(which node) — x86_64, OpenClaw или JS-линтеры тихо идут через перевод: горит CPU, логи крашей нечитаемы.

Двойная полоса: глубина очереди, память, диск

Mac mini на Apple Silicon сияют, пока три тяжёлых Archive плюс UI-тесты не съедают 16 ГБ ОЗУ. На время миграции ограничьте одновременные xcodebuild на хост по измеренному давлению памяти: отдельные метки для «ARM только компиляция» и «ARM Archive». Диск: ARM64 не уменьшает DerivedData; сочетайте миграцию с изоляцией DerivedData, чтобы эксперименты не вытесняли кэши друг друга.

Восемь шагов переключения, которые SRE вставит в Jira

  1. Заморозить обновления зависимостей на 72 часа до выходных переключения.
  2. Запустить скрипт инвентаризации на каждом региональном хосте; зафиксировать diff в infra-репо.
  3. Применить политику xcconfig ко всем схемам, включая расширения.
  4. Пересобрать Pods/SwiftPM с чистых checkout на arm64.
  5. Включить две очереди с одинаковыми сидами; сравнить время стены, флейки, размеры артефактов.
  6. Переключить маршрут PR по умолчанию на ARM64, оставив Intel только для чтения.
  7. Наблюдать 14 дней; при всплеске сбоев откатывайте метки, а не секреты.
  8. Списать Intel или отвести на нишевые задачи с биллинг-тегами вне мобильных путей.

Таблица метрик: что считать успехом на арендованном M4

Метрика База Intel (пример) Цель ARM64
Чистая сборка p50 19,5 мин 12,0 мин или лучше на том же коммите
UI-тесты симулятора p95 41 мин 28–33 мин после нормализации целей
Прокси недельной энергозатрат 1,00 (нормировано) 0,62–0,78 с учётом простоя Вт и пропускной способности

Замените примеры своими гистограммами Grafana или Buildkite — без сырых кривых не выпускайте миграционную презентацию.

FAQ: Rosetta, симуляторы, подпись

Вопрос Практический ответ на 2026-04-30
Стоит ли гонять CI под Rosetta ради скорости? Нет для компиляции iOS: нативные arm64-цепочки выигрывают; Rosetta — только для наследуемых вспомогательных CLI.
Нужны ли отдельные подписи на архитектуру? Сами удостоверения не привязаны к arch, но профили и entitlements должны соответствовать фактически отгружаемым бинарникам — переэкспорт после изменения графа.

Для автоматизации подписи продолжайте использовать Keychain и профили CI: миграции архитектуры часто вскрывают скрытые несоответствия профилей.

Почему ставка на bare-metal Mac mini M4 всё ещё выигрывает

ARM64 CI — не только тактовая частота: это детерминированное поведение тулчейна без лжи гипервизора. Арендованный Mac mini M4 с 1–2 ТБ NVMe в регионах MacXCode даёт место для двойных полос, нескольких деревьев DEVELOPER_DIR и всплесков DerivedData, пока инженеры спят в другом часовом поясе. Этот запас превращает миграцию в измеряемый и обратимый раскат, особенно с прозрачными ценами на второй узел вместо перегрузки первого. Для редких визуальных подтверждений — VNC; повседневная миграция остаётся SSH и grep по логам.

Поднимите нативные ARM64-билдеры рядом с legacy

Mac mini M4, HK / JP / KR / SG / US, SSH и опционально VNC