CI: Forgejo — split workflows + rust-cache + cargo-audit pre-buildt #232

Closed
opened 2026-07-01 00:06:22 +00:00 by maximus · 2 comments
Owner

Refs: spec-decisions-ci-build-optimization.md + spec-plan-ci-build-optimization.md — RE-SEQUENCE post-baseline #231 (2026-06-30), puis re-analyse /analyze (2026-07-24).

Baseline re-mesuree — run 326 (2026-07-21, PR #304)

La baseline #231 tient toujours (job rust 21-22 min encore le 2026-07-21). Chrono exact par etape :

Etape Fenetre Duree
Install (apt + Node + rustup) 02:05:29 -> 02:07:20 1m51s
Checkout + restore cache (2 x timeout + MISS) 02:07:20 -> 02:08:03 43s
cargo check 02:08:03 -> 02:11:12 3m09s
cargo test (compile 4m00 + run 15s) 02:11:12 -> 02:15:29 4m17s
cargo install cargo-audit (compile release 4m34) + audit 02:15:29 -> 02:20:10 4m41s
Post: save target/ -> reserveCache failed 02:20:10 -> 02:26:21 6m11s, ECHOUE
Post: save registry -> reserveCache failed 02:26:21 -> 02:27:04 43s, ECHOUE
Total 21m44s

Nouveau vs #231 : le restore timeout aussi desormais (getCacheEntry failed: Request timeout), la baseline du 30 juin n'avait qu'un MISS propre. ~12m15s des 21m44 sont retirables sans toucher au VPS.

Trois constats qui revisent le cadrage

  1. Les 2 jobs ne tournent PAS en parallele — le runner est a capacite 1 : frontend demarre a la seconde ou rust finit, sur tous les runs de l'historique. Le feedback reel d'une PR = rust + frontend = ~24,5 min, pour toutes les PR. Or 3 des 40 derniers commits first-parent de main touchent src-tauri/, dont 2 sont des chore: release (push sur main, ne declenche pas check.yml). Le path-filter fait donc passer la PR typique de 24,5 min a ~2,5 min : c'est le gain dominant, pas un effet de bord.
  2. Le risque « required check skippe » est nul — la protection de main a enable_status_check: false / status_check_contexts: null (whitelist de push seulement). Aucune PR ne peut rester bloquee sur un check qui ne tourne plus.
  3. Trou de couverture : les PR stackees ne recoivent aucune CIon.pull_request.branches: [main] ne matche pas une PR dont la base est une autre branche. Verifie sur la pile feature-gating : #305, #306, #307, #308 n'ont aucune tache CI ; seules #303 et #304 (base main) ont tourne. L'autopilot produit des piles lineaires en routine (3 des 4 dernieres milestones) -> 4 PR sur 5 mergent sans CI. Decision (2026-07-24) : corrige ici, puisque #232 reecrit deja ces lignes.

Travail a faire

  • Supprimer .forgejo/workflows/check.yml ; creer check-rust.yml + check-frontend.yml.
  • check-rust.yml : paths: [src-tauri/**, self] ; sans branches: (couvre les PR stackees) ; concurrency: ci-rust-${{ github.ref }} ; permissions: contents: read ; etape « install sysdeps + Node.js + toolchain » verbatim ; env CARGO_INCREMENTAL=0 / CARGO_PROFILE_TEST_DEBUG=0.
  • Retirer les 2 etapes de cache cargo (registry+git ET target). Point laisse ouvert dans l'ancien corps, tranche : restore et save echouent tous les deux, il n'y a rien a preserver. Commentaire pointant #234 pour la remise via rust-cache.
  • cargo-audit via https://github.com/taiki-e/install-action@v2 (tool: cargo-audit) : etape d'install sans continue-on-error (une panne d'outillage doit casser le job) ; etape cargo audit avec continue-on-error et sans || true (advisories visibles, non bloquantes).
  • check-frontend.yml : paths-ignore (denylist) ; concurrency: ci-frontend-${{ github.ref }} ; permissions: contents: read. Ecart assume vs l'ancien corps : le cache npm est retire lui aussi — meme diagnostic (Cache not found au restore + reserveCache failed au save), 23s gaspillees sur un job de 2m27 (~15 %), sur le job qui tournera desormais sur 39 PR sur 40.
  • audit.yml dedie : on: schedule quotidien + workflow_dispatch ; sans toolchain Rust (cargo-audit audit --file src-tauri/Cargo.lock) ; echec bloquant (c'est la notification). Retenu contre un schedule sur check-rust.yml, qui couterait ~22 min de runner/jour a capacite 1.
  • Corriger docs/architecture.md (l. 417-426) et CLAUDE.md section CI/CD : les deux sont perimes (trigger push retire en #171 ; jobs decrits « en parallele » alors qu'ils sont sequentiels).
  • Pas d'entree CHANGELOG : config CI, aucun impact utilisateur.

Choix de conception

  • Denylist pour le frontend, allowlist pour le rust. Le job cher garde un paths: strict ; le job a 2,5 min prend un paths-ignore. Si un fichier de config racine apparait plus tard, un allowlist arreterait silencieusement de le couvrir, alors qu'un denylist fait tourner un job court pour rien. Fail-safe du bon cote.
  • Miroir GitHub intouche#233 fermee (le miroir ne recoit aucune PR).

Criteres d'acceptation

  • Sur la PR d'implementation (touche check-rust.yml -> self-path) : check-rust vert, aucune etape de cache, cargo-audit installe en binaire (< 30s au lieu de 4m41).
  • Job rust ~9-10 min au lieu de 21m44 (cible revue a la baisse : l'ancien corps disait 11-12 min).
  • Sur la PR suivante frontend-only : check-rust ne se declenche pas ; feedback ~2,5 min au lieu de 24,5.
  • Sur une PR stackee (base != main) : la CI se declenche.
  • Post-merge : audit.yml declenchable via workflow_dispatch et vert.

Defere (follow-up apres #234)

  • Ajouter Swatinem/rust-cache@v2 (workspaces: "src-tauri -> target") une fois la connectivite serveur-de-cache reparee (#234), et remettre le cache npm cote frontend. Verifier alors un vrai Cache restored au run suivant.

Depends on #231 (baseline, fait). Prerequis pour rust-cache : #234.

Refs: spec-decisions-ci-build-optimization.md + spec-plan-ci-build-optimization.md — RE-SEQUENCE post-baseline #231 (2026-06-30), puis **re-analyse `/analyze` (2026-07-24)**. ## Baseline re-mesuree — run 326 (2026-07-21, PR #304) La baseline #231 tient toujours (job rust 21-22 min encore le 2026-07-21). Chrono exact par etape : | Etape | Fenetre | Duree | |---|---|---| | Install (apt + Node + rustup) | 02:05:29 -> 02:07:20 | 1m51s | | Checkout + restore cache (2 x timeout + MISS) | 02:07:20 -> 02:08:03 | 43s | | `cargo check` | 02:08:03 -> 02:11:12 | 3m09s | | `cargo test` (compile 4m00 + run 15s) | 02:11:12 -> 02:15:29 | 4m17s | | **`cargo install cargo-audit`** (compile release 4m34) + audit | 02:15:29 -> 02:20:10 | **4m41s** | | **Post: save `target/`** -> `reserveCache failed` | 02:20:10 -> 02:26:21 | **6m11s, ECHOUE** | | **Post: save registry** -> `reserveCache failed` | 02:26:21 -> 02:27:04 | **43s, ECHOUE** | | **Total** | | **21m44s** | Nouveau vs #231 : le **restore timeout aussi** desormais (`getCacheEntry failed: Request timeout`), la baseline du 30 juin n'avait qu'un MISS propre. ~12m15s des 21m44 sont retirables sans toucher au VPS. ## Trois constats qui revisent le cadrage 1. **Les 2 jobs ne tournent PAS en parallele** — le runner est a capacite 1 : `frontend` demarre a la seconde ou `rust` finit, sur tous les runs de l'historique. Le feedback reel d'une PR = rust + frontend = **~24,5 min, pour toutes les PR**. Or **3 des 40 derniers commits first-parent de `main` touchent `src-tauri/`**, dont 2 sont des `chore: release` (push sur main, ne declenche pas check.yml). Le path-filter fait donc passer la PR *typique* de 24,5 min a ~2,5 min : c'est le gain dominant, pas un effet de bord. 2. **Le risque « required check skippe » est nul** — la protection de `main` a `enable_status_check: false` / `status_check_contexts: null` (whitelist de push seulement). Aucune PR ne peut rester bloquee sur un check qui ne tourne plus. 3. **Trou de couverture : les PR stackees ne recoivent aucune CI** — `on.pull_request.branches: [main]` ne matche pas une PR dont la base est une autre branche. Verifie sur la pile feature-gating : #305, #306, #307, #308 n'ont **aucune** tache CI ; seules #303 et #304 (base `main`) ont tourne. L'autopilot produit des piles lineaires en routine (3 des 4 dernieres milestones) -> 4 PR sur 5 mergent sans CI. **Decision (2026-07-24) : corrige ici**, puisque #232 reecrit deja ces lignes. ## Travail a faire - [ ] Supprimer `.forgejo/workflows/check.yml` ; creer `check-rust.yml` + `check-frontend.yml`. - [ ] `check-rust.yml` : `paths: [src-tauri/**, self]` ; **sans** `branches:` (couvre les PR stackees) ; `concurrency: ci-rust-${{ github.ref }}` ; `permissions: contents: read` ; etape « install sysdeps + Node.js + toolchain » **verbatim** ; env `CARGO_INCREMENTAL=0` / `CARGO_PROFILE_TEST_DEBUG=0`. - [ ] **Retirer les 2 etapes de cache cargo** (registry+git ET target). Point laisse ouvert dans l'ancien corps, tranche : restore et save echouent tous les deux, il n'y a rien a preserver. Commentaire pointant #234 pour la remise via rust-cache. - [ ] `cargo-audit` via `https://github.com/taiki-e/install-action@v2` (`tool: cargo-audit`) : etape d'install **sans** `continue-on-error` (une panne d'outillage doit casser le job) ; etape `cargo audit` **avec** `continue-on-error` et **sans** `|| true` (advisories visibles, non bloquantes). - [ ] `check-frontend.yml` : `paths-ignore` (denylist) ; `concurrency: ci-frontend-${{ github.ref }}` ; `permissions: contents: read`. **Ecart assume vs l'ancien corps** : le cache npm est retire lui aussi — meme diagnostic (`Cache not found` au restore + `reserveCache failed` au save), 23s gaspillees sur un job de 2m27 (~15 %), sur le job qui tournera desormais sur 39 PR sur 40. - [ ] `audit.yml` dedie : `on: schedule` quotidien + `workflow_dispatch` ; sans toolchain Rust (`cargo-audit audit --file src-tauri/Cargo.lock`) ; echec bloquant (c'est la notification). Retenu contre un `schedule` sur check-rust.yml, qui couterait ~22 min de runner/jour a capacite 1. - [ ] Corriger `docs/architecture.md` (l. 417-426) et `CLAUDE.md` section CI/CD : les deux sont perimes (trigger `push` retire en #171 ; jobs decrits « en parallele » alors qu'ils sont sequentiels). - [ ] Pas d'entree CHANGELOG : config CI, aucun impact utilisateur. ## Choix de conception - **Denylist pour le frontend, allowlist pour le rust.** Le job cher garde un `paths:` strict ; le job a 2,5 min prend un `paths-ignore`. Si un fichier de config racine apparait plus tard, un allowlist arreterait silencieusement de le couvrir, alors qu'un denylist fait tourner un job court pour rien. Fail-safe du bon cote. - **Miroir GitHub intouche** — #233 fermee (le miroir ne recoit aucune PR). ## Criteres d'acceptation - [ ] Sur la PR d'implementation (touche `check-rust.yml` -> self-path) : `check-rust` vert, **aucune** etape de cache, `cargo-audit` installe en binaire (< 30s au lieu de 4m41). - [ ] Job rust **~9-10 min** au lieu de 21m44 (cible revue a la baisse : l'ancien corps disait 11-12 min). - [ ] Sur la PR suivante frontend-only : `check-rust` **ne se declenche pas** ; feedback ~2,5 min au lieu de 24,5. - [ ] Sur une PR stackee (base != `main`) : la CI se declenche. - [ ] Post-merge : `audit.yml` declenchable via `workflow_dispatch` et vert. ## Defere (follow-up apres #234) - [ ] Ajouter `Swatinem/rust-cache@v2` (`workspaces: "src-tauri -> target"`) une fois la connectivite serveur-de-cache reparee (#234), et remettre le cache npm cote frontend. Verifier alors un vrai `Cache restored` au run suivant. Depends on #231 (baseline, fait). Prerequis pour rust-cache : #234.
maximus added this to the spec-ci-build-optimization milestone 2026-07-01 00:06:22 +00:00
maximus added the
status:ready
type:infra
source:human
labels 2026-07-01 00:06:22 +00:00
Author
Owner

Ajustements issus de /review-spec (2026-06-30) — à intégrer en plus du body :

  • 🔴 Concurrency : chaque fichier splitté doit re-déclarer on.pull_request.branches:[main] ET un groupe concurrency DISTINCT (ci-rust-${{ github.ref }} / ci-frontend-${{ github.ref }}). Sinon, en héritant de ci-${{ github.ref }} + cancel-in-progress, les 2 workflows s'annulent mutuellement sur une PR mixte.
  • Conserver l'étape « install sysdeps + Node.js + toolchain » verbatim dans check-rust : rust-cache et taiki-e/install-action sont des actions JS qui exigent node dans le PATH.
  • Ajouter permissions: contents: read en tête de chaque nouveau workflow.
  • cargo-audit : ajouter un on: schedule quotidien (ou un workflow audit dédié sans paths:) pour garder la couverture RustSec hors des PR Rust ; retirer le || true (échouer sur erreur d'outillage, advisories non-bloquantes).
  • paths rust = src-tauri/** + self (retirer les globs **/*.rs redondants — tout le Rust est sous src-tauri/).
  • Dépendance assouplie : baseline (#231) capturée AVANT le merge, sinon parallélisable.

Détail : spec-plan-ci-build-optimization.md → Issue 2 + « Revision — Synthese ».

Ajustements issus de /review-spec (2026-06-30) — à intégrer en plus du body : - 🔴 **Concurrency** : chaque fichier splitté doit re-déclarer `on.pull_request.branches:[main]` ET un groupe `concurrency` DISTINCT (`ci-rust-${{ github.ref }}` / `ci-frontend-${{ github.ref }}`). Sinon, en héritant de `ci-${{ github.ref }}` + `cancel-in-progress`, les 2 workflows s'annulent mutuellement sur une PR mixte. - Conserver l'étape « install sysdeps + Node.js + toolchain » **verbatim** dans check-rust : rust-cache et taiki-e/install-action sont des actions JS qui exigent `node` dans le PATH. - Ajouter `permissions: contents: read` en tête de chaque nouveau workflow. - cargo-audit : ajouter un `on: schedule` quotidien (ou un workflow audit dédié sans `paths:`) pour garder la couverture RustSec hors des PR Rust ; retirer le `|| true` (échouer sur erreur d'outillage, advisories non-bloquantes). - paths rust = `src-tauri/** + self` (retirer les globs `**/*.rs` redondants — tout le Rust est sous src-tauri/). - Dépendance assouplie : baseline (#231) capturée AVANT le merge, sinon parallélisable. Détail : spec-plan-ci-build-optimization.md → Issue 2 + « Revision — Synthese ».
Author
Owner

Ré-orientation suite à la baseline #231 : la cause dominante est #2 (save échoue, reserveCache timeout), pas #1. rust-cache seul ne débloquera PAS les 24 min — il partage le backend reserveCache.

→ Prérequis : #234 (connectivité serveur-de-cache du runner, accès hôte VPS). Une fois #234 résolu, rust-cache reprend tout son sens (cache pruné + réellement persisté).

Restent applicables indépendamment dans cette issue (gains immédiats, sans dépendre de #234) : cargo-audit en binaire pré-buildé (~5.5 min/run), path-filter (skip rust sur PR frontend), + le fix concurrency/permissions/install-Node de la revue. À reséquencer : ces gains d'abord, rust-cache après #234.

Ré-orientation suite à la baseline #231 : la cause dominante est **#2 (save échoue, `reserveCache timeout`)**, pas #1. **rust-cache seul ne débloquera PAS les 24 min** — il partage le backend `reserveCache`. → Prérequis : #234 (connectivité serveur-de-cache du runner, accès hôte VPS). Une fois #234 résolu, rust-cache reprend tout son sens (cache pruné + réellement persisté). Restent applicables **indépendamment** dans cette issue (gains immédiats, sans dépendre de #234) : **cargo-audit en binaire pré-buildé** (~5.5 min/run), **path-filter** (skip rust sur PR frontend), + le fix concurrency/permissions/install-Node de la revue. À reséquencer : ces gains d'abord, rust-cache après #234.
maximus added
status:review
and removed
status:ready
labels 2026-07-25 00:27:27 +00:00
maximus added
status:approved
and removed
status:review
labels 2026-07-25 01:00:41 +00:00
Sign in to join this conversation.
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#232
No description provided.