Оставьте конвейер — замените машину

Запустите эти конвейеры на облачном Mac

Перенесите на выделенный физический Mac mini этапы сборки и тестирования, которым необходима macOS. У нативных приложений iOS, Flutter, Unity и MLX разные узкие места: сначала проверьте команды и требования, затем выберите конфигурацию с учетом памяти, кэша и параллельных задач. Здесь — практические рабочие процессы, а не результаты тестов производительности.

Выделенный физический сервер, не виртуальная машина. Аренда от одного дня, стартовая цена $20.5 в день; актуальную доступность смотрите в консоли.

Подберите конфигурацию под задачу

Всего 5 сценариев — все развернуты. Выберите категорию, чтобы выделить нужные сценарии и перейти к ним; остальные останутся на странице.

От условия запуска до проверки результата

Найдите нужный этап.

Выполняйте команды на узле. Сначала установите зависимости проекта, затем задайте нужные переменные окружения; пути должны указывать на ваш проект и файлы конфигурации. Кнопка копирует команды, но не запускает задачу.

Нативная iOS · ночная сборка

Запускайте archive при push в Git, а загрузку поручите fastlane.

Зарегистрируйте облачный Mac как self-hosted runner GitHub Actions, GitLab Runner или агент Jenkins. После push в ветку релиза сначала получите код фиксированного коммита, затем создайте Release archive и IPA. Загрузка в TestFlight — отдельный этап: так ошибки сборки и загрузки можно устранять и повторять независимо.

Сначала подготовьте три вещи

  • Задайте WORKSPACE, SCHEME и EXPORT_OPTIONS: укажите рабочую область, общую схему и конфигурацию экспорта соответственно.
  • Настройте сертификат подписи и профиль подготовки для текущего пользователя сборки. Управлять ими можно через fastlane match, а расшифрованные учетные данные передавайте через секреты CI.
  • Задайте ASC_API_KEY_JSON: путь к JSON-файлу ключа API App Store Connect для fastlane. Не храните ключ в репозитории.

Что проверить при приемке

Сохраните архив build/App.xcarchive, экспортированный IPA, идентификатор коммита и версию Xcode. Убедитесь, что TestFlight получил нужную сборку: успешное завершение команды сборки не означает, что загрузка завершена.

Почему эта конфигурация: 24 ГБ объединенной памяти Host M4 Plus подходят для повседневной сборки проектов с несколькими target. Сначала проверьте последовательный запуск, затем решите, увеличивать ли параллельность, учитывая давление на память и размер DerivedData.

archive → export → upload
set -euo pipefail
: "${WORKSPACE:?Set WORKSPACE}"
: "${SCHEME:?Set SCHEME}"
: "${EXPORT_OPTIONS:?Set EXPORT_OPTIONS}"
: "${ASC_API_KEY_JSON:?Set ASC_API_KEY_JSON}"

mkdir -p build
xcodebuild -version
xcodebuild \
  -workspace "$WORKSPACE" -scheme "$SCHEME" \
  -configuration Release \
  -destination 'generic/platform=iOS' \
  -archivePath build/App.xcarchive archive

xcodebuild -exportArchive \
  -archivePath build/App.xcarchive \
  -exportPath build/export \
  -exportOptionsPlist "$EXPORT_OPTIONS"

IPA_PATH="$(find build/export -type f -name '*.ipa' -print -quit)"
test -n "$IPA_PATH"
bundle exec fastlane pilot upload \
  --ipa "$IPA_PATH" \
  --api_key_path "$ASC_API_KEY_JSON"
Конфигурация: Host M4 Plus · M4 / 24 ГБ / 512 ГБ Рекомендуемый узел: Япония (Токио)
Арендовать Host M4 Plus

Кроссплатформенная разработка · Flutter

Android оставьте на Linux — перенесите только этап iOS.

Не нужно переносить весь конвейер для обеих платформ. Оставьте задачи Android на Linux runner, а облачному Mac поручите CocoaPods, сборку в Xcode и экспорт IPA. Используйте один идентификатор коммита на обеих платформах и объединяйте готовые артефакты. Если одна платформа завершится с ошибкой, повторите только ее задачу.

Задайте условия сброса кэша

  • Зафиксируйте версии Flutter, Ruby, CocoaPods и Xcode; сохраните pubspec.lock, Podfile.lock и Gemfile.lock.
  • Кэшируйте каталоги загрузок Pub и CocoaPods. Ключ кэша должен включать как минимум версии инструментов и хеши файлов блокировки зависимостей.
  • Не позволяйте параллельным задачам записывать данные в один каталог проекта. Разделяйте DerivedData и каталоги результатов, чтобы кэши не мешали друг другу.

Что проверить при приемке

Сохраните подписанный IPA из каталога build/ios/ipa , журналы сборки и файлы блокировки зависимостей. Сначала проверьте артефакт на устройстве или в отдельной задаче тестирования, а затем пометьте результат сборки как готовый к выпуску.

Почему эта конфигурация: Host M4 Lite — хороший старт для одной задачи. Если одновременно запустить симулятор, тесты и упаковку, сначала измерьте пиковое потребление памяти. Только после этого рассматривайте Host M4 Plus, вместо того чтобы сразу увеличивать параллельность.

Flutter · задача iOS
set -euo pipefail
: "${EXPORT_OPTIONS:?Set EXPORT_OPTIONS}"

flutter --version
xcodebuild -version
flutter doctor -v
bundle check || bundle install
flutter pub get

(
  cd ios
  bundle exec pod install --deployment
)

flutter build ipa \
  --release \
  --export-options-plist="$EXPORT_OPTIONS"

find build/ios/ipa -type f -name '*.ipa' -print
Конфигурация: Host M4 Lite · M4 / 16 ГБ / 256 ГБ Рекомендуемый узел: Сингапур
Арендовать Host M4 Lite

Игры · сборка iOS

Подготовьте экспортированный Unity-проект, подпишите сборку и проверьте ее размер.

Обработка ресурсов в Unity и сборка в Xcode — отдельные этапы. Сначала экспортируйте Xcode-проект штатными средствами проекта, затем создайте archive и выполните export на облачном Mac. Сравнивайте размер сборок с одинаковыми настройками ресурсов — так будет понятно, что именно изменилось: ресурсы, параметры сборки или способ экспорта.

Четко обозначьте границы экспорта

  • UNITY_IOS_DIR должен указывать на каталог экспортированного проекта iOS. Команды ниже начинаются с этапа Xcode и не заменяют скрипт сборки Unity.
  • Если плагин создал workspace, задайте UNITY_WORKSPACE; иначе используйте Unity-iPhone.xcodeproj. Не смешивайте два варианта.
  • Подготовьте подпись и EXPORT_OPTIONS. Чтобы получить отчет App Thinning, включите соответствующий параметр отчета в конфигурации экспорта.

Что проверить при приемке

Проверьте размер IPA, журналы экспорта и изменения ресурсов. Размер сжатого IPA не равен фактическому размеру загрузки или установки для пользователя. Принимая решение о выпуске, учитывайте отчет экспорта и результаты обработки при распространении.

Почему эта конфигурация: Host M4 Pro с 64 ГБ объединенной памяти и SSD на 2 ТБ подходит для крупных проектов с большим количеством ресурсов и кэшем архивов. Сначала зафиксируйте потребление на этапах импорта ресурсов, компиляции и экспорта, затем настройте очередь задач.

Экспорт Unity → Xcode
set -euo pipefail
: "${UNITY_IOS_DIR:?Set UNITY_IOS_DIR}"
: "${EXPORT_OPTIONS:?Set EXPORT_OPTIONS}"

mkdir -p build
if [ -n "${UNITY_WORKSPACE:-}" ]; then
  xcodebuild -workspace "$UNITY_WORKSPACE" \
    -scheme Unity-iPhone -configuration Release \
    -destination 'generic/platform=iOS' \
    -archivePath build/Game.xcarchive archive
else
  xcodebuild \
    -project "$UNITY_IOS_DIR/Unity-iPhone.xcodeproj" \
    -scheme Unity-iPhone -configuration Release \
    -destination 'generic/platform=iOS' \
    -archivePath build/Game.xcarchive archive
fi

xcodebuild -exportArchive \
  -archivePath build/Game.xcarchive \
  -exportPath build/game-export \
  -exportOptionsPlist "$EXPORT_OPTIONS"

find build/game-export -type f -name '*.ipa' \
  -exec du -h {} \;
Конфигурация: Host M4 Pro · M4 Pro / 64 ГБ / 2 ТБ Рекомендуемый узел: Южная Корея (Сеул)
Арендовать Host M4 Pro

Нативная iOS · тестирование совместимости

Зафиксируйте версию Xcode и последовательно проверьте все симуляторы.

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

Фиксируйте версии и устройства

  • Управляйте несколькими версиями Xcode с помощью xcodes. Задавайте версию для каждой задачи через DEVELOPER_DIR , чтобы параллельные задачи не меняли системную версию инструментов.
  • Сначала проверьте, какие симуляторы доступны в текущей версии Xcode, и задайте разные UDID для SIM_A и SIM_B . Симуляторы нужных устройств необходимо установить заранее.
  • Сохраняйте .xcresult — не ограничивайтесь последней строкой вывода в терминале. Скриншоты интерфейса, упавшие тесты и записи повторных запусков должны относиться к одному и тому же коммиту.

Что проверить при приемке

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

Почему эта конфигурация: Host M4 Plus подойдет для повседневных регрессионных тестов. Количество симуляторов зависит от реальной нагрузки на память: 24 ГБ не означают, что задачи можно запускать параллельно без ограничений.

Xcode · матрица симуляторов
set -euo pipefail
: "${DEVELOPER_DIR:?Set DEVELOPER_DIR}"
: "${WORKSPACE:?Set WORKSPACE}"
: "${SCHEME:?Set SCHEME}"
: "${SIM_A:?Set SIM_A}"
: "${SIM_B:?Set SIM_B}"
export DEVELOPER_DIR

mkdir -p build
xcodebuild -version
xcrun simctl list devices available

RUN_ID="$(date +%s)-$$"
for DEVICE_ID in "$SIM_A" "$SIM_B"; do
  xcodebuild test \
    -workspace "$WORKSPACE" \
    -scheme "$SCHEME" \
    -destination "platform=iOS Simulator,id=$DEVICE_ID" \
    -parallel-testing-enabled NO \
    -resultBundlePath \
      "build/$RUN_ID-$DEVICE_ID.xcresult"
done
Конфигурация: Host M4 Plus · M4 / 24 ГБ / 512 ГБ Рекомендуемый узел: Гонконг
Арендовать Host M4 Plus

ИИ · эксперименты с инференсом MLX

Загрузите модель в объединенную память и сначала проверьте стабильность работы.

Запустите совместимую модель через MLX на физическом узле Apple Silicon и зафиксируйте скорость генерации, пиковое потребление памяти и длину контекста. Сначала проверьте одиночный запрос, затем пакетную обработку. Сборка и эксперименты с инференсом используют ресурсы одной машины — не запускайте их одновременно на полной нагрузке без предварительных замеров.

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

  • MODEL_DIR должен указывать на подготовленный каталог модели, совместимой с MLX. Проверьте источник модели, лицензию, формат квантования и версии зависимостей.
  • 64 ГБ — это общая память всей машины: ее используют система, веса модели, кэш и другие процессы. Возможность загрузки модели зависит от ее размера и настроек контекста.
  • Зафиксируйте промпт и длину генерации, измерьте холодный запуск и последующие запросы. Не включайте время загрузки модели в скорость инференса.

Что проверить при приемке

Сохраните версию модели, настройки квантования, окружение MLX и журналы запуска. Используйте /usr/bin/time -l для оценки потребления ресурсов процессом, а затем проверьте по нагрузке на системную память, происходит ли выгрузка страниц на диск.

Почему эта конфигурация: 64 ГБ объединенной памяти Host M4 Pro подходят для экспериментов, требующих больше памяти. SSD на 2 ТБ предназначен для файлов моделей и результатов экспериментов и не увеличивает объем доступной модели памяти.

MLX · локальный инференс
set -euo pipefail
: "${MODEL_DIR:?Set MODEL_DIR}"

python3 -m venv .venv
. .venv/bin/activate
python -m pip install mlx-lm
mkdir -p build

python -m pip freeze > build/mlx-environment.txt
/usr/bin/time -l \
  python -m mlx_lm.generate \
    --model "$MODEL_DIR" \
    --prompt "Explain reproducible builds." \
    --max-tokens 128 \
    > build/mlx-output.txt \
    2> build/mlx-metrics.txt

cat build/mlx-output.txt
cat build/mlx-metrics.txt
Конфигурация: Host M4 Pro · M4 Pro / 64 ГБ / 2 ТБ Рекомендуемый узел: запад США
Арендовать Host M4 Pro

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

Рекомендация — не гарантия производительности

Проверьте конфигурацию на полной задаче.

Рекомендуемые узлы выбраны с учетом часовых поясов команд и не основаны на измерениях сетевой задержки. На удобство работы также влияют расположение репозитория, хранилища артефактов и участников команды.

01

Зафиксируйте пиковую нагрузку

Зафиксируйте коммит и версии зависимостей, затем выполните задачу целиком. Запишите нагрузку на память, размер кэша и артефактов — не выбирайте конфигурацию только по времени одной сборки.

02

Разделите очередь и выполнение

Начните с одного исполнителя. Убедитесь в стабильности самой задачи и только затем увеличивайте параллельность. Отдельно учитывайте время ожидания runner, загрузки зависимостей и компиляции.

03

Выберите узел рядом с командой

Доступны 5 узлов: Сингапур, Япония (Токио), Южная Корея (Сеул), Гонконг и запад США. Сначала проверьте синхронизацию проекта и интерактивное подключение, затем закрепите узел за командой.

Определите критерии приемки

Что вы хотите увидеть утром?

Ниже приведены примеры целей для трех ролей — это не отзывы клиентов и не результаты измерений. Четкие критерии приемки в конвейере полезнее, чем погоня за единичным ускорением сборки.

«Утром я хочу получить архив, результаты тестов и журнал ошибок для нужного коммита, а не начинать с проверки офисного компьютера для сборок».
Ответственный за iOS · цель ночной сборки
«Я переношу только этап Flutter для iOS. Обе платформы собираются для одного коммита, а упавшую задачу можно запустить повторно отдельно — без перезапуска всего конвейера».
Архитектор мобильных приложений · цель разделения конвейера
«Мне нужно сохранять версию модели, потребление памяти и результаты генерации. Воспроизводимые эксперименты помогут обоснованно выбрать машину в следующий раз».
Инженер по машинному обучению · цель экспериментов с инференсом

Сначала выберите этап, затем машину.

Для одной задачи начните с Host M4 Lite, для нескольких target и повседневных регрессионных тестов выберите Host M4 Plus, а для крупных проектов и ресурсоемких экспериментов — Host M4 Pro. На странице планов сравните три конфигурации, четыре срока аренды и дополнительные опции, затем оформите заказ.

Оплата только в долларах США. Принимаются USDT-TRC20 и Visa / Mastercard / Amex через Stripe; доступные способы оплаты уточняйте по ответу серверного интерфейса.