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

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

Когда сопровождающий может напрямую слить собственный pull request, и церемония для защиты ветки, которая требует одобрения и применяет это требование к администраторам.

Канонический справочник по самостоятельному слиянию PR при защите ветки проекта. Действующая защита main требует 0 одобряющих рецензий и оставляет enforce_admins выключенным, как записано на странице Защита веток. Поэтому сопровождающий сливает собственный pull request напрямую. Церемония временного переключения на этой странице применяется только тогда, когда защита требует одобрения и применяет это требование к администраторам.


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

Действующая защита main содержит:

  • required_pull_request_reviews.required_approving_review_count: 0
  • enforce_admins: false

При этих настройках взаимоблокировки нет. Pull request сопровождающего сливается с помощью gh pr merge <pr-number> --squash --delete-branch, как только его обязательные проверки статуса зелёные, а его обсуждения рецензии разрешены.

Взаимоблокировка существует только тогда, когда защита содержит обе следующие более строгие настройки:

  • required_pull_request_reviews.required_approving_review_count: 1
  • enforce_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.

On this page