Que fait land-renovate ?
Parcourir la file d'attente des PR Renovate ouvertes dans le dépôt actuel et intégrer les PR sûres : énumérer, classifier, approuver + fusionner par rebasage dans l'ordre croissant des numéros de PR, notifier les autres en cochant la case de rebasage, et s'arrêter proprement en cas d'échec réel ou de cas bloquants.
Cette compétence opère entièrement sur les PR distantes existantes via gh. Elle n'appelle pas /create-commit, /create-pr ou /wrap, et elle ne crée pas de commits locaux.
Arguments
| Argument | Défaut | Description |
|---|---|---|
limit=N | 30 | Limiter le nombre de PR à parcourir. |
<pr-number>... | toutes les PR ouvertes de Renovate | Numéros de PR séparés par des espaces ; n'opérer que sur celles-ci. |
Valeurs par défaut : dépôt actuel (via gh repo view --json nameWithOwner), PR ouvertes créées par Renovate, ordre croissant des numéros de PR, aucun filtre d'étiquette.
Workflow
1. Résoudre le dépôt
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
2. Énumérer les PR Renovate
Lister les PR ouvertes créées par Renovate, des plus anciennes (numéro le plus bas) aux plus récentes :
gh pr list -R "$REPO" --author "app/renovate" --state open --limit 30 \
--json number,title,mergeable,mergeStateStatus,statusCheckRollup
Trier par number croissant et les parcourir dans cet ordre. Si des numéros de PR explicites sont passés en arguments, restreindre l'ensemble à ceux-ci.
Remarque :
gh pr listrenvoie souventmergeable: UNKNOWNcar GitHub calcule la fusionnabilité paresseusement. Ungh pr view <n> --json mergeablesur une seule PR force le calcul. Lorsque le champmergeabled'une PR estUNKNOWN, relisez-la avecgh pr viewavant de la classifier.
3. Classifier chaque PR
Ranger chaque PR en utilisant statusCheckRollup + mergeable + mergeStateStatus :
| Catégorie | Signal | Action |
|---|---|---|
| VERT | aucun FAILURE/CANCELLED/TIMED_OUT dans le rollup, rien en attente, mergeable=MERGEABLE | approuver + fusionner par rebasage (étape 4) |
| CONFLIT | mergeable=CONFLICTING ou mergeStateStatus=DIRTY | cocher la case de rebasage (étape 5), surveiller |
| ÉCHEC RÉEL | le rollup contient un FAILURE non auto-réparable par mise à jour postérieure | ignorer ; laisser pour un tri humain |
| BLOQUÉ | coordination entre fichiers nécessaire (liste de contrôle manuelle — voir ci-dessous) | signaler pour une décision humaine ; ne pas continuer |
Un contrôle dans le rollup est en attente lorsqu'un CheckRun a status != COMPLETED ou qu'un StatusContext a un state de PENDING/EXPECTED. C'est un échec lorsqu'un CheckRun.conclusion est FAILURE/CANCELLED/TIMED_OUT/ACTION_REQUIRED/STARTUP_FAILURE, ou qu'un StatusContext.state est FAILURE/ERROR.
Liste de contrôle pour BLOQUÉ (manuel — pas codé en dur)
La détection des cas BLOQUÉ est un jugement de l'agent, pas une règle automatisée. Considérez une PR comme candidate BLOQUÉ si son intégration isolée casserait quelque chose dans un autre fichier, par exemple :
- Mauvaise correspondance de version terraform-version — un changement de fournisseur/CLI Terraform qui nécessite une mise à jour correspondante ailleurs (par exemple
.terraform-version, workflow CI, ou une contrainterequired_version) avant d'être sûr. - Changements de schéma nécessitant des modifications de code — une mise à jour de dépendance dont la nouvelle version majeure modifie un schéma/type dont dépend toujours le code écrit à la main ; les hooks post- mise à jour ne peuvent pas générer la modification de code.
- toute mise à jour dont le journal des modifications appelle une modification coordonnée que le job post- mise à jour n'effectuera pas.
Lorsqu'une PR ressemble à un cas BLOQUÉ, signalez-la et demandez à l'utilisateur — ne fusionnez pas automatiquement et ne cochez pas la case de rebasage. Continuez à parcourir le reste de la file d'attente.
4. Approuver + fusionner (VERT)
gh pr review "$PR" -R "$REPO" --approve \
--body "LGTM — approuvé automatiquement dans le cadre d'un lot d'intégration Renovate."
gh pr merge "$PR" -R "$REPO" --rebase --delete-branch
5. Cocher la case de rebasage (CONFLIT)
Activer la case de rebasage de Renovate pour qu'il rebase la branche, puis surveiller :
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
Capturer le SHA de la tête actuelle comme référence avant de cocher la case, puis exécuter le moniteur (étape 6) pour pouvoir distinguer le rebasage de l'état de départ :
BASELINE=$(gh pr view "$PR" -R "$REPO" --json headRefOid -q .headRefOid)
Ne jamais cocher la case de rebasage sur un ÉCHEC RÉEL — cela gaspille des cycles Renovate et cache le vrai problème.
6. Surveiller jusqu'à stabilisation
Le script fourni scripts/monitor-renovate-pr.sh interroge une seule PR jusqu'à ce que ses contrôles se stabilisent et imprime un verdict que l'agent consomme via l'outil Monitor.
scripts/monitor-renovate-pr.sh <numéro-pr> <dépôt> <sha-court-tête-référence>
- Interroge
gh pr view --json headRefOid,mergeable,mergeStateStatus,statusCheckRolluptoutes les 45s (POLL_INTERVALsurcharge) et imprime une ligne seulement lorsque la signature${head:0:9}|<mergeable>:<state>|ok=N pend=M fail=Kchange. - Émet un verdict une fois que la tête s'est éloignée de la référence, qu'aucun contrôle n'est en attente, et que la signature est stable sur deux interrogations consécutives.
- La dernière ligne stdout est l'une des suivantes :
GREEN: #<n> ready to merge→ revenir à l'étape 4 et approuver + fusionner.NOT-GREEN: #<n> settled failures=X mergeable=Y state=Z→ reclassifier ; c'est maintenant un ÉCHEC RÉEL ou BLOQUÉ.
- Variables d'environnement optionnelles :
POLL_INTERVAL(secondes, défaut 45),MAX_POLLS(abandonner après N interrogations,0= illimité ; à l'épuisement émetNOT-GREEN: #<n> timeout ...).
Pourquoi une boucle d'interrogation et pas gh pr checks --watch
gh pr checks <n> --watch convient pour une PR déjà fusionnable et dont les contrôles tournent, mais il induit en erreur sur le chemin de rebasage pour lequel cette compétence existe :
- Il se termine en vert sur la tête périmée. Juste après avoir coché la case de rebasage, les contrôles actuels de la PR sont déjà terminés — ils ont passé sur la tête pré-rebasage (en conflit).
--watchvoit "aucun contrôle en attente" et retourne un succès immédiatement, avant même que Renovate n'ait rebasé. La conditionhead moved off baselineest exactement ce qui protège contre ce faux-vert. - Il ne connaît que les contrôles, pas la fusionnabilité. Le verdict VERT nécessite
mergeable=MERGEABLE+mergeStateStatus=CLEAN, et CONFLIT est détecté via ces champs — quegh pr checksne rapporte jamais. Une seule interrogationgh pr viewcouvre les deux en une fois. - La tête peut bouger deux fois (push de Renovate, puis push du bot de post-mise à jour). Il y a une fenêtre entre les deux où les contrôles connus sont momentanément complets ;
--watchpeut se terminer dans cet intervalle. La protection "aucun en attente et stable pendant deux interrogations" évite cela.
7. Chaîne de commits attendue après rebasage
Après avoir coché la case de rebasage (ou que Renovate rebase de lui-même), un déploiement VERT passe généralement par cette chaîne — savoir cela vous indique que l'agitation du moniteur est attendue, pas un échec :
- Renovate pousse une nouvelle tête en tant que
renovate[bot]. - Les workflows
pull_requestse déclenchent. L'étape post-mise à jour decheck.ymlexécuteeslint --fix,prettier --write,vitest --update,projen, et une entrée de changementbeachball. - Si l'étape post-mise à jour produit un diff, le job
commit-upgrade-changescrée un token d'application viaactions/create-github-app-token@v2et pousse la correction en tant que<app-slug>[bot]. Ce push du bot déclenche à nouveau les workflowspull_request, donc la tête bouge une deuxième fois et les contrôles se relancent. - État final prêt :
mergeable=MERGEABLE,mergeStateStatus=CLEAN, tous les contrôlesSUCCESS/SKIPPED.
Parce que la tête peut bouger deux fois (Renovate, puis le bot de l'application), le moniteur base son verdict sur "tête déplacée par rapport à la référence + aucun en attente + deux interrogations stables" plutôt que sur le premier push qu'il voit.
Conditions d'arrêt
- Aucune PR VERTE restante — terminé.
- ÉCHEC RÉEL — ignorer, continuer avec la PR suivante ; ne jamais rebaser automatiquement un ÉCHEC RÉEL.
- Candidate BLOQUÉ — signaler pour une décision humaine ; ne pas fusionner automatiquement.
- L'utilisateur annule.
Contraintes
- Les sujets de commit ne doivent pas contenir de références à des issues/PR (règle du projet). Non applicable ici pour la fusion de PR distantes, mais si cette compétence est jamais étendue pour créer un commit local, gardez les références hors du sujet — mettez-les dans le corps. Voir
/create-commit. - Ne jamais cocher la case de rebasage sur un ÉCHEC RÉEL.
- Ne jamais fusionner automatiquement un candidat BLOQUÉ.
- La détection BLOQUÉ est une liste de contrôle manuelle, pas une règle codée en dur. Reconnaître les catégories ci-dessus et signaler les candidats ; ne pas essayer d'automatiser la décision.
Notes de test
Classification à blanc
Énumérer et inspecter les catégories sans rien toucher :
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)"'
Ajouter un résumé du rollup par PR pour repérer les contrôles en attente/en échec :
gh pr list -R "$REPO" --author "app/renovate" --state open \
--json number,statusCheckRollup \
| jq -r '.[] | "\(.number)\t" + ([.statusCheckRollup[] | .conclusion // .state] | join(","))'
Test de fumée du moniteur
Exécuter le moniteur contre une PR connue avec un SHA de référence fictif (pour que la tête soit déjà considérée comme "déplacée") et un intervalle court pour observer les lignes d'état et le verdict final :
POLL_INTERVAL=2 MAX_POLLS=4 \
scripts/monitor-renovate-pr.sh <pr-connue> "$REPO" deadbeef0
Vous devriez voir une ligne d'état par changement de signature, puis un verdict GREEN: / NOT-GREEN:. Passer la vraie tête de la PR comme référence exerce le chemin sans rebasage : la tête ne bouge jamais, donc elle ne se stabilise jamais et l'exécution se termine sur le délai d'attente MAX_POLLS.
Hors de portée
- Règles de détection BLOQUÉ codées en dur (commencer par la liste de contrôle manuelle ci-dessus ; étendre plus tard).
- Intégration de cette compétence dans une couche d'orchestration.