Сначала подключение, затем перенос

Подключите облачный Mac за три минуты

Запускайте команды по SSH, а macOS с графическим интерфейсом используйте через VNC. Выделенный физический Mac, не виртуальная машина. Переносите исходный код, инструменты и CI поэтапно, не перенося вместе с ними проблемы локальной среды.

Если данные для подключения и SSH-ключ уже готовы, следуйте инструкциям ниже. Первичная настройка инструментов потребует дополнительного времени и не входит в шаги подключения.

Сначала подключитесь по SSH — дальше всё пойдёт через этот канал

Подготовьте локальный терминал, SSH-ключ и сведения о хосте из консоли. В примере HOST,PORTиUSER замените на выданные адрес хоста, SSH-порт и имя пользователя — не копируйте значения как есть.

01 · Подготовка

Добавьте открытый ключ, не передавайте закрытый

Если у вас уже есть отдельный ключ, используйте его. Если нет, создайте на своём компьютере пару ключей Ed25519, задайте парольную фразу, а содержимое файла .pub добавьте в соответствующий раздел SSH-ключей в консоли.

ssh-keygen -t ed25519 \
  -f ~/.ssh/osxbuild_ed25519

cat ~/.ssh/osxbuild_ed25519.pub

Закрытый ключ храните локально. Не вставляйте его в заявку, письмо или репозиторий. После загрузки проверьте в консоли, что открытый ключ применён к нужному экземпляру.

02 · Проверка доступа

Подключитесь напрямую по выданному порту

Откройте сведения о подключении в карточке экземпляра в консоли. При первом запросе на подтверждение отпечатка хоста сравните его с проверяемыми данными о подключении. Если подтвердить отпечаток не удаётся, отправьте заявку — не отключайте проверку хоста ради пропуска предупреждения.

ssh -i ~/.ssh/osxbuild_ed25519 \
  -p PORT USER@HOST

sw_vers
uname -m
xcodebuild -version

Сначала проверьте систему, архитектуру и версию Xcode. Если последняя команда сообщит, что инструменты не настроены, установите их и выберите нужный путь, прежде чем подключать задачи сборки.

03 · Постоянный адрес

Задайте машине локальный псевдоним

Добавьте приведённый ниже текст в локальный файл ~/.ssh/config. В примере используется псевдоним bake, который пригодится для синхронизации, туннеля и диагностики. Так не придётся каждый раз вводить адрес и порт вручную.

Host bake
  HostName HOST
  Port SSH_PORT
  User SSH_USER
  IdentityFile ~/.ssh/osxbuild_ed25519
  IdentitiesOnly yes
  ServerAliveInterval 30
  ServerAliveCountMax 3

Сохраните файл и выполните команду ssh bake. Параметры keepalive помогают обнаружить разорванное соединение, но не восстанавливают сеть и не перезапускают задачи терминала автоматически.

Для графического рабочего стола используйте VNC, подключённый через SSH-туннель

Откройте рабочий стол, если нужно настроить Xcode, проверить связку ключей или просмотреть симулятор. Сначала уточните выданные в консоли параметры VNC. Не считайте стандартный порт параметром подключения для каждой машины.

Выберите привычный клиент

В macOS можно использовать встроенную функцию «Общий экран». В Windows и Linux подойдут VNC-клиенты, например TigerVNC. Если клиент нужно устанавливать отдельно, скачайте его с официального сайта и проверьте, что он поддерживает способ аутентификации, используемый сервером.

Сначала снизьте нагрузку на сеть, затем настройте чёткость

Начните с разрешения 1440 × 900 или 1600 × 1000 и не выводите сразу весь экран с высоким разрешением. Если клиент позволяет выбрать глубину цвета, сначала попробуйте 24 бита; при ограниченной пропускной способности — 16 бит. Доступные параметры зависят от поддержки клиента и сервера.

Сборка в терминале и удалённый рабочий стол — два разных способа работы. Если перетаскивание окон тормозит, запускайте сборку по SSH, а затем скачивайте логи и IPA. Не привязывайте весь конвейер к обновлению изображения на экране.

Перенаправляйте порт рабочего стола только на локальный компьютер

Выполните команду ниже локально и оставьте этот терминал открытым.VNC_PORT замените на выданный порт сервера. В примере 15900 — локальный порт; если он занят, выберите свободный.

ssh -N \
  -L 127.0.0.1:15900:127.0.0.1:VNC_PORT \
  -o ExitOnForwardFailure=yes \
  bake

В поле адреса VNC-клиента укажите 127.0.0.1, а в поле порта — 15900. Если у клиента одно поле для адреса, введите данные в формате, указанном в его документации.

VNC по-прежнему использует выданные учётные данные рабочего стола — SSH-ключ не заменяет пароль. Завершив работу, закройте клиент, а затем нажмите Ctrl + C , чтобы закрыть туннель.

Не удаётся подключиться к рабочему столу? Проверьте каждый участок цепочки
Симптом Что проверить сначала Что делать дальше
Не удаётся открыть локальный порт Подключён ли SSH и не занят ли локальный порт Выберите другой локальный порт и сохраните сообщение об ошибке из терминала с туннелем
Туннель установлен, но рабочий стол отклоняет подключение Выданный порт VNC и состояние прослушивания сервера Сверьтесь с данными экземпляра и не открывайте порт рабочего стола для доступа из интернета
Ошибка после начала аутентификации Имя пользователя и пароль рабочего стола, совместимость аутентификации с клиентом Ещё раз проверьте выданные учётные данные. SSH-ключ не является паролем VNC
Войти удалось, но изображение обновляется медленно Разрешение, глубина цвета, локальная сеть и расстояние до узла Снизьте объём передаваемых данных и продолжайте сборку по SSH, если графический интерфейс не нужен

Переносите среду в три этапа, а не копируйте весь диск

Сначала перенесите данные, затем настройте инструменты и подключите CI. На каждом этапе сохраните результат проверки. Сначала добейтесь чистой сборки архива и только потом восстанавливайте кэш и автоматизацию.

Этап 1 · Данные

Синхронизируйте исходный код, пересоздайте временные файлы

Клонируйте проект через Git или синхронизируйте локальную рабочую папку и ресурсы вне репозитория с помощью rsync. При первом переносе не копируйте DerivedData и старую папку build. Не включайте закрытый ключ для подписи в обычную синхронизацию файлов.

rsync -az --progress \
  --exclude='DerivedData/' \
  --exclude='build/' \
  --exclude='*.p12' \
  --exclude='*.mobileprovision' \
  ./ bake:~/project/

Проверка: убедитесь, что целевая папка, версия коммита и необходимые ресурсы совпадают. В примере нет параметров удаления — это помогает избежать случайного удаления файлов на удалённой машине при первой синхронизации. Успешная синхронизация не заменяет резервное копирование.

Этап 2 · Инструменты

Сначала согласуйте версии, затем восстановите зависимости

Установите или выберите Xcode согласно требованиям проекта и настройте Homebrew. Восстановите CocoaPods по lock-файлу, а SPM — повторным разрешением зависимостей. Кэш должен соответствовать версиям инструментов и зависимостей; не используйте повторно каталоги неизвестного происхождения.

xcode-select -p
xcodebuild -version
brew --version

bundle install
bundle exec pod install

Проверка: версии совпадают с локальной базовой средой, зависимости разрешаются. Последние две команды выполняйте только для проектов с CocoaPods. Сертификат подписи импортируйте в связку ключей отдельно через защищённый канал и проверьте срок действия и соответствие профиля подготовки.

Этап 3 · Подключение CI

Зарегистрируйте runner, затем настройте распространение

Зарегистрируйте выделенный runner в GitHub Actions или GitLab Runner. Сначала проверьте версии инструментов, затем запустите Fastlane lane проекта. Сначала проверьте создание архива и экспорт, и только потом добавляйте шаг загрузки.

xcodebuild -list \
  -workspace App.xcworkspace

bundle exec fastlane ios build

Проверка: по логам можно определить версию коммита, Scheme и путь к артефакту. Замените примеры рабочего пространства и lane на фактические имена проекта. Доступ к учётным данным для выпуска выдавайте отдельно — не распространяйте их вместе с исходным кодом.

Настройте CI так, чтобы задачи запускались на этой машине

Self-hosted runner использует арендованный вами физический узел. Метки задают маршрутизацию, учётные данные — права доступа. Не путайте одно с другим. Сначала запустите одну задачу, затем оцените допустимую параллельность и использование диска.

GitHub Actions: закрепите runner за машиной с помощью метки

Зарегистрируйте self-hosted runner по инструкциям в настройках репозитория или организации и добавьте пользовательскую метку osxbuild. Приведённый ниже workflow проверяет инструменты и создаёт архив. Внедрение материалов для подписи, экспорт IPA и распространение в него не входят.

name: iOS archive
on:
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ios-${{ github.ref }}
  cancel-in-progress: false

jobs:
  archive:
    runs-on: [self-hosted, macOS, ARM64, osxbuild]
    steps:
      - uses: actions/checkout@v4
      - name: Check Xcode
        run: xcodebuild -version
      - name: Archive
        run: |
          xcodebuild \
            -workspace App.xcworkspace \
            -scheme App \
            -configuration Release \
            -archivePath "$RUNNER_TEMP/App.xcarchive" \
            archive

Замените рабочее пространство и Scheme и проверьте, что Scheme опубликована в репозитории. Разрешайте запуск на runner с материалами для подписи только для доверенных репозиториев и задач. Для разных веток создаются отдельные группы параллельного выполнения, но конфликты при совместном использовании каталога сборки всё равно нужно предотвращать.

Jenkins: запустите отдельный agent по SSH

Добавьте в Jenkins постоянный узел, укажите для него отдельный каталог сборки и задайте метку osxbuild-mac. Выберите запуск agent по SSH, укажите выданные хост и порт. Закрытый ключ храните в хранилище учётных данных Jenkins.

pipeline {
  agent { label 'osxbuild-mac' }

  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }
    stage('Toolchain') {
      steps {
        sh 'xcodebuild -version'
      }
    }
    stage('Build') {
      steps {
        sh 'bundle exec fastlane ios build'
      }
    }
  }
}

Убедитесь, что доступна необходимая agent версия Java, учётные данные SSH действительны, а отпечаток хоста проверен. Неинтерактивный сеанс, запущенный по SSH, может не загружать локальные настройки оболочки, поэтому явно укажите пути к Homebrew, Ruby и Fastlane.

Подключите GitLab Runner в том же порядке: зарегистрируйте runner, ограничьте доступ доверенными проектами, задайте метки проекта и проверьте среду задачей, которая проверяет версии. Если тестам нужен графический сеанс, сначала отдельно проверьте условия их запуска.

Начните с одного слота выполнения. Перед увеличением параллельности проверьте пиковое потребление памяти, количество симуляторов и путь к DerivedData. Не позволяйте нескольким задачам одновременно записывать архив в один каталог.

Шесть узлов: выбирайте с учётом того, кто и как будет работать

Если вы часто работаете через графический интерфейс, в первую очередь оцените качество соединения команды с узлом. Для CI важнее маршрут исходного кода, зависимостей и загрузки артефактов. Географическая близость — лишь отправная точка: на работу соединения также влияют оператор, маршрутизация и локальная сеть.

Сингапур

SG · UTC+8

Для команд, работающих в часовом поясе Юго-Восточной Азии. Если вам часто приходится удалённо работать в Xcode днём, сначала сравните качество соединения с этим узлом.

Выбрать узел в Сингапуре

Токио

JP · UTC+9

Для команд, работающих в часовом поясе Восточной Азии. Подходит, чтобы вести интерактивную разработку днём, а сборку архива — ночью на одной машине и не передавать среду между системами.

Выбрать узел в Токио

Сеул

KR · UTC+9

Для команд, работающих в часовом поясе Северо-Восточной Азии. Если вы часто используете удалённый рабочий стол, сначала проверьте скорость обновления изображения и отклик на ввод, а затем закрепите адрес подключения за командой.

Выбрать узел в Сеуле

Гонконг

HK · UTC+8

Для команд, работающих в часовом поясе Южного Китая и Юго-Восточной Азии. Оцените не только отклик удалённого рабочего стола, но и скорость загрузки зависимостей и отправки артефактов — не ограничивайтесь разовой проверкой соединения.

Выбрать узел в Гонконге

Восточное побережье США

US-E · UTC−5 / −4

Для совместной работы команд на востоке Северной Америки и в Западной Европе. При планировании ночных сборок задайте часовой пояс явно и учитывайте переход на летнее время.

Выбрать узел на востоке США

Западное побережье США

US-W · UTC−8 / −7

Для команд, работающих на западном побережье Северной Америки. Удобно назначать сборки на рабочее время по местному часовому поясу. При передаче задач между часовыми поясами сохраняйте в логах однозначные отметки времени.

Выбрать узел на западе США

Обе конфигурации доступны во всех шести локациях. Актуальную доступность проверяйте в консоли. Узлы работают круглосуточно, 365 дней в году; перебои локальной сети и обрыв SSH-сеанса не означают, что машина остановилась.

После подключения настройте доступ и защитите материалы для подписи

Сначала сохраните проверенное рабочее подключение, затем меняйте правила доступа. Вносите по одному изменению и проверяйте новое подключение, прежде чем закрыть старый сеанс, чтобы не потерять доступ к машине.

  1. 01

    Проверьте ключ и отключите вход по паролю

    Откройте второй терминал и убедитесь, что вход по отдельному ключу работает. Затем отключите аутентификацию по паролю в соответствии с настройками SSH системы. Перед изменением конфигурации проверьте синтаксис и убедитесь, что сможете восстановить подключение. Если вы не знакомы с настройками системы, сначала уточните порядок действий в заявке.

  2. 02

    Оставьте только необходимые порты

    Ограничьте удалённый вход и доступ к сервисам только необходимыми для работы портами. Для VNC по возможности используйте SSH-туннель. Не открывайте напрямую в интернете отладочные службы, интерфейсы управления сборкой или временные файловые серверы. Одновременно проверьте привязку к локальному адресу и настройки контроля доступа.

  3. 03

    Используйте отдельные ключи для каждого человека и задачи

    Для ручного входа и CI используйте разные ключи. При смене сотрудника или подозрении на утечку немедленно отзовите старый доступ. При ротации сначала добавьте и проверьте новый открытый ключ, затем удалите старый и обновите настройки runner и записи о передаче доступа команде.

  4. 04

    Не сохраняйте материалы для подписи в обычных логах

    Разблокируйте связку ключей только на время, необходимое для сборки, а после работы ограничьте доступ. Передавайте API Key, пароль сертификата и данные для расшифровки match через систему управления секретами. Убедитесь, что скрипты не выводят чувствительные переменные, и не храните файлы закрытых ключей в репозитории.

  5. 05

    Скачайте артефакты и конфигурацию до окончания срока аренды

    Синхронизируйте нужный исходный код, IPA, архивы и конфигурацию конвейера с хранилищем вашей команды и проверьте, что файлы читаются. При завершении аренды диск очищается, а система устанавливается заново — не используйте локальную папку машины как единственную копию.

Для диагностики достаточно передать нужные сведения.В заявке укажите номер заказа, узел, время ошибки и часовой пояс, а также последние 50 строк логов после удаления конфиденциальных данных. Не отправляйте закрытые ключи, пароли сертификатов или пароли учётных записей. По вопросам подключения обратитесь через консоль или по адресу support@osxbuild.com .

Настройте подключение и подготовьтесь к следующей сборке архива

Если машина у вас уже есть, проверьте данные о ней в консоли. Если конфигурацию ещё не выбрали, начните с двух вариантов выделенного облачного Mac: выберите машину по объёму сборок, а узел — по расположению команды.