2026 Очереди сборок Mac в облаке: параллелизм, DerivedData и запас диска для стабильного xcodebuild

Перенеся iOS/macOS CI на облачные Mac, команды сначала описывают подпись и профили — но параллельные джобы, разросшийся DerivedData и полные диски дают нестабильные красные сборки задолго до ошибок подписи. Этот материал для пайплайнов Xcode 26 разбирает три класса ресурсных сбоев, даёт таблицу параллелизма и памяти, пять и более шагов с готовым df-скриптом и FAQ, чтобы политика очереди и диска была на одном уровне наблюдаемости с сертификатами.

Схема CI Xcode и очередей сборок на облачном Mac-хосте

Содержание

1. Почему очередь и диск — в одном Runbook с подписью

На Linux VPS смотрят на CPU и глубину очереди; на macOS Xcode и Swift пишут огромные промежуточные файлы в DerivedData, кеши модулей и SourcePackages — пропускная способность диска и свободное место сопоставимы с CPU. Если вы уже внедрили чеклист headless-подписи и гайд по CI/CD, следующий класс сбоев — конкуренция за ресурсы. Без явных правил останутся сборки «зелёные со второго раза».

  1. Параллельные archive борются за RAM и временные файлы линкера: несколько xcodebuild archive часто превышают оценку памяти на джоб; линковка заполняет /tmp гигабайтами. При заполнении тома clang/ld редко пишут явно «диск полон».
  2. DerivedData растёт монотонно: путь по умолчанию ~/Library/Developer/Xcode/DerivedData разрастается с каждой веткой и схемой. Без очистки по джобам системный том может уйти ниже 5 % свободного, macOS запускает уборку и появляется джиттер времени компиляции.
  3. Без метрик диска ошибки принимают за «сеть»: повторы Swift Package похожи на проблемы CDN, но незаписываемый кеш даёт похожие логи. df и размер DerivedData должны быть на одной панели с задержкой очереди.

Практика 2026: правила подписи, максимальный параллелизм, корни DerivedData на джоб и пороги диска до/после сборки — в одном шаблоне пайплайна. Таблица ниже задаёт грубые диапазоны; уточняйте по xcodebuild -showBuildSettings и метрикам CI.

2. Параллелизм на узле vs RAM и CPU

Матрица для типичных облачных SKU M4 / M4 Pro. Принцип: без измеренных пиков линкера ограничьте одновременные archive одной-двумя; compile/test можно выше. Держите ~15 % свободными под логи и снимки.

SKU (пример)Реком. параллельные archiveВерхняя граница compile/testСтратегия DerivedDataЦель свободного места
16 ГБ RAM / ≤10 ядер12 (зависит от проекта)Подкаталог на джоб или ночной wipe≥20 % свободно
24–36 ГБ RAM1–23–4Пространства имён веток + еженедельная глубокая очистка≥15 % свободно
48 ГБ+ UMA2–3 (проверить линкер)4–6Многоуровневый кеш: последние N коммитов≥15 %; отдельный том данных — идеал

Для меток Jenkins или self-hosted runner добавьте блокировку, чтобы два archive не делили один DERIVED_DATA_PATH под одним логином — иначе блокировки кеша модулей и ошибки «файл изменён». Сверяйтесь с гайдом по RAM и конфигурации при масштабировании.

3. DerivedData, кеш SPM и пороги диска (5+ шагов)

Автоматизируйте на тех же SSH-точках входа, что и в плейбуке миграции Linux → Mac.

  1. Отдельный путь DerivedData на джоб, напр. export DERIVED_DATA_PATH="$WORK/DerivedData/$BUILD_ID" и всегда -derivedDataPath в xcodebuild.
  2. Быстрый отказ при малом диске до долгой компиляции — фрагмент ниже.
  3. Версионируйте политику кеша SPM: предсказуемый ~/Library/Caches/org.swift.swiftpm; после крупных апдейтов Xcode — полная очистка.
  4. Утилизация после успеха/ошибки: храните последние K деревьев DerivedData для инкремента; каталоги упавших джобов удаляйте сразу; ночью удаляйте старше 7 дней.
  5. COMPILER_INDEX_STORE_ENABLE=NO для чистого CI, если индексация IDE не нужна — сильно режет IO. Индексация только на аналитических пайплайнах.
  6. (Доп.) Метрики: логируйте df -h и du -sh; крупные .ipa/.xcarchive отправляйте в объектное хранилище и удаляйте локально.
# Перед сборкой: код выхода ≠0 если свободно <12% (подставьте нужный mount) AVAIL=$(df -h / | awk 'NR==2 {gsub(/%/,"",$5); print 100-$5}') THRESH=12 if [ "${AVAIL%%.*}" -lt "$THRESH" ]; then echo "Свободно меньше ${THRESH}% — очистите DerivedData или расширьте том"; exit 1 fi
Совет: смешивать интерактивный Xcode и headless CI под одним пользователем macOS опасно из‑за конфликта DerivedData по умолчанию. Лучше отдельный CI-аккаунт или отдельные облачные узлы — как для пользователя подписи.

4. Факты и параметры для ссылок

Для внутренних аудитов: ① главный рубильник параллельной изоляции — xcodebuild -derivedDataPath. ② SPM может логировать сетевые повторы, когда кеш не пишется. ③ APFS при ~5–10 % свободного может вызывать локальные снимки и длинные хвосты сборок. ④ ObjC/Swift при линковке может требовать почти вдвое больше RAM, чем пик компиляции — больше ядер ≠ больше параллельных archive. ⑤ Артефакты на отдельном томе снижают износ системного и упрощают retention.

5. От импровизированных Mac к масштабируемой базе сборок

Четыре archive на маленьком личном Mac «работают», пока диск не заполнится, сбои не станут невоспроизводимыми, а отключение питания не сорвёт релиз. Только удалённый рабочий стол плохо сочетается с версионируемой политикой очереди и с узлами, выдаваемыми по API.

Закрепив очередь на эластичных облачных Mac с предсказуемыми уровнями RAM/диска, SSH-автоматизацией и запасом на замену билдеров, вы управляете жизненным циклом кеша как на Linux-runner, сохраняя полный стек Xcode. Для команд на Xcode 26, сдерживающих рост DerivedData и меняющих узлы при проблемах с диском, аренда облачных Mac M4 у VPSMAC обычно предсказуемее, чем выжимать один хрупкий сервер: параллелизм и уборка в коде, платформа даёт базовые вычисления и хранилище, и релизные поезда реже умирают от «загадочного полного диска» в пятницу.

6. FAQ

Можно ли делить один DerivedData для быстрого инкремента?

Последовательные джобы на ветке — да. Параллельные archive — отдельные каталоги, иначе блокировки и «отравленный» кеш. Можно symlink на свой удалённый кеш.

Агрессивное удаление DerivedData не замедлит каждую сборку?

Холодные сборки дольше, но планируемы — чаще лучше случайных сбоев на полном диске. Бинарные кеши или хранение нескольких последних деревьев помогают.

Облачный Mac против кластера Mac mini on-prem?

On-prem: питание, стойка, замена дисков; облако проще для burst-параллелизма. См. аренда vs покупка и ROI.