Repository navigation
fix(ci,#17253): un fetch promisor en echec ne rougit plus Scripts Tests (CPU) - #17254
Conversation
…ts (CPU)
Scripts Tests (CPU) etait rouge sur main (run 35612584784, 14:30Z) sur un seul
test : test_retroactive_control_sees_third_pair_pre_consolidation, en
"checkout-index ... returned non-zero exit status 128". Le test extrait un arbre
HISTORIQUE via read-tree + checkout-index, sur le checkout partiel des workflows
du depot (scripts-tests.yml L195-205 : fetch-depth 0 + filter blob:none).
Mecanisme reproduit avec controle negatif sur un clone blob:none reel, remote
promisor rendu injoignable :
read-tree rc=0
checkout-index rc=128
fatal: could not fetch <sha> from promisor remote
checkout-index n'est PAS en cause : il est bien fetch-aware (2364 fichiers
extraits du meme clone quand le remote repond). C'est le FETCH qui echoue -- et
sur le runner il echoue sous le meme quota d'installation dont le 403 saturait
l'agregateur PR gate au meme moment (15:47Z / 15:52Z). Un seul quota sature
avait donc deux victimes, et la seconde se lisait comme une regression du
scanner.
D'ou l'imputation fausse : check=True + capture_output=True avalait le stderr de
git, ne laissant dans le log CI qu'un "exit status 128" nu -- invisible a qui ne
dispose que du check. Flaky par construction : vert a 12:36Z (head dc0ccbf),
rouge a 14:30Z (head 54d510f), sans aucun commit sur ce test entre les deux
(workdir promisor chaud vs froid).
Le correctif :
- _run_git() remonte le stderr de git dans tous les chemins d'echec ;
- PromisorObjectUnavailable est levee quand git rapporte un fetch promisor en
echec ("promisor remote") ;
- le test traduit EXACTEMENT cette classe en pytest.skip motive (non jouable),
et rien d'autre : revision invalide, arbre corrompu ou assertion du scanner
restent des echecs durs (fail-closed preserve).
Validation, 4 bras :
- controle (fichier d'origine, clone blob:none, promisor casse) : FAILED exit
128 -- reproduit la CI a l'identique ;
- fichier corrige, meme clone, promisor casse : 1 skipped, cause reelle dans le
motif ;
- fichier corrige, promisor retabli (blobs froids) : 8 passed -- le garde mord
toujours ;
- clone complet : 8 passed.
Portee : un seul test du depot materialise des objets git ainsi (grep sur
checkout-index / read-tree / GIT_INDEX_FILE) -- la classe est d'un seul membre.
Cause racine (saturation du quota d'installation) hors perimetre.
Closes #17253
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Trivial-diff advisory (#15740, non bloquant). |
|
[ADJOINT PREFLIGHT] [Tell c.81 - BLOCKED-WITH-SUBSTANCE] PR gate FAIL (Scripts Tests CPU failure). Cycle 12 hub secretaire. |
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels |
|
[ADJOINT PREFLIGHT] Lecture complète à la tête |
Grain: LIGHT/test -- lane myia-po-2026:CoursIA -- prev: LIGHT/docs #17252
Quoi:
Scripts Tests (CPU)etait rouge surmainsur un seul test, parce qu'un fetch promisor en echec pendant l'extraction d'un arbre historique sortait en 128 — et le test jetait le message de git, rendant le rouge opaque. Le helper remonte desormais le stderr et traduit la seule classe « objet non materialisable » en test non jouable ; tout le reste reste un echec dur.Preuve: mecanisme reproduit avec controle negatif (4 bras ci-dessous) ;
Closes #17253.Perimetre: 1 fichier de test, +56/−17. Hors scope : la cause racine (saturation du quota d'installation), et les 2 rouges
PR gatede mes PRs en vol (#17230/#17233/#17237) qui sont un 403 et non du contenu.Le rouge, et pourquoi il se lisait mal
Scripts Tests (CPU)surmain:dc0ccbfd54d510f0Aucun commit ne touche ce test entre les deux : le rouge depend de l'etat du workdir du runner, pas du contenu. Le log CI ne portait que :
fatal: could not fetch <sha> from promisor remote— la cause — etait avalee parcheck=True, capture_output=True. C'est ce qui a fait classer ce rouge « herite de la base » et l'a laisse plusieurs heures sans diagnostic.Le mecanisme, mesure
Le checkout des workflows est un clone partiel (
scripts-tests.ymlL195-205 :fetch-depth: 0+filter: blob:none) : tous les commits sont presents — donc leskipif(_commit_exists(...))du test ne se declenche pas — mais aucun blob. Le test extrait l'arbre PRE-consolidation parread-tree+checkout-index, ce qui exige les blobs historiques.Sur un clone
blob:nonereel, remote promisor rendu injoignable :checkout-indexn'est pas fautif — il est bien fetch-aware : sur le meme clone avec un remote qui repond, il materialise 2364 fichiers (rc=0). Le docstring du test supposait cette voie sure ; elle l'est, sauf quand le remote ne repond pas. C'est le fetch qui echoue.Deux victimes pour un seul quota
Le fetch promisor du runner utilise le meme token d'installation dont le quota renvoyait, au meme moment,
API rate limit exceeded for installation (HTTP 403)a l'agregateurPR gate(mesure 15:47Z sur #17249 et 15:52Z sur #17252). Un seul quota sature faisait donc deux degats : l'agregateur du gate, et le fetch paresseux des blobs — le second sous la forme d'un rouge de check requis, avec une imputation fausse (le test, pas le quota).Validation — 4 bras, dont un controle negatif
blob:noneblob:noneblob:noneLe bras 1 est le controle qui qualifie le correctif : meme clone, meme panne, seul le fichier change. Le bras 3 est celui qui interdit de lire ce correctif comme un affaiblissement : quand les objets sont materialisables, les assertions du controle retroactif s'executent normalement.
Ce qui change dans le code
_run_git(): lance git et, sur echec, remonte le stderr — plus aucunexit status Nnu ;PromisorObjectUnavailable: levee quand git rapportepromisor remote(cause d'infrastructure) ;pytest.skipmotive. Une revision invalide, un arbre corrompu ou une assertion du scanner restent des echecs durs — fail-closed preserve.Portee
Un seul test du depot materialise des objets git ainsi (
grepsurcheckout-index/read-tree/GIT_INDEX_FILEdansscripts/) : la classe est d'un seul membre, le correctif la couvre entierement. Tout test futur qui extrairait un arbre historique sur un checkoutblob:nonedevra traiter la meme classe.Cause racine hors perimetre : la saturation du quota d'installation GitHub n'est pas traitee ici. Ce correctif empeche qu'elle se transforme en rouge de check requis et en imputation fausse — il ne l'empeche pas d'arriver.
Closes #17253🤖 Generated with Claude Code