Skip to content
Apothem
Runbooks

PR-Merge-Zeremonie für Solo-Maintainer

Wann der Maintainer seinen eigenen Pull Request direkt mergen kann, und die Zeremonie für einen Branch-Schutz, der eine Genehmigung verlangt und sie für Administratoren durchsetzt.

Kanonische Referenz für das Selbst-Mergen von PRs unter dem Branch-Schutz des Projekts. Der aktuell geltende Schutz auf main verlangt 0 genehmigende Reviews und lässt enforce_admins ausgeschaltet, wie auf der Seite Branch-Schutz festgehalten. Der Maintainer mergt seinen eigenen Pull Request daher direkt. Die temporäre Umschalt-Zeremonie auf dieser Seite gilt nur, wenn der Schutz eine Genehmigung verlangt und sie für Administratoren durchsetzt.


1. Die Sperre

Der aktuell geltende Schutz von main enthält:

  • required_pull_request_reviews.required_approving_review_count: 0
  • enforce_admins: false

Unter diesen Einstellungen gibt es keine Sperre. Ein Pull Request des Maintainers wird mit gh pr merge <pr-number> --squash --delete-branch gemergt, sobald seine erforderlichen Statusprüfungen grün und seine Review-Konversationen aufgelöst sind.

Eine Sperre besteht nur, wenn der Schutz beide dieser strengeren Einstellungen enthält:

  • required_pull_request_reviews.required_approving_review_count: 1
  • enforce_admins: true

Diese Regeln sind für Szenarien mit mehreren Maintainern korrekt (jede Änderung erreicht main über einen von Kollegen geprüften PR; Administratoren sind nicht ausgenommen). Für Solo-Maintainer erzeugen sie eine Sperre: GitHubs Richtlinie verbietet die Selbstgenehmigung eines PR, den Sie selbst erstellt haben, und enforce_admins=true blockiert die gh pr merge --admin-Überschreibung der Anforderung einer Review-Genehmigung. Mit enforce_admins: false umgeht --admin die Genehmigungsanforderung, und es ist kein Umschalten nötig, aber es umgeht auch rote erforderliche Prüfungen; bestätigen Sie daher, dass sie grün sind, bevor Sie es verwenden.

Es gibt drei Auflösungspfade:

PfadWann zu verwenden
required_approving_review_count: 0 dauerhaft setzen (aktuelle Einstellung)Nur übernehmen, wenn das Repository auf unbestimmte Zeit ein Solo-Maintainer-Repository bleiben wird; kehrt die Review-Absicht des Schutzes um
Temporäre Umschalt-ZeremonieSelbst-Merges eines Solo-Maintainers, während der Schutz eine Genehmigung mit enforce_admins=true verlangt; bewahrt die Schutzinvariante außerhalb des Merge-Fensters
Eine CI-Bot-Identität mit Schreibzugriff bereitstellenNur übernehmen, wenn das Onboarding mehrerer Maintainer unmittelbar bevorsteht; eine Bot-Genehmigung untergräbt die Absicht der menschlichen Überprüfung, die der Schutz verfolgt

Dieses Repository verwendet derzeit den Pfad der dauerhaften Null-Genehmigung. Die temporäre Umschalt-Zeremonie ist der kanonische Pfad, wann immer der Schutz eine Genehmigung verlangt und sie für Administratoren durchsetzt.

2. Die temporäre Umschalt-Zeremonie

Die Invariante der Zeremonie: Der Schutzzustand zu Beginn der Zeremonie ist gleich dem Schutzzustand am Ende. Die Lockerung existiert nur innerhalb des Merge-Fensters.

Manuelle Form:

# 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

Gekapselte Form: Siehe scripts/dev/admin_merge.py für den atomaren Python-Wrapper, der die Schritte 2 → 3 → 4 in einer einzigen nicht-interaktiven Sequenz ausführt, mit try / finally-Rollback-Sicherheit bei einem Fehlschlag von Schritt 3.

python scripts/dev/admin_merge.py <pr-number>

3. Invarianten

  • Umschaltfenster minimiert. Die Schritte 2 → 3 → 4 werden in einer einzigen nicht-interaktiven Sequenz ausgeführt. Der Schutz befindet sich nur für die Dauer des Merge-API-Aufrufs im gelockerten Zustand — bei jedem beobachteten Lauf unter einer Sekunde.
  • Die Wiederherstellung ist bedingungslos. Schritt 4 läuft auch dann, wenn Schritt 3 fehlschlägt (die try / finally-Klausel des Wrappers stellt die Wiederherstellung auf jedem Ausstiegspfad sicher). Ein fehlgeschlagener Merge-Versuch hinterlässt den Schutz nicht im gelockerten Zustand.
  • CI-Gating bleibt durchgehend erhalten, solange enforce_admins eingeschaltet ist. required_status_checks ist vom Umschalten nicht betroffen; mit enforce_admins: true erfordert der Merge weiterhin, dass die konfigurierten Statusprüfungs-Kontexte grün sind. Mit enforce_admins: false umgeht der --admin-Merge in Schritt 3 auch rote erforderliche Prüfungen; führen Sie die Zeremonie in diesem Zustand daher nicht aus.
  • Audit-Spur sichtbar. Die gh pr merge --admin-Anmerkung erscheint in den Merge-Metadaten des PR; die Umschaltungen über die Schutz-API erscheinen im Audit-Log des Repositorys unter der Identität des Maintainers.

4. Wann die Zeremonie NICHT zu verwenden ist

Solange der Schutz 0 genehmigende Reviews verlangt oder enforce_admins ausgeschaltet lässt, ist die Zeremonie unnötig: Mergen Sie direkt, wie Abschnitt 1 beschreibt.

Die Zeremonie dient dem Selbst-Merge der eigenen PRs des Maintainers. Wenn ein Peer-Reviewer verfügbar ist (ein Mitwirkender mit Schreibzugriff), ist der Standardpfad gh pr review --approve + gh pr merge --squash --delete-branch korrekt und die Zeremonie unnötig.

Wenn das Repository einen zweiten Maintainer aufnimmt, stellen Sie die Zeremonie ein: Der Standard-PR-Review-Ablauf stellt die Absicht der menschlichen Überprüfung, die der Schutz verfolgt, ohne jegliches Umschalten wieder her.

5. Einen vergangenen Lauf prüfen

Jeder Aufruf der Zeremonie hinterlässt Spuren auf drei dauerhaften Oberflächen, die ein Operator im Nachhinein inspizieren kann:

  • Die Merge-Metadaten des PR. gh pr view <pr-number> --json mergedBy,mergedAt,mergeCommit liefert den Merge-Akteur, den Merge-Zeitstempel und den SHA des Squash-Commits. Der Akteur mergedBy stimmt mit der Maintainer-Identität überein, die Schritt 3 ausgeführt hat.
  • Das Audit-Log des Repositorys. gh api /repos/<owner>/<repo>/actions/runs --jq '.workflow_runs[] | select(.event=="push")' ordnet den CI-Lauf nach dem Merge dem Merge-Commit zu; das Audit-Log der Schutzregeln des Repositorys (der Verlauf von gh api /repos/<owner>/<repo>/branches/main/protection über die Oberfläche Settings → Branches) zeigt die Umschaltungen aus Schritt 2 und Schritt 4, die das Merge-Fenster einrahmen.
  • Die Git-Historie des Maintainers. git log main --first-parent --oneline listet jeden Squash-Merge-Commit auf main mit der zugehörigen PR-Nummer im Commit-Betreff auf (Suffix (#<pr-number>) gemäß der Voreinstellung von gh pr merge --squash), sodass der Operator jede frühere Übernahme bis zu ihrem PR und dem Aufruf des Zeremoniells zurückverfolgen kann.

Wenn scripts/dev/admin_merge.py der Einstiegspunkt ist, nennt sein nicht-interaktives Log (stderr) die drei Aufrufe der Schutz-API und den Aufruf der Merge-API in dieser Reihenfolge. Leitet man seinen stderr per Pipe an tee (2>&1 | tee), entsteht pro Lauf ein Audit-Fragment, ohne von der Log-Aufbewahrung auf Seiten von GitHub abzuhängen.

On this page