Skip to content
Apothem
Руководства по эксплуатации

Церемония слияния PR для единственного сопровождающего

Церемония для самостоятельного слияния pull request'ов, когда правила защиты ветки и enforce_admins иначе заблокировали бы единственного сопровождающего.

Канонический справочник по самостоятельному слиянию PR при инварианте защиты ветки проекта. Когда сопровождающий — единственный участник с правом записи, правила защиты ветки GitHub enforce_admins=true + required_approving_review_count=1 создают взаимоблокировку самослияния, разрешение которой документирует эта страница.


1. Взаимоблокировка

Ветка main репозитория несёт следующий набор защиты:

  • required_pull_request_reviews.required_approving_review_count: 1
  • enforce_admins: true

Эти правила корректны для сценариев с несколькими сопровождающими (каждое изменение попадает в main через PR, прошедший рецензирование коллегой; администраторы не освобождаются). Для единственного сопровождающего они создают взаимоблокировку: политика GitHub запрещает самостоятельное одобрение PR, который вы сами создали, а enforce_admins=true блокирует переопределение требования одобрения проверки через gh pr merge --admin.

Существует три пути разрешения:

ПутьКогда использовать
Церемония временного переключения (каноническая для этого репозитория)По умолчанию для самослияний единственного сопровождающего; сохраняет инвариант защиты за пределами окна слияния
Завести идентичность CI-бота с правом записиПрименять только при неминуемом подключении нескольких сопровождающих; одобрение ботом подрывает заложенное в защите намерение человеческой проверки
Постоянно установить required_approving_review_count: 0Применять только если репозиторий бессрочно останется с единственным сопровождающим; обращает вспять намерение защиты в части проверки

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

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 сохраняется на всём протяжении. required_status_checks не затрагивается переключением; слияние по-прежнему требует, чтобы настроенные контексты проверок статуса были зелёными.
  • След аудита виден. Аннотация gh pr merge --admin появляется в метаданных слияния PR; переключения API защиты появляются в журнале аудита репозитория под идентичностью сопровождающего.

4. Когда НЕ следует использовать церемонию

Церемония предназначена для самослияния собственных 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 --merges --first-parent перечисляет каждый squash-merge-коммит в main с соответствующим номером PR в теме коммита (суффикс (#<pr-number>) согласно умолчанию gh pr merge --squash), позволяя оператору проследить любое прошлое приземление вплоть до его PR и вызова церемонии.

Когда точкой входа служит scripts/dev/admin_merge.py, его неинтерактивный журнал (stdout) последовательно называет три вызова API защиты и вызов API слияния; направление обёртки через канал в tee фиксирует фрагмент аудита для каждого запуска, не завися от удержания журнала на стороне GitHub.

On this page