Cérémonie de fusion de PR pour mainteneur unique
Quand le mainteneur peut fusionner directement sa propre pull request, et la cérémonie pour une protection de branche qui exige une approbation et l'applique aux administrateurs.
Référence canonique pour fusionner soi-même des PR sous la protection de branche du projet. La protection en vigueur sur
mainexige 0 revue d'approbation et laisseenforce_adminsdésactivé, comme le consigne la page Protection de branche. Le mainteneur fusionne donc directement sa propre pull request. La cérémonie de bascule temporaire de cette page ne s'applique que lorsque la protection exige une approbation et l'applique aux administrateurs.
1. Le blocage
La protection en vigueur sur main porte :
required_pull_request_reviews.required_approving_review_count: 0enforce_admins: false
Avec ces paramètres, il n'y a pas de blocage. Une pull request du mainteneur se fusionne avec gh pr merge <pr-number> --squash --delete-branch dès que ses vérifications de statut requises sont au vert et que ses conversations de revue sont résolues.
Un blocage n'existe que lorsque la protection porte ces deux paramètres plus stricts :
required_pull_request_reviews.required_approving_review_count: 1enforce_admins: true
Ces règles sont correctes pour les scénarios à plusieurs mainteneurs (chaque changement atteint main via une PR relue par un pair ; les administrateurs ne sont pas exemptés). Elles produisent un blocage pour les mainteneurs uniques : la politique de GitHub interdit l'auto-approbation d'une PR que vous avez créée, et enforce_admins=true bloque le contournement gh pr merge --admin de l'exigence d'approbation de revue. Avec enforce_admins: false, --admin contourne l'exigence d'approbation et aucune bascule n'est nécessaire, mais il contourne aussi les vérifications requises en rouge ; confirmez donc qu'elles sont au vert avant de l'utiliser.
Trois voies de résolution existent :
| Voie | Quand l'utiliser |
|---|---|
Définir required_approving_review_count: 0 de façon permanente (paramètre en vigueur) | À adopter seulement si le dépôt restera à mainteneur unique indéfiniment ; inverse l'intention de revue de la protection |
| Cérémonie de bascule temporaire | Auto-fusions du mainteneur unique tant que la protection exige une approbation avec enforce_admins=true ; préserve l'invariant de protection en dehors de la fenêtre de fusion |
| Provisionner une identité de bot CI avec accès en écriture | À adopter seulement si l'intégration de plusieurs mainteneurs est imminente ; l'approbation par bot affaiblit l'intention de revue humaine de la protection |
Ce dépôt utilise actuellement la voie zéro approbation permanente. La cérémonie de bascule temporaire est la voie canonique chaque fois que la protection exige une approbation et l'applique aux administrateurs.
2. La cérémonie de bascule temporaire
L'invariant de la cérémonie : l'état de protection au début de la cérémonie est égal à l'état de protection à la fin. L'assouplissement ne vit qu'à l'intérieur de la fenêtre de fusion.
Forme manuelle :
# 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=1Forme encapsulée : voir scripts/dev/admin_merge.py pour l'enveloppe Python atomique qui exécute les étapes 2 → 3 → 4 en une seule séquence non interactive, avec une sécurité de retour arrière try / finally en cas d'échec de l'étape 3.
python scripts/dev/admin_merge.py <pr-number>3. Invariants
- Fenêtre de bascule minimisée. Les étapes 2 → 3 → 4 s'exécutent en une seule séquence non interactive. La protection n'est dans son état assoupli que pendant la durée de l'appel à l'API de fusion — moins d'une seconde à chaque exécution observée.
- La restauration est inconditionnelle. L'étape 4 s'exécute même lorsque l'étape 3 échoue (la clause
try/finallyde l'enveloppe garantit la restauration sur tout chemin de sortie). Une tentative de fusion échouée ne laisse pas la protection assouplie. - Le contrôle CI est préservé tout du long, tant que
enforce_adminsest activé.required_status_checksn'est pas affecté par la bascule ; avecenforce_admins: true, la fusion exige toujours que les contextes de vérification de statut configurés soient au vert. Avecenforce_admins: false, la fusion--adminde l'étape 3 contourne aussi les vérifications requises en rouge ; n'exécutez donc pas la cérémonie dans cet état. - Piste d'audit visible. L'annotation
gh pr merge --adminapparaît dans les métadonnées de fusion de la PR ; les bascules de l'API de protection apparaissent dans le journal d'audit du dépôt sous l'identité du mainteneur.
4. Quand NE PAS utiliser la cérémonie
Tant que la protection exige 0 revue d'approbation ou laisse enforce_admins désactivé, la cérémonie est inutile : fusionnez directement comme le décrit la section 1.
La cérémonie sert à l'auto-fusion des PR du mainteneur lui-même. Lorsqu'un relecteur pair est disponible (un contributeur avec accès en écriture), la voie standard gh pr review --approve + gh pr merge --squash --delete-branch est la bonne et la cérémonie est inutile.
Si le dépôt intègre un second mainteneur, retirez la cérémonie : le flux standard de revue de PR restaure l'intention de revue humaine de la protection sans aucune bascule.
5. Auditer une exécution passée
Chaque invocation de la cérémonie laisse une trace sur trois surfaces durables qu'un opérateur peut inspecter après coup :
- Les métadonnées de fusion de la PR.
gh pr view <pr-number> --json mergedBy,mergedAt,mergeCommitrenvoie l'acteur de la fusion, l'horodatage de la fusion et le SHA du commit de squash. L'acteurmergedBycorrespond à l'identité du mainteneur qui a exécuté l'étape 3. - Le journal d'audit du dépôt.
gh api /repos/<owner>/<repo>/actions/runs --jq '.workflow_runs[] | select(.event=="push")'met en correspondance l'exécution CI post-fusion et le commit de fusion ; le journal d'audit des règles de protection du dépôt (historique degh api /repos/<owner>/<repo>/branches/main/protectionvia l'interface Settings → Branches) montre les bascules de l'étape 2 et de l'étape 4 qui encadrent la fenêtre de fusion. - L'historique git du mainteneur.
git log main --first-parent --onelineliste chaque commit de squash-merge surmainavec le numéro de PR correspondant dans l'objet du commit (suffixe(#<pr-number>)selon la valeur par défaut degh pr merge --squash), ce qui permet à l'opérateur de remonter de tout atterrissage passé à sa PR et à l'invocation de sa cérémonie.
Lorsque scripts/dev/admin_merge.py est le point d'entrée, son journal non interactif (stderr) nomme, dans l'ordre, les trois appels à l'API de protection et l'appel à l'API de fusion ; rediriger sa sortie d'erreur vers tee (2>&1 | tee) capture un fragment d'audit par exécution sans dépendre de la rétention du journal côté GitHub.
Liste de vérification de synchronisation inter-machines
Procédure de vérification pour confirmer que l'adaptateur Claude Code s'installe, se valide et se désinstalle correctement sur un hôte neuf, avec des contrôles complets de portabilité.
Exemples
Exemples Apothem — des parcours commentés, de bout en bout, pour rédiger des adaptateurs, des règles, des hooks et des suites de planification.