fix(release): apply the review follow-ups of the release-deps stack, drop the linux-x86_64 key #418
3 changed files with 28 additions and 15 deletions
|
|
@ -25,6 +25,12 @@ updated: 2026-10-11
|
|||
- `package.json` (champ `"version"`)
|
||||
- `package-lock.json` (deux champs `"version"` — root ~ligne 3 et le package racine `""` ~ligne 9)
|
||||
- Si `package-lock.json` est stale (hygiene warning `package-lock.json plus ancien que package.json`) : `npm install --package-lock-only --no-audit --no-fund` pour resync. Note : peut ajouter des entrees bundled optionnelles (tailwindcss oxide wasm etc.) — cosmetique, pas d'install effective.
|
||||
- Puis rejouer le garde `windows-sys` de `check-rust.yml` sur le lock édité : le commit de release touche `Cargo.lock` directement sur `main`, sans PR, et `check-rust` ne le verrait qu'au lundi suivant, après le build du tag ([ADR 0023](../../../docs/adr/0023-windows-sys-pinning.md)). Depuis la racine du dépôt, le texte exact de l'étape avec les options du runner :
|
||||
```bash
|
||||
python3 -c 'import sys, yaml; steps = yaml.safe_load(open(".forgejo/workflows/check-rust.yml"))["jobs"]["rust"]["steps"]; sys.stdout.write(next(s["run"] for s in steps if s.get("name") == "Verify windows-sys pinning"))' \
|
||||
| bash --noprofile --norc -e -o pipefail
|
||||
```
|
||||
Attendu : code de sortie 0 et dernière ligne `windows-sys pinning: N checks, exit 0`. Une ligne `FAIL:` arrête la release : suivre la procédure de l'ADR 0023 avant de tagger.
|
||||
3. Mettre a jour les 2 changelogs — format **Keep a Changelog** :
|
||||
- `CHANGELOG.md` (EN) : header `## [Unreleased]`
|
||||
- `CHANGELOG.fr.md` (FR) : header `## [Non publié]` (PAS `[Unreleased]` — ne pas le confondre avec un changelog vide)
|
||||
|
|
@ -84,3 +90,4 @@ updated: 2026-10-11
|
|||
- 2026-10-10 — Étape 9 (post-CI) : lire `node --version` dans le journal du run de release (route web, seule ligne `vX.Y.Z` du journal). `release.yml` n'est exercé qu'au tag, donc la montée Node 20 → 24 de #376 ne se prouve qu'à la release suivante. Source : caveat de planification de #376 (milestone `planned-2026-10-10-release-deps`).
|
||||
- 2026-10-10 — Étape 9 (post-CI) : `verify-release.sh` exige les quatre clés de `latest.json` (`linux-x86_64`, `linux-x86_64-deb`, `linux-x86_64-rpm`, `windows-x86_64`), l'extension de chaque URL et le `file:` minisign de chaque signature, et sort en 1 sur tout écart (verdict en dernière ligne) ; lire l'étape « Generate latest.json » du journal. Source : #320 (milestone `planned-2026-10-10-release-deps`).
|
||||
- 2026-10-11 — Étape 9 (post-CI) : `latest.json` à trois clés, la clé générique `linux-x86_64` étant retirée (décision de Max sur #320 : ses derniers lecteurs, AppImage v0.4.3 à v0.4.5 et binaires hors paquet, ne savaient pas installer le `.deb` qu'elle servait). Le filtre d'avant le `DELETE` vit dans `scripts/check-latest-json.jq`, que les tests de `check-frontend` exercent à chaque PR, avec la comparaison des trois listes de clés. Source : revue de la PR #416.
|
||||
- 2026-10-11 — Étape 2 : rejouer le garde `windows-sys` de `check-rust.yml` (ADR 0023) juste après l'édition de `Cargo.lock`, puisque le commit de release n'a pas de PR et que `check-rust` ne le verrait qu'au lundi suivant. Commande éprouvée sur le lock de la pile (exit 0) et sur une arête dérivée (exit 1). Source : revue de la PR #415.
|
||||
|
|
|
|||
|
|
@ -202,11 +202,15 @@ jobs:
|
|||
# docs/adr/0023-windows-sys-pinning.md holds the measurements, the exit
|
||||
# condition and what to do when this step fails.
|
||||
#
|
||||
# awk reads Cargo.lock, since the ubuntu:22.04 container has no Python.
|
||||
# Its exit code is tested apart from its output, so a read failure fails
|
||||
# the step instead of passing for a clean, empty result. As in the step
|
||||
# above, every check echoes its result, including the passing ones, and a
|
||||
# canary must be read and checked, or the loop's silence proves nothing.
|
||||
# awk reads Cargo.lock: mawk is part of the ubuntu:22.04 base image,
|
||||
# while python3 is only here as a transitive dependency of the apt
|
||||
# packages installed above (run 517), which nothing guarantees. Its exit
|
||||
# code is tested apart from its output: an empty output already fails the
|
||||
# checks below (version set, missing blocks, canary), but an awk that
|
||||
# fails after printing every fact would pass without that test. As in the
|
||||
# step above, every check echoes its result, including the passing ones,
|
||||
# and a canary must be read and checked, or the loop's silence proves
|
||||
# nothing.
|
||||
#
|
||||
# No cargo call, so neither the warm index nor --locked matters here: the
|
||||
# step reads the lockfile as cargo check left it, which is the committed
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
- Status: **Accepted**
|
||||
- Date: 2026-10-10
|
||||
- Issues: #345 (cette décision), #344 (troisième dérive, contournée en n'appliquant que la strophe `h2` à la main), #348 (mesure `rustls` : la couche TLS en général ne déclenche pas la dérive)
|
||||
- Issues: #345 (cette décision), PR #344 (deuxième dérive, contournée en n'appliquant que la strophe `h2` à la main), #348 (mesure `rustls` : la couche TLS en général ne déclenche pas la dérive)
|
||||
- S'appuie sur l'[ADR 0018](0018-suppression-advisories-non-atteignables.md) : même motif de garde-fou (chaque vérification loggée, canari, code de sortie de l'outil testé à part de sa sortie)
|
||||
|
||||
## Contexte
|
||||
|
|
@ -26,7 +26,7 @@ Les sept pointent **`0.61.2`**. C'est l'état du tag v0.14.0 (2026-07-18), dont
|
|||
|---|---|
|
||||
| #310 (2026-07-27) | `cargo update -p rustls-webpki -p tar` fait descendre les sept arêtes ; vu, et jugé inoffensif parce que sans effet sur Linux |
|
||||
| PR #321 (2026-08-15) | la revue les remonte à `0.61.2`, crate par crate contre le tag v0.14.0 |
|
||||
| #344 (2026-09-04) | `cargo update -p h2` recommence ; contourné en n'appliquant que la strophe `h2` à la main |
|
||||
| PR #344 (2026-09-04) | `cargo update -p h2` recommence ; contourné en n'appliquant que la strophe `h2` à la main |
|
||||
| #348 (2026-09-21) | `cargo update -p rustls --precise 0.23.45` ne bouge rien, mais il a fallu remesurer pour le savoir |
|
||||
|
||||
Hors du lock, la contrainte ne vivait que dans de la prose (`STATE.md`, des messages de commit) : la prochaine mise à jour la régresserait, et il faudrait qu'un relecteur reconnaisse sept noms de crates pour le voir. C'est le mode d'échec que l'ADR 0018 traite pour les suppressions d'advisories : une décision qui ne vit que dans de la prose n'est pas une décision tenue.
|
||||
|
|
@ -39,7 +39,7 @@ Hors du lock, la contrainte ne vivait que dans de la prose (`STATE.md`, des mess
|
|||
| `cargo update -p rustls --precise 0.23.45` | aucun ; le `diff` de toutes les lignes `windows-sys` du lock est vide | 2026-09-21 (#348) |
|
||||
| `cargo update -p hyper` | les sept descendent : `colored` et `winapi-util` vers 0.48.0, `errno`, `rustix`, `tempfile` et `rustls-platform-verifier` vers 0.52.0, `dirs-sys` vers 0.59.0 | 2026-09-04, refaite le 2026-10-10 (`hyper` 1.8.1 → 1.12.0) |
|
||||
|
||||
Dans cette mesure, chaque arête est descendue vers la plus basse version déjà présente que sa borne admet, et la dérive de #310 (commit `f4b09b0`) a la même répartition : deux arêtes vers 0.48.0, quatre vers 0.52.0, une vers 0.59.0. `hyper` et ce qu'il tire (`h2` en #344) la déclenchent, la couche TLS en général non : `rustls`, en son cœur, ne déplace rien. Mais `rustls-webpki` et `tar` l'ont déclenchée en #310. Aucune règle simple ne dit quelle mise à jour la provoque, et la dernière qu'on a formulée (« tout bump du sous-arbre réseau/TLS ») a été démentie par #348. C'est donc la version résolue qu'il faut garder, pas une liste de déclencheurs.
|
||||
Dans cette mesure, chaque arête est descendue vers la plus basse version déjà présente que sa borne admet, et la dérive de #310 (commit `f4b09b0`) a la même répartition : deux arêtes vers 0.48.0, quatre vers 0.52.0, une vers 0.59.0. `hyper` et ce qu'il tire (`h2` dans la PR #344) la déclenchent, la couche TLS en général non : `rustls`, en son cœur, ne déplace rien. Mais `rustls-webpki` et `tar` l'ont déclenchée en #310. Aucune règle simple ne dit quelle mise à jour la provoque, et la dernière qu'on a formulée (« tout bump du sous-arbre réseau/TLS ») a été démentie par #348. C'est donc la version résolue qu'il faut garder, pas une liste de déclencheurs.
|
||||
|
||||
**Et cargo n'en dit rien.** Le 2026-10-10, `cargo update -p hyper` annonce :
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ Dans cette mesure, chaque arête est descendue vers la plus basse version déjà
|
|||
Updating want v0.3.1 -> v0.3.2
|
||||
```
|
||||
|
||||
pendant qu'il réécrit aussi les sept arêtes. L'ensemble des paquets ne bouge pas (666 avant et après) ; seules les arêtes changent, et cargo ne rapporte que les paquets. Or les deux dérives passées sont venues avec des correctifs d'advisories RustSec (`rustls-webpki` et `tar` en #310, `h2` en #344) : la dérive arrive avec les changements les plus pressés et les moins relus.
|
||||
pendant qu'il réécrit aussi les sept arêtes. L'ensemble des paquets ne bouge pas (666 avant et après) ; seules les arêtes changent, et cargo ne rapporte que les paquets. Or les deux dérives passées sont venues avec des correctifs d'advisories RustSec (`rustls-webpki` et `tar` en #310, `h2` dans la PR #344) : la dérive arrive avec les changements les plus pressés et les moins relus.
|
||||
|
||||
### Ce que coûte la dérive
|
||||
|
||||
|
|
@ -66,14 +66,14 @@ Mesuré par `cargo tree --target x86_64-pc-windows-msvc -e normal,build`, refait
|
|||
|
||||
**Un garde-fou CI bloquant sur la version résolue, et cet ADR pour en porter la raison et la sortie.**
|
||||
|
||||
L'étape `Verify windows-sys pinning` de `check-rust.yml`, placée après `cargo check` à côté du garde des suppressions, lit `src-tauri/Cargo.lock` avec `awk` (le conteneur `ubuntu:22.04` n'a pas Python) et applique quatre règles :
|
||||
L'étape `Verify windows-sys pinning` de `check-rust.yml`, placée après `cargo check` à côté du garde des suppressions, lit `src-tauri/Cargo.lock` avec `awk` et applique quatre règles. `awk` (mawk) fait partie de l'image de base `ubuntu:22.04`, alors que `python3` n'est présent dans ce conteneur que comme dépendance transitive des paquets `apt` installés à l'étape précédente (journal du run 517), ce que rien ne garantit :
|
||||
|
||||
1. **Chaque arête des sept crates.** Pour `colored`, `dirs-sys`, `errno`, `rustix`, `rustls-platform-verifier`, `tempfile` et `winapi-util`, chaque bloc `[[package]]` de ce nom doit porter au moins une arête `windows-sys`, et chacune doit nommer `0.61.2`. L'absence de bloc pour l'un de ces noms fait échouer l'étape (crate renommé ou sorti du graphe). Un suffixe de source sur une arête (` (registry+…)`) est toléré.
|
||||
2. **Arête nue.** Cargo n'écrit `"windows-sys 0.61.2"` que tant que plusieurs versions coexistent ; quand il n'en reste qu'une, il écrit `"windows-sys"`. Une arête nue ne passe que si le lock ne contient qu'un seul paquet `windows-sys`, en `0.61.2`.
|
||||
3. **Ensemble des versions.** Les versions de `windows-sys` du lock, toutes cibles confondues et doublons compris, doivent égaler exactement `{0.45.0, 0.48.0, 0.52.0, 0.59.0, 0.60.2, 0.61.2}` (état du 2026-10-10). Une version qui apparaît ou disparaît fait échouer l'étape avec un renvoi à cet ADR : c'est soit le coût réel (une version de plus), soit le début de la sortie, et dans les deux cas une décision.
|
||||
4. **Canari.** La boucle doit avoir lu et vérifié une arête de `tempfile`, crate connu pour en porter une, faute de quoi son silence ne prouve rien et l'étape échoue.
|
||||
|
||||
Comme dans l'ADR 0018, chaque vérification est loggée, succès compris (`ok: rustix 1.1.3 -> windows-sys 0.61.2`), puis un bilan (`windows-sys pinning: 9 checks, exit 0`), et le code de sortie d'`awk` est testé à part de sa sortie : une panne de lecture fait échouer l'étape au lieu de passer pour un lock propre. Le garde n'appelle pas cargo, donc ni l'index chaud ni `--locked` ne le concernent ; il lit le lock tel que `cargo check` l'a laissé.
|
||||
Comme dans l'ADR 0018, chaque vérification est loggée, succès compris (`ok: rustix 1.1.3 -> windows-sys 0.61.2`), puis un bilan (`windows-sys pinning: 9 checks, exit 0`), et le code de sortie d'`awk` est testé à part de sa sortie. Une sortie vide échoue déjà (ensemble des versions, blocs introuvables, canari) ; ce test attrape seul un `awk` qui échoue après avoir tout imprimé, et sans lui le garde sortirait en 0 (éprouvé à la revue de la PR #415). Le garde n'appelle pas cargo, donc ni l'index chaud ni `--locked` ne le concernent ; il lit le lock tel que `cargo check` l'a laissé.
|
||||
|
||||
La liste gardée, la version épinglée et l'ensemble attendu sont en tête du script, sous un commentaire qui renvoie ici. On ne les modifie que sur la preuve que demandent les sections suivantes, jamais pour faire passer l'étape au vert.
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ Le 2026-10-10, le texte du `run:` a été extrait du workflow et lancé tel quel
|
|||
La ligne `FAIL:` dit quelle règle a cédé.
|
||||
|
||||
- **Une arête a quitté `0.61.2`** (règle 1), en général après un `cargo update` (`-p hyper`, `-p h2` et `-p rustls-webpki -p tar` l'ont fait). Garder la mise à jour voulue et remettre les arêtes, de l'une de deux façons qui mènent au même lock :
|
||||
- n'appliquer à la main que la ou les strophes du paquet visé (version, checksum, dépendances), comme #344 l'a fait pour `h2` ;
|
||||
- n'appliquer à la main que la ou les strophes du paquet visé (version, checksum, dépendances), comme la PR #344 l'a fait pour `h2` ;
|
||||
- ou garder la sortie de `cargo update` et ramener à la main les arêtes signalées à `"windows-sys 0.61.2"`, les seules lignes à toucher.
|
||||
|
||||
Puis vérifier que cargo accepte le lock tel quel, sans le réécrire :
|
||||
|
|
@ -109,6 +109,8 @@ La ligne `FAIL:` dit quelle règle a cédé.
|
|||
Éprouvé le 2026-10-10 sur la copie dérivée par `cargo update -p hyper` : les sept arêtes remises, le diff contre `main` se réduit aux strophes `hyper` et `want`, `cargo metadata --locked` l'accepte sans modifier le fichier, et le garde repasse.
|
||||
- **L'ensemble des versions a changé** (règle 3). Pour une version ajoutée, chercher qui la tire et si elle est compilée pour Windows (`cargo tree --manifest-path src-tauri/Cargo.toml -i windows-sys@<version> --target x86_64-pc-windows-msvc`) ; si c'est le début du passage à 0.62, la condition de sortie est atteinte (section suivante). Une version retirée est un pas vers la convergence. Dans les deux cas, `EXPECTED` change dans la PR qui change le lock, preuve à l'appui dans la PR.
|
||||
- **Bloc introuvable** : le crate a été renommé ou est sorti du graphe. Retirer son nom de `CRATES` après avoir revérifié la liste des bornes larges (commande de la section Conséquences).
|
||||
- **Plus d'arête `windows-sys` dans un bloc gardé** (`has no windows-sys edge left`) : le crate a cessé de dépendre de `windows-sys` dans cette version. Même traitement qu'un bloc introuvable ; si c'est `tempfile`, choisir aussi un autre canari parmi les crates restants.
|
||||
- **Un second bloc d'un crate gardé dont la borne exclut `0.61.2`** (par exemple un `tempfile` plus ancien, d'avant les bornes larges, tiré par une autre dépendance) : la règle 1 échoue, et la réparation de la première puce est impossible, puisque `cargo metadata --locked` refuse une arête hors borne (code 101, éprouvé à la revue de la PR #415). Décider dans la PR qui change le lock : admettre ce bloc par nom et version dans le script, ou écarter la dépendance qui le tire ; dans les deux cas, amender cet ADR.
|
||||
- **Canari ou `awk` en échec** : le garde lui-même est cassé. Le réparer ; ne jamais changer le canari ou la liste pour le faire taire.
|
||||
|
||||
## Condition de sortie
|
||||
|
|
@ -136,7 +138,7 @@ L'épinglage n'est pas fait pour durer indéfiniment. Il change ou disparaît da
|
|||
### Négatives
|
||||
|
||||
- **Friction** : chaque mise à jour qui déplace ces arêtes demande une édition à la main du lock.
|
||||
- **La liste des sept est tenue à la main.** Un crate à borne large qui entrerait dans le graphe ne serait pas gardé, et s'il pointait une version déjà présente, la règle 3 ne le verrait pas non plus. La commande suivante liste les exigences sur `windows-sys` qui ne sont pas un `^0.x` ; le 2026-10-10, elle sort exactement les sept crates de `CRATES` :
|
||||
- **La liste des sept est tenue à la main.** Un crate à borne large qui entrerait dans le graphe ne serait pas gardé, et s'il pointait une version déjà présente, la règle 3 ne le verrait pas non plus. À l'inverse, retirer de `CRATES` un autre nom que le canari passe, avec une vérification de moins dans le bilan (9 → 8) : seule la relecture du diff, sous le commentaire qui renvoie ici, l'attrape. La commande suivante liste les exigences sur `windows-sys` qui ne sont pas un `^0.x` ; le 2026-10-10, elle sort exactement les sept crates de `CRATES` :
|
||||
|
||||
```
|
||||
cargo metadata --manifest-path src-tauri/Cargo.toml --format-version 1 --locked \
|
||||
|
|
@ -145,7 +147,7 @@ L'épinglage n'est pas fait pour durer indéfiniment. Il change ou disparaît da
|
|||
```
|
||||
|
||||
- La règle 3 compte toutes les cibles : 0.45.0, 0.48.0 et 0.52.0 ne sont pas compilées pour `x86_64-pc-windows-msvc` aujourd'hui, et un changement qui ne touche qu'elles la fera rougir quand même. Assumé : le lock ne dit pas ce qui est compilé pour quelle cible, et une fausse alerte se lève en une vérification `cargo tree`.
|
||||
- Le garde ne tourne que sur les PR qui touchent `src-tauri/**`, `.cargo/**` ou le workflow, et le lundi sur `main` : exactement là où le lock change, mais pas en continu.
|
||||
- Le garde tourne sur les PR qui touchent `src-tauri/**`, `.cargo/**` ou le workflow, et le lundi sur `main`, pas en continu. Une exception : le commit de `/release` modifie `Cargo.lock` directement sur `main`, sans PR, et le garde ne le verrait qu'au lundi suivant, après le build du tag. Le skill `/release` le rejoue donc en local juste après avoir édité le lock, avant de tagger (étape 2).
|
||||
|
||||
### Neutre
|
||||
|
||||
|
|
@ -156,4 +158,4 @@ L'épinglage n'est pas fait pour durer indéfiniment. Il change ou disparaît da
|
|||
|
||||
- [`.forgejo/workflows/check-rust.yml`](../../.forgejo/workflows/check-rust.yml) — étape « Verify windows-sys pinning »
|
||||
- [ADR 0018](0018-suppression-advisories-non-atteignables.md) — le garde-fou des suppressions, dont celui-ci reprend le motif
|
||||
- Issues #345 (cette décision), #344 (strophe `h2` appliquée à la main), #348 (mesure `rustls`), #310 (première dérive) ; PR #321 (arêtes remontées à `0.61.2`)
|
||||
- Issues #345 (cette décision), #348 (mesure `rustls`), #310 (première dérive) ; PR #344 (strophe `h2` appliquée à la main), PR #321 (arêtes remontées à `0.61.2`)
|
||||
|
|
|
|||
Loading…
Reference in a new issue