Swift 6 и режим strict concurrency подрывают доверие к CI, если локально всё зелёное, а конвейер дёргается. Частая причина не бизнес-логика, а разные build settings, гонки DerivedData, другой destination симулятора или предупреждения без gate. Текст даёт семь болевых точек, сравнительную таблицу и шестишаговый runbook с приёмкой. Дополнительно: SwiftPM, CocoaPods и DerivedData, воспроизводимый отпечаток сборки, self-hosted runner и разделение кэша.
Диагностика конкурентности зависит от таймингов; малое расхождение окружения размазывает симптомы.
На ноутбуке и в CI разная пара Swift/Xcode:без логирования swift --version и xcodebuild -version нет базы для Sendable.
Строгий режим включается только перед релизом:накопленный дифф тормозит откат.
Параллельные xcodebuild делят один DerivedData:инкрементальная сборка ломается, растёт число clean.
Предупреждения допускаются при зелёном CI:паттерны всплывают только после повышения SWIFT_STRICT_CONCURRENCY.
UI- и unit-тесты в одном job без плана акторов:нагрузка симулятора смешивается с флагами.
Нет строки Runbook про xcode-select / TOOLCHAINS:ночной job легко сменить GUI-переключением Xcode.
Только swift build на Linux:iOS-таргеты не получают тот же строгий набор диагностик.
Общий корень состояние компилятора не инвариантировано на входе CI; выделенный Mac фиксирует его по SSH как инфраструктуру.
Цель каждый раз получать одинаковое множество диагностик.
| Измерение | Xcode Cloud | Хостинговый macOS runner | Выделенный Mac (SSH) |
|---|---|---|---|
| Pinning toolchain | Следует управляемым обновлениям | Зависит от тега образа | xcode-select и диск контрактуются |
| Воспроизводимость | Высокая при дисциплине workflow | Шум от общего пула | DerivedData на job изолируется |
| Свобода xcodebuild | Могут быть ограничения | Политика администратора | Стабильны destination и пути |
| Частые сбои | Очереди, квоты | Пропажи зависимостей на чистых образах | Сон, переполнение диска |
| Профиль команд | Стандарт у App Store | Много коротких smoke | Monorepo со строгими gate |
Strict concurrency в CI это ещё и физика кэша компилятора.
См. также SLA аренды и биллинг.
Заморозить профиль Xcode, заархивировать xcode-select -p.
Всегда печатать версии SDK и компилятора.
Выровнять SWIFT_STRICT_CONCURRENCY, этапы миграции в тикете.
Зафиксировать scheme, destination, -derivedDataPath, при SPM отделить -clonedSourcePackagesDirPath.
Развести уровни тестов и лимиты параллелизма по контракту.
Подписать чек-лист приёмки с фрагментами логов.
#!/usr/bin/env bash set -euo pipefail xcodebuild -version xcodebuild -showsdks swift --version export DERIVED_DATA="$(pwd)/.derivedData/$CI_JOB_ID" xcodebuild -scheme "App" \ -destination 'platform=iOS Simulator,name=iPhone 16' \ -derivedDataPath "$DERIVED_DATA" \ build
Совет:держите сторонние модули в targeted/minimal, пока не готов путь обновления.
Не смешивайте ночную автоматизацию и интерактив на одной учётной записи.
Публикуйте матрицу таргетов; первичны release notes Apple и Swift.
Оговорка:статья про эксплуатацию, не про нормативное определение режимов компилятора.
Предупреждения гонок данных зависят от загрузки симулятора; разносите perf и функциональные логи.
Общие runner плохо одновременно борются с дрейфом toolchain и дисковым contention; строгие ворота Swift 6 выглядят как флейки. NodeMini аренда выделенных Mac Mini в облаке подходит командам, где SSH, диск и параллелизм закреплены как услуга. Цены: Mac Mini цены аренды, подключение и приёмка: центр помощи Cloud Mac.
После запуска агрегируйте нарушения strict mode еженедельно и связывайте с roadmap зависимостей.
Стабильнее версия компилятора и расположение кэша. См. цены аренды.
scheme, destination, derivedDataPath и единый уровень strict в settings. Центр помощи.
Номер сборки Xcode, xcode-select, опц. TOOLCHAINS, bootstrap-команды CI. Тарифы: цены.