Когда ветка живёт часами, а очередь общих раннеров растёт, команда подключает свежий облачный Mac и регистрирует на нём GitLab Runner с executor = shell: минимум обвязки, максимум совпадения с тем, как разработчик уже запускает fastlane или xcodebuild локально. Ниже — практическая связка «узел → конфиг → кэш → теги», плюс матрица, когда оставить всплески на GitLab, а когда — перенести на GitHub Actions без дублирования секретов. Для сценариев «горящий релиз» и посуточной аренды см. Внезапные сборки и срочная проверка App Store в 2026: купить Mac или арендовать облачный Mac посуточно или на неделю?; про сеть и минимальные токены при онбординге runner на облачном Mac — в чеклисте и FAQ по регистрации Runner за 30–60 минут.
Shell executor на облачном Mac: пути и конкуренция
Для Apple-проектов shell остаётся самым предсказуемым: тот же PATH, Keychain и симлинки Homebrew, что и у инженера на столе. В config.toml зафиксируйте builds_dir и cache_dir на быстром локальном томе (не сетевой диск по умолчанию), ограничьте concurrent = 1 на первые сутки после выдачи узла, затем поднимайте по метрикам CPU и I/O wait. Отдельный пользователь ОС под runner снижает риск смешения личного Apple ID и CI-сертификатов.
# Пути — на локальный SSD узла concurrent = 1 [[runners]] executor = "shell" builds_dir = "/Users/gitlab-runner/builds" cache_dir = "/Users/gitlab-runner/cache"
Ключи cache в GitLab CI под Xcode и зависимости
Встроенный cache: в .gitlab-ci.yml должен инвалидироваться вместе с контрактом зависимостей: хэшируйте Package.resolved, Podfile.lock, Gemfile.lock и при необходимости версию Xcode из переменной окружения. Политика policy: pull-push на основной ветке и pull на feature-ветках уменьшает гонки за запись в общий кэш. Для DerivedData на runner с длинным TTL диска допускается отдельный job «прогрева» или синхронизация каталога в конце ночного пайплайна — главное, чтобы ключ не жил дольше, чем допустимый дрейф toolchain.
cache: key: files: - ios/Package.resolved - ios/Podfile.lock prefix: "xcode-${XCODE_VERSION}-arm64" paths: - .derived_data/ - ios/Pods/
Теги runner и маршрутизация jobs
Регистрируйте узел с явным списком: macos, apple-silicon, регион, окружение (burst / prod). В job указывайте пересечение тегов, которое однозначно попадает только в нужный пул; не используйте «общие» теги вроде одного слова ci на всех платформах. Для гибрида GitLab+GitHub разведите токены и machine users по ролям, чтобы отзыв runner на облачном Mac не затронул зеркальный workflow на GitHub.
Матрица смешения с GitHub Actions
Две системы редко заменяют друг друга полностью: GitLab удобен для приватного Git и единого реестра контейнеров, GitHub — для OSS и marketplace actions. Ниже — сжатая логика распределения без дублирования тяжёлых шагов.
| Критерий | GitLab shell на облачном Mac | GitHub Actions self-hosted macOS | Практический вывод |
|---|---|---|---|
| Очередь и burst | Свой runner = предсказуемый старт job | Лимиты concurrent и метки runner | Всплески подписи и архива — на выделенный Mac в одной системе |
| Кэш | cache: + локальный том runner |
actions/cache или собственный NFS | Не синхронизируйте один и тот же tarball кэша между SCM без версии ключа |
| Секреты | GitLab CI Variables / файловые маски | GitHub Environments / OIDC | Разные хранилища — дублируйте только публичные ключи, не приватные PEM |
| Наблюдаемость | Job artifacts + runner logs | Workflow run URL + runner journal | В матрице укажите единый корреляционный BUILD_ID в обеих системах |
FAQ: исполняемые параметры и переменные
Проверка runner после регистрации. На узле выполните gitlab-runner verify и gitlab-runner --version — версия бинарника должна быть не ниже, чем у сервера GitLab. Глубина клона. GIT_DEPTH: "20" в variables job ускоряет shallow clone для больших монореп. Трассировка шага. CI_DEBUG_TRACE: "true" включайте точечно: лог раздувается и может утечь секрет в маскировку непопавший фрагмент. Сеть. Перед первым реальным job выполните curl -I к вашему GitLab и DNS-запрос к хосту CocoaPods CDN — это отсекает половину «медленных сборок», на самом деле являющихся сетевыми таймаутами.
variables: GIT_STRATEGY: fetch GIT_DEPTH: "20" FASTLANE_SKIP_UPDATE_CHECK: "1"
concurrent и суммарный размер каталога cache_dir. Любое отклонение двух из трёх — сигнал к ротации образа или очистке кэша.
На облачном Mac mini M4 пайплайн GitLab стартует быстрее
Self-hosted runner на macOS выигрывает, когда узел совпадает с «золотым» профилем сборки: Apple Silicon, достаточный объём унифицированной памяти и локальный SSD без лишних слоёв виртуализации. Облачный Mac mini M4 даёт нативный Xcode и инструменты командной строки без компромиссов WSL; типичное энергопотребление в простое около 4 Вт делает такой узел экономичным для ночных и всплесковых job.
macOS остаётся стабильной платформой для длительно работающих агентов: низкая частота критических сбоев, встроенные Gatekeeper и SIP снижают класс рисков по сравнению с типичными Windows-рабочими станциями, а компактный корпус без вентиляторного шума упрощает эксплуатацию в распределённых командах.
Если вы наращиваете короткие циклы CI и хотите закрепить shell-runner на предсказуемом железе, VPSSpark с облачным Mac mini M4 — удобная точка входа по цене и времени запуска — узнайте тарифы и конфигурации и уберите очереди из критического пути релиза.