Церемония слияния PR для единственного сопровождающего
Когда сопровождающий может напрямую слить собственный pull request, и церемония для защиты ветки, которая требует одобрения и применяет это требование к администраторам.
Канонический справочник по самостоятельному слиянию PR при защите ветки проекта. Действующая защита
mainтребует 0 одобряющих рецензий и оставляетenforce_adminsвыключенным, как записано на странице Защита веток. Поэтому сопровождающий сливает собственный pull request напрямую. Церемония временного переключения на этой странице применяется только тогда, когда защита требует одобрения и применяет это требование к администраторам.
1. Взаимоблокировка
Действующая защита main содержит:
required_pull_request_reviews.required_approving_review_count: 0enforce_admins: false
При этих настройках взаимоблокировки нет. Pull request сопровождающего сливается с помощью gh pr merge <pr-number> --squash --delete-branch, как только его обязательные проверки статуса зелёные, а его обсуждения рецензии разрешены.
Взаимоблокировка существует только тогда, когда защита содержит обе следующие более строгие настройки:
required_pull_request_reviews.required_approving_review_count: 1enforce_admins: true
Эти правила корректны для сценариев с несколькими сопровождающими (каждое изменение попадает в main через PR, прошедший рецензирование коллегой; администраторы не освобождаются). Для единственного сопровождающего они создают взаимоблокировку: политика GitHub запрещает самостоятельное одобрение PR, автором которого являетесь вы, а enforce_admins=true блокирует переопределение требования одобрения рецензии через gh pr merge --admin. При enforce_admins: false флаг --admin обходит требование одобрения, и переключение не нужно, но он также обходит красные обязательные проверки, поэтому перед его использованием убедитесь, что они зелёные.
Существует три пути разрешения:
| Путь | Когда использовать |
|---|---|
Постоянно установить required_approving_review_count: 0 (действующая настройка) | Применять, только если репозиторий бессрочно останется с единственным сопровождающим; обращает вспять заложенное в защите намерение рецензирования |
| Церемония временного переключения | Самослияния единственного сопровождающего, пока защита требует одобрения при enforce_admins=true; сохраняет инвариант защиты за пределами окна слияния |
| Завести идентичность CI-бота с правом записи | Применять, только если подключение нескольких сопровождающих неминуемо; одобрение ботом подрывает заложенное в защите намерение рецензирования человеком |
Этот репозиторий в настоящее время использует путь постоянного нулевого числа одобрений. Церемония временного переключения — канонический путь всякий раз, когда защита требует одобрения и применяет это требование к администраторам.
2. Церемония временного переключения
Инвариант церемонии: состояние защиты в начале церемонии равно состоянию защиты в конце. Послабление существует только внутри окна слияния.
Ручная форма:
# 1. Open the PR, push branch, wait for CI green.
gh pr create --base main --head <feature-branch> --title "..." --body "..."
gh pr checks <pr-number> # poll until all green
# 2. Relax approver-count to 0.
gh api repos/<owner>/<repo>/branches/main/protection/required_pull_request_reviews \
-X PATCH -F required_approving_review_count=0
# 3. Squash-merge with admin override (admin override now succeeds because the
# review-approval requirement is the only block enforce_admins refuses).
gh pr merge <pr-number> --squash --delete-branch --admin
# 4. Restore approver-count to 1.
gh api repos/<owner>/<repo>/branches/main/protection/required_pull_request_reviews \
-X PATCH -F required_approving_review_count=1Обёрнутая форма: см. scripts/dev/admin_merge.py — атомарную Python-обёртку, которая выполняет шаги 2 → 3 → 4 в единой неинтерактивной последовательности с безопасным откатом через try / finally при сбое шага 3.
python scripts/dev/admin_merge.py <pr-number>3. Инварианты
- Окно переключения минимизировано. Шаги 2 → 3 → 4 выполняются в единой неинтерактивной последовательности. Защита находится в ослабленном состоянии только на время вызова API слияния — менее секунды при каждом наблюдавшемся запуске.
- Восстановление безусловно. Шаг 4 выполняется, даже когда шаг 3 даёт сбой (блок
try/finallyобёртки гарантирует восстановление на любом пути выхода). Неудачная попытка слияния не оставляет защиту ослабленной. - Контроль через CI сохраняется на всём протяжении, пока
enforce_adminsвключён. Переключение не затрагиваетrequired_status_checks; приenforce_admins: trueслияние по-прежнему требует, чтобы настроенные контексты проверок статуса были зелёными. Приenforce_admins: falseслияние с--adminна шаге 3 также обходит красные обязательные проверки, поэтому не запускайте церемонию в этом состоянии. - След аудита виден. Аннотация
gh pr merge --adminпоявляется в метаданных слияния PR; переключения через API защиты появляются в журнале аудита репозитория под идентичностью сопровождающего.
4. Когда НЕ следует использовать церемонию
Пока защита требует 0 одобряющих рецензий или оставляет enforce_admins выключенным, церемония не нужна: сливайте напрямую, как описано в разделе 1.
Церемония предназначена для самослияния собственных PR сопровождающего. Когда доступен рецензент-коллега (участник с правом записи), правильным является стандартный путь gh pr review --approve + gh pr merge --squash --delete-branch, и церемония не нужна.
Если в репозиторий приходит второй сопровождающий, выведите церемонию из обращения: стандартный поток рецензирования PR восстанавливает заложенное в защите намерение рецензирования человеком без какого-либо переключения.
5. Аудит прошлого запуска
Каждый вызов церемонии оставляет след на трёх долговременных поверхностях, которые оператор может проверить постфактум:
- Метаданные слияния PR.
gh pr view <pr-number> --json mergedBy,mergedAt,mergeCommitвозвращает субъекта слияния, временную метку слияния и SHA squash-коммита. СубъектmergedByсовпадает с идентичностью сопровождающего, выполнившего шаг 3. - Журнал аудита репозитория.
gh api /repos/<owner>/<repo>/actions/runs --jq '.workflow_runs[] | select(.event=="push")'сопоставляет запуск CI после слияния с коммитом слияния; журнал аудита правил защиты репозитория (историяgh api /repos/<owner>/<repo>/branches/main/protectionчерез интерфейс Settings → Branches) показывает переключения шага 2 и шага 4, обрамляющие окно слияния. - История git сопровождающего.
git log main --first-parent --onelineперечисляет каждый коммит squash-слияния вmainс соответствующим номером PR в теме коммита (суффикс(#<pr-number>)по умолчанию уgh pr merge --squash), позволяя оператору проследить любое прошлое слияние до его PR и вызова церемонии.
Когда точкой входа служит scripts/dev/admin_merge.py, его неинтерактивный журнал (stderr) по порядку называет три вызова API защиты и вызов API слияния; перенаправление его stderr в tee (2>&1 | tee) сохраняет фрагмент аудита для каждого запуска, не завися от срока хранения журналов на стороне GitHub.
Контрольный список проверки межмашинной синхронизации
Процедура проверки, подтверждающая, что адаптер Claude Code корректно устанавливается, валидируется и удаляется на новом хосте, с полными проверками переносимости.
Примеры
Примеры Apothem — проработанные сквозные пошаговые разборы создания адаптеров, правил, хуков и наборов планов.