Ceremonia de fusión de PR para mantenedor único
Cuándo el mantenedor puede fusionar directamente su propia pull request, y la ceremonia para una protección de rama que exige una aprobación y la aplica a los administradores.
Referencia canónica para autofusionar PR bajo la protección de rama del proyecto. La protección vigente en
mainexige 0 revisiones de aprobación y dejaenforce_adminsdesactivado, tal como se registra en la página Protección de ramas. Por lo tanto, el mantenedor fusiona directamente su propia pull request. La ceremonia de alternancia temporal de esta página se aplica solo cuando la protección exige una aprobación y la aplica a los administradores.
1. El bloqueo mutuo
La protección vigente de main incluye:
required_pull_request_reviews.required_approving_review_count: 0enforce_admins: false
Con estos ajustes no hay bloqueo mutuo. Una pull request del mantenedor se fusiona con gh pr merge <pr-number> --squash --delete-branch una vez que sus verificaciones de estado requeridas están en verde y sus conversaciones de revisión están resueltas.
Solo existe un bloqueo mutuo cuando la protección incluye estos dos ajustes más estrictos:
required_pull_request_reviews.required_approving_review_count: 1enforce_admins: true
Estas reglas son correctas para escenarios con varios mantenedores (cada cambio llega a main a través de una PR revisada por pares; los administradores no están exentos). Producen un bloqueo mutuo para los mantenedores únicos: la política de GitHub no permite autoaprobar una PR de la que eres autor, y enforce_admins=true bloquea la anulación gh pr merge --admin del requisito de aprobación de revisión. Con enforce_admins: false, --admin omite el requisito de aprobación y no hace falta ninguna alternancia, pero también omite las verificaciones requeridas en rojo, así que confirma que estén en verde antes de usarlo.
Existen tres rutas de resolución:
| Ruta | Cuándo usarla |
|---|---|
Establecer permanentemente required_approving_review_count: 0 (ajuste vigente) | Adóptala solo si el repositorio seguirá teniendo un único mantenedor indefinidamente; revierte la intención de revisión de la protección |
| Ceremonia de alternancia temporal | Autofusiones de mantenedor único mientras la protección exige una aprobación con enforce_admins=true; preserva el invariante de la protección fuera de la ventana de fusión |
| Aprovisionar una identidad de bot de CI con acceso de escritura | Adóptala solo si la incorporación de varios mantenedores es inminente; la aprobación por bot socava la intención de revisión humana de la protección |
Actualmente este repositorio usa la ruta de cero aprobaciones permanente. La ceremonia de alternancia temporal es la ruta canónica siempre que la protección exija una aprobación y la aplique a los administradores.
2. La ceremonia de alternancia temporal
El invariante de la ceremonia: el estado de la protección al inicio de la ceremonia es igual al estado de la protección al final. La relajación existe únicamente dentro de la ventana de fusión.
Forma manual:
# 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=1Forma envuelta: consulta scripts/dev/admin_merge.py para ver el envoltorio atómico de Python que ejecuta los pasos 2 → 3 → 4 en una sola secuencia no interactiva, con seguridad de reversión mediante try / finally ante un fallo en el paso 3.
python scripts/dev/admin_merge.py <pr-number>3. Invariantes
- Ventana de alternancia minimizada. Los pasos 2 → 3 → 4 se ejecutan en una sola secuencia no interactiva. La protección está en su estado relajado solo durante la llamada a la API de fusión: menos de un segundo en cada ejecución observada.
- La restauración es incondicional. El paso 4 se ejecuta incluso cuando el paso 3 falla (la cláusula
try/finallydel envoltorio garantiza la restauración en cualquier ruta de salida). Un intento de fusión fallido no deja la protección relajada. - El control de CI se preserva en todo momento, mientras
enforce_adminsestá activado.required_status_checksno se ve afectado por la alternancia; conenforce_admins: true, la fusión sigue requiriendo que los contextos de verificación de estado configurados estén en verde. Conenforce_admins: false, la fusión--admindel paso 3 también omite las verificaciones requeridas en rojo, así que no ejecutes la ceremonia en ese estado. - Rastro de auditoría visible. La anotación
gh pr merge --adminaparece en los metadatos de fusión de la PR; las alternancias de la API de protección aparecen en el registro de auditoría del repositorio bajo la identidad del mantenedor.
4. Cuándo NO usar la ceremonia
Mientras la protección exija 0 revisiones de aprobación o deje enforce_admins desactivado, la ceremonia es innecesaria: fusiona directamente como se describe en la sección 1.
La ceremonia es para la autofusión de las PR del propio mantenedor. Cuando hay un revisor par disponible (un colaborador con acceso de escritura), la ruta estándar gh pr review --approve + gh pr merge --squash --delete-branch es la correcta y la ceremonia es innecesaria.
Si el repositorio incorpora a un segundo mantenedor, retira la ceremonia: el flujo estándar de revisión de PR restaura la intención de revisión humana de la protección sin ninguna alternancia.
5. Auditar una ejecución pasada
Cada invocación de la ceremonia queda registrada en tres superficies duraderas que un operador puede inspeccionar a posteriori:
- Los metadatos de fusión de la PR.
gh pr view <pr-number> --json mergedBy,mergedAt,mergeCommitdevuelve el actor de la fusión, la marca de tiempo de la fusión y el SHA del commit de squash. El actormergedBycoincide con la identidad del mantenedor que ejecutó el paso 3. - El registro de auditoría del repositorio.
gh api /repos/<owner>/<repo>/actions/runs --jq '.workflow_runs[] | select(.event=="push")'correlaciona la ejecución de CI posterior a la fusión con el commit de fusión; el registro de auditoría de las reglas de protección del repositorio (el historial degh api /repos/<owner>/<repo>/branches/main/protection, a través de la interfaz Settings → Branches) muestra las alternancias de los pasos 2 y 4 que delimitan la ventana de fusión. - El historial de git del mantenedor.
git log main --first-parent --onelineenumera cada commit de squash-merge enmaincon el número de PR correspondiente en el asunto del commit (sufijo(#<pr-number>)según el valor predeterminado degh pr merge --squash), lo que permite al operador rastrear cualquier integración anterior hasta su PR y su invocación de la ceremonia.
Cuando scripts/dev/admin_merge.py es el punto de entrada, su registro no interactivo (stderr) nombra en secuencia las tres llamadas a la API de protección y la llamada a la API de fusión; canalizar su stderr a tee (2>&1 | tee) captura un fragmento de auditoría por ejecución sin depender de la retención de registros del lado de GitHub.
Lista de verificación de sincronización entre máquinas
Procedimiento de verificación para confirmar que el adaptador de Claude Code se instala, valida y desinstala correctamente en un host nuevo, con comprobaciones completas de portabilidad.
Ejemplos
Ejemplos de Apothem — recorridos completos, de principio a fin, para crear adaptadores, reglas, hooks y suites de plan.