From cf1da2bea074e8659a53df495ac9d8d20d44985d Mon Sep 17 00:00:00 2001 From: le king fu Date: Sat, 3 Oct 2026 15:09:00 -0400 Subject: [PATCH 1/3] ci: restore the Rust cache with rust-cache and a weekly run on main (#234) The runner's cache server is reachable again since the VPS fix of 2026-10-03 (cache proxy pinned to port 28100, ufw rule scoped to the Docker job networks; diagnosed in #374). Bring caching back to check-rust through Swatinem/rust-cache, as #232 deferred. forgejo-runner v12.7.0 keeps what a pull_request run saves private to that PR, so PR runs alone would only warm later pushes to the same PR. A weekly scheduled run on main (Mondays 06:30 UTC) and workflow_dispatch write the shared entries that every PR falls back to. rust-cache v2.9+ declares node24 and the runner starts JavaScript actions with the container's node, so the job now installs Node.js 24. zstd is installed for faster, smaller cache archives. No npm cache in check-frontend, by decision: with per-PR isolation it would only serve later pushes of a PR, and npm ci takes 9s there. audit.yml loses two comments this change makes false. No CHANGELOG entry: CI configuration only. Refs #234 Co-Authored-By: Claude Opus 5.5 --- .forgejo/workflows/audit.yml | 15 ++++--- .forgejo/workflows/check-frontend.yml | 9 ++-- .forgejo/workflows/check-rust.yml | 62 ++++++++++++++++++++------- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/.forgejo/workflows/audit.yml b/.forgejo/workflows/audit.yml index 752c561..34c794e 100644 --- a/.forgejo/workflows/audit.yml +++ b/.forgejo/workflows/audit.yml @@ -2,14 +2,14 @@ name: Security audit # Daily RustSec coverage (#232). # -# check-rust.yml only runs when src-tauri/ changes, which is roughly 1 PR in -# 40 — without this workflow a new advisory published against an unchanged -# dependency would go unnoticed for weeks. +# check-rust.yml runs on PRs that change src-tauri/ and once a week on main, +# and its cargo audit step never fails the job — without this workflow a new +# advisory published against an unchanged dependency would go unnoticed. # # Runs without a Rust toolchain: cargo-audit only reads Cargo.lock, so the # binary is invoked directly instead of as a `cargo` subcommand. That keeps -# this to ~1-2 min rather than the ~22 min a scheduled check-rust would cost -# every day on a capacity-1 runner. +# this to ~1 min, where a daily check-rust would hold the capacity-1 runner +# for several minutes. # # Note: PATH is deliberately NOT overridden at job level (unlike check-rust, # which needs /root/.cargo/bin for the toolchain) so that the install dir @@ -44,8 +44,9 @@ jobs: apt-get update apt-get install -y --no-install-recommends \ curl ca-certificates git tar gzip - # Node.js is required by actions/checkout and taiki-e/install-action - # (JavaScript actions need `node` in the container PATH). + # Node.js is required by actions/checkout, a JavaScript action that + # needs `node` in the container PATH (taiki-e/install-action is a + # composite action). curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs node --version diff --git a/.forgejo/workflows/check-frontend.yml b/.forgejo/workflows/check-frontend.yml index a5e0905..24ae6c5 100644 --- a/.forgejo/workflows/check-frontend.yml +++ b/.forgejo/workflows/check-frontend.yml @@ -50,10 +50,11 @@ jobs: - name: Checkout uses: https://github.com/actions/checkout@v4 - # No npm cache step here, deliberately — same reason as the cargo caches - # in check-rust.yml: the restore misses and the save times out against - # the runner's cache server (#234), which cost ~23s per run for nothing. - # Restore it together with rust-cache once #234 is fixed. + # No npm cache step, by decision (#234). The runner's cache works since + # 2026-10-03, but it keeps what a pull_request run saves private to that + # PR, and this workflow runs on PRs only: a cache would serve later + # pushes to the same PR, while `npm ci` takes 9s here (run 456) and + # each PR's first run would pay for the save. - name: Install dependencies run: npm ci diff --git a/.forgejo/workflows/check-rust.yml b/.forgejo/workflows/check-rust.yml index 9a66f85..6a4f371 100644 --- a/.forgejo/workflows/check-rust.yml +++ b/.forgejo/workflows/check-rust.yml @@ -2,9 +2,10 @@ name: PR Check — Rust # Rust half of the former check.yml (split in #232). # -# Only runs when Rust actually changes. On this repo roughly 1 PR in 40 touches -# src-tauri/, and the runner has capacity 1 — jobs queue instead of running in -# parallel, so every minute spent here is a minute the next PR waits. +# Runs on PRs that change Rust, plus once a week on main to refresh the shared +# cache (see the note on the triggers). The runner has capacity 1 — jobs queue +# instead of running in parallel, so every minute spent here is a minute the +# next PR waits. # # No `branches:` filter on purpose. `branches: [main]` never matched a PR # stacked on top of another feature branch, which is what /autopilot produces: @@ -19,6 +20,26 @@ on: # (rustflags, linker, target dir) would change the Rust build, and an # exact-path entry would let it skip Rust CI unnoticed. - '.cargo/**' + # The weekly run is what feeds the cache to pull requests (#234). The runner + # (forgejo-runner v12.7.0) isolates what a pull_request run writes to that + # PR's ref: later pushes to the same PR read it back, other PRs never see it. + # A PR run falls back to the shared, non-isolated entries only when nothing + # matches in its own scope. Scheduled and dispatched runs write to the shared + # scope, which makes them this workflow's only writers of it (a merged PR's + # `closed` event would be another, but this workflow does not subscribe to + # it). + # + # The runner deletes an entry unused for 7 days or created more than 30 days + # ago, and the next Monday run saves a fresh one. Cold runs that do not mean + # #234 is back: every new stable Rust until the next Monday (the toolchain + # floats on `stable`, and rustc is part of the cache key); PR runs once an + # entry that only got exact hits, hence never re-saved, reaches 30 days; and, + # after a week without any PR run, possibly the Monday run itself. + # workflow_dispatch re-seeds by hand. + schedule: + # Mondays 06:30 UTC, after audit.yml (06:00 UTC). + - cron: '30 6 * * 1' + workflow_dispatch: # Cancel obsolete runs (e.g. on force-push) so only the latest commit runs. # Distinct from the frontend group: a shared group would make the two @@ -37,22 +58,27 @@ jobs: env: PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin CARGO_TERM_COLOR: always - # Nothing persists between runs (see the caching note below), so - # incremental artifacts get written and never reused — pure overhead. - # Test debug info is dead weight here for the same reason. + # rust-cache keeps the dependencies and drops this crate's own artifacts + # before saving, so incremental data would never be reused — pure + # overhead — and test debug info would only make the cached target/ + # bigger. CARGO_INCREMENTAL: 0 CARGO_PROFILE_TEST_DEBUG: 0 steps: - name: Install system dependencies, Node.js and Rust run: | apt-get update + # zstd: the cache archives are compressed with it when present, + # faster and smaller than the gzip fallback. apt-get install -y --no-install-recommends \ curl wget git ca-certificates build-essential pkg-config \ libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libssl-dev \ - libdbus-1-dev - # Node.js is required by actions/checkout and taiki-e/install-action - # (they are JavaScript actions and need `node` in the container PATH). - curl -fsSL https://deb.nodesource.com/setup_20.x | bash - + libdbus-1-dev zstd + # Node.js runs the JavaScript actions: actions/checkout (node20) and + # Swatinem/rust-cache (node24 since v2.9). The runner starts them + # with whatever `node` the container has, so install the newest + # runtime they declare. taiki-e/install-action is a composite action. + curl -fsSL https://deb.nodesource.com/setup_24.x | bash - apt-get install -y nodejs # Rust toolchain curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal @@ -63,11 +89,17 @@ jobs: - name: Checkout uses: https://github.com/actions/checkout@v4 - # No actions/cache step here, deliberately. The job container cannot - # reach the runner's cache server (#234): the restore times out into a - # miss AND the save times out, so the cache cost ~7 min per run and - # returned nothing. Bring caching back through Swatinem/rust-cache once - # #234 is fixed — not before, it shares the same backend. + # Caches ~/.cargo (registry, git, bin) and src-tauri/target, keyed on the + # rustc version, the Cargo manifests and lockfile, and this job. Saved + # only when the job succeeds and the key was not an exact hit. Served by + # the runner's cache proxy on port 28100, which ufw opens to the Docker + # job networks only; until 2026-10-03 every restore and save timed out + # there (#234, la-compagnie-maximus docs/forgejo-ops.md). What a PR run + # saves stays private to that PR: see the note on the triggers. + - name: Rust cache + uses: https://github.com/Swatinem/rust-cache@v2 + with: + workspaces: "src-tauri -> target" - name: cargo check run: cargo check --manifest-path src-tauri/Cargo.toml --all-targets -- 2.45.2 From 20db766f52133f06ec9fda2e5ee1cf6a3d6e8a4c Mon Sep 17 00:00:00 2001 From: le king fu Date: Sat, 3 Oct 2026 15:22:08 -0400 Subject: [PATCH 2/3] docs: describe the Rust cache, its weekly writer and the absent npm cache (#234) CLAUDE.md and docs/architecture.md still said the Actions cache was removed until #234 was fixed. They now describe rust-cache, the per-PR isolation of what a pull_request run saves, the weekly run on main that writes the shared cache, the expected cold runs, and why check-frontend has no npm cache. The audit.yml paragraph no longer quotes the outdated "1 PR in 40" figure. Refs #234 Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 4 ++-- docs/architecture.md | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 099e037..1437f45 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -161,12 +161,12 @@ Pour maintenir l'éligibilité aux crédits d'impôt R&D (RS&DE fédéral + CRIC Workflows Forgejo Actions dans `.forgejo/workflows/`. Le runner est à **capacité 1** — les jobs se suivent, ils ne tournent pas en parallèle. -- **`check-rust.yml`** — déclenché sur les PR touchant `src-tauri/**` ou `.cargo/**`. Lance `cargo check`, une vérification bloquante que les advisories acceptées restent non atteignables, `cargo test` et un `cargo audit` informatif. Doit être vert avant tout merge. +- **`check-rust.yml`** — déclenché sur les PR touchant `src-tauri/**` ou `.cargo/**`, plus chaque lundi à 06:30 UTC sur `main` et par `workflow_dispatch`. Lance `cargo check`, une vérification bloquante que les advisories acceptées restent non atteignables, `cargo test` et un `cargo audit` informatif, avec le cache `Swatinem/rust-cache`. Doit être vert avant tout merge. - **`check-frontend.yml`** — déclenché sur les PR, sauf si tous les fichiers modifiés sont du Rust, de la doc ou du markdown. Lance `npm run build` (tsc + vite) et `npm test` (vitest). Doit être vert avant tout merge. **Aucune étape `npm audit`** : les advisories npm ne sont pas un gate de CI. `npm audit` remonte 2 high en permanence — une seule advisory `react-router` (mode RSC, inatteignable dans une app de bureau sans serveur), acceptée et suivie en [#317](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/317). - **`audit.yml`** — audit RustSec quotidien (06:00 UTC) + `workflow_dispatch`, pour couvrir les avis de sécurité entre deux PR Rust. Échec bloquant. **Un run vert signifie « zéro advisory hors de la liste acceptée »**, pas « zéro advisory » : cette liste est dans `.cargo/audit.toml` (preuve de non-atteignabilité et condition de retrait par entrée), encadrée par l'[ADR 0018](docs/adr/0018-suppression-advisories-non-atteignables.md). Ne jamais y ajouter une advisory atteignable ni élargir une entrée à un crate entier. - **`release.yml`** — déclenché par les tags `v*`. Build Windows (NSIS `.exe`) + Linux (`.deb`, `.rpm`), signe les binaires et publie le JSON d'updater pour les mises à jour automatiques. -Aucun workflow `check-*` ne filtre sur `branches:` : une PR stackée sur une autre branche de feature déclenche donc bien la CI. Le cache Actions est retiré partout tant que [#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234) (connectivité du serveur de cache) n'est pas réglé — restore et save échouent tous les deux. Le miroir `.github/workflows/` est dormant (aucune PR côté GitHub). +Aucun workflow `check-*` ne filtre sur `branches:` : une PR stackée sur une autre branche de feature déclenche donc bien la CI. Le cache Rust passe par `Swatinem/rust-cache` ([#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234)) : le runner garde ce qu'écrit un run de PR pour cette seule PR, donc c'est le run du lundi (ou un `workflow_dispatch`) qui alimente le cache partagé que lisent les autres PR. Un run à froid reste normal après une nouvelle version stable de Rust, ou quand une entrée expire (7 jours sans usage, 30 jours d'âge). Pas de cache npm : `check-frontend` ne tourne que sur des PR, et `npm ci` y prend 9 s. Le miroir `.github/workflows/` est dormant (aucune PR côté GitHub). --- diff --git a/docs/architecture.md b/docs/architecture.md index 3bcbb1f..654750b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -485,23 +485,25 @@ Page spéciale : `ProfileSelectionPage` (affichée quand aucun profil n'est acti Quatre workflows Forgejo Actions dans `.forgejo/workflows/`. Le runner est à **capacité 1** : les jobs se suivent, ils ne tournent pas en parallèle. -### `check-rust.yml` — Vérifications Rust sur PR +### `check-rust.yml` — Vérifications Rust sur PR et chaque semaine -Déclenché sur les PR qui touchent `src-tauri/**`, `.cargo/**` (ou le workflow lui-même). Lance `cargo check` puis `cargo test`, et un `cargo audit` informatif (non bloquant, binaire pré-buildé via `taiki-e/install-action`). +Déclenché sur les PR qui touchent `src-tauri/**`, `.cargo/**` (ou le workflow lui-même), chaque lundi à 06:30 UTC sur `main` et par `workflow_dispatch`. Lance `cargo check` puis `cargo test`, et un `cargo audit` informatif (non bloquant, binaire pré-buildé via `taiki-e/install-action`). Entre `cargo check` et `cargo test`, une étape **bloquante** rejoue la justification des advisories acceptées dans `.cargo/audit.toml` : elle vérifie par `cargo tree --locked` que chaque crate supprimé reste absent des deux cibles livrées, et échoue si l'un d'eux redevient atteignable. Un canari (`tar`, réellement présent) garantit que son silence prouve quelque chose. Voir [ADR 0018](adr/0018-suppression-advisories-non-atteignables.md). -Aucun `branches:` : une PR stackée sur une autre branche de feature — ce que produit `/autopilot` — déclenche donc bien la CI. Aucune étape de cache non plus : le conteneur de job n'atteint pas le serveur de cache du runner ([#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234)), le restore et le save échouent tous les deux. Le cache reviendra via `Swatinem/rust-cache` une fois #234 réglé. +Aucun `branches:` : une PR stackée sur une autre branche de feature — ce que produit `/autopilot` — déclenche donc bien la CI. + +**Cache** ([#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234)) : `Swatinem/rust-cache` garde `~/.cargo` et les dépendances compilées de `src-tauri/target`, sous une clé faite de la version de rustc, des manifestes et du lockfile Cargo, et du job. Il passe par le proxy de cache du runner, sur le port 28100 qu'ufw n'ouvre qu'aux réseaux Docker des jobs (procédure et retour arrière dans `docs/forgejo-ops.md` de la-compagnie-maximus). Le runner (v12.7.0) garde ce qu'écrit un run de PR pour cette seule PR : ses pushes suivants le relisent, les autres PR non. Le run du lundi et `workflow_dispatch` sont donc les seuls à écrire le cache partagé, sur lequel une PR se rabat quand rien ne correspond dans sa propre portée. Le runner supprime une entrée inutilisée depuis 7 jours ou créée il y a plus de 30 jours. Un run à froid est donc normal après une nouvelle version stable de Rust (rustc fait partie de la clé) jusqu'au lundi suivant, et quand une entrée expire. ### `check-frontend.yml` — Vérifications frontend sur PR -Déclenché sur les PR, sauf si tous les fichiers modifiés sont du Rust, de la doc ou du markdown (`paths-ignore`). Lance `npm ci`, `npm run build` (tsc + vite) et `npm test` (vitest). Le cache npm est retiré pour la même raison que côté Rust. +Déclenché sur les PR, sauf si tous les fichiers modifiés sont du Rust, de la doc ou du markdown (`paths-ignore`). Lance `npm ci`, `npm run build` (tsc + vite) et `npm test` (vitest). Pas de cache npm : ce workflow ne tourne que sur des PR, donc un cache ne servirait qu'aux pushes suivants d'une même PR, et `npm ci` y prend 9 s. **Aucune étape `npm audit`** — contrairement au Rust, les advisories npm ne sont donc pas un gate de CI. Conséquence à connaître : `npm audit` remonte **2 high en permanence**, les deux clés d'une même advisory `react-router` ([GHSA-qwww-vcr4-c8h2](https://github.com/advisories/GHSA-qwww-vcr4-c8h2), mode React Server Components). Elle est acceptée : l'app est un client de bureau sans serveur — `App.tsx` monte un `BrowserRouter` client-only — et `react-router-dom` étant figé en 7.18.1, sortir de la plage vulnérable demanderait une migration vers react-router v8, pas un bump. Déclencheur de re-évaluation : [#317](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/317). `npm audit` n'a pas de mécanisme d'exclusion natif, il n'y a donc pas d'équivalent du `.cargo/audit.toml` côté npm. ### `audit.yml` — Audit RustSec quotidien -`schedule` quotidien (06:00 UTC) + `workflow_dispatch`. `check-rust.yml` ne tournant que sur les PR qui touchent le Rust — environ 1 PR sur 40 — ce workflow garantit qu'un avis de sécurité publié sur une dépendance inchangée ne passe pas inaperçu. Échec bloquant : c'est le canal de notification. +`schedule` quotidien (06:00 UTC) + `workflow_dispatch`. `check-rust.yml` ne tournant que sur les PR qui touchent le Rust et une fois par semaine, avec un `cargo audit` non bloquant, ce workflow garantit qu'un avis de sécurité publié sur une dépendance inchangée ne passe pas inaperçu. Échec bloquant : c'est le canal de notification. **Un run vert ne signifie pas « zéro advisory »** mais « zéro advisory hors de la liste acceptée ». Cette liste vit dans `.cargo/audit.toml`, à la racine du dépôt, avec pour chaque entrée sa preuve de non-atteignabilité et sa condition de retrait ; la politique qui l'encadre est l'[ADR 0018](adr/0018-suppression-advisories-non-atteignables.md). Au moment de sa mise en place, le `schedule` n'avait encore jamais déclenché ce workflow ([#314](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/314)) — un `workflow_dispatch` vert prouve que la commande sort en 0, pas que l'alarme quotidienne fonctionne. -- 2.45.2 From f821492274b70534bee879108bab877ccee7fdac Mon Sep 17 00:00:00 2001 From: le king fu Date: Sat, 3 Oct 2026 18:04:50 -0400 Subject: [PATCH 3/3] ci: document the cache evictions and key inputs found in review (#234) Applies the three suggestions of the review of #375: - The runner's cleanup keeps one entry per key, whatever its scope: a PR run that saves under the shared entry's key evicts it for every PR until the next Monday, and two PRs on the same non-main lockfile evict each other. Added to the list of cold runs. - The cache key also hashes the job's CARGO*/RUST*/CC*/CFLAGS*/CXX*/CMAKE* variables, and ignores the app's own version: changing env: means a cold run until Monday, a release does not. - A Monday restore that fails with a 404 after a quiet week is a known runner race (forgejo/runner#1741), not #234 coming back. Refs #234 Co-Authored-By: Claude Opus 5.5 --- .forgejo/workflows/check-rust.yml | 27 ++++++++++++++++++++------- CLAUDE.md | 2 +- docs/architecture.md | 7 ++++++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.forgejo/workflows/check-rust.yml b/.forgejo/workflows/check-rust.yml index 6a4f371..bba8cd9 100644 --- a/.forgejo/workflows/check-rust.yml +++ b/.forgejo/workflows/check-rust.yml @@ -30,11 +30,22 @@ on: # it). # # The runner deletes an entry unused for 7 days or created more than 30 days - # ago, and the next Monday run saves a fresh one. Cold runs that do not mean - # #234 is back: every new stable Rust until the next Monday (the toolchain - # floats on `stable`, and rustc is part of the cache key); PR runs once an - # entry that only got exact hits, hence never re-saved, reaches 30 days; and, - # after a week without any PR run, possibly the Monday run itself. + # ago, and keeps only the newest entry per key, whatever its scope; the next + # Monday run saves a fresh one. Cold runs that do not mean #234 is back (a + # timeout would): + # - a new stable Rust (the toolchain floats on `stable`) or a change to this + # job's `env:`: the key hashes rustc and the CARGO*, RUST*, CC*, CFLAGS*, + # CXX* and CMAKE* variables. Cold until the next Monday; + # - a PR run that saves under the shared entry's key evicts it for every PR + # until the next Monday. It saves when its own scope holds an older entry + # for another Cargo.lock, served before the shared one: a PR that bumped a + # dependency, then went back to main's lockfile. Two open PRs on the same + # lockfile, different from main's, evict each other the same way; + # - PR runs once an entry that only got exact hits, hence never re-saved, + # reaches 30 days; + # - after a week without any cache request, the Monday restore can fail with + # a 404: the lookup does not refresh the entry, and the cleanup it triggers + # may delete it (forgejo/runner#1741). The run then saves a fresh entry. # workflow_dispatch re-seeds by hand. schedule: # Mondays 06:30 UTC, after audit.yml (06:00 UTC). @@ -90,8 +101,10 @@ jobs: uses: https://github.com/actions/checkout@v4 # Caches ~/.cargo (registry, git, bin) and src-tauri/target, keyed on the - # rustc version, the Cargo manifests and lockfile, and this job. Saved - # only when the job succeeds and the key was not an exact hit. Served by + # rustc version, the job's CARGO*/RUST* environment, the dependencies + # declared in the Cargo manifests and lockfile (not the app's own + # version), and this job. Saved only when the job succeeds and the key + # was not an exact hit. Served by # the runner's cache proxy on port 28100, which ufw opens to the Docker # job networks only; until 2026-10-03 every restore and save timed out # there (#234, la-compagnie-maximus docs/forgejo-ops.md). What a PR run diff --git a/CLAUDE.md b/CLAUDE.md index 1437f45..c7f8810 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -166,7 +166,7 @@ Workflows Forgejo Actions dans `.forgejo/workflows/`. Le runner est à **capacit - **`audit.yml`** — audit RustSec quotidien (06:00 UTC) + `workflow_dispatch`, pour couvrir les avis de sécurité entre deux PR Rust. Échec bloquant. **Un run vert signifie « zéro advisory hors de la liste acceptée »**, pas « zéro advisory » : cette liste est dans `.cargo/audit.toml` (preuve de non-atteignabilité et condition de retrait par entrée), encadrée par l'[ADR 0018](docs/adr/0018-suppression-advisories-non-atteignables.md). Ne jamais y ajouter une advisory atteignable ni élargir une entrée à un crate entier. - **`release.yml`** — déclenché par les tags `v*`. Build Windows (NSIS `.exe`) + Linux (`.deb`, `.rpm`), signe les binaires et publie le JSON d'updater pour les mises à jour automatiques. -Aucun workflow `check-*` ne filtre sur `branches:` : une PR stackée sur une autre branche de feature déclenche donc bien la CI. Le cache Rust passe par `Swatinem/rust-cache` ([#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234)) : le runner garde ce qu'écrit un run de PR pour cette seule PR, donc c'est le run du lundi (ou un `workflow_dispatch`) qui alimente le cache partagé que lisent les autres PR. Un run à froid reste normal après une nouvelle version stable de Rust, ou quand une entrée expire (7 jours sans usage, 30 jours d'âge). Pas de cache npm : `check-frontend` ne tourne que sur des PR, et `npm ci` y prend 9 s. Le miroir `.github/workflows/` est dormant (aucune PR côté GitHub). +Aucun workflow `check-*` ne filtre sur `branches:` : une PR stackée sur une autre branche de feature déclenche donc bien la CI. Le cache Rust passe par `Swatinem/rust-cache` ([#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234)) : le runner garde ce qu'écrit un run de PR pour cette seule PR, donc c'est le run du lundi (ou un `workflow_dispatch`) qui alimente le cache partagé que lisent les autres PR. Un run à froid reste normal après une nouvelle version stable de Rust ou une modification de l'`env:` du job, quand une entrée expire (7 jours sans usage, 30 jours d'âge), ou quand une PR sauvegarde sous la clé de l'entrée partagée et l'évince, le runner ne gardant qu'une entrée par clé. La liste complète est en tête de `check-rust.yml` ; seul un délai dépassé signale un retour de #234. Pas de cache npm : `check-frontend` ne tourne que sur des PR, et `npm ci` y prend 9 s. Le miroir `.github/workflows/` est dormant (aucune PR côté GitHub). --- diff --git a/docs/architecture.md b/docs/architecture.md index 654750b..3366d75 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -493,7 +493,12 @@ Entre `cargo check` et `cargo test`, une étape **bloquante** rejoue la justific Aucun `branches:` : une PR stackée sur une autre branche de feature — ce que produit `/autopilot` — déclenche donc bien la CI. -**Cache** ([#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234)) : `Swatinem/rust-cache` garde `~/.cargo` et les dépendances compilées de `src-tauri/target`, sous une clé faite de la version de rustc, des manifestes et du lockfile Cargo, et du job. Il passe par le proxy de cache du runner, sur le port 28100 qu'ufw n'ouvre qu'aux réseaux Docker des jobs (procédure et retour arrière dans `docs/forgejo-ops.md` de la-compagnie-maximus). Le runner (v12.7.0) garde ce qu'écrit un run de PR pour cette seule PR : ses pushes suivants le relisent, les autres PR non. Le run du lundi et `workflow_dispatch` sont donc les seuls à écrire le cache partagé, sur lequel une PR se rabat quand rien ne correspond dans sa propre portée. Le runner supprime une entrée inutilisée depuis 7 jours ou créée il y a plus de 30 jours. Un run à froid est donc normal après une nouvelle version stable de Rust (rustc fait partie de la clé) jusqu'au lundi suivant, et quand une entrée expire. +**Cache** ([#234](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/234)) : `Swatinem/rust-cache` garde `~/.cargo` et les dépendances compilées de `src-tauri/target`, sous une clé faite de la version de rustc, des variables `CARGO*` et `RUST*` du job, des dépendances déclarées dans les manifestes et le lockfile Cargo (la version de l'app n'en fait pas partie), et du job. Il passe par le proxy de cache du runner, sur le port 28100 qu'ufw n'ouvre qu'aux réseaux Docker des jobs (procédure et retour arrière dans `docs/forgejo-ops.md` de la-compagnie-maximus). Le runner (v12.7.0) garde ce qu'écrit un run de PR pour cette seule PR : ses pushes suivants le relisent, les autres PR non. Le run du lundi et `workflow_dispatch` sont donc les seuls à écrire le cache partagé, sur lequel une PR se rabat quand rien ne correspond dans sa propre portée. Le runner supprime une entrée inutilisée depuis 7 jours ou créée il y a plus de 30 jours, et ne garde qu'une entrée par clé, toutes portées confondues. Un run à froid est donc normal dans les cas suivants ; seul un délai dépassé signale un retour de #234 : + +- après une nouvelle version stable de Rust ou une modification de l'`env:` du job, jusqu'au lundi suivant ; +- quand une PR sauvegarde sous la clé de l'entrée partagée : elle l'évince pour toutes les PR jusqu'au lundi suivant. Ça arrive quand sa propre portée contient une entrée plus ancienne pour un autre `Cargo.lock`, servie avant l'entrée partagée, par exemple une PR qui a monté une dépendance puis est revenue au lockfile de `main`. Deux PR ouvertes sur un même lockfile, différent de celui de `main`, s'évincent l'une l'autre ; +- quand une entrée qui n'a eu que des correspondances exactes, donc jamais re-sauvegardée, atteint 30 jours ; +- un lundi après une semaine sans requête au cache, la restauration peut échouer en 404 : la recherche ne rafraîchit pas l'entrée, et le ménage qu'elle déclenche peut la supprimer ([forgejo/runner#1741](https://code.forgejo.org/forgejo/runner/issues/1741)). Le run repart alors à froid et re-sauvegarde. ### `check-frontend.yml` — Vérifications frontend sur PR -- 2.45.2