Repository navigation
Conversation
Nothing in CI built the slides on a pull request. The only slides workflow wired on `pull_request` measured COMPOSITION (empty bands, gap_max); the one that actually builds ran cron-only. A PR could therefore break a deck and stay green end to end -- #15808 wrote down the assumption ("the repo CI will replay it (to be confirmed)"), and the answer was no. That is the one job a CI exists to make unnecessary. The wiring, following the issue's own four points: - a `pull_request` leg filtered on `paths: ['slides/**']` on the EXISTING build workflow -- one build path, not a second implementation that will drift from the first (point 4); - it builds only the decks of the diff, and all of them when shared slides infra moved (point 1); - it BLOCKS: exit 1 on a build failure, so the check-run goes red on the PR that introduced it (point 2). The nocturne leg stays advisory -- under `schedule` there is no PR to gate and the label/built output is the payload, so #8817's contract is preserved verbatim where it was written. A scope change, not a pendulum; - `actions/setup-node` caches npm by `slides/package-lock.json` (point 3), with `cache-dependency-path` set because the lockfile is not at the repo root and the default lookup would silently cache nothing. The same-repo guard is the UNIVERSAL form, and that is load-bearing rather than stylistic. The direct form (`head.repo.full_name == github.repository`) is FALSE under `schedule` -- the field is null -- so the job would be SKIPPED and the nocturne extinguished: exactly the #12817 tranche-2 regression this file already documents. Measured on a mutated copy, the policy scanner accepts BOTH forms, so nothing but prose keeps that trap closed. Second, unplanned find: the discovery was ALREADY red on main. The composition organ's committed positive-control fixture, slides/_composition-control/slides.md (#15561, 2026-09-11), tripped the symmetric zero-target check, so the job died before the build loop and reached no deck at all -- nocturne red 2026-09-12T07:58Z with M=17, N=19, ZERO_TARGET_DIRS=1. Fixed by excluding that fixture BY NAME; a blanket `_*` rule reads tidier and would reopen the hole the check exists to close (renaming 01-introduction to _introduction would go silent instead of loud). Verification: - scripts/ci/check_self_hosted_runner_policy.py --check: 159 workflows OK - scripts/tests/test_check_self_hosted_runner_policy.py: 58/58 - scripts/ci/check_unique_check_run_names.py --check: no duplicates - guard negative control on a copy: removing `if:` -> VIOLATION SAME_REPO_GUARD rc=1; the direct form -> OK rc=0 (the blind spot above) - the extracted step replayed locally on three simulated diffs: broken deck -> ::error:: + exit 1; sound deck -> "build cleanly" + exit 0; no deck touched -> exit 0 Closes #15835 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Path-collision (organ #13359/#13615)Cette PR #15848 (
|
|
G-VAR-2 light cap reached (advisory, non bloquant). |
Grain: LIGHT/test — lane myia-po-2026:CoursIA — prev: LIGHT/notebook-python #15680
CONTROLE JETABLE (jumeau sain) — NE PAS MERGER. Ferme et branche supprimee une fois le verdict observe.
Acceptation 2 de #15835 : « Une PR qui casse volontairement un deck produit un check-run rouge attribue a cette PR. » Un gate qu'on n'a jamais vu rougir n'est pas un gate mesure, c'est un gate suppose.
Cette PR porte exactement deux choses :
slides/98-positive-control-sound/slides.md, un deck NEUF et valide.Le deck est additif : aucun deck de cours n'est touche. Attendu : le check-run du job
Slidev build (PR blocking, nocturne advisory)conclut success, en quelques minutes (cachenode_modules+ cache npm).🤖 Generated with Claude Code