2026 Общие удалённые Mac для GitHub Actions:
Merge Queue и лейблы runner, чтобы проверки merge не голодали

Две очереди · Маршрутизация лейблов · Concurrency · Наблюдаемость полосы merge

2026 GitHub Merge Queue и удалённый self-hosted runner на Mac

Запуская self-hosted runner на нескольких арендованных удалённых Mac, часто ошибаются, думая, что Merge Queue распределяет машинную очередь: очередь GitHub управляет порядком и защитными воротами в ветку по умолчанию, но backlog runner по-прежнему задают лейблы и группы concurrency. Статья разделяет две очереди таблицей контрольной плоскости, рекомендует маршрут ci-pr / ci-merge / ci-release, правила concurrency и cancel-in-progress, критерии p95 для добавления Mac или настройки GitHub; ссылки на общий пул сборки, мьютекс мест и оркестрацию Mac Mesh.

01

Две очереди и шесть болей: почему голодание merge остаётся при включённой Merge Queue

Merge Queue защищает целостность ветки по умолчанию: батчирует проверки перед интеграцией; она не гарантирует свободные CPU на удалённых Mac runner. Если PR и merge делят одни runs-on лейблы, GitHub может двигать слияния, пока runner занят опциональными PR.

  1. 01

    Путаница очередей: \"Queued\" в Actions принимают за автоматический приоритет merge-джобов.

  2. 02

    Смешение лейблов: размытый ci сваливает nightly, PR и merge на одни runner.

  3. 03

    Плохие отмены: тот же cancel-in-progress: true на полосе merge, что и у PR, рвёт батчи.

  4. 04

    Коллизии concurrency: несколько репо делят одну строку concurrency и гасят друг друга.

  5. 05

    Слабая наблюдаемость: не разделяют ожидание merge queue и занятость runner.

  6. 06

    Расхождение с mesh lease: полосе merge нужна стабильная занятость узла без порогов аренды.

Подсказка: если вы всё ещё сравниваете ноутбук и удалённый ролью, а не CI-плоскостью, сначала прочитайте лёгкое локальное редактирование и тяжёлые удалённые сборки.

02

Разделение контрольной плоскости и лейблов: когда нужна полоса ci-merge

Таблица ниже для ревью: делать оба имеет смысл только при честной ёмкости runner, а не театре лейблов.

ПлоскостьGitHub Merge QueueBacklog runner (машинная очередь)
Отвечает заПорядок в default branch, батчи merge, семантику required checksКакой Mac когда выполняет какой workflow job
Не отвечает заСколько ядер M4 свободноДолжен ли PR логически обойти очередь
Типичный сбойБатчи таймаутятся при верной логике, но нехватке CPUMerge job днями в очереди при короткой merge queue
Первый шагУжать required checks и допущения батчейРазделить runs-on, добавить runner или резерв мест

Гладкость merge зависит от честно зарезервированной ёмкости runner для merge, а не от одного тумблера Merge Queue.

Рекомендуемый шаблон лейблов (подставьте свои краткие имена)

  • Шум PR: self-hosted + macOS + ci-pr + закрепление тулчейна (например xcode-16-2).
  • Полоса merge: те же пины плюс честный суффикс ёмкости ci-merge на минимум одном удалённом Mac runner.
  • Релиз: ci-release отдельно от merge, чтобы гигантские релизные джобы не голодали trunk.
03

Шестишаговый runbook: закрепить полосу merge в YAML, а не в Slack

Шаги сочетаются с SSH-гайдом общего пула: там — достижимость runner, здесь — кто владеет какой временной шкалой CPU.

  1. 01

    Инвентаризация required checks: что реально блокирует default branch, длительности, что можно поднять в PR.

  2. 02

    Разделить runs-on: merge-only workflow или job получают ci-merge; одна машина может иметь много лейблов, но нужны слоты или выделенные узлы.

  3. 03

    Проверить concurrency: PR с cancel-in-progress: true; merge/release с cancel-in-progress: false или более узкими ключами групп.

  4. 04

    Именовать группы concurrency: репозиторий, workflow и суффикс среды.

  5. 05

    Инструментировать: на доске раздельно ожидание merge queue и busy minutes runner.

  6. 06

    Разбор ворот: дважды в неделю короткая очередь, но merge job висит — сначала топология runner, потом параллелизм GitHub.

yaml
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  merge-gate:
    runs-on: [self-hosted, macOS, ci-merge, xcode-16-2]
    timeout-minutes: 45
    steps:
      - run: echo "merge lane only"
04

Сигналы и критерии: сначала Mac или настройки GitHub

Шаблоны из типичных постмортемов; подставьте свои пороги. Не смешивайте оба ожидания на одном графике.

СигналВероятная причинаПервый ход
Длинная merge queue, простаивающие runnerСлишком жёсткие required checks или батч-политикаПересмотреть граф checks и допущения параллелизма
Короткая очередь, merge job долго в queueМаршрут лейблов или мало runnerРазделить ci-merge, добавить узлы или места
Батчи падают как инфраТаймауты, диск, связка ключей, сетьСверить логи runner с чеклистом управления подписями
Быстрые PR, медленные mergePR и merge делят лейблыРазделить runs-on, урезать опциональные PR jobs

Внимание: более быстрые машины без разделения лейблов часто отодвигают голодание на ночи релиза; долгосрочно нужны отдельные имена ёмкости.

05

Опорные метрики и ограждения (инженерный разбор)

Диапазоны — типичные опоры для распределённых команд; привяжите SQL или поля API к внутреннему runbook.

  • Ожидание в очереди merge job: если P95 > 20 минут в течение двух релизных недель при глубине merge queue ниже 3 — сначала честность лейблов runner.
  • Вытеснение PR: опциональные workflow на runner с ci-merge и busy минут > 85 % в рабочее время — nightly в пул ci-pr.
  • Шторма отмен: больше одной отменённой merge-проверки в неделю — аудит общей с PR политики concurrency.
Размер командыЧастота merge trunkПервый ход
МалаяНесколько раз в деньВыделенный ci-merge runner + жёсткие required checks
СредняяНепрерывные батчиМультирегион runner + явный release pool
ПлатформаОбщий пул на много репоОрг-стандарт лейблов + cost board queue vs runner

Ноутбук как временный runner даёт сон, термику и слабо аудируемый интерактивный вход; своя стойка Mac — закупка и кабель. Оба плохо для договорного merge SLO.

Для пулов удалённых Mac, где iOS CI/CD и длинные задачи AI-агентов сосуществуют, облачная аренда Mac Mini VpsMesh обычно лучше: масштабируйте флот по региону и SKU, разнесите merge, release и шум на именованные узлы, закрепляйте доступность и политику мест в договоре, а не в чате.

FAQ

Часто задаваемые вопросы

Не обязательно отдельный физический корпус, но нужно честно разделить лейблы и параллелизм, иначе PR-шум голодает merge-проверки. Надёжнее привязать ci-merge к фиксированным местам или узлам. Масштаб: страница цен и страница оформления заказа.

Push PR естественно устаревают проверки; повторная отмена merge-батчей увеличивает риск «уже влито, но автоматика не замкнулась». Фиксируйте политику в YAML и ведите runbook из центра помощи.

Сначала общий пул сборки для SSH и регистрации runner, затем эта статья для полосы merge; детали блокировок мест в статье про mutex TTL.