ИНЖЕНЕРНАЯ ЗАМЕТКА

Hosted-сборки Xcode или управляемый облачный Mac

Hosted-сборки Xcode или управляемый облачный Mac

У команды уже есть рабочий конвейер сборки iOS, но каждое добавление зависимости, смена Xcode или изменение настроек подписи снова вызывает один и тот же спор: продолжать использовать hosted-сборки или перенести задачи на самостоятельно управляемый облачный Mac. Не стоит начинать со сравнения секунд, сэкономленных на одной сборке. На долгосрочные затраты в действительности влияют воспроизводимость среды, управляемость кешей, возможность сохранить состояние на момент сбоя и объём эксплуатационной работы, который придётся взять на себя инженерам.

Сначала разделите рабочую нагрузку на три категории

Вместо выбора платформы по субъективным впечатлениям проанализируйте задачи за последние две недели. Рекомендуется разделить их на проверки при слиянии, архивные сборки для выпуска и разовую диагностику. Проверки при слиянии обычно выполняются недолго, получают чётко определённые входные данные и могут быть перезапущены после сбоя. Архивные сборки требуют работы с материалами подписи, хранения артефактов и строгой фиксации версий. Для разовой диагностики инженерам нужен доступ в ту же среду, чтобы воспроизвести проблему.

Как минимум фиксируйте следующие данные:

Параметр Что нужно записывать Цель
Инструментарий Версии macOS, Xcode, Ruby и менеджеров пакетов Оценить сложность фиксации среды
Входные данные Хеш коммита, lock-файлы и параметры сборки Определить воспроизводимость задачи
Этапы Время ожидания в очереди, выполнения, загрузки и очистки Найти настоящее узкое место
Данные о сбое Журналы, result bundle и архивные артефакты Оценить возможности расследования сбоев
Кеш Пути, размеры, условия попадания и способы инвалидации Оценить долгосрочную пользу

Одиночный успешный запуск не доказывает стабильность процесса. Выполните один и тот же коммит как минимум три раза подряд, а затем повторно проверьте поведение кеша на коммите, который меняет только исходный код приложения, не затрагивая зависимости.

Создайте единый отпечаток среды сборки

Оба варианта должны использовать один и тот же скрипт проверки среды. Недостаточно выводить только xcodebuild -version: необходимо также сохранять версию системы, текущий каталог разработчика, SDK, версию Ruby и состояние менеджеров пакетов. Файл с отпечатком следует сохранять как обычный артефакт каждой задачи. При сбое сначала сравнивайте этот файл и лишь затем проверяйте код приложения.

#!/bin/zsh
set -euo pipefail

mkdir -p artifacts
{
  sw_vers
  uname -m
  xcodebuild -version
  xcode-select -p
  xcrun --sdk iphoneos --show-sdk-version
  ruby --version
  git --version
} > artifacts/environment.txt

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
xcodebuild \
  -workspace App.xcworkspace \
  -scheme App \
  -configuration Release \
  -derivedDataPath "$PWD/.build/DerivedData" \
  -resultBundlePath "$PWD/artifacts/App.xcresult" \
  build

DEVELOPER_DIR не должен указывать на непроверенный путь. В самостоятельно управляемой среде можно хранить несколько версий Xcode, но конвейер обязан выбирать нужную версию явно. В hosted-среде фактическую версию следует проверять в начале задачи и сразу завершать выполнение при несовпадении. Это позволяет не ждать этапа архивации, чтобы обнаружить различия SDK.

Проверяйте кеш, подпись и параллельное выполнение отдельно

Не переносите в кеше каталоги целиком

Ключ кеша должен включать как минимум основную версию Xcode, архитектуру и хеш lock-файлов зависимостей. Каталоги SwiftPM, CocoaPods и промежуточных результатов сборки следует кешировать отдельно, поскольку условия их инвалидации различаются. Не упаковывайте и не восстанавливайте весь пользовательский каталог: вместе с ним в новую задачу попадут старые разрешения, временные файлы и скрытые настройки.

Самостоятельно управляемый облачный Mac хорошо подходит для конвейеров, которым нужно долго хранить крупные кеши зависимостей. Однако для каждого репозитория необходимо выделить отдельный рабочий каталог и периодически проверять, что после удаления кеша по-прежнему выполняется полная сборка. Срок жизни кеша hosted-сборок обычно контролирует платформа, поэтому кеширование следует считать оптимизацией, а не обязательным условием успешного выполнения.

Материалы подписи должны быть доступны только во время задачи

Материалы подписи должны поступать из контролируемого хранилища в начале задачи, а их временные копии необходимо удалять сразу после завершения. В журналы нельзя выводить пароли, содержимое ключей или полные пути к файлам. Независимо от выбранного подхода убедитесь, что очистка выполняется не только при успехе, но и при сбое.

Проверку параллельного выполнения следует начинать с двух задач. Определите, используют ли они общие DerivedData, симуляторы, Keychain или фиксированные порты. Любое общее состояние с возможностью записи может увеличить частоту случайных сбоев при росте числа параллельных задач.

Проверяйте восстановление с помощью учебных сбоев

Не ждите реального сбоя выпуска, чтобы проверить процедуру восстановления. Подготовьте четыре безопасных сценария: намеренно укажите несуществующую scheme, удалите один кеш зависимостей, заставьте тест завершиться ошибкой и остановите задачу перед архивацией. В каждом случае проверяйте код завершения, последние строки журнала, result bundle, временные материалы подписи и состояние рабочего каталога.

Для hosted-сборок прежде всего убедитесь, что журналы достаточно подробно объясняют причину сбоя, среду всё ещё можно воспроизвести, а при повторном запуске используются полностью идентичные входные данные. На самостоятельно управляемом облачном Mac дополнительно проверьте, что оставшиеся процессы, подключённые каталоги и занятые порты не влияют на следующую задачу. Рекомендуется выделять каждой задаче уникальный каталог и завершать дочерние процессы с помощью обработчика выхода.

workdir="$(mktemp -d "$PWD/.job.XXXXXX")"
cleanup() {
  jobs -p | xargs -r kill 2>/dev/null || true
  rm -rf "$workdir"
}
trap cleanup EXIT INT TERM

Сначала проверяйте скрипты очистки в тестовом каталоге, чтобы слишком широкие шаблоны не затронули другие задачи. Журналы и артефакты сборки, которые требуется сохранить, следует заранее скопировать в отдельный каталог artifacts и только после этого запускать очистку.

Принимайте решение по уровню контроля, а не по лозунгам

Hosted-сборки обычно подходят лучше, если проект использует стандартные зависимости, задачи выполняются быстро, после сбоя допустим простой перезапуск, а команда не хочет обслуживать состояние машин. Самостоятельно управляемый облачный Mac позволяет проще установить чёткие границы, если требуется зафиксировать несколько версий Xcode, долго использовать кеши, запускать специальные инструменты, входить в среду для диагностики или непрерывно выполнять длительные задачи.

Эти подходы также можно совмещать: запускать облегчённые тесты для запросов на слияние, а архивирование и углублённую диагностику стабильных веток выполнять в самостоятельно управляемой среде. Главное — использовать в обеих средах одинаковые отпечатки окружения, lock-файлы, точки входа сборки и правила именования артефактов. Иначе возникнут два несовместимых конвейера.

Итоговую оценку следует проводить не по самому быстрому запуску, а по доле успешных выполнений, количеству различий среды, возможности восстановления после удаления кеша, полноте данных о сбоях и числу шагов, требующих ручного вмешательства. Запишите результаты в документ с обоснованием решения внутри репозитория и договоритесь повторно оценивать выбор после изменения основной версии Xcode, системы зависимостей или масштаба задач. Тогда первоначальное решение не превратится в неизменное допущение.

Часто задаваемые вопросы

Hosted-сборки всегда проще в эксплуатации?

Нет. Они удобны для стандартных проектов, но фиксированная версия Xcode, постоянный кэш, особые инструменты и глубокая диагностика часто проще на управляемом Mac.

Можно ли совместить обе модели?

Да. Проверки слияния можно выполнять в hosted-среде, а архивы со сложной подписью, устойчивым кэшем и полными журналами — на управляемом облачном Mac.

Что проверить перед выбором?

Несколько раз выполните одну ревизию с одинаковыми lock-файлами и командами, затем сравните стабильность, кэш, полноту журналов и время восстановления после сбоя.

VMDebug облачные Mac

Нужен физический Mac mini, выделенный под один заказ?

Сравните конфигурации M4 и M4 Pro, четыре периода аренды и 5 доступных узлов, а затем выберите устройство под свой рабочий процесс.

Выбрать конфигурацию и заказать