Для стандартной сборки и тестирования сначала проверьте управляемый macOS Agent; выбирайте удалённый Mac, когда нужны фиксированная среда, доступ к узлу или подключение к закрытой инфраструктуре. Подпись и публикацию оценивайте отдельно: наличие Mac само по себе не означает, что ваши секреты и выпуск приложения уже организованы безопасно.
На этой неделе зафиксируйте границы CI, затем проведите пилот на одном и том же коммите; решение о постоянной среде принимайте только после проверки сборки, тестов, подписи и восстановления.
Статья для разработчиков без собственного Mac, которым нужно проверить iOS-цель Kotlin Multiplatform.
Она также пригодится техническим руководителям, переводящим KMP из эксперимента в командную поставку, и DevOps-инженерам, отвечающим за Apple-платформенную инфраструктуру.
Последняя проверка: 18 октября 2026 года. Платформенные требования и примеры сверены с документацией Kotlin по CI/CD и iOS-сборке, описанием требований к платформам и текущим руководством по совместимости Kotlin Multiplatform. Перед публикацией или внедрением перепроверьте эти документы и фактические возможности выбранного CI.
SECTION 01 Границы проверки общего кода и iOS CI
Начинайте с цели каждого задания, а не с вопроса, у кого в команде есть Mac. Общий код KMP и тесты для настроенных не-Apple-целей можно проверять на уже имеющихся исполнителях, если конфигурация проекта и зависимости это позволяют. Но сборка iOS-цели, запуск iOS Simulator и действия, зависящие от Xcode, требуют среды macOS с подходящим Xcode. Это платформенное ограничение описано в справке Kotlin о требованиях к Apple-целям и официальной инструкции по первой сборке KMP-приложения для iOS.
Можно ли обойтись без Mac, если нужно запустить CI для KMP-проекта? Да, если задача ограничена проверками общего кода и доступными в вашей конфигурации не-Apple-целями. Если pipeline должен компилировать iOS-приложение, выполнять тесты в симуляторе или готовить приложение к выпуску, добавьте отдельный macOS-этап. Не называйте проверку Kotlin-модулей полной проверкой iOS: она не подтверждает, что Xcode собрал приложение и что интеграция с Apple SDK работает.
Перед проектированием pipeline разделите задания на самостоятельные группы:
- Общая логика и проверки Gradle. Сюда относятся задачи, которые не требуют iOS SDK и могут выполниться в вашей текущей среде. Их разумно оставить на существующих Linux- или других агентах, если проектная конфигурация это подтверждает.
- Компиляция Apple-целей. Когда Gradle должен обратиться к инструментам Apple для создания iOS-артефакта, запускайте соответствующий этап на macOS с Xcode.
- Проверки в симуляторе. Они требуют не только компиляции общего кода, но и доступной конфигурации симулятора, целевого устройства и тестовой схемы.
- Подпись и выпуск. Здесь добавляются сертификаты, профили, полномочия и процедура загрузки. Успешная компиляция не проверяет эти части процесса.
Такое разделение сокращает объём macOS CI, не создавая ложного ощущения, что общий тест уже подтвердил готовность приложения к iOS-поставке.
SECTION 02 Ограничения среды перед выбором агента
Управляемый macOS Agent и удалённый Mac отличаются не тем, что один из них автоматически быстрее или надёжнее, а границами контроля. У управляемого варианта исполнитель обслуживается провайдером CI; доступные настройки и ограничения зависят от конкретного сервиса. Например, документация GitHub отдельно описывает ограничения размещённых исполнителей; используйте их как перечень того, что нужно сверить, а не как доказательство возможностей любого управляемого агента: ограничения размещённых GitHub Actions Runner.
У удалённого Mac вы можете получить больше контроля над установленными инструментами и способом доступа, но вместе с ним появляются обязанности по настройке и обслуживанию узла. Проверьте, кто обновляет Xcode, как узел подключается к репозиторию и внутренним ресурсам, кто может читать артефакты и как удаляются временные данные. Само слово «удалённый» не гарантирует ни постоянной доступности, ни подходящего уровня изоляции.
Для первичного отбора сопоставьте потребности с фактическими возможностями:
- Выбор и закрепление инструментов. Узнайте, можно ли зафиксировать нужные macOS, Xcode и вспомогательные утилиты либо изменение образа выполняет только провайдер. На собственном узле проверьте, кто отвечает за установку, обновление и откат.
- Доступ к узлу. Выясните, доступны ли вам нужные средства диагностики, журналы, рабочие каталоги и операции перезапуска. Не предполагайте, что управляемая система предоставляет прямой доступ к машине.
- Сетевые зависимости. Проверьте доступ к приватным репозиториям, внутренним пакетам, тестовым сервисам и хранилищам. Успешная сборка открытого проекта не доказывает, что исполнитель сможет работать в вашей сетевой схеме.
- Изоляция и очистка. Уточните, как разделяются задания, где остаются ключи и временные файлы и что происходит с рабочей копией после завершения.
- Обновление среды. Зафиксируйте, кто и как меняет системные инструменты и как команда узнаёт об изменении образа.
Когда команде нужен собственный или арендуемый удалённый Mac? Когда обязательны контроль системной среды, нестандартные инструменты, доступ в приватную сеть либо обслуживание одного и того же узла по внутренним правилам команды. Если задача стандартная и ограничения управляемого исполнителя не мешают, сначала испытайте управляемый путь: преждевременное обслуживание отдельной машины создаёт дополнительную работу без подтверждённой выгоды.
SECTION 03 Проверка совместимости без предположений
Совместимость нужно подтвердить на конфигурации самого проекта. Нельзя вывести её только из слова «Kotlin Multiplatform»: результат зависит от используемых версий Kotlin, Gradle и Xcode, выбранной macOS, iOS-цели, Gradle-плагинов, нативных библиотек и способа интеграции проекта с Xcode.
Составьте перечень до первого CI-запуска:
- Версия Kotlin и применяемые плагины, включая плагины, которые влияют на KMP-конфигурацию.
- Версия Gradle Wrapper и набор параметров сборки, используемый локально.
- Требуемая версия Xcode и соответствующая ей среда macOS.
- Конкретная iOS-цель и схема Xcode, которую должен собирать pipeline.
- Нативные зависимости, CocoaPods или другие механизмы интеграции, если они присутствуют в проекте.
- Команды для сборки, модульных тестов, тестов в симуляторе и подготовки артефакта.
Для платформ и Kotlin используйте таблицу совместимости Kotlin Multiplatform, а конкретные возможности выбранной версии Kotlin проверяйте по официальным материалам Kotlin. Не переносите требования одного компонента на весь проект: совместимость Kotlin с целевой платформой ещё не подтверждает, что сторонний Gradle-плагин или нативный SDK поддерживает ту же комбинацию.
В качестве базовой точки берите текущие lock-файлы и команды проекта, а не обновляйте инструменты одновременно с созданием CI. Для воспроизводимого запуска используйте Gradle Wrapper, который фиксирует выбранную версию Gradle через конфигурацию репозитория; назначение и настройка механизма описаны в руководстве Gradle Wrapper. Проверьте, что CI запускает именно wrapper проекта, а не случайно установленную системную версию Gradle.
Дальше действуйте по этапам:
- Зафиксируйте коммит, на котором локальная конфигурация проекта проходит доступные проверки.
- Запишите версии инструментов и команды, которыми сейчас собираются KMP-модули и iOS-приложение.
- На выбранном macOS-исполнителе воспроизведите сборку iOS-цели без изменения lock-файлов и зависимостей.
- Добавьте тесты общего кода, затем отдельно — запуск тестов в симуляторе, если он входит в критерии выпуска.
- Сохраните логи, результаты тестов и сведения об артефакте; повторите запуск на том же коммите, чтобы проверить, что результат объясним и воспроизводим.
- Только после этого меняйте версии инструментов, настройки кэша или способ получения зависимостей — по одному изменению за раз.
Если сборка падает, классифицируйте причину: несовместимая связка инструментов, недостающая зависимость, ошибка схемы Xcode или сетевое ограничение. Перенос проекта на другой тип агента до такой диагностики может лишь поменять место проявления ошибки.
SECTION 04 Проверка подписи и публикации в TestFlight
Разделяйте возможности построить приложение и полномочия выпустить его. Компиляция iOS-приложения может пройти без завершённой настройки публикации; обратное тоже верно — доступ к сертификату не исправит ошибку компиляции или тестов. Apple описывает подготовку приложения к распространению отдельно от загрузки сборок: используйте руководство Apple по подготовке приложения к распространению и инструкцию App Store Connect по загрузке сборок.
Как связать iOS CI с подписью и TestFlight? Опишите процесс как последовательность проверяемых переходов: сборка артефакта, тестирование, подписание допустимыми для проекта средствами, передача в App Store Connect и подтверждение результата загрузки. Если ваша политика требует проверки человеком или отдельного одобрения перед выпуском, включите её в критерий готовности CI, а не считайте автоматическую загрузку достаточным доказательством безопасного релиза.
До передачи секретов в pipeline ответьте на следующие вопросы:
- Где хранятся сертификаты, ключи и профили; кто может изменять секреты и кто может инициировать задание с доступом к ним?
- Выдаётся ли доступ к полномочиям только тому этапу, которому они необходимы, и можно ли отделить обычный pull request от доверенного процесса выпуска?
- Как секреты удаляются из временного окружения и что происходит с ними при аварийном завершении задания?
- Как команда проверяет, что загружена нужная сборка и её можно найти в App Store Connect?
- Можно ли остановить публикацию после успешной сборки, если не пройдены ручная проверка или внутреннее одобрение?
Управляемый агент подходит, если его секреты, разграничение доступа, сетевые правила и журналирование удовлетворяют требованиям вашей команды. Если требуется более тонкий контроль над машиной или её подключением к внутренней среде, удалённый Mac может оказаться удобнее, но это не отменяет отдельной проверки секретов, доступа и очистки. Не размещайте долговременные ключи в репозитории и не используйте факт наличия root-доступа как замену модели разграничения полномочий.
SECTION 05 Оценка воспроизводимости и стоимости эксплуатации
Проверка одного зелёного запуска недостаточна для постоянной поставки. Успешный запуск подтверждает только конкретный коммит и конкретные условия. Команде нужно понимать, где лежат журналы и тестовые результаты, можно ли повторно запустить упавшее задание, как закреплены инструменты и кто возвращает среду в рабочее состояние после изменения конфигурации.
В ходе пилота проверяйте воспроизводимость на неизменном коммите и одинаковом целевом задании. Сохраняйте идентификатор коммита, параметры Gradle, выбранную схему Xcode, журналы, результаты тестов и сведения о собранном артефакте. Если повторный запуск отличается, сначала выясните, не изменились ли зависимости, образ, кэш или внешняя служба. Не приписывайте различие выбранному типу агента без такого сравнения.
Затем проверьте операционные сценарии: доступна ли команде диагностика упавшей задачи; можно ли повторить только нужный этап; сохраняются ли сведения, необходимые для расследования; понятна ли процедура восстановления после сбоя или изменения инструментария. Для удалённой машины добавьте проверку доступа после перезапуска и порядок возврата к известной конфигурации. Для управляемой среды уточните, какие действия доступны пользователю, а какие зависят от провайдера. Ни постоянная работа узла, ни восстановление после перезапуска, ни меньшие эксплуатационные расходы не следуют автоматически из типа размещения — эти выводы требуют фактической проверки.
Расходы тоже сравнивайте по входным данным, а не по рекламному названию решения. Сведите вместе стоимость фактического использования, ожидаемую нагрузку, обслуживание, настройку секретов, время диагностики, ограничения сетевого доступа и цену перехода между вариантами. Если вы рассматриваете удалённую аренду Mac, сначала сверьте доступные условия и состав услуги в актуальной информации о тарифах VPSNIX; не переносите в расчёт непроверенные предположения о конфигурации, доступности или цене.
| Показатель для проверки | Управляемый macOS Agent | Удалённый Mac |
|---|---|---|
| Инструменты и системная конфигурация | Уточните допустимый выбор образа и порядок обновления у поставщика CI | Проверьте, кто устанавливает, обновляет и фиксирует Xcode и вспомогательные инструменты |
| Доступ к узлу и внутренней сети | Сверьте доступные способы диагностики, сетевые правила и ограничения размещённого исполнителя | Проверьте SSH или иной предусмотренный доступ, подключение к приватным ресурсам и ответственность за безопасность |
| Секреты и публикация | Подтвердите разграничение секретов между проверками и выпуском | Проверьте хранение ключей, их доступность только нужным этапам и очистку временных данных |
| Диагностика и повторный запуск | Уточните, какие логи, результаты тестов и механизмы повтора доступны | Проверьте, как команда получает журналы и восстанавливает рабочую конфигурацию узла |
| Обслуживание | Учитывайте ограничения провайдера и время команды на настройку pipeline | Добавьте обслуживание ОС и инструментов, мониторинг доступа и процедуру восстановления |
| Финансовая оценка | Считайте фактическое использование по условиям выбранного CI | Считайте фактический период использования и внутренние затраты на эксплуатацию; не подменяйте их одним тарифом |
Если вы не можете получить достоверные условия для расчёта, оставьте численную стоимость за пределами сравнения. Сначала соберите собственные данные о периодичности запусков, простоях, времени сопровождения и числе проверок, требующих Apple-среды. Для удалённого Mac отдельно оцените время инженера на обслуживание; для управляемого — ограничения, из-за которых часть работ может потребовать изменения pipeline.
SECTION 06 Выбор среды после пилота
Переходите от пилота к решению по результатам проекта, а не по общему обещанию сервиса. Ниже — рабочая матрица: она не присваивает платформам универсальные преимущества, а показывает, какое условие должно быть подтверждено, чтобы выбор был обоснован.
| Условие команды | Решение для следующего этапа | Что считать подтверждением |
|---|---|---|
| Нужны стандартные сборка и тестирование, а требования выполняются в управляемой среде | Сначала оставить управляемый Agent | iOS-этап проходит на целевом коммите, логи доступны, ограничения и секреты приемлемы |
| Нужны закреплённые системные инструменты или контроль конфигурации узла | Оценить удалённый Mac | Команда описала владельца обновлений, доступа, очистки и восстановления |
| CI должен обращаться к приватным ресурсам, а сеть управляемого исполнителя не подходит | Проверить удалённый Mac и сетевую схему | Доступ разрешён политиками безопасности, а сборка действительно получает необходимые зависимости |
| Подпись и выпуск ещё не проверены либо полномочия разделены между командами | Сохранить небольшой параллельный пилот | Сборка, симулятор, подпись и загрузка проверяются раздельно, без передачи избыточных секретов |
| Задача пока ограничена общим кодом и не включает iOS-артефакт | Не вводить Mac-этап только «на будущее» | Текущие проверки соответствуют целям проекта; потребность в Apple-этапе оформлена как отдельное требование |
Подходит ли управляемый macOS Agent для KMP-проекта? Да, если он позволяет выполнить именно ваши iOS-сборку и тесты, а управление инструментами, сетью, журналами и секретами укладывается в правила команды. Если хотя бы один обязательный пункт не подтверждён, сначала проведите ограниченный пилот или проверьте другой тип среды, не переводя сразу весь выпускной процесс.
На практике управляемый вариант чаще стоит проверять первым для стандартизированного pipeline: вам не требуется заранее брать на себя обслуживание отдельного узла. Удалённый Mac оправдан, когда необходимость контроля, приватного доступа или постоянной настройки подтверждена проектом. Но за этот контроль вы платите эксплуатационной работой, а сама аренда не решает автоматически вопросы обновлений, безопасности и восстановления.
Если текущий CI не даёт нужного доступа к узлу, ограничивает изменение образа или затрудняет интеграцию с приватной сетью, это реальные основания испытать удалённый Mac. Если же единственная причина — отсутствие личного Mac, а управляемый исполнитель проходит ваши тесты, обслуживание отдельной машины может быть лишним. И наоборот: покупка собственной техники не обязательна для каждого CI-проекта, особенно когда потребность в macOS ограничена сборками и тестированием.
Когда проверка покажет, что нужны именно управляемая конфигурация и доступ к отдельному узлу, сравните фактический рабочий процесс удалённого Mac с вашим pipeline. В справочном центре VPSNIX уточните доступные способы подключения и ограничения перед пилотом; если условия подходят, испытайте среду на своём коммите и отдельно проверьте секреты и восстановление. Для периодических стандартных заданий оставьте управляемый CI, для требовательной к контролю среды рассмотрите аренду Mac, а при незавершённой проверке подписи временно сохраните оба пути.