GitLab относит Shell executor к режиму обслуживания — это прямо указано в документации об исполнителях. Поэтому GitLab CI Mac Runner развернуть можно, но начинайте с выделенного узла и доверенных заданий: не считайте общий Mac или Runner для непроверенного кода безопасной производственной средой.
Кому пригодится: iOS- и macOS-разработчикам, которым нужно передать сборку или тесты Mac-узлу в GitLab CI.
DevOps-инженерам, отвечающим за регистрацию Runner, доступность и восстановление после перезапуска.
Руководителям платформ и специалистам по безопасности, оценивающим границы Shell executor.
SECTION 01До установки: подходит ли Mac Runner для ваших заданий?
Сначала отделите задачи, которым действительно нужен macOS, от общей оркестрации. Компиляция и тестирование проекта с помощью Xcode относятся к подходящим кандидатам на Mac Runner. Подготовку контейнеров, анализ исходников и другие задачи, не зависящие от инструментов Apple, обычно разумнее оставлять на уже имеющихся CI-узлах. Так вы не превратите Mac в универсальный исполнитель, которому приходится доверять весь поток изменений.
Можно ли установить GitLab Runner на macOS?
Да. GitLab публикует отдельные инструкции по установке Runner на macOS, а для заданий сборки iOS и macOS описывает использование Shell executor. Но факт установки ещё не означает, что узел готов к безопасному запуску заданий: исполнитель работает с ограниченной изоляцией, а сама документация GitLab указывает для него статус режима обслуживания.
Отсюда практический допуск: перед пробным запуском подтвердите, что узел выделен под CI, репозитории доверенные, область доступа ограничена, а способ возврата к прежней схеме понятен. Если на Mac работают сотрудники, хранятся личные данные или открыты секреты других проектов, не регистрируйте его как общий Runner «на время проверки». Задание Shell executor выполняется в среде хоста; считать её изолированным контейнером нельзя. Подробности ограничений приведены в документации Shell executor.
Проверьте также, кто сможет менять конфигурацию Runner, запускать задания и читать журналы. В рекомендациях GitLab по безопасности self-managed Runner есть отдельные предостережения насчёт недоверенного кода и границ доступа. Если команда не может ограничить исходящие задания доверенными проектами, остановитесь до регистрации. Безопасность здесь определяется не названием узла, а тем, какие именно репозитории и задания могут на нём выполняться.
Сценарий для проверки: проект собирает приложение из внутреннего репозитория, а Mac используется только для задач с Xcode. Если в тот же пул могут попасть merge request из внешних веток, прежде чем включать их в расписание, нужно определить политику доступа, изоляции и обработки секретов. При отсутствии такой политики начните с доверенного проекта и ручного пробного запуска, а не с общего Runner.
SECTION 02Подготовка: закрепите узел, учётную запись и инструменты
Выделите Mac под предсказуемую CI-функцию. Зафиксируйте владельца узла, назначение, учётную запись, список разрешённых проектов и ответственного за обновление инструментов. Отдельная учётная запись для заданий помогает не смешивать рабочую среду разработчика с каталогами, настройками и секретами, доступными процессу сборки. Не выдавайте ей доступ шире, чем требуют операции сборки и тестирования.
До установки Runner определите, какой комплект инструментов нужен проекту: полная версия Xcode или только Command Line Tools. Не выбирайте их по предположению, что «для сборки хватит командной строки»: требования зависят от проекта, SDK, схемы и тестов. Apple отдельно описывает установку Command Line Tools и публикует справочник командной строки Xcode. Сверьте эти сведения с требованиями вашего репозитория и фактическим состоянием узла.
| Что зафиксировать до регистрации | Как проверить | Что считать проблемой |
|---|---|---|
| Учётная запись выполнения | Войти в неё и проверить доступ к репозиторию и каталогам сборки | Задания должны выполняться от неожиданного пользователя либо видеть персональные файлы |
| Выбранный Xcode | Выполнить xcode-select -p и xcodebuild -version в среде, доступной Runner |
Путь или версия отличаются от зафиксированной для проекта |
| Доступные схемы | Для проекта выполнить xcodebuild -list -project <PROJECT_PATH> |
Нужной схемы нет или путь к проекту не совпадает |
| Рабочий каталог | Проверить расположение checkout и права на запись | Данные прошлого задания остаются доступными следующему без утверждённой очистки |
| Назначение Runner | Записать разрешённые проекты и метки в операционной документации | Узел можно назначить произвольным заданиям без контроля |
Узнайте, какой Developer Directory выбран системой, а затем проверьте его из самой CI-задачи. Команда в интерактивном терминале не доказывает, что процесс Runner видит то же окружение: отличаются пользователь, переменные и контекст запуска. Для воспроизводимости сохраните вывод проверки в журнале задания вместе с версией инструмента. Если используется несколько установок Xcode, выбор каталога должен быть явным и повторяемым, а не зависеть от настроек конкретной сессии разработчика.
Не оценивайте производительность и допустимое число параллельных задач «по модели Mac». В этом руководстве нет измерений вашего проекта, конфигурации узла или длительности сборки. Сначала запустите репрезентативную задачу и соберите собственные данные: время этапов, ошибки, потребление ресурсов и поведение при повторном запуске. Без реального измерения нельзя обещать ни пропускную способность, ни экономию времени.
SECTION 03Установка и регистрация: оформите Runner в нужном контексте
Поставьте GitLab Runner по актуальной для вашей версии инструкции GitLab. До регистрации согласуйте URL GitLab, область доступа Runner, метки и разрешённые проекты. Важно, чтобы узел не стал доступен более широкому кругу задач только потому, что конфигурация по умолчанию оказалась удобной. Передавайте регистрационные данные как секрет: в командах, документации и примерах оставляйте только плейсхолдеры.
Типовой этап регистрации можно представить так:
gitlab-runner register \
--url <GITLAB_URL> \
--token <RUNNER_TOKEN>
Это схема с подстановочными значениями, а не приглашение помещать рабочий токен в историю команд или файл проекта. Следуйте актуальному руководству GitLab по регистрации Runner и правилам хранения секретов вашей организации. После регистрации зафиксируйте фактические параметры и проверьте, что Runner получил ожидаемые метки и область назначения. Если проект не должен делить узел с другими командами, это ограничение должно быть закреплено в настройках, а не только в устной договорённости.
Какой executor использовать для GitLab CI на Mac?
Для заданий, которым нужны Xcode и инструменты macOS, GitLab описывает Shell executor как применимый вариант. Но его нельзя трактовать как контейнерную границу безопасности: команды выполняются в окружении хоста, а статус обслуживания и ограниченная изоляция требуют осознанного ограничения сценария. Выбирайте его для пробного или рабочего запуска только тогда, когда доверяете заданиям и можете контролировать, какие проекты их создают.
| Тип задания | Где выполнять | Условие допуска |
|---|---|---|
| Сборка или тест Xcode | Выделенный macOS Runner с Shell executor | Репозиторий и задания доверенные; инструменты проверяются в CI |
| Общие проверки, не требующие macOS | Имеющийся исполнитель для таких задач | Нет причины занимать Mac-узел |
| Задание из недоверенного источника | Не допускать к общему Shell Runner | Сначала требуется подходящая изоляция и отдельная оценка угроз |
| Подписание приложения | Только узел с явно проверенными правами и границами секретов | Доступ к Keychain и signing assets ограничен и проверяем |
На macOS существенен и контекст запуска службы. В инструкции GitLab описан запуск Runner как пользовательского LaunchAgent, который зависит от активной пользовательской сессии; это не то же самое, что системный LaunchDaemon. Не меняйте способ запуска, исходя из сходства названий: проверьте описанный GitLab порядок для macOS и фактическое поведение узла.
Пользовательская сессия создаёт операционный компромисс. Автоматический вход может упростить восстановление после перезапуска, но расширяет последствия физического доступа и оставляет систему в открытой пользовательской сессии. Это не универсальная рекомендация и не замена контролю доступа. Если политика безопасности не разрешает автоматический вход, не включайте его только ради зелёного статуса Runner: выберите допустимый способ управления сессией или отложите использование такого узла.
SECTION 04Первый запуск: докажите, что CI действительно использует нужный Xcode
Создайте минимальное задание, которое адресуется именно нужному Runner по метке, получает код из требуемого репозитория и записывает сведения об исполнении. В конфигурации ниже замените плейсхолдеры на реальные значения проекта. Секреты в YAML не размещайте; используйте защищённые переменные и область доступа, принятую в вашей организации.
stages:
- verify
macos_toolchain_check:
stage: verify
tags:
- <MAC_RUNNER_TAG>
script:
- whoami
- pwd
- xcode-select -p
- xcodebuild -version
- xcodebuild -list -project <PROJECT_PATH>
Этот тест проверяет больше, чем наличие строки «online» в интерфейсе. Убедитесь, что задание назначено нужному Runner, checkout выполнен из ожидаемого репозитория, команда whoami показывает ожидаемую учётную запись, а каталог соответствует плану. Затем сравните путь и версию Xcode с базовой записью, подготовленной до регистрации. Если Runner онлайн, но задача остаётся в очереди, проблема может быть в метках или назначении; это не подтверждает исправность инструментария и не является провалом Xcode.
Следующий этап — не просто вызвать Xcode, а выполнить команду, соответствующую реальной схеме проекта:
xcodebuild \
-project <PROJECT_PATH> \
-scheme <SCHEME_NAME> \
-destination '<DESTINATION>' \
build
Параметры проекта, схемы и назначения здесь условные. Сверьте набор параметров с официальным справочником команд Xcode и конфигурацией конкретного репозитория. Для приёмки сохраните журнал команды, код завершения и идентификатор коммита. Успех команды проверки версии не доказывает, что проект компилируется; успешная сборка, в свою очередь, не доказывает, что безопасны подпись, доступ к секретам или повторное использование рабочего каталога.
Разделяйте результаты проверки по уровням:
| Наблюдение | Что оно подтверждает | Чего оно не подтверждает |
|---|---|---|
| Runner отображается как доступный | Служба зарегистрирована и отвечает GitLab | Что задача совпадает по меткам или может успешно собраться |
| Задание получило журнал выполнения | Задача была назначена и начала исполняться | Что используется нужная версия Xcode |
xcode-select -p и xcodebuild -version совпали с базовой записью |
В контексте задания выбран ожидаемый инструмент | Что схема проекта собирается и тесты проходят |
| Реальная команда сборки завершилась успешно | Проверенный коммит собран выбранной схемой | Что секреты изолированы и узел восстановится после перезапуска |
| Повторный запуск после выхода пользователя или перезапуска отработал | Проверенный сценарий восстановления сработал | Что любые изменения системы и политик не повлияют на доступность |
Если требуется Xcode CI с тестированием, добавьте в проверку именно те тесты и назначения, которые нужны проекту. Начинайте с задачи без подписи, если подпись не является целью конкретного этапа: так вы отделите проблемы toolchain и сборки от проблем Keychain. Не включайте сразу весь процесс доставки, пока не поняли, какие этапы должны получать сертификаты и профили.
SECTION 05Перед расширением задач: ограничьте репозиторий, остатки и секреты
У Shell executor нет контейнерной изоляции, на которую можно было бы полагаться как на защиту между любыми задачами. Поэтому проверяйте реальный периметр доступа: кто может отправить изменение, запустить pipeline, изменить конфигурацию и получить доступ к журналам. Если один узел обслуживает несколько проектов, определите, не может ли задание одного проекта прочитать файлы, оставленные другим.
Проверьте очистку рабочей области на практическом примере. После тестового задания найдите временные файлы, артефакты, кэш и переменные, которые могли сохраниться. Не полагайтесь только на то, что следующий checkout выглядит чистым: проверьте каталоги, используемые вашим процессом сборки, и подтвердите, что политика очистки соответствует их расположению. Данные и секреты предыдущего задания не должны становиться доступными следующему без сознательного решения владельца узла.
Для подписи приложения выделите отдельную точку контроля. Уточните, под каким пользователем доступен Keychain, какие сертификаты и профили установлены, какие задания могут обратиться к ним и как отзываются или заменяются учётные данные. Сам факт успешной сборки не подтверждает корректность этой границы. Пока права и очистка не проверены, оставляйте задания подписи вне общего расписания.
Остановите расширение использования, если обнаружили хотя бы одно из условий:
- Runner принимает задания из репозиториев, которым команда не доверяет.
- Несколько проектов делят рабочую область без проверенной очистки и разделения доступа.
- Учётная запись Runner имеет доступ к персональным файлам или секретам, не нужным сборке.
- Ключи подписи доступны заданиям, которые не должны подписывать приложения.
- Команда рассчитывает на Shell executor как на изолированную среду.
- Нельзя объяснить, кто вправе регистрировать, настраивать и запускать задачи на узле.
При таких условиях не пытайтесь компенсировать пробел дополнительными тегами или обещанием «не запускать опасные задания». Сначала пересмотрите топологию исполнения и доступные GitLab варианты; статус и особенности исполнителей сверяйте с официальным перечнем GitLab. Если требуемую границу изоляции нельзя обеспечить на этом Shell Runner, не используйте его для такого класса задач.
SECTION 06Повторная проверка и решение о вводе в работу
Приёмка не заканчивается первой успешной сборкой. Проведите согласованные с вашей политикой проверки выхода пользователя из сессии, перезапуска macOS и изменения состояния службы, фиксируя, доступно ли задание для планирования и где появляется причина сбоя. Поскольку macOS Runner связан с пользовательской сессией, не переносите результат одной проверки на все способы запуска и восстановления.
Перед каждым испытанием запишите ожидаемое поведение, чтобы не принять отказ за случайную задержку. После выхода пользователя проверьте состояние службы и попробуйте запустить безопасную тестовую задачу. Затем верните узел в утверждённое состояние и повторите проверку после перезапуска системы. Отдельно подтвердите, что выбранный режим автоматического входа разрешён политикой; если нет, тестируйте восстановление без него и принимайте решение по фактическому результату.
Используйте эту проверочную последовательность перед решением о статусе узла:
- [ ] Назначение Mac, владелец и ответственный за обслуживание записаны.
- [ ] Runner закреплён за доверенными проектами; метки и область доступа проверены.
- [ ] Учётная запись выполнения не использует рабочий профиль сотрудника.
- [ ] Путь и версия Xcode проверяются внутри CI, а не только в терминале.
- [ ] Минимальная реальная сборка завершилась для нужного коммита и схемы.
- [ ] Очистка workspace и границы доступа к Keychain проверены отдельно.
- [ ] Выход из пользовательской сессии и перезапуск проверены, результат зафиксирован.
- [ ] Для отказа определён возврат к прежнему CI-процессу.
Допуск к пробному использованию уместен, если доверие к репозиторию ограничено, инструментальная цепочка проверена, а откат понятен. Ввод в регулярный процесс требует дополнительно подтвердить восстановление после событий, предусмотренных эксплуатационной политикой, и согласовать доступ к секретам. Если Runner остаётся недоступен без открытой сессии, а такая сессия противоречит требованиям безопасности, не расширяйте использование: сначала измените схему запуска или выберите подходящую альтернативу.
Для первичного теста или ограниченного проекта удалённый Mac может избавить от необходимости сразу покупать отдельную машину, но аренда сама по себе не исправит слабую изоляцию, неправильные права или неуправляемую сессию. Если вы уже прошли критерии допуска и хотите сравнить временный тестовый узел с собственным оборудованием, изучите варианты удалённого Mac в MACNOX и условия аренды. Для команды, которой нужен физический интерфейс, локальное управление устройством или постоянная нагрузка с фиксированной конфигурацией, собственный Mac может оказаться уместнее; для короткого испытания и проверки CI-процесса аренда позволит не принимать решение о покупке до того, как будут проверены сборка, безопасность и восстановление.