land-renovate

Parcourir et intégrer les PR Renovate dans le dépôt actuel : énumérer, classifier, approuver et fusionner les PR sûres, tout en gérant les conflits et les cas bloquants.

Qu'est-ce que land-renovate ?

Cette compétence permet de traiter automatiquement une file d'attente de PR Renovate ouvertes dans un dépôt GitHub. Elle énumère les PR créées par l'application Renovate, les classe en différentes catégories (VERT, CONFLIT, ÉCHEC RÉEL, BLOQUÉ), puis approuve et fusionne les PR sûres dans l'ordre croissant des numéros. Pour les PR en conflit, elle coche la case de rebasage pour demander un rebas automatique, et pour les PR en échec réel ou bloquantes, elle les laisse de côté pour une intervention humaine. L'outil utilise exclusivement `gh` pour interagir avec les PR distantes, sans effectuer de commits locaux. Il est idéal pour les équipes qui veulent automatiser l'intégration de mises à jour de dépendances tout en gardant un contrôle sur les cas problématiques.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/langri-sha/skills/tree/main/land-renovate

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

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

ArgumentDéfautDescription
limit=N30Limiter le nombre de PR à parcourir.
<pr-number>...toutes les PR ouvertes de RenovateNumé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 list renvoie souvent mergeable: UNKNOWN car GitHub calcule la fusionnabilité paresseusement. Un gh pr view <n> --json mergeable sur une seule PR force le calcul. Lorsque le champ mergeable d'une PR est UNKNOWN, relisez-la avec gh pr view avant de la classifier.

3. Classifier chaque PR

Ranger chaque PR en utilisant statusCheckRollup + mergeable + mergeStateStatus :

CatégorieSignalAction
VERTaucun FAILURE/CANCELLED/TIMED_OUT dans le rollup, rien en attente, mergeable=MERGEABLEapprouver + fusionner par rebasage (étape 4)
CONFLITmergeable=CONFLICTING ou mergeStateStatus=DIRTYcocher la case de rebasage (étape 5), surveiller
ÉCHEC RÉELle rollup contient un FAILURE non auto-réparable par mise à jour postérieureignorer ; 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 contrainte required_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,statusCheckRollup toutes les 45s (POLL_INTERVAL surcharge) et imprime une ligne seulement lorsque la signature ${head:0:9}|<mergeable>:<state>|ok=N pend=M fail=K change.
  • É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 émet NOT-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). --watch voit "aucun contrôle en attente" et retourne un succès immédiatement, avant même que Renovate n'ait rebasé. La condition head moved off baseline est 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 — que gh pr checks ne rapporte jamais. Une seule interrogation gh pr view couvre 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 ; --watch peut 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 :

  1. Renovate pousse une nouvelle tête en tant que renovate[bot].
  2. Les workflows pull_request se déclenchent. L'étape post-mise à jour de check.yml exécute eslint --fix, prettier --write, vitest --update, projen, et une entrée de changement beachball.
  3. Si l'étape post-mise à jour produit un diff, le job commit-upgrade-changes crée un token d'application via actions/create-github-app-token@v2 et pousse la correction en tant que <app-slug>[bot]. Ce push du bot déclenche à nouveau les workflows pull_request, donc la tête bouge une deuxième fois et les contrôles se relancent.
  4. État final prêt : mergeable=MERGEABLE, mergeStateStatus=CLEAN, tous les contrôles SUCCESS/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.

Skills associés