¿Qué hace land-renovate?
Recorre la cola de PRs abiertas de Renovate en el repositorio actual y aplica las seguras: enumera, clasifica, aprueba y fusiona con rebase en orden ascendente de número de PR, notifica las demás marcando la casilla de rebase y se detiene limpiamante ante fallos reales o casos de ESPERA.
Esto opera completamente sobre PRs remotas existentes a través de gh. No
llama a /create-commit, /create-pr ni /wrap, y no autor commits locales.
Argumentos
| Argumento | Por defecto | Descripción |
|---|---|---|
limit=N | 30 | Límite de PRs a recorrer. |
<pr-number>... | todas las PRs abiertas de Renovate | Números de PR separados por espacios; opera solo sobre esos. |
Por defecto: repositorio actual (de gh repo view --json nameWithOwner),
PRs abiertas creadas por Renovate, orden ascendente por número de PR, sin filtro de etiquetas.
Flujo de trabajo
1. Resolver el repositorio
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
2. Enumerar PRs de Renovate
Lista las PRs abiertas creadas por Renovate, primero las más antiguas (número más bajo):
gh pr list -R "$REPO" --author "app/renovate" --state open --limit 30 \
--json number,title,mergeable,mergeStateStatus,statusCheckRollup
Ordena ascendentemente por number y recórrelas en ese orden. Si se pasaron números de PR explícitos
como argumentos, restringe el conjunto a esos.
Nota:
gh pr lista menudo devuelvemergeable: UNKNOWNporque GitHub calcula la capacidad de fusión de forma diferida. Una llamadagh pr view <n> --json mergeablesobre una sola PR fuerza el cálculo. Cuando elmergeablede una PR esUNKNOWN, vuelve a leerla congh pr viewantes de clasificar.
3. Clasificar cada PR
Agrupa cada PR usando statusCheckRollup + mergeable + mergeStateStatus:
| Grupo | Señal | Acción |
|---|---|---|
| VERDE | sin FAILURE/CANCELLED/TIMED_OUT en el resumen, nada pendiente, mergeable=MERGEABLE | aprobar + fusionar con rebase (paso 4) |
| CONFLICTO | mergeable=CONFLICTING o mergeStateStatus=DIRTY | marcar la casilla de rebase (paso 5), monitorear |
| FALLO_REAL | el resumen contiene un FAILURE que no se puede arreglar automáticamente con la actualización posterior | omitir; dejar para revisión humana |
| ESPERA | coordinación entre archivos necesaria (lista de verificación manual — ver abajo) | informar al humano; no continuar |
Una comprobación en el resumen está pendiente cuando un CheckRun tiene status != COMPLETED
o un StatusContext tiene state de PENDING/EXPECTED. Es un fallo cuando un
CheckRun.conclusion es FAILURE/CANCELLED/TIMED_OUT/ACTION_REQUIRED/STARTUP_FAILURE,
o un StatusContext.state es FAILURE/ERROR.
Lista de verificación de ESPERA (manual — no codificada)
La detección de ESPERA es un juicio del agente, no una regla automatizada. Trata una PR como candidata a ESPERA cuando fusionarla de forma aislada rompería algo que está en otro archivo, por ejemplo:
- Discrepancia de versión de terraform — una actualización de proveedor/CLI de Terraform que necesita
que se actualice una versión relacionada en otro lugar (ej.
.terraform-version, workflow de CI, o una restricciónrequired_version) antes de que sea segura. - Actualizaciones de esquema que requieren ediciones de código — una actualización de dependencia cuyo nuevo major cambia un esquema/tipo del que aún depende código escrito a mano; los hooks posteriores a la actualización no pueden generar la edición de código.
- Cualquier actualización cuyo registro de cambios requiera una edición coordinada que el trabajo posterior a la actualización no realizará.
Cuando una PR parece ser una ESPERA, infórmala y pregunta al usuario — no la fusiones automáticamente ni marques la casilla de rebase. Sigue recorriendo el resto de la cola.
4. Aprobar + fusionar (VERDE)
gh pr review "$PR" -R "$REPO" --approve \
--body "LGTM — aprobación automática como parte del lote de fusiones de Renovate."
gh pr merge "$PR" -R "$REPO" --rebase --delete-branch
5. Marcar la casilla de rebase (CONFLICTO)
Activa la casilla de rebase de Renovate para que rebase la rama, luego monitorea:
body=$(gh pr view "$PR" -R "$REPO" --json body -q .body)
new=$(printf '%s' "$body" | sed 's|^\( *\)- \[ \] <!-- rebase-check -->|\1- [x] <!-- rebase-check -->|')
printf '%s' "$new" | gh pr edit "$PR" -R "$REPO" --body-file - >/dev/null
Captura el SHA de la cabeza actual como referencia antes de marcar la casilla, luego ejecuta el monitor (paso 6) para poder distinguir el rebase del estado inicial:
BASELINE=$(gh pr view "$PR" -R "$REPO" --json headRefOid -q .headRefOid)
Nunca marques la casilla de rebase en un FALLO_REAL — desperdicia ciclos de Renovate y oculta el problema real.
6. Monitorear hasta que se estabilice
El script incluido scripts/monitor-renovate-pr.sh consulta una sola PR hasta que sus comprobaciones
se estabilizan e imprime un veredicto que el agente consume a través de la herramienta Monitor.
scripts/monitor-renovate-pr.sh <pr-number> <repo> <baseline-head-sha-short>
- Consulta
gh pr view --json headRefOid,mergeable,mergeStateStatus,statusCheckRollupcada 45s (se puede sobrescribir conPOLL_INTERVAL) e imprime una línea solo cuando la firma${head:0:9}|<mergeable>:<state>|ok=N pend=M fail=Kcambia. - Emite un veredicto una vez que la cabeza se ha movido de la línea base, no hay comprobaciones pendientes y la firma es estable durante dos consultas consecutivas.
- La última línea de stdout es una de:
GREEN: #<n> ready to merge→ vuelve al paso 4 y aprueba + fusiona.NOT-GREEN: #<n> settled failures=X mergeable=Y state=Z→ reclasifica; ahora es un FALLO_REAL o ESPERA.
- Variables de entorno opcionales:
POLL_INTERVAL(segundos, por defecto 45),MAX_POLLS(rendirse después de N consultas,0= ilimitado; al agotarse emiteNOT-GREEN: #<n> timeout ...).
Por qué un bucle de consulta y no gh pr checks --watch
gh pr checks <n> --watch es adecuado para una PR que ya es fusionable y solo
está ejecutando comprobaciones, pero es engañoso en el camino de rebase para el que existe esta habilidad:
- Sale en verde sobre la cabeza obsoleta. Justo después de marcar la casilla de rebase,
las comprobaciones actuales de la PR ya son terminales — pasaron en la cabeza anterior al rebase
(conflictiva).
--watchve "sin comprobaciones pendientes" y devuelve éxito inmediatamente, antes de que Renovate siquiera haya hecho el rebase. La condiciónhead moved off baselinees exactamente la que protege contra ese falso verde. - Solo conoce comprobaciones, no capacidad de fusión. El veredicto VERDE necesita
mergeable=MERGEABLE+mergeStateStatus=CLEAN, y CONFLICTO se detecta a través de esos campos — quegh pr checksnunca informa. Una sola consultagh pr viewcubre ambos de un solo golpe. - La cabeza puede moverse dos veces (push de Renovate, luego push posterior a la actualización del
bot de la aplicación). Hay una ventana entre ellos donde las comprobaciones conocidas están momentáneamente
completas;
--watchpuede salir en ese lapso. La protección de "sin pendientes y estable durante dos consultas" pasa por encima de eso.
7. Cadena de commits esperada después del rebase
Después de marcar la casilla de rebase (o de que Renovate rebase por su cuenta), una fusión VERDE típicamente sigue esta cadena — saberlo te indica que el movimiento del monitor es esperado, no un fallo:
- Renovate empuja una nueva cabeza como
renovate[bot]. - Los workflows
pull_requestse disparan. El paso posterior a la actualización decheck.ymlejecutaeslint --fix,prettier --write,vitest --update,projeny una entrada de cambio debeachball. - Si el paso posterior a la actualización produjo un diff, el trabajo
commit-upgrade-changesgenera un token de App medianteactions/create-github-app-token@v2y empuja la corrección como<app-slug>[bot]. Ese push del bot vuelve a disparar los workflowspull_request, por lo que la cabeza se mueve por segunda vez y las comprobaciones se vuelven a ejecutar. - Estado final listo:
mergeable=MERGEABLE,mergeStateStatus=CLEAN, todas las comprobacionesSUCCESS/SKIPPED.
Debido a que la cabeza puede moverse dos veces (Renovate, luego el bot de la aplicación), el monitor basa su veredicto en "cabeza movida de la línea base + sin pendientes + dos consultas estables" en lugar del primer push que ve.
Condiciones de parada
- No quedan PRs VERDES — terminado.
- FALLO_REAL — omítelo, continúa con la siguiente PR; nunca hagas rebase automático de un FALLO_REAL.
- Candidato a ESPERA — infórmalo para decisión humana; no lo fusiones automáticamente.
- El usuario cancela.
Restricciones
- Los asuntos de los commits no deben contener referencias a issues/PRs (regla del proyecto). No
aplica al fusionar PRs remotas aquí, pero si esta habilidad se extiende para
autor un commit local, mantén las referencias fuera del asunto — ponlas en el cuerpo.
Consulta
/create-commit. - Nunca marques la casilla de rebase en un FALLO_REAL.
- Nunca fusiones automáticamente un candidato a ESPERA.
- La detección de ESPERA es una lista de verificación manual, no una regla codificada. Reconoce las categorías anteriores e informa candidatos; no intentes automatizar la decisión.
Notas de prueba
Clasificación en seco
Enumera y revisa visualmente los grupos sin tocar nada:
gh pr list -R "$REPO" --author "app/renovate" --state open \
--json number,title,mergeable,mergeStateStatus,statusCheckRollup \
| jq -r '.[] | "\(.number)\t\(.mergeable)\t\(.mergeStateStatus)\t\(.title)"'
Añade un resumen de comprobaciones por PR para detectar comprobaciones pendientes/fallidas:
gh pr list -R "$REPO" --author "app/renovate" --state open \
--json number,statusCheckRollup \
| jq -r '.[] | "\(.number)\t" + ([.statusCheckRollup[] | .conclusion // .state] | join(","))'
Prueba de humo del monitor
Ejecuta el monitor contra una PR conocida con un SHA de línea base falso (para que la cabeza ya cuente como "movida") y un intervalo corto para observar las líneas de estado y el veredicto final:
POLL_INTERVAL=2 MAX_POLLS=4 \
scripts/monitor-renovate-pr.sh <pr-conocida> "$REPO" deadbeef0
Deberías ver una línea de estado por cada cambio de firma, luego un veredicto GREEN: /
NOT-GREEN:. Pasar la cabeza real de la PR como línea base en cambio ejercita
la ruta sin rebase: la cabeza nunca se mueve, por lo que nunca se estabiliza y la ejecución termina
con el tiempo de espera de MAX_POLLS.
Fuera del alcance
- Reglas de detección de ESPERA codificadas (comienza como la lista de verificación manual anterior; extiende después).
- Conectar esta habilidad a cualquier capa de orquestación.