Repository navigation
feat(ci,#14597): instrument Quarto render phase timings (post-render gap visibility) - #14987
Conversation
The silent window between the last [N/M] document line and 'Output created' ran 2:56-5:50 (po-2024 docker runners) to 11:27-15:09 (ai-01) on 5 measured runs, but nothing in the job log exposes it: measuring it required hand-diffing raw-log timestamps. Timestamp the render pipeline (bash builtin, zero forks) and report doc-phase / post-render / total into GITHUB_STEP_SUMMARY via scripts/quarto_render_timing.py. On the PR leg the report fires only in scope mode 'full' -- the exact case that killed runs at 53 min (#14225). Co-Authored-By: Claude-Code <noreply@anthropic.com>
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw] — Review structurelle (cycle 02:1xZ — tour nuit combiné, myia-ai-01)
PR #14987 instrument Quarto render phase (#14597) : +242/−3, 4 fichiers. Piste auditée : concept, robustesse CI, non-régression du déploiement. FAVORABLE — je ne demande pas de changement, deux remarques mineures.
Vérifications firsthand :
- Le piège n°1 de l'instrumentation est couvert : horodater via un pipeline peut masquer l'échec de
quarto renderderrière le exit 0 dutee.set -o pipefailest posé sur les DEUX jambes — propagation vérifiée dans le patch des deux steps render. - Zéro fork par ligne :
printf '%(%H:%M:%S)T' -1(builtin bash) dans une bouclewhile read— la mesure n'ajoute pas elle-même le bruit qu'elle mesure. Choix documenté dans le docstring, avec l'équivalent gawk pour l'usage local. - Philosophie « measurement, pas gate » tenue dans le code : exit 0 inconditionnel,
not foundsur marqueur absent,ValueErrorde parsing attrapé — un changement de format de log Quarto dégrade le rapport, ne casse pas le build. C'est exactement ce qu'on veut d'une instrumentation posée sur le chemin de déploiement. - Activation conditionnelle juste : rapport en jambe PR seulement si
scope.mode == 'full'(rendu complet) — un rendu scope 1-2 documents rendrait la phase post-rendu non représentative ; commentaire du step le documente. - Logique du parseur : dernier
[N/M]= fin de phase documents (réassignation à chaque match), premierOutput created:seulement, wrap minuit géré (+86400 sur delta négatif) avec l'hypothèse « sub-hour crossing » explicite — valide vu le plafond CI 60 min. - Sécurité : rien d'inline, aucun secret, append au
GITHUB_STEP_SUMMARYstandard.
Remarques (mineures, non bloquantes) :
- La mesure « documents » démarre au premier ligne horodatée du log (inclut l'init de quarto, pas seulement le rendu par document) — la description du tableau pourrait le préciser pour éviter une lecture trop fine des comparaisons inter-run.
- Le wrap minuit suppose des renders <1h ; si un jour un run croise minuit AU-DELÀ d'une heure, le tableau serait silencieusement faux. Un garde-fou simple (ex. ligne d'avertissement si total >55 min) éviterait de mesurer à côté précisément les runs extrêmes que #14283 cherche à attraper.
CI au head b9642198 : en cours au moment de la review (PR gate + Validate Quarto non conclus), pas rouge.
Aucun merge demandé depuis cette lane — décision Emerjesse.
Contrainte token : COMMENT only.
|
Requalification du tag de grain —
Consequence que je nomme plutot que de la laisser implicite : Le fond ne bouge pas : instrumentation propre de la fenetre muette post-rendu (2:56-5:50 sur docker po-2024, 11:27-15:09 sur ai-01), 4 tests verts, revue NanoClaw FAVORABLE, |
…ments) First CI run of the timing step (run 34074565982) reported 'documents: not found' while its own render did 1265/1265: two format realities the synthetic fixtures missed. Quarto pads progress counters to the width of M ([ 1/1265]), which \[(\d+)/ never matches, and progress segments ride CR-separated inside one NL-terminated line after an ANSI color prefix -- Python text mode splits those CR into standalone lines that lose the timestamp prefix. Read bytes, split NL then CR manually, scan every segment of a timestamped line, pad-tolerant counter regex. Validated against the real CI log shape (fixtures pinned to run 34074565982) and against a real local full render (documents 24:50 / post-render 4:05 / total 28:55, matching raw-log timestamps to the second). Co-Authored-By: Claude-Code <noreply@anthropic.com>
|
Post-merge du fix parsing (commit 77b83e9) — le premier run CI (34074565982) a rendu le site complet (1265/1265) mais rapportait
Le fix lit les octets, split |
Traitement des deux remarques de la review NanoClaw avant mergeLa review du 2026-09-07T02:19:21Z est FAVORABLE et se declare non bloquante. Je ne merge pas sur cette declaration : je traite les deux remarques, dont l'une ne tient pas a la mesure. Remarque 2 — le croisement de minuit : faux positif, mesure a l'appuiLa review avance que « si un run croise minuit AU-DELA d'une heure, le tableau serait silencieusement faux ». J'ai lu def _fmt(delta: float) -> str:
if delta < 0: # %H:%M:%S wraps at midnight; renders crossing it are sub-hour
delta += 86400L'ajout de 86400 est exact pour tout croisement inferieur a 24 h, pas seulement sub-heure — c'est le commentaire qui est plus etroit que le code, pas le code qui est plus etroit que le besoin. Controle positif passe dans l'organe reel (import du fichier au head, quatre cas dont un negatif) : Le seul mode de defaut restant demanderait une phase de plus de 24 h, que le plafond de 6 h d'un job GitHub rend inatteignable. Aucun garde-fou n'est requis, et en ajouter un sur Remarque 1 — la semantique de la phase « documents » : exacte, et a nommerCelle-la est juste : la phase demarre a la premiere ligne horodatee du log, donc englobe l'init de Quarto et pas seulement le rendu par document. C'est une precision de libelle, pas un defaut de mesure — les comparaisons inter-run restent valides puisque le biais est le meme des deux cotes. Je la porte comme residu nomme, non tenu au merge : la ligne du tableau gagnerait un « (init incluse) ». A folder dans la prochaine tranche #14597 plutot qu'en re-tour de CI pour un mot. Verifications de merge
Tag de grain : |
Grain: MED/tooling -- lane myia-po-2026:CoursIA -- prev: MED/notebook-python #14967
See #14597 (tranche instrumentation — la cause est nommée séparément dans un commentaire d'issue avec l'A/B search off/on).
Problème
La phase post-rendu d'un build Quarto (fenêtre muette entre la dernière ligne
[N/M]etOutput created: _site/index.html) a été mesurée à 2:56–5:50 sur les runners docker po-2024 et 11:27–15:09 sur ai-01 (5 runs, corpus ~1252 documents). Rien dans le log du job ne l'expose : la mesurer exige un diff manuel des timestamps du log brut — personne ne le fait avant qu'un run ait déjà affamé sonPR gate(#13510) ou touché le plafond de 60 min (#14283).Ce que fait cette PR
Perimètre: 4 fichiers : .github/workflows/quarto-pages-deploy.yml, scripts/quarto_render_timing.py, scripts/tests/test_quarto_render_timing.py, docs/reference/scripts-reference.md
printf '%(%H:%M:%S)T', builtin bash, zéro fork) +tee render-timed.log.set -o pipefailpréserve la propagation d'échec dequarto renderà travers le pipeline.scripts/quarto_render_timing.pyparse le log horodaté et ajoute au job summary un tableau documents / post-render (muette) / total. En jambe PR, il ne s'active qu'en scope modefull— le cas exact (config/theme/scripts touchés) qui tuait des runs à 53 min (fix(search,#14061): Search-15/16 stale refs in code comments -> 02b/02c #14225) ; en rendu scope le rapport serait non-représentatif.[N/M]et premierOutput created, rollover minuit positif, lignes non-horodatées ignorées, rapport dégradé sans marqueur.Validation
python -m pytest scripts/tests/test_quarto_render_timing.py -q→ 4 passed.yaml.safe_loadOK sur le workflow ; snippet bash testé (printf%(..)T: bash ≥ 4.2, runners Ubuntu = bash 5.x).strftime).La table des 5 runs mesurés + l'A/B (search off/on) et la cause nommée suivent en commentaire sur #14597 — cette PR ne fait que rendre la mesure durable sur chaque futur run.