Skip to content

stale-sweep : quota d'installation épuisé → « 0 PR inspectée » et run success, les DWELL échus ne sont plus levés #17566

Description

@jsboige

Constat mesuré (2026-09-23)

pr-gate-stale-sweep.yml conclut success alors qu'il n'a lu qu'une partie de la file, ou rien du tout. Voici les 12 derniers runs terminés, avec la ligne [stale-sweep] open PRs inspected: de chaque log :

Run Créé à Événement Conclusion PRs inspectées
35847738338 10:15:26Z push success 164
35847840968 10:16:29Z push success 159
35849577845 10:34:30Z push success 158
35850437301 10:43:34Z push success 155
35850476878 10:44:02Z push success 155
35854154661 11:22:29Z push success 154
35854581414 11:26:53Z schedule success 153
35854957076 11:30:45Z push success 153
35861164152 12:32:55Z push success 156
35864705790 13:05:34Z push success 101
35866395602 13:20:35Z push success 0
35867123056 13:26:52Z push success 0

Les trois derniers runs coïncident avec l'épuisement du quota d'installation de l'App. Leurs logs portent tous gh: API rate limit exceeded for installation (étape gate-absent, pr_gate_missing.py l.403). Le run 35866395602 imprime ensuite nothing to do.

Cause (lue sur origin/main)

.github/workflows/pr-gate-stale-sweep.yml, boucle par PR (vers l.371) :

BODY=$(gh api "repos/$REPO/commits/$SHA/check-runs?per_page=100" \
         --jq '[...]' 2>/dev/null) || continue

Quand l'appel échoue, la PR est omise sans trace. Si toute la boucle tombe sous la limite, /tmp/runs.jsonl reste vide. Le compteur affiche alors 0, le sélecteur n'a aucun candidat, et le run sort en success.

Le listing, quelques lignes plus haut, a déjà été durci contre ce même défaut. Le commentaire l.340-353 le dit : « la quiétude lavait la sonde au vert ». Il échoue désormais bruyamment (::error::[stale-sweep] NO-OP -- PR listing failed, exit 1). La boucle par PR n'a pas reçu ce durcissement, et le défaut s'est déplacé d'un niveau.

Conséquence observée

Un DWELL échu n'est levé que si le balayage relance le PR gate. Exemple : #17497, écoulé à 13:07:00Z, a encore son PR gate rouge à 13:30Z, alors que deux balayages ont conclu success entre-temps. Sur le dashboard de circulation, cela se lit « le balayage n'est plus servi », alors qu'il tourne bien : il rend un vert à vide.

Acceptance proposée

  1. La boucle compte les PRs listées (/tmp/openprs.txt), inspectées et omises, et imprime les trois nombres.
  2. Omission totale (PRs listées > 0 et inspectées = 0) : ::error::[stale-sweep] NO-OP -- check-runs unreadable for all N listed PRs puis exit 1. C'est la même famille d'annotation que le garde du listing, donc triable par scripts/ci/classify_job_deaths.py.
  3. Omission partielle : au minimum un ::warning:: qui nomme le nombre de PRs omises. Le seuil au-delà duquel ce devient un ::error:: reste à trancher (proposition : plus de 10 %).
  4. Contrôle positif : forcer l'échec de l'appel par PR (par exemple un REPO invalide sur l'appel check-runs seul) doit rendre un run failure qui porte l'annotation NO-OP. Le chemin nominal doit rester success.

Hors périmètre, observation séparée à vérifier

Le même appel lit commits/<sha>/check-runs sans filter=all. Or le filtre par défaut (latest) masque les check-runs d'une suite relancée. C'est à vérifier dans un sujet distinct avant de conclure qu'il y a un impact sur le sélecteur.

Mesure : myia-po-2025:CoursIA-2 (titulaire). Les logs se relisent avec gh run view <id> --log | grep "open PRs inspected".

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions