Перед релизом знакомая картина: в Slack «кто нажмёт TestFlight», другой вручную по SSHxcodebuild, третий «у меня проходит». Cloud Mac решает железо — если проверки вручную,«у меня работает» остаётся лотереей. OpenClaw на выделенных узлах Zutcloud: цель —оркестрация + фиксированный узел, trigger, сборка, проверка подписи и receipt в проверяемой цепочке.
От «ручного релиза» к «цепочному релизу»
До автоматизации: средняя iOS-команда ~40 мин на релиз только на «подтверждение окружения»:
| Ручной шаг | Скрытая стоимость | После автоматизации |
|---|---|---|
| Подтвердить версии Xcode / сертификатов | Устно, легко забыть | Версия образа в manifest pipeline |
| Пробная локальная Archive | У каждого своё окружение | Фиксированный путь DerivedData на выделенном узле |
| Загрузка TestFlight | Кто свободен — тот делает | Stage подписи автоматически altool / Transporter |
| Уведомить QA | Номер сборки не сходится | Webhook receipt с commit + hash артефакта |
Пятиступенчатая цепочка pre-release
Pre-release checks делим на пять независимо повторяемых фаз. Каждая отдаёт структурированный JSON оркестрации, не только stderr:
- Trigger— merge PR, push tag или ночная сборка по расписанию; фиксирует
trigger_idи ветку - Freeze (заморозка окружения)— проверяет образ узла, версию Xcode,
openclaw.yamlregion и root кэша в - Build—
xcodebuild/fastlane; выдаёт .xcarchive и отчёт unit-тестов - Gate— пороги static analysis, покрытие, размер пакета WoW; блокирует downstream при fail
- Receipt— hash артефакта, node ID, длительность в webhook / read-only канал
Пример конфигурации оркестрации
Упрощённый пример: зарегистрировать выделенный узел Zutcloud как runner OpenClaw и внедрить метаданные при trigger (имена полей по вашему CI):
name: pre-release-mac on: push: tags: ['v*'] jobs: build-on-cloud-mac: runs-on: [self-hosted, macOS, zutcloud-ap-northeast] steps: - run: openclaw daemon health --json - run: | export OPENCLAW_NODE_ID="vn-apne1-m4-01" export ARTIFACT_ROOT="/Volumes/artifacts/ap-northeast-1" ./scripts/ci-build.sh - run: openclaw receipt publish \ --trigger-id "${{ github.run_id }}" \ --sha "${{ github.sha }}" \ --artifact-hash "$(shasum -a 256 dist/*.ipa)"
Три детали:health check на первом шаге, чтобы при падении daemon не гонять полчаса компиляции;явно export переменных окружения в shell-блоке, не полагаться на profile при SSH;receipt отдельным шагом, даже если upload TestFlight упал — доказательство «сборка успешна» сохраняется.
Выделенный узел: почему не shared runner
Shared Mac CI кажется дешёвым, для pre-release три минуса: неконтролируемый кэш, изоляция сертификатов, непредсказуемая очередь. Выделенный узел связывает DerivedData, кэш Pods и keychain подписи с одной физической машиной —детерминизм цепочкинамного выше «каждый раз случайная машина».
| Измерение | Shared runner | Zutcloud выделенный + OpenClaw |
|---|---|---|
| Кэш | Стирается после job | Снимок тома, привязка к версии Xcode |
| Сертификат | Риск multi-tenant | Single-tenant keychain, offline-машина подписи |
| Аудит | Логи разрознены | триггер → узел → строка артефакта до конца |
| очередь | Пик может быть ежечасным | Эксклюзивная вычислительная мощность, ночное строительство может быть зарезервировано. |
Квитанции о возврате и возможность проверки
«Auditable» — это не хранение огромного архива журналов, а ответы на пять вопросов для каждого выпуска:
- Кто это спровоцировал? (автор пиара/тег/плановое задание)
- На каком узле и в каком районе он был скомпилирован? (
node_id+region) - Что использовать Xcode с кэшированными снимками? (Версия образа + корневой путь к кэшу)
- Что такое хэш артефакта? (воспроизводимость IPA/dSYM)
- Какой этап провалился? (заморозить/создать/закрыть/загрузить)
Мы передаем квитанции в канал команды Slack только для чтения (или его эквивалент), и формат фиксируется как однострочная ссылка JSON «Сводка + подробности». QA больше не нужно спрашивать: «Что это за сборка?» — в сообщении номер сборки, коммит и хэш уже выровнены.
{
"trigger_id": "gh-1849201",
"sha": "a1b2c3d",
"node_id": "vn-apne1-m4-01",
"region": "ap-northeast-1",
"xcode": "16.2",
"stages": {
"freeze": "ok",
"build": "ok",
"gate": "ok",
"receipt": "ok"
},
"artifact_sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
}
Предложения по прогрессивной реализации
Нет необходимости закрывать все местные архивы в первую неделю. Более безопасный путь:
Неделя 2: открыть этап шлюза и заблокировать слияние, если тест не пройден.
Неделя 3: релизы тегов проходят полную пятиэтапную цепочку; локальный архив становится путем исключения.
СотрудничатьРуководство по выбору зоны и дискаСовместное использование: метаданные узла объединяются в пары в первую неделю, и не будет никакой переработки «ссылка подключена, но путь к продукту неправильный», когда версия будет вырезана на третьей неделе.
Что делать, если вы терпите неудачу
Ценность автоматических ссылок наполовину заключается в успехе, наполовину вНеисправность может быть локализована. Мы поддерживаем простую схему:
- заморозить не удалось— Смещение изображения или openclaw.yaml не соответствует узлу → заморозить узел и выполнить откат тега изображения.
- сборка не удалась— Проблемы с кодом или зависимостями → НИОКР и исправление кода, независимо от инфраструктуры.
- ворота не удалось— Регрессия объема покрытия или пакета → блокировка выпуска, необходимо явно исключить утверждение
- получение не удалось— Сборка прошла успешно, но уведомление/загрузка не удалась → Вы можете повторно запустить этап получения без необходимости его полного перепрограммирования.
После разделения этапов стоимость «перезапуска» снижается с часа полной компиляции до нескольких минут получения или повторной попытки — это реальное время, сэкономленное уровнем оркестрации.
Запустите всю ссылку на Mac в облаке
Демон OpenClaw, сценарии проверки работоспособности и конвейера могут выполняться без присмотра 7×24 на Zutcloud Mac mini M4. Потребляемая мощность в режиме ожидания около 4 Вт подходит для использования в качестве резидентного узла CI; исключительная вычислительная мощность позволяет DerivedData однозначно соответствовать политикам сертификатов и конфигурациям уровня оркестрации.
Когда вы измените проверку перед выпуском с «кнопки, нажатой человеком» на «получение при срабатывании», групповое обсуждение перейдет от «в чьей среде есть проблема» к «какое правило доступа необходимо отрегулировать» — это уверенность, которую должен принести облачный Mac.
Готовы создать первую ссылку на предварительную версию?Начните с эксклюзивного узла для Азиатско-Тихоокеанского региона или Запада США + создайте cron в одночасье.——Смотреть тарифы Mac cloud, запустите OpenClaw на стационарном оборудовании.