Обновление macOS 26.6 для CI не следует включать одновременно на всём пуле: сначала проверьте требования Xcode 27 на пилотном узле, затем выполните drain, поэтапную установку, контролируемый перезапуск и реальную сборку. Для подписывающих узлов оставьте незатронутый контур или заранее проверенный резервный удалённый Mac.
Этот материал для вас, если вы управляете постоянно работающими Mac CI-узлами, планируете окно обслуживания macOS 26.6 или переводите производственные задачи на Xcode 27. Он также пригодится ответственным за FileVault, обновления Apple Silicon, удалённое восстановление и резервную ёмкость.
Последнее обновление: 18 сентября 2026 года. Версии и порядок авторизации сверены по документации Apple Developer и Apple Platform Deployment; конкретные возможности вашей MDM-платформы необходимо подтвердить отдельно.
01 Граница совместимости Xcode 27 и macOS 26.6
Первое решение принимает не политика обновлений, а цепочка инструментов. Сверьте текущую версию macOS каждого пула с официальной таблицей системных требований Xcode. Если Xcode 27 требует macOS 26.6 для нового производственного контура, соответствующие узлы включайте в отдельный пул миграции. Старые узлы, на которых ещё разрешены прежние версии Xcode, не нужно обновлять только ради единообразия.
Разделите три разных события:
| Событие | Что меняется | Базовое решение для Mac CI |
|---|---|---|
| Фоновое исправление безопасности | Обновляются отдельные защитные компоненты или системные данные | Разрешать только после проверки поведения Runner и требований к перезапуску |
| Обновление в пределах текущей версии macOS | Меняются системные компоненты, службы и иногда инструменты разработчика | Выполнять по пулу, после drain и в заданное окно |
| Переход на новую основную версию | Меняется совместимость ОС, Xcode, SDK и зависимостей | Проводить как отдельный проект с пилотом и планом отката |
Официальная документация описывает разные классы обновлений и способы их применения на управляемых устройствах. Не переносите поведение одной политики на другую: обзор программных обновлений не является подтверждением того, что ваш Runner корректно переживёт перезапуск.
Проверьте перед запуском:
- текущую версию macOS и целевую версию;
- установленный путь Xcode и активный developer directory;
- список разрешённых SDK и зависимостей;
- тип заданий: Pull Request, nightly, архивирование или релиз;
- наличие чистого узла, на котором можно повторить сборку;
- возможность запретить автоматическую установку на подписывающих машинах.
Если конкретный проект ещё не готов к Xcode 27, оставьте его на прежнем совместимом пуле. Если системное обновление необходимо для устранения критического риска, не смешивайте этот случай с плановой миграцией инструментов.
02 Пул ежедневных сборок
Обычный PR-пул легче обслуживать, чем контур релизной подписи, но он тоже не должен обновляться «на лету». Автоматическое обновление может инициировать перезапуск в момент, когда Runner сообщил о доступности, но процесс сборки ещё работает. Статус хоста и состояние Job — разные сигналы.
Правильная последовательность выглядит так:
- Создайте список узлов, разрешённых для первой волны. Не выбирайте весь пул.
- Установите для этих машин метку обслуживания или исключите их из маршрутизации.
- Переведите Runner в drain. Новые задания должны уходить на незатронутые узлы.
- Дождитесь завершения активных Job и проверьте пустую очередь на конкретной машине.
- Зафиксируйте версии macOS, Xcode, зависимостей и состояние агента.
- Установите обновление через утверждённый канал управления.
- После перезапуска проверьте доступность хоста и запуск Runner.
- Проверьте активный путь Xcode и разрешение зависимостей.
- Запустите чистую сборку из настоящего репозитория.
- Снимите результат, логи, версии и решение о переходе к следующей волне.
Минимальный набор статусов для журнала:
| Проверка | До обновления | После обновления | Условие продолжения |
|---|---|---|---|
| Хост доступен | Зафиксирован | Проверен после перезапуска | Удалённый канал работает |
| Runner | Принимает drain | Запущен и зарегистрирован | Новые задания маршрутизируются корректно |
| Xcode | Путь и версия записаны | Путь и версия подтверждены | Используется ожидаемый toolchain |
| Сборка | Базовый результат сохранён | Выполнена чистая сборка | Нет необъяснимого расхождения |
| Очередь | Размер и лимит записаны | Проверен перенос заданий | Ожидание не превысило внутренний предел |
Не принимайте узел обратно только потому, что он отвечает по SSH или отображается в консоли управления. Для CI важны минимум четыре уровня: хост онлайн, Runner онлайн, Xcode вызывается и сборка завершается. Каждый следующий уровень должен быть отдельной отметкой.
Для проектов, где требуется раздельное обслуживание нескольких версий Xcode 27, полезно заранее оформить схему пулов Mac CI с несколькими версиями Xcode. В ней должны быть не только теги, но и правила выбора SDK, ограничения на подпись и понятный маршрут отката.
03 Контур подписи и публикации
Подписывающий узел нельзя обслуживать с той же частотой и по тому же сигналу, что и PR-машины. Здесь ошибка проявляется позже: архив может создаться, но подпись, загрузка или запись аудита завершатся неудачей после возвращения узла в работу.
Перед окном обслуживания:
- заморозьте релизные задания и ручные публикации;
- проверьте границу между рабочим и резервным узлом;
- убедитесь, что Keychain доступен в ожидаемом пользовательском контексте;
- проверьте сертификаты и закрытые ключи;
- подтвердите наличие учётных данных для App Store Connect;
- сохраните идентификатор сборки и артефакты до обновления;
- назначьте человека, который принимает решение о возврате узла.
После перезапуска приёмка должна включать:
- создание архива;
- выполнение кода подписи;
- проверку профиля и сертификата;
- загрузку тестового или разрешённого артефакта;
- проверку журнала действий;
- подтверждение, что секреты не были выведены в лог;
- повторное включение релизной очереди только после всех проверок.
| Тип узла | Допустимое действие во время обслуживания | Что считается восстановлением |
|---|---|---|
| PR-сборки | Перенаправить задания на незатронутый пул | Чистая сборка и корректная регистрация Runner |
| Ночные сборки | Перенести окно или изменить маршрут | Прохождение полного сценария зависимостей |
| Архивирование | Заморозить задания | Создание проверяемого архива |
| Подпись и публикация | Использовать отдельный резервный контур | Архив, подпись, загрузка и аудит |
| Общий релизный узел | Не обновлять одновременно с резервом | Успешная контрольная публикация |
Не удаляйте старый узел и не очищайте Keychain до завершения контрольной публикации. Резервный узел без заранее проверенного доступа к ключам — это только свободное железо, а не готовая замена.
04 Безоператорный Apple Silicon
Для Apple Silicon основная опасность — не сам факт перезапуска, а отсутствие подтверждённого пути возврата без человека у стойки. В управляемой среде нужно проверить bootstrap token, secure token и владельца тома. Документация объясняет их роль в авторизации программных обновлений, но не гарантирует, что конкретная система управления корректно передаст команду, дождётся перезапуска и вернёт точный статус.
Изучите требования к авторизации в документации по bootstrap token. Отдельно проверьте, как ваша платформа обрабатывает:
- FileVault и разблокировку тома после перезапуска;
- владельца тома на конкретном Apple Silicon Mac;
- активную или отсутствующую пользовательскую сессию;
- автоматический запуск CI-агента;
- удалённый доступ по SSH или VNC;
- отчёт об успешном завершении обновления;
- повторную постановку узла в очередь.
Предупреждение: наличие bootstrap token в инвентаризации не доказывает, что безоператорский сценарий пройдёт от установки до первой реальной сборки. Проверяйте весь путь на узле, который можно безопасно вывести из производства.
Проведите контролируемую репетицию. Сначала исключите машину из планировщика. Затем сохраните журналы, выполните перезапуск по утверждённой политике и проверьте, что никто не должен вводить пароль локально. После загрузки проверьте FileVault, удалённый канал, агент, доступ к Keychain и тестовую сборку.
Документируйте приёмку безоператорного перезапуска Mac CI как отдельный внутренний протокол. Результаты конкретной платформы управления всё равно должны быть подтверждены вашими журналами, а не только наличием токенов в инвентаризации.
05 Межрегиональные пулы и резервная ёмкость
В распределённой инфраструктуре нельзя ориентироваться только на локальное время одной команды. Одновременная политика установки может затронуть несколько зон, если расписание задано централизованно. Разделите топологию на пул одного помещения, межрегиональный пул и узлы общей подписи.
Маршрутизацию задайте через метки и очереди:
maintenance-ready— машина прошла приёмку и может получать обычные задания;draining— новые задания запрещены, текущие завершаются;xcode-27— узел принадлежит проверенному toolchain-пулу;signing-isolated— машина не принимает обычные PR-задачи;rollback-ready— узел сохранён для возврата проекта или релиза.
Запас ёмкости считайте от фактической очереди, а не от общего числа Mac. Зафиксируйте максимальное приемлемое ожидание для каждой категории заданий, длительность типичного Job по журналам и число узлов, которые одновременно будут выведены. Если расчёт не подтверждён, не объявляйте резерв «достаточным» только потому, что в консоли есть свободные машины.
| Топология | Риск при одновременном обновлении | Предпочтительная схема |
|---|---|---|
| Один пул в одном помещении | Очередь полностью зависит от оставшихся узлов | Маленькая пилотная волна и drain по узлам |
| Несколько регионов | Единая политика может совпасть по времени | Разные окна и независимые маршруты |
| Общий подписывающий узел | Сбой блокирует публикацию | Незатронутый резерв или временный удалённый Mac |
| Небольшой пул без резерва | Нет безопасного места для проверки | Сначала создать внешний пилотный контур |
| Пул с разными Xcode | Неверный toolchain может принять задание | Жёсткие теги и правила очереди |
Если собственного резерва нет, перед окном обслуживания закажите временный удалённый Mac для PoC и проверки восстановления. На нём нужно прогнать тот же репозиторий, зависимости и сценарий подписи, если это допускается вашей политикой секретов. Не переводите на него весь продакшен, пока не подтверждены подключение, права, журналирование и границы хранения данных.
06 Экстренное исправление и решение по риску
Не каждое исправление безопасности требует немедленного обновления всего пула. Решение принимайте по четырём осям:
- Риск безопасности. Какой актив закрывает исправление и есть ли подтверждённая эксплуатация?
- Производственное влияние. Какие очереди и релизные окна будут затронуты?
- Совместимость toolchain. Подтверждены ли Xcode, SDK, зависимости и агенты?
- Обратимость. Есть ли рабочий незатронутый узел и доказанный способ вернуть задания?
| Условие | Действие |
|---|---|
| Пилотная сборка успешна, подпись подтверждена, резерв доступен | Начать поэтапное расширение |
| Обновление закрывает существенный риск, но пилот ещё не завершён | Обновить изолированный пилот, не трогать весь пул |
| После обновления Runner работает, но чистая сборка не проходит | Остановить волну и вернуть задания на незатронутые узлы |
| FileVault или удалённое восстановление требуют локального ввода | Не обновлять без оператора; подготовить другой сценарий |
| Релизное окно уже открыто, резерв не проверен | Отложить плановое обновление или использовать проверенный временный Mac |
| Не хватает ёмкости после drain | Не расширять волну; поднять лимит очереди только после согласования |
Описывайте решение в журнале изменения: причина, затронутые метки, версии до и после, состояние очереди, результат первой сборки, результат подписи и лицо, разрешившее следующую волну. Такая запись нужна не только для аудита. Она позволяет отличить системную проблему от случайной ошибки проекта.
Документация по принудительному перезапуску и управлению обновлениями должна читаться вместе с фактическими возможностями вашей платформы. Также проверьте описание декларативных конфигураций обновлений: наличие поддерживаемого механизма не означает, что выбранная политика безопасна для общего производственного пула.
07 Контрольный список перед окном
Отметьте пункты до того, как разрешить первую установку:
- [ ] Системные требования Xcode 27 сверены с каждой группой узлов.
- [ ] Пулы PR, ночных сборок и подписи разделены.
- [ ] Для пилота назначены конкретные узлы и метки.
- [ ] Runner умеет переходить в drain.
- [ ] Активные Job и очередь проверяются отдельно.
- [ ] FileVault и удалённая разблокировка проверены на Apple Silicon.
- [ ] Bootstrap token, secure token и владелец тома подтверждены.
- [ ] После перезапуска агент запускается без ручного входа.
- [ ] Есть чистая сборка из рабочего репозитория.
- [ ] Для релизного узла проверены архив, подпись, загрузка и аудит.
- [ ] Определён лимит ожидания очереди.
- [ ] Проверен незатронутый узел для отката.
- [ ] В журнале есть версии, время, логи и решение об расширении волны.
- [ ] Временный удалённый Mac подготовлен, если собственного резерва недостаточно.
Правило выбора простое:
- если Xcode 27 требует целевую версию macOS, пилот прошёл, drain подтверждён, удалённое восстановление проверено и есть незатронутый маршрут — выбирайте поэтапное обновление;
- если хотя бы один из этих пунктов не подтверждён — оставьте текущий пул без изменений и создайте отдельный пилот;
- если подпись или публикация не имеют проверенного резерва — не совмещайте их обслуживание с обновлением PR-пула;
- если резервной ёмкости нет совсем — сначала используйте временный удалённый Mac, а затем планируйте основную волну.
Собственная покупка Mac даёт физический контроль, но для разового окна обслуживания она одновременно требует заранее оплаченного резерва, помещения, удалённого управления и проверки восстановления после перезапуска. Облачный общий исполнитель может добавить непредсказуемую очередь и ограничения на секреты. Если вам нужно только пережить миграцию, проверить Xcode 27 или получить временный узел для отката, аренда Mac через CALMVPS обычно проще как операционная мера: можно выделить отдельную машину на нужный срок, прогнать тот же сценарий и не превращать кратковременную потребность в постоянный парк.
Перед заказом проверьте, что проект допускает удалённое выполнение, а секреты и требования к физическим интерфейсам совместимы с таким размещением. Начните с ограниченного теста на странице вариантов аренды Mac для вашей команды, зафиксируйте результаты приёмки и только после этого решайте, нужен ли вам постоянный узел или временная ёмкость на период обновления.