ci: split check.yml, drop dead caches, prebuild cargo-audit (#232) #309

Merged
maximus merged 2 commits from issue-232-split-ci-workflows into main 2026-07-27 22:53:17 +00:00
Owner

Resolves #232

Split de check.yml en check-rust.yml + check-frontend.yml, retrait des caches morts, cargo-audit en binaire pre-buildé, et nouveau audit.yml quotidien.

Pourquoi

Le job rust coutait 21m44s sur chaque PR alors qu'environ 1 PR sur 40 touche src-tauri/. Le runner est a capacite 1 : le job frontend fait la queue derriere, donc chaque PR payait ~24,5 min de feedback.

Chrono du run 326 (2026-07-21, PR #304) — 12m15s des 21m44 sont du pur gaspillage :

Etape Duree Sort
cargo install cargo-audit (compile release) 4m41s recompile a chaque run
Post: save target/ 6m11s reserveCache failed: Request timeout
Post: save registry 43s reserveCache failed: Request timeout
Restore des 2 caches ~40s getCacheEntry failed: Request timeout -> MISS

Le cache ne marche a aucun des deux bouts : le restore timeout aussi desormais, ce que la baseline du 30 juin (#231) ne montrait pas — elle n'avait qu'un MISS propre.

Ce que fait la PR

  • check-rust.ymlpaths: [src-tauri/**, self], concurrency: ci-rust-*, permissions: contents: read, etape d'install verbatim, CARGO_INCREMENTAL=0 + CARGO_PROFILE_TEST_DEBUG=0, aucune etape de cache, cargo-audit via taiki-e/install-action.
  • check-frontend.ymlpaths-ignore (denylist), concurrency: ci-frontend-*, cache npm retire lui aussi (meme diagnostic : 23s gaspillees par run sur un job de 2m27).
  • audit.yml — RustSec quotidien 06:00 UTC + workflow_dispatch, sans toolchain Rust (cargo-audit lit seulement Cargo.lock), echec bloquant.
  • docs/architecture.md + CLAUDE.md — la section CI/CD etait perimee sur deux points independants de cette PR : trigger push retire en #171, et jobs decrits « en parallele » alors qu'ils sont sequentiels.

Deux ecarts assumes vs le corps d'origine de l'issue, tous deux tranches a l'analyse : le cache npm part aussi, et le filtre frontend est une denylist (job a 2,5 min : le faire tourner pour rien est bon marche, ne PAS le faire tourner silencieusement ne l'est pas ; le job cher garde un allowlist strict).

Trou de couverture ferme au passage

Aucun des deux workflows ne filtre plus sur branches:. branches: [main] ne matchait pas une PR stackee sur une autre branche de feature — ce que produit /autopilot : les PR #305, #306, #307 et #308 de la milestone feature-gating n'ont aucune tache CI, seules #303 et #304 (base main) ont tourne. 4 PR sur 5 mergeaient sans check.

cargo audit garde continue-on-error (les advisories peuvent tomber sur des crates sans rapport) mais perd le || true qui masquait aussi les pannes d'outillage ; l'etape d'install, elle, est bloquante.

Miroir GitHub intouche (#233 : il ne recoit aucune PR).

Verification

Simulation des filtres sur 7 scenarios (semantique de glob GitHub : * ne traverse pas /, ** oui) :

Scenario check-rust check-frontend
cette PR oui oui
frontend seul non oui
rust seul oui non
docs seuls non non
mixte rust+front oui oui
config racine (vite.config.ts) non oui
release.yml seul non non

871 tests vitest verts. YAML des 4 workflows valide.

Deux criteres ne sont pas auto-verifiables par cette PR, a controler explicitement :

  1. « Une PR frontend-only ne declenche pas check-rust » -> observable seulement sur la PR suivante (celle-ci touche check-rust.yml, donc son self-path la declenche a dessein).
  2. audit.yml -> testable seulement apres merge : Gitea lit schedule et workflow_dispatch depuis la branche par defaut. A declencher a la main une fois merge. Si cargo-audit n'est pas trouve sur le PATH sans toolchain cargo, le correctif est d'ajouter rustup a ce workflow (1 etape).

Cible attendue sur le run de cette PR : job rust ~9-10 min au lieu de 21m44.

Resolves #232 Split de `check.yml` en `check-rust.yml` + `check-frontend.yml`, retrait des caches morts, `cargo-audit` en binaire pre-buildé, et nouveau `audit.yml` quotidien. ## Pourquoi Le job rust coutait **21m44s sur chaque PR** alors qu'environ **1 PR sur 40** touche `src-tauri/`. Le runner est a capacite 1 : le job frontend fait la queue derriere, donc chaque PR payait ~24,5 min de feedback. Chrono du run 326 (2026-07-21, PR #304) — **12m15s des 21m44 sont du pur gaspillage** : | Etape | Duree | Sort | |---|---|---| | `cargo install cargo-audit` (compile release) | 4m41s | recompile a chaque run | | Post: save `target/` | 6m11s | `reserveCache failed: Request timeout` | | Post: save registry | 43s | `reserveCache failed: Request timeout` | | Restore des 2 caches | ~40s | `getCacheEntry failed: Request timeout` -> MISS | Le cache ne marche a **aucun des deux bouts** : le restore timeout aussi desormais, ce que la baseline du 30 juin (#231) ne montrait pas — elle n'avait qu'un MISS propre. ## Ce que fait la PR - `check-rust.yml` — `paths: [src-tauri/**, self]`, `concurrency: ci-rust-*`, `permissions: contents: read`, etape d'install verbatim, `CARGO_INCREMENTAL=0` + `CARGO_PROFILE_TEST_DEBUG=0`, **aucune etape de cache**, `cargo-audit` via `taiki-e/install-action`. - `check-frontend.yml` — `paths-ignore` (denylist), `concurrency: ci-frontend-*`, cache npm retire lui aussi (meme diagnostic : 23s gaspillees par run sur un job de 2m27). - `audit.yml` — RustSec quotidien 06:00 UTC + `workflow_dispatch`, sans toolchain Rust (`cargo-audit` lit seulement `Cargo.lock`), echec bloquant. - `docs/architecture.md` + `CLAUDE.md` — la section CI/CD etait perimee sur deux points independants de cette PR : trigger `push` retire en #171, et jobs decrits « en parallele » alors qu'ils sont sequentiels. Deux ecarts assumes vs le corps d'origine de l'issue, tous deux tranches a l'analyse : le cache npm part aussi, et le filtre frontend est une denylist (job a 2,5 min : le faire tourner pour rien est bon marche, ne PAS le faire tourner silencieusement ne l'est pas ; le job cher garde un allowlist strict). ## Trou de couverture ferme au passage Aucun des deux workflows ne filtre plus sur `branches:`. `branches: [main]` ne matchait pas une PR stackee sur une autre branche de feature — ce que produit `/autopilot` : **les PR #305, #306, #307 et #308 de la milestone feature-gating n'ont aucune tache CI**, seules #303 et #304 (base `main`) ont tourne. 4 PR sur 5 mergeaient sans check. `cargo audit` garde `continue-on-error` (les advisories peuvent tomber sur des crates sans rapport) mais perd le `|| true` qui masquait aussi les pannes d'outillage ; l'etape d'install, elle, est bloquante. Miroir GitHub intouche (#233 : il ne recoit aucune PR). ## Verification Simulation des filtres sur 7 scenarios (semantique de glob GitHub : `*` ne traverse pas `/`, `**` oui) : | Scenario | check-rust | check-frontend | |---|---|---| | cette PR | oui | oui | | frontend seul | **non** | oui | | rust seul | oui | **non** | | docs seuls | non | non | | mixte rust+front | oui | oui | | config racine (`vite.config.ts`) | non | oui | | `release.yml` seul | non | non | 871 tests vitest verts. YAML des 4 workflows valide. **Deux criteres ne sont pas auto-verifiables par cette PR**, a controler explicitement : 1. « Une PR frontend-only ne declenche pas check-rust » -> observable seulement sur la **PR suivante** (celle-ci touche `check-rust.yml`, donc son self-path la declenche a dessein). 2. `audit.yml` -> testable seulement **apres merge** : Gitea lit `schedule` et `workflow_dispatch` depuis la branche par defaut. A declencher a la main une fois merge. Si `cargo-audit` n'est pas trouve sur le PATH sans toolchain cargo, le correctif est d'ajouter rustup a ce workflow (1 etape). Cible attendue sur le run de cette PR : job rust **~9-10 min** au lieu de 21m44.
maximus added 1 commit 2026-07-25 00:27:10 +00:00
ci: split check.yml, drop dead caches, prebuild cargo-audit (#232)
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m43s
PR Check — Rust / rust (pull_request) Successful in 8m55s
263ebe1495
The rust job cost 21m44s on every PR while only ~1 PR in 40 touches
src-tauri/, and the runner has capacity 1 — the frontend job queues behind
it, so every PR paid ~24.5 min of feedback.

Measured on run 326 (2026-07-21), 12m15s of that was pure waste:
- 6m54s tarring target/ and the cargo registry for saves that time out
  against the runner's unreachable cache server (#234). The restore times
  out into a miss too, so nothing was ever cached at either end.
- 4m41s recompiling cargo-audit from source on every run.
- ~40s on the two doomed restores.

Split check.yml into check-rust.yml (paths: src-tauri/**) and
check-frontend.yml (paths-ignore denylist), drop every actions/cache step
until #234 is fixed, and install cargo-audit as a prebuilt binary via
taiki-e/install-action. The audit step keeps continue-on-error — advisories
are informational and can land on unrelated crates — but loses the `|| true`
that also hid tooling failures; the install step is blocking.

The frontend filter is a denylist on purpose: that job costs ~2.5 min, so
running it needlessly is cheap while silently not running it is not. The
expensive job keeps a strict allowlist.

Neither workflow filters on `branches:` anymore. `branches: [main]` never
matched a PR stacked on another feature branch, which is what /autopilot
produces: PRs #305-#308 of the feature-gating milestone ran no CI at all.

Adds audit.yml for daily RustSec coverage, since check-rust.yml now only
runs on Rust PRs. It skips the Rust toolchain entirely — cargo-audit only
reads Cargo.lock — so it costs ~1-2 min rather than the ~22 a scheduled
check-rust would burn daily on a capacity-1 runner.

The GitHub mirror is left untouched (#233: it receives no PRs).

Expected: Rust PR ~9-10 min, frontend-only PR ~2.5 min instead of ~24.5.

Resolves #232
Author
Owner

/pr-review — APPROVE

Objectif atteint et verifie sur le run reel (head 263ebe1) : job rust 8m55s contre 21m44 en baseline (cible 9-10 min tenue), frontend 1m43s. 106 tests Rust + 871 vitest verts.

Verifications

Point Resultat
cargo-audit en binaire pre-buildé OK — installe en ~1s dans /root/.cargo/bin/cargo-audit (v0.22.2, checksum sha256 verifie), contre 4m41s de compilation
L'override PATH du job ne masque pas le binaire OK — l'audit a reellement tourne (advisory DB fetchee, 666 crates scannes) : rien d'avale par continue-on-error
Aucune etape de cache OK — plus aucun reserveCache failed / getCacheEntry failed dans le log
Risque « required check skippe » Nul — enable_status_check: false sur la protection de main
paths-ignore supporte (Forgejo 8.0.3 / gitea 1.22) OK — check-frontend s'est declenche normalement
Conformite au plan #232 OK — les 8 items, y compris les 2 ecarts (cache npm, denylist frontend) et l'absence d'entree CHANGELOG, tous tranches dans le corps de l'issue
Etape d'install verbatim OK — libdbus-1-dev & co preserves
Docs OK — CLAUDE.md + docs/architecture.md exacts (4 workflows, arbre coherent, miroir dormant)

Bonus non signale dans la description : permissions: contents: read n'existait sur aucun job auparavant.

Suggestions (non bloquantes)

1. Le glob src-tauri/** reste non prouve. Ce run ne valide que l'entree chemin-exact .forgejo/workflows/check-rust.yml de l'allowlist — le ** n'a pas encore ete exerce. Le mode d'echec est silencieux et tombe sur la PR Rust (1 sur 40) : ni cargo check ni cargo test. A controler a l'oeil sur la premiere PR qui touche src-tauri/ ; les criteres d'acceptation de #232 ne couvrent que la direction inverse (frontend-only ne declenche pas rust).

2. audit.yml sera rouge des son premier run, et tous les jours ensuite. Le log de cette PR le montre : error: 9 vulnerabilities found! (2x quick-xml 7.5 high, 4x rustls-webpki, 2x tar, 1x rsa) — les 9 de #310. Un job quotidien rouge en permanence ne signale plus l'avis nouveau : le 10e ressemblera aux 9 connus. Deux sorties : lander #310 avant, ou passer --ignore RUSTSEC-... sur les advisories tries pour que le job reparte au vert. RUSTSEC-2023-0071 (rsa, « No fixed upgrade is available! ») demandera un --ignore permanent de toute facon.

3. Asymetrie install bloquant / audit non bloquant. Une panne de taiki-e/install-action (rate-limit GitHub, reseau) casse le job rust pour une etape dont le resultat est explicitement informatif. Le choix est assume dans #232, mais maintenant qu'audit.yml est le vrai canal, continue-on-error: true sur l'install se defend.

4. .claude/** absent du paths-ignore frontend — un commit qui ne touche qu'un SKILL.md declenche 2m30 de build+tests. Coherent avec le raisonnement fail-safe, mais l'ajout est gratuit.

5. References perimees a check.yml dans .claude/skills/release/SKILL.md (l. 18 et 57). Le fond reste vrai (rien ne tourne sur main), seul le nom du fichier a disparu. docs/adr/0006 et spec-issue-66-*.md en parlent aussi, mais ce sont des archives — a laisser.

6. CARGO_PROFILE_TEST_DEBUG: 0 ne couvre que le profil test ; les dependances se compilent sous dev et gardent leurs infos de debug. CARGO_PROFILE_DEV_DEBUG: 0 gratterait un peu de link time. Micro-optim, la cible est deja tenue.

Sur les 2 points « non auto-verifiables » de la description

Le second est largement de-risque par le log : install-action lance lui-meme cargo-audit audit --version apres installation, soit exactement la forme d'invocation d'audit.yml. Reste l'inconnue de l'emplacement d'install quand rustup n'a jamais tourne ($HOME/.cargo/bin inexistant) — le fallback documente (ajouter rustup) tient.

## /pr-review — APPROVE Objectif atteint et **verifie sur le run reel** (head `263ebe1`) : job rust **8m55s** contre 21m44 en baseline (cible 9-10 min tenue), frontend **1m43s**. 106 tests Rust + 871 vitest verts. ### Verifications | Point | Resultat | |---|---| | `cargo-audit` en binaire pre-buildé | OK — installe en **~1s** dans `/root/.cargo/bin/cargo-audit` (v0.22.2, checksum sha256 verifie), contre 4m41s de compilation | | L'override `PATH` du job ne masque pas le binaire | OK — l'audit a reellement tourne (advisory DB fetchee, 666 crates scannes) : rien d'avale par `continue-on-error` | | Aucune etape de cache | OK — plus aucun `reserveCache failed` / `getCacheEntry failed` dans le log | | Risque « required check skippe » | Nul — `enable_status_check: false` sur la protection de `main` | | `paths-ignore` supporte (Forgejo 8.0.3 / gitea 1.22) | OK — check-frontend s'est declenche normalement | | Conformite au plan #232 | OK — les 8 items, y compris les 2 ecarts (cache npm, denylist frontend) et l'absence d'entree CHANGELOG, tous tranches dans le corps de l'issue | | Etape d'install verbatim | OK — `libdbus-1-dev` & co preserves | | Docs | OK — `CLAUDE.md` + `docs/architecture.md` exacts (4 workflows, arbre coherent, miroir dormant) | Bonus non signale dans la description : `permissions: contents: read` n'existait sur aucun job auparavant. ### Suggestions (non bloquantes) **1. Le glob `src-tauri/**` reste non prouve.** Ce run ne valide que l'entree chemin-exact `.forgejo/workflows/check-rust.yml` de l'allowlist — le `**` n'a pas encore ete exerce. Le mode d'echec est silencieux et tombe sur la PR Rust (1 sur 40) : ni `cargo check` ni `cargo test`. A controler a l'oeil sur la premiere PR qui touche `src-tauri/` ; les criteres d'acceptation de #232 ne couvrent que la direction inverse (frontend-only ne declenche pas rust). **2. `audit.yml` sera rouge des son premier run, et tous les jours ensuite.** Le log de cette PR le montre : `error: 9 vulnerabilities found!` (2x quick-xml 7.5 high, 4x rustls-webpki, 2x tar, 1x rsa) — les 9 de #310. Un job quotidien rouge en permanence ne signale plus l'avis *nouveau* : le 10e ressemblera aux 9 connus. Deux sorties : lander #310 avant, ou passer `--ignore RUSTSEC-...` sur les advisories tries pour que le job reparte au vert. RUSTSEC-2023-0071 (`rsa`, « No fixed upgrade is available! ») demandera un `--ignore` permanent de toute facon. **3. Asymetrie install bloquant / audit non bloquant.** Une panne de `taiki-e/install-action` (rate-limit GitHub, reseau) casse le job rust pour une etape dont le resultat est explicitement informatif. Le choix est assume dans #232, mais maintenant qu'`audit.yml` est le vrai canal, `continue-on-error: true` sur l'install se defend. **4. `.claude/**` absent du `paths-ignore` frontend** — un commit qui ne touche qu'un `SKILL.md` declenche 2m30 de build+tests. Coherent avec le raisonnement fail-safe, mais l'ajout est gratuit. **5. References perimees a `check.yml`** dans `.claude/skills/release/SKILL.md` (l. 18 et 57). Le fond reste vrai (rien ne tourne sur `main`), seul le nom du fichier a disparu. `docs/adr/0006` et `spec-issue-66-*.md` en parlent aussi, mais ce sont des archives — a laisser. **6. `CARGO_PROFILE_TEST_DEBUG: 0` ne couvre que le profil `test`** ; les dependances se compilent sous `dev` et gardent leurs infos de debug. `CARGO_PROFILE_DEV_DEBUG: 0` gratterait un peu de link time. Micro-optim, la cible est deja tenue. ### Sur les 2 points « non auto-verifiables » de la description Le second est largement de-risque par le log : install-action lance lui-meme `cargo-audit audit --version` apres installation, soit exactement la forme d'invocation d'`audit.yml`. Reste l'inconnue de l'emplacement d'install quand rustup n'a jamais tourne (`$HOME/.cargo/bin` inexistant) — le fallback documente (ajouter rustup) tient.
maximus added 1 commit 2026-07-25 01:02:15 +00:00
ci: ignore .claude/ in the frontend filter, drop stale check.yml ref
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m44s
PR Check — Rust / rust (pull_request) Successful in 9m6s
7779f7dc52
Follow-up on the review of #232:

- .claude/ is tracked (rules + skills) and cannot affect the frontend build,
  so a change confined to it no longer queues a 1m43s job for nothing.
- The release skill's pre-flight step named check.yml, which this PR deletes.
  The reasoning still holds — the check workflows only run on PRs, never on
  main, so a merged tip has never been seen by CI — only the filename moved.
  Its dated changelog entry is left alone.

Resolves #232
maximus merged commit 7779f7dc52 into main 2026-07-27 22:53:17 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#309
No description provided.