O que land-renovate faz?
Percorre a fila de Pull Requests abertas do Renovate no repositório atual e mescla as seguras: enumera, classifica, aprova e faz rebase-merge em ordem crescente de número da PR, notifica as restantes com a caixa de seleção de rebase e para limpo em caso de falhas reais ou casos HOLD.
Isso opera inteiramente sobre PRs remotas existentes através do gh. Não
chama /create-commit, /create-pr ou /wrap, e não cria commits locais.
Argumentos
| Argumento | Padrão | Descrição |
|---|---|---|
limit=N | 30 | Limita quantas PRs processar. |
<pr-number>... | todas as PRs abertas do Renovate | Números de PR separados por espaço; opera apenas nessas. |
Padrões: repositório atual (de gh repo view --json nameWithOwner),
PRs abertas do Renovate, ordem crescente de número, sem filtro de label.
Fluxo de trabalho
1. Resolver o repositório
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
2. Enumerar PRs do Renovate
Lista PRs abertas do Renovate, mais antigas (menor número) primeiro:
gh pr list -R "$REPO" --author "app/renovate" --state open --limit 30 \
--json number,title,mergeable,mergeStateStatus,statusCheckRollup
Ordena crescentemente por number e as percorre nessa ordem. Se números de PR explícitos
forem passados como argumentos, restringe o conjunto a esses.
Nota:
gh pr listfrequentemente retornamergeable: UNKNOWNporque o GitHub calcula mergeabilidade preguiçosamente. Umgh pr view <n> --json mergeableem uma única PR força o cálculo. Quando amergeablede uma PR éUNKNOWN, releia-a comgh pr viewantes de classificar.
3. Classificar cada PR
Coloca cada PR em um grupo usando statusCheckRollup + mergeable + mergeStateStatus:
| Grupo | Sinal | Ação |
|---|---|---|
| GREEN | nenhum FAILURE/CANCELLED/TIMED_OUT no rollup, nada pendente, mergeable=MERGEABLE | aprovar + rebase-merge (passo 4) |
| CONFLICTING | mergeable=CONFLICTING ou mergeStateStatus=DIRTY | marcar a caixa de rebase (passo 5), monitorar |
| REAL_FAILURE | rollup contém um FAILURE não corrigível automaticamente por pós-upgrade | pular; deixar para triagem humana |
| HOLD | coordenação entre arquivos necessária (checklist manual — veja abaixo) | exibir para humano; não prosseguir |
Uma verificação no rollup está pendente quando um CheckRun tem status != COMPLETED
ou um StatusContext tem state de PENDING/EXPECTED. É uma falha
quando um CheckRun.conclusion é FAILURE/CANCELLED/TIMED_OUT/
ACTION_REQUIRED/STARTUP_FAILURE, ou um StatusContext.state é FAILURE/
ERROR.
Checklist HOLD (manual — não codificado)
A detecção HOLD é um julgamento do agente, não uma regra automatizada. Trate uma PR como candidata a HOLD quando mesclá-la isoladamente quebraria algo que vive em outro arquivo, por exemplo:
- Incompatibilidade de versão do terraform — um bump de provider/CLI do Terraform que precisa
de um pin correspondente atualizado em outro lugar (ex.:
.terraform-version, workflow de CI, ou uma restriçãorequired_version) antes de ser seguro. - Bumps de esquema que exigem edições de código — uma atualização de dependência cuja nova major altera um schema/tipo do qual o código escrito manualmente ainda depende; os hooks de pós-upgrade não conseguem gerar a edição de código.
- qualquer atualização cujo changelog exija uma edição coordenada que o job de pós-upgrade não realizará.
Quando uma PR parece ser um HOLD, exiba-a e pergunte ao usuário — não faça auto-merge e não marque a caixa de seleção de rebase. Continue percorrendo o resto da fila.
4. Aprovar + mesclar (GREEN)
gh pr review "$PR" -R "$REPO" --approve \
--body "LGTM — aprovado automaticamente como parte da mesclagem em lote do Renovate."
gh pr merge "$PR" -R "$REPO" --rebase --delete-branch
5. Marcar a caixa de rebase (CONFLICTING)
Ativa a caixa de seleção de rebase do Renovate para que ele faça rebase do branch, depois monitore:
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
Capture o SHA atual do HEAD como linha de base antes de marcar a caixa, depois execute o monitor (passo 6) para que você possa distinguir o rebase do estado inicial:
BASELINE=$(gh pr view "$PR" -R "$REPO" --json headRefOid -q .headRefOid)
Nunca marque a caixa de rebase em uma REAL_FAILURE — isso desperdiça ciclos do Renovate e esconde o problema real.
6. Monitorar até estabilizar
O script scripts/monitor-renovate-pr.sh incluso faz polling de uma única PR até que seus checks
se estabilizem e imprime um veredito que o agente consome através da ferramenta Monitor.
scripts/monitor-renovate-pr.sh <pr-number> <repo> <baseline-head-sha-short>
- Faz polling de
gh pr view --json headRefOid,mergeable,mergeStateStatus,statusCheckRollupa cada 45s (substituível porPOLL_INTERVAL) e imprime uma linha apenas quando a assinatura${head:0:9}|<mergeable>:<state>|ok=N pend=M fail=Kmuda. - Emite um veredito assim que o head tiver se movido para fora da linha de base, nenhum check estiver pendente e a assinatura estiver estável em duas consultas consecutivas.
- A última linha do stdout é uma de:
GREEN: #<n> ready to merge→ volte ao passo 4 e aprove + mescle.NOT-GREEN: #<n> settled failures=X mergeable=Y state=Z→ reclassifique; agora é uma REAL_FAILURE ou HOLD.
- Env opcionais:
POLL_INTERVAL(segundos, padrão 45),MAX_POLLS(desistir após N polls,0= ilimitado; na exaustão emiteNOT-GREEN: #<n> timeout ...).
Por que um loop de polling e não gh pr checks --watch
gh pr checks <n> --watch é bom para uma PR que já está mergeável e apenas
tem checks rodando, mas engana ativamente no caminho de rebase para o qual este skill existe:
- Ele sai verde no head desatualizado. Logo após marcar a caixa de rebase,
os checks atuais da PR já são terminais — eles passaram no head pré-rebase (conflitante).
--watchvê "nenhum check pendente" e retorna sucesso imediatamente, antes mesmo do Renovate fazer o rebase. A condiçãohead moved off baselineé exatamente o que protege contra esse falso-verde. - Ele só conhece checks, não mergeabilidade. O veredito GREEN precisa
de
mergeable=MERGEABLE+mergeStateStatus=CLEAN, e CONFLICTING é detectada através desses campos — quegh pr checksnunca informa. Uma única consultagh pr viewcobre ambos de uma vez. - O head pode se mover duas vezes (push do Renovate, depois push do app-bot de pós-upgrade).
Há uma janela entre eles onde os checks conhecidos estão momentaneamente
completos;
--watchpode sair nesse intervalo. A proteção "nenhum pendente e estável por dois polls" passa por cima disso.
7. Cadeia de commits esperada após rebase
Depois que a caixa de rebase é marcada (ou o Renovate faz rebase por conta própria), uma mesclagem GREEN normalmente flui através desta cadeia — sabendo disso, você reconhece que a instabilidade do monitor é esperada, não uma falha:
- Renovate envia um novo head como
renovate[bot]. - Workflows
pull_requestdisparam. O passo de pós-upgrade docheck.ymlexecutaeslint --fix,prettier --write,vitest --update,projen, e uma entrada de mudançabeachball. - Se o passo de pós-upgrade produziu um diff, o job
commit-upgrade-changesgera um token de App viaactions/create-github-app-token@v2e envia o fix como<app-slug>[bot]. Esse push do bot re-dispara os workflowspull_request, então o head se move uma segunda vez e os checks são executados novamente. - Estado final pronto:
mergeable=MERGEABLE,mergeStateStatus=CLEAN, todos os checksSUCCESS/SKIPPED.
Como o head pode se mover duas vezes (Renovate, depois o app bot), o monitor baseia seu veredito em "head moveu da linha de base + nenhum pendente + dois polls estáveis" em vez no primeiro push que vê.
Condições de parada
- Nenhuma PR GREEN restante — concluído.
- REAL_FAILURE — pule-a, continue com a próxima PR; nunca faça auto-rebase em uma REAL_FAILURE.
- Candidato HOLD — exiba-o para decisão humana; não faça auto-merge.
- Usuário cancela.
Restrições
- Assuntos de commit não devem conter referências a issues/PRs (regra do projeto). Não
aplicável à mesclagem de PRs remotas aqui, mas se este skill for estendido para
criar um commit local, mantenha as referências fora do assunto — coloque-as no corpo.
Veja
/create-commit. - Nunca marque a caixa de rebase em uma REAL_FAILURE.
- Nunca faça auto-merge em um candidato HOLD.
- A detecção HOLD é uma checklist manual, não uma regra codificada. Reconheça as categorias acima e exiba candidatos; não tente automatizar a decisão.
Notas de teste
Classificação em modo simulação
Enumere e inspecione os grupos sem tocar em 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)"'
Adicione um resumo do rollup por PR para identificar checks pendentes/com falha:
gh pr list -R "$REPO" --author "app/renovate" --state open \
--json number,statusCheckRollup \
| jq -r '.[] | "\(.number)\t" + ([.statusCheckRollup[] | .conclusion // .state] | join(","))'
Teste de fumaça do monitor
Execute o monitor contra uma PR conhecida com um SHA de linha de base falso (para que o head já conte como "movido") e um intervalo curto para observar as linhas de estado e o veredito final:
POLL_INTERVAL=2 MAX_POLLS=4 \
scripts/monitor-renovate-pr.sh <pr-conhecida> "$REPO" deadbeef0
Você deve ver uma linha de estado por mudança de assinatura, depois um veredito GREEN: /
NOT-GREEN:. Passar o head real da PR como linha de base em vez disso
exercita o caminho sem rebase: o head nunca se move, então nunca estabiliza e a execução termina
no timeout de MAX_POLLS.
Fora do escopo
- Regras de detecção HOLD codificadas (comece como a checklist manual acima; estenda depois).
- Conectar este skill a qualquer camada de orquestração.