2026 Очереди сборок Mac в облаке: параллелизм, DerivedData и запас диска для стабильного xcodebuild
Перенеся iOS/macOS CI на облачные Mac, команды сначала описывают подпись и профили — но параллельные джобы, разросшийся DerivedData и полные диски дают нестабильные красные сборки задолго до ошибок подписи. Этот материал для пайплайнов Xcode 26 разбирает три класса ресурсных сбоев, даёт таблицу параллелизма и памяти, пять и более шагов с готовым df-скриптом и FAQ, чтобы политика очереди и диска была на одном уровне наблюдаемости с сертификатами.
Содержание
1. Почему очередь и диск — в одном Runbook с подписью
На Linux VPS смотрят на CPU и глубину очереди; на macOS Xcode и Swift пишут огромные промежуточные файлы в DerivedData, кеши модулей и SourcePackages — пропускная способность диска и свободное место сопоставимы с CPU. Если вы уже внедрили чеклист headless-подписи и гайд по CI/CD, следующий класс сбоев — конкуренция за ресурсы. Без явных правил останутся сборки «зелёные со второго раза».
- Параллельные archive борются за RAM и временные файлы линкера: несколько
xcodebuild archiveчасто превышают оценку памяти на джоб; линковка заполняет/tmpгигабайтами. При заполнении томаclang/ldредко пишут явно «диск полон». - DerivedData растёт монотонно: путь по умолчанию
~/Library/Developer/Xcode/DerivedDataразрастается с каждой веткой и схемой. Без очистки по джобам системный том может уйти ниже 5 % свободного, macOS запускает уборку и появляется джиттер времени компиляции. - Без метрик диска ошибки принимают за «сеть»: повторы 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 ядер | 1 | 2 (зависит от проекта) | Подкаталог на джоб или ночной wipe | ≥20 % свободно |
| 24–36 ГБ RAM | 1–2 | 3–4 | Пространства имён веток + еженедельная глубокая очистка | ≥15 % свободно |
| 48 ГБ+ UMA | 2–3 (проверить линкер) | 4–6 | Многоуровневый кеш: последние N коммитов | ≥15 %; отдельный том данных — идеал |
Для меток Jenkins или self-hosted runner добавьте блокировку, чтобы два archive не делили один DERIVED_DATA_PATH под одним логином — иначе блокировки кеша модулей и ошибки «файл изменён». Сверяйтесь с гайдом по RAM и конфигурации при масштабировании.
3. DerivedData, кеш SPM и пороги диска (5+ шагов)
Автоматизируйте на тех же SSH-точках входа, что и в плейбуке миграции Linux → Mac.
- Отдельный путь DerivedData на джоб, напр.
export DERIVED_DATA_PATH="$WORK/DerivedData/$BUILD_ID"и всегда-derivedDataPathвxcodebuild. - Быстрый отказ при малом диске до долгой компиляции — фрагмент ниже.
- Версионируйте политику кеша SPM: предсказуемый
~/Library/Caches/org.swift.swiftpm; после крупных апдейтов Xcode — полная очистка. - Утилизация после успеха/ошибки: храните последние K деревьев DerivedData для инкремента; каталоги упавших джобов удаляйте сразу; ночью удаляйте старше 7 дней.
COMPILER_INDEX_STORE_ENABLE=NOдля чистого CI, если индексация IDE не нужна — сильно режет IO. Индексация только на аналитических пайплайнах.- (Доп.) Метрики: логируйте
df -hиdu -sh; крупные.ipa/.xcarchiveотправляйте в объектное хранилище и удаляйте локально.
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.