fix(release): drop the generic linux-x86_64 key from latest.json
Max's decision on PR #416, after its review measured who still read the key. tauri-plugin-updater looks up "{os}-{arch}-{installer}" first, and every version that ships the updater (v0.2.1 and later, plugin 2.10.0, tauri-utils 2.8.2 in each tag's Cargo.lock) carries its bundle-type marker, so .deb and .rpm installs never reach the generic key. Its last readers were the AppImage installs v0.4.3 to v0.4.5 (v0.4.2 targets a route that answers 404, earlier versions read GitHub) and binaries run outside a package; none of them can install the .deb it served, and the updater wrote that .deb over the running file. They now get TargetsNotFound when checking: an error on the Updates card, nothing installed. The key leaves the script, scripts/check-latest-json.jq and verify-release.sh together; the test compares the three lists. Docs fix the readers named by #416 (v0.4.2 is not one) and the CHANGELOG entry says what changes for those AppImage installs. Refs #320 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ba3db7c35d
commit
230ecd85ad
10 changed files with 37 additions and 37 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
name: release
|
name: release
|
||||||
description: Release a new version of Simpl-Resultat (bump, changelog, tag, push)
|
description: Release a new version of Simpl-Resultat (bump, changelog, tag, push)
|
||||||
user-invocable: true
|
user-invocable: true
|
||||||
updated: 2026-10-10
|
updated: 2026-10-11
|
||||||
---
|
---
|
||||||
|
|
||||||
# /release — Release Simpl-Resultat
|
# /release — Release Simpl-Resultat
|
||||||
|
|
@ -43,7 +43,7 @@ updated: 2026-10-10
|
||||||
```bash
|
```bash
|
||||||
bash .claude/skills/release/scripts/verify-release.sh vX.Y.Z
|
bash .claude/skills/release/scripts/verify-release.sh vX.Y.Z
|
||||||
```
|
```
|
||||||
Le script (token `~/.forgejo-token`) lit la release par tag, compte les 7 artefacts **par suffixe** (`.exe` NSIS, `.deb`, `.rpm`, leurs 3 signatures `.sig`, `latest.json` — les noms exacts varient selon la version de Tauri), puis télécharge `latest.json` (il pilote l'auto-update des installations existantes) et vérifie `version` (il affiche `pub_date` et la longueur des notes), puis exige **exactement quatre clés** (#320) : `linux-x86_64`, `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64`. Pour chacune : l'extension de l'URL (`.deb`, `.deb`, `.rpm`, `.exe`), une signature non vide dont le `file:` (commentaire de confiance minisign, signature décodée du base64) est le nom de fichier de l'URL, décodé, et la version dans l'URL. **Il sort en 1 sur tout écart** (`MANQUANT`, `VIDE`, `MAUVAISE VERSION`, `MAUVAISE EXTENSION`, `DIFFÉRENT`, `INATTENDUE`) et finit par `VERDICT : OK` ou `VERDICT : ÉCHEC` : pas d'annonce de la release ni d'étape 10 avant un verdict OK. Un second argument (`verify-release.sh vX.Y.Z fichier.json`) contrôle un `latest.json` local au lieu de l'asset, pour éprouver les contrôles sur un fichier fabriqué.
|
Le script (token `~/.forgejo-token`) lit la release par tag, compte les 7 artefacts **par suffixe** (`.exe` NSIS, `.deb`, `.rpm`, leurs 3 signatures `.sig`, `latest.json` — les noms exacts varient selon la version de Tauri), puis télécharge `latest.json` (il pilote l'auto-update des installations existantes) et vérifie `version` (il affiche `pub_date` et la longueur des notes), puis exige **exactement trois clés** (#320) : `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64`, sans clé générique `linux-x86_64` depuis le 2026-10-11 (`docs/qa-update-cycle.md`). Pour chacune : l'extension de l'URL (`.deb`, `.rpm`, `.exe`), une signature non vide dont le `file:` (commentaire de confiance minisign, signature décodée du base64) est le nom de fichier de l'URL, décodé, et la version dans l'URL. **Il sort en 1 sur tout écart** (`MANQUANT`, `VIDE`, `MAUVAISE VERSION`, `MAUVAISE EXTENSION`, `DIFFÉRENT`, `INATTENDUE`) et finit par `VERDICT : OK` ou `VERDICT : ÉCHEC` : pas d'annonce de la release ni d'étape 10 avant un verdict OK. Un second argument (`verify-release.sh vX.Y.Z fichier.json`) contrôle un `latest.json` local au lieu de l'asset, pour éprouver les contrôles sur un fichier fabriqué.
|
||||||
**Lire aussi l'étape « Generate latest.json » du journal du run** (même route web que ci-dessous) : `scripts/build-latest-json.sh` y nomme le paquet retenu pour chaque type (`build-latest-json: .rpm <- …`), puis le `latest.json` généré est affiché. Le script et le filtre `scripts/check-latest-json.jq` passent par les tests de `check-frontend` à chaque PR ; leur appel par `release.yml` et le délimiteur aléatoire des notes ne s'exercent qu'au tag. Un manifeste refusé par le filtre arrête le job sur `ERROR: release-assets/latest.json failed scripts/check-latest-json.jq`, avant le `DELETE` : registre intact, et la release Forgejo reste créée sans mise à jour servie.
|
**Lire aussi l'étape « Generate latest.json » du journal du run** (même route web que ci-dessous) : `scripts/build-latest-json.sh` y nomme le paquet retenu pour chaque type (`build-latest-json: .rpm <- …`), puis le `latest.json` généré est affiché. Le script et le filtre `scripts/check-latest-json.jq` passent par les tests de `check-frontend` à chaque PR ; leur appel par `release.yml` et le délimiteur aléatoire des notes ne s'exercent qu'au tag. Un manifeste refusé par le filtre arrête le job sur `ERROR: release-assets/latest.json failed scripts/check-latest-json.jq`, avant le `DELETE` : registre intact, et la release Forgejo reste créée sans mise à jour servie.
|
||||||
Durée observée du run : 22 à 30 min sur les 12 dernières releases — poser le `Monitor` puis passer à autre chose.
|
Durée observée du run : 22 à 30 min sur les 12 dernières releases — poser le `Monitor` puis passer à autre chose.
|
||||||
**Lire aussi le Node.js du run.** `release.yml` n'est exercé qu'au tag : une montée de Node (Node 20 → 24 par #376) ne se prouve que dans ce journal. Il passe par la route web (l'API v1 des journaux répond 404). Le `run_number` vient de `/actions/tasks`, qui rend toute la liste, la plus récente en tête (le paramètre `limit` y est ignoré) :
|
**Lire aussi le Node.js du run.** `release.yml` n'est exercé qu'au tag : une montée de Node (Node 20 → 24 par #376) ne se prouve que dans ce journal. Il passe par la route web (l'API v1 des journaux répond 404). Le `run_number` vient de `/actions/tasks`, qui rend toute la liste, la plus récente en tête (le paramètre `limit` y est ignoré) :
|
||||||
|
|
@ -83,3 +83,4 @@ updated: 2026-10-10
|
||||||
- 2026-09-13 — Étape 0 : prérequis « clés testeurs saisies avant le tag » précisé (déclencheurs `FEATURE_TIERS`, gating, `auto-update` ; cas réel v0.15.0, deux clés Premium émises le jour même). Étape 9 : script `scripts/verify-release.sh` (7 artefacts par suffixe + contenu de `latest.json`) au lieu d'un script réécrit à chaque release ; durée de run observée 22-30 min. Source : session 690a6129 (release v0.15.0, run 402) via /skills-review-inbox (draft 2026-09-12).
|
- 2026-09-13 — Étape 0 : prérequis « clés testeurs saisies avant le tag » précisé (déclencheurs `FEATURE_TIERS`, gating, `auto-update` ; cas réel v0.15.0, deux clés Premium émises le jour même). Étape 9 : script `scripts/verify-release.sh` (7 artefacts par suffixe + contenu de `latest.json`) au lieu d'un script réécrit à chaque release ; durée de run observée 22-30 min. Source : session 690a6129 (release v0.15.0, run 402) via /skills-review-inbox (draft 2026-09-12).
|
||||||
- 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) : 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-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.
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,14 @@ print(f"version={v} {'OK' if v == version else 'MAUVAISE VERSION'} | pub_date={p
|
||||||
ok &= v == version
|
ok &= v == version
|
||||||
print(f"notes: {len(notes)} caractères — début: {notes[:120]!r}")
|
print(f"notes: {len(notes)} caractères — début: {notes[:120]!r}")
|
||||||
|
|
||||||
# The four keys (#320): tauri-plugin-updater looks up "{os}-{arch}-{installer}",
|
# The three keys (#320): tauri-plugin-updater looks up "{os}-{arch}-{installer}",
|
||||||
# then "{os}-{arch}". Each with the extension its URL must end with. Same set
|
# then "{os}-{arch}". Each with the extension its URL must end with. No generic
|
||||||
# as scripts/build-latest-json.sh writes and scripts/check-latest-json.jq
|
# linux-x86_64 since 2026-10-11, so a manifest that still has it fails here as
|
||||||
# checks: scripts/build-latest-json.test.mjs reads this line and compares.
|
# INATTENDUE. Same set as scripts/build-latest-json.sh writes and
|
||||||
EXPECTED = {"linux-x86_64": ".deb", "linux-x86_64-deb": ".deb",
|
# scripts/check-latest-json.jq checks: scripts/build-latest-json.test.mjs reads
|
||||||
"linux-x86_64-rpm": ".rpm", "windows-x86_64": ".exe"}
|
# this line and compares.
|
||||||
|
EXPECTED = {"linux-x86_64-deb": ".deb", "linux-x86_64-rpm": ".rpm",
|
||||||
|
"windows-x86_64": ".exe"}
|
||||||
|
|
||||||
def signed_file(sig):
|
def signed_file(sig):
|
||||||
"""The file: field of the trusted comment, in the base64 minisign signature."""
|
"""The file: field of the trusted comment, in the base64 minisign signature."""
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
### Corrigé
|
### Corrigé
|
||||||
|
|
||||||
- Les installations faites depuis le paquet `.rpm` reçoivent désormais les mises à jour automatiques. Le manifeste de mise à jour ne listait que le `.deb`, qu'une installation `.rpm` téléchargeait puis refusait ; il liste maintenant chaque paquet Linux sous sa propre clé. Les installations `.rpm` existantes n'ont rien à réinstaller : elles recevront la prochaine version (vérifié sur le paquet v0.17.1 publié). Les instructions de téléchargement de la page de release ne mentionnent plus d'AppImage, qui n'est pas construite, et nomment désormais le `.rpm` (#320).
|
- Les installations faites depuis le paquet `.rpm` reçoivent désormais les mises à jour automatiques. Le manifeste de mise à jour ne listait que le `.deb`, qu'une installation `.rpm` téléchargeait puis refusait ; il liste maintenant chaque paquet Linux sous sa propre clé. Les installations `.rpm` existantes n'ont rien à réinstaller : elles recevront la prochaine version (vérifié sur le paquet v0.17.1 publié). Les instructions de téléchargement de la page de release ne mentionnent plus d'AppImage, qui n'est pas construite, et nomment désormais le `.rpm`. Le manifeste n'a plus d'entrée Linux générique : les AppImage des versions 0.4.3 à 0.4.5, qui ne savaient pas installer le `.deb` qu'elle désignait et en étaient cassées, affichent désormais une erreur à la vérification des mises à jour ; installez plutôt le paquet `.deb` ou `.rpm` (#320).
|
||||||
|
|
||||||
### Sécurité
|
### Sécurité
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Installs from the `.rpm` package now receive automatic updates. The update manifest only listed the `.deb`, which an `.rpm` install downloaded and then refused; it now lists each Linux package under its own key. Existing `.rpm` installs need no reinstall: they will receive the next version (checked on the published v0.17.1 package). The download instructions of the release page no longer mention an AppImage, which is not built, and now name the `.rpm` (#320).
|
- Installs from the `.rpm` package now receive automatic updates. The update manifest only listed the `.deb`, which an `.rpm` install downloaded and then refused; it now lists each Linux package under its own key. Existing `.rpm` installs need no reinstall: they will receive the next version (checked on the published v0.17.1 package). The download instructions of the release page no longer mention an AppImage, which is not built, and now name the `.rpm`. The manifest no longer has a generic Linux entry: the AppImage builds of 0.4.3 to 0.4.5, which could not install the `.deb` it pointed to and were broken by it, now report an error when checking for updates instead; install the `.deb` or `.rpm` package (#320).
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|
|
||||||
2
STATE.md
2
STATE.md
|
|
@ -75,7 +75,7 @@ Audit critique de la page Bilan livré (`docs/audit-bilan-2026-05.md`, revue CPA
|
||||||
- Aucun blocker externe dur. `spec-monetisation` **fermée 12/12** (2026-07-08) — #50/#52/#53/#135/#136 livrées, ne sont plus des blockers.
|
- Aucun blocker externe dur. `spec-monetisation` **fermée 12/12** (2026-07-08) — #50/#52/#53/#135/#136 livrées, ne sont plus des blockers.
|
||||||
- **Vérifications dues à la prochaine release** (après le tag, étape 9 de `/release`) :
|
- **Vérifications dues à la prochaine release** (après le tag, étape 9 de `/release`) :
|
||||||
- `release.yml` sous Node 24 (#376) : `node --version` à `v24.x` dans le journal du run de release, et `verify-release.sh` vert. Le diff touchant `release.yml`, l'étape 10 de `/release` (cycle réel de mise à jour, `docs/qa-update-cycle.md`) s'applique aussi, selon la règle du skill.
|
- `release.yml` sous Node 24 (#376) : `node --version` à `v24.x` dans le journal du run de release, et `verify-release.sh` vert. Le diff touchant `release.yml`, l'étape 10 de `/release` (cycle réel de mise à jour, `docs/qa-update-cycle.md`) s'applique aussi, selon la règle du skill.
|
||||||
- `latest.json` à quatre clés (#320) : étape « Generate latest.json » du journal lue (un paquet retenu par type), `verify-release.sh` en `VERDICT : OK` sur `linux-x86_64`, `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64` (extensions, `file:` des signatures). Cycle réel depuis une installation `.rpm` (§3 de `docs/qa-update-cycle.md`) dès qu'une machine Fedora ou openSUSE est disponible, sinon « non déroulé » avec la raison dans la trace de la release.
|
- `latest.json` à trois clés (#320, clé générique `linux-x86_64` retirée le 2026-10-11) : étape « Generate latest.json » du journal lue (un paquet retenu par type), `verify-release.sh` en `VERDICT : OK` sur `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64` (extensions, `file:` des signatures). Cycle réel depuis une installation `.rpm` (§3 de `docs/qa-update-cycle.md`) dès qu'une machine Fedora ou openSUSE est disponible, sinon « non déroulé » avec la raison dans la trace de la release.
|
||||||
- **Le paiement est live : « aucun tag avant le go-live » n'a plus de raison d'être, et la release desktop qu'attendait le go-live est publiée (v0.16.0, 2026-10-03).** Bascule live le 2026-09-29 (Product et Price live à 19 $ CAD, webhook, variables Stripe de production, redeploy `3673d09` de maximus-api, URL `cs_live_` vérifiée), puis achat réel de contrôle le 2026-09-30 : clé sur `/merci` et par courriel, activation dans l'app, remboursement complet et licence révoquée par `charge.refunded`. **Volet serveur clos le 2026-10-03** (derniers commentaires relus le 2026-10-04) : maximus-api#62 fermée, tous critères cochés (maximus-api 0.4.2 en prod, secrets en runtime seul), avec la milestone `spec-paiements` de maximus-api (12/12) ; la-compagnie-maximus#150 (Link dans les textes légaux) livrée et fermée le 2026-10-01. **Go-live clos : la-compagnie-maximus#141** fermée le 2026-10-10 sur décision de Max, l'updater vérifié (Free refuse et invite à acheter, Base accepte ; confirmé le même jour). Restent pour mémoire, sans issue : le Dashboard Stripe (logo, paramètres Checkout, reçus automatiques, alertes d'échec de webhook) et les relevés du commentaire de fermeture. la-compagnie-maximus#184 (politique de confidentialité : données d'activation, contrôle au démarrage) est en `status:review` ; sa PR reste en brouillon jusqu'au déploiement de maximus-api#85 (commentaire du 2026-10-03). Les deux textes des suites de licence (contrôle à la saisie, retrait de la clé) y sont postés depuis le 2026-10-05 (commentaire 19724). **Vérifications manuelles sur la release publiée, toutes faites** : #365 le 2026-10-03, #346 et #350 le 2026-10-04 (voir Décisions). L'étape 10 sous Windows est faite (Michel, confirmée le 2026-10-10).
|
- **Le paiement est live : « aucun tag avant le go-live » n'a plus de raison d'être, et la release desktop qu'attendait le go-live est publiée (v0.16.0, 2026-10-03).** Bascule live le 2026-09-29 (Product et Price live à 19 $ CAD, webhook, variables Stripe de production, redeploy `3673d09` de maximus-api, URL `cs_live_` vérifiée), puis achat réel de contrôle le 2026-09-30 : clé sur `/merci` et par courriel, activation dans l'app, remboursement complet et licence révoquée par `charge.refunded`. **Volet serveur clos le 2026-10-03** (derniers commentaires relus le 2026-10-04) : maximus-api#62 fermée, tous critères cochés (maximus-api 0.4.2 en prod, secrets en runtime seul), avec la milestone `spec-paiements` de maximus-api (12/12) ; la-compagnie-maximus#150 (Link dans les textes légaux) livrée et fermée le 2026-10-01. **Go-live clos : la-compagnie-maximus#141** fermée le 2026-10-10 sur décision de Max, l'updater vérifié (Free refuse et invite à acheter, Base accepte ; confirmé le même jour). Restent pour mémoire, sans issue : le Dashboard Stripe (logo, paramètres Checkout, reçus automatiques, alertes d'échec de webhook) et les relevés du commentaire de fermeture. la-compagnie-maximus#184 (politique de confidentialité : données d'activation, contrôle au démarrage) est en `status:review` ; sa PR reste en brouillon jusqu'au déploiement de maximus-api#85 (commentaire du 2026-10-03). Les deux textes des suites de licence (contrôle à la saisie, retrait de la clé) y sont postés depuis le 2026-10-05 (commentaire 19724). **Vérifications manuelles sur la release publiée, toutes faites** : #365 le 2026-10-03, #346 et #350 le 2026-10-04 (voir Décisions). L'étape 10 sous Windows est faite (Michel, confirmée le 2026-10-10).
|
||||||
- Backlog ouvert : **vague `planned-2026-09-24-paiements` close 3/3** (milestone fermée le 2026-09-30) : #270 (PR #359) et #346 (PR #362) mergées le 2026-09-27, #347 (PR #364, ferme aussi #360) mergée le 2026-09-30 ; volet site **clos** (maximus/la-compagnie-maximus#153, redirection de `/simpl-resultat` en prod). **#365 fermée le 2026-10-03** après sa vérification manuelle. **Milestone `planned-2026-10-03-suites-licence` fermée 3/3 le 2026-10-05** (#373, #370, #367 mergées, voir Décisions ; suivi #389 en `status:triage`). Hors milestone, en `status:ready` : **#369** (réserver le fractionnement de transactions à l'édition Base) et **#372** (la liste complète des versions repousse le Journal en bas de Paramètres → Systèmes). **#350 fermée le 2026-10-04** (étape 3 vérifiée en production, voir Décisions) ; #363 fermée le 2026-10-10 sur décision de Max (ses tests, absorbés par #347, sont livrés dans la v0.16.0) ; réglés côté serveur et site : maximus-api#63 (clés de 100 ans) et maximus-api#70 (réactivation d'une machine désactivée), fermées et contenues dans `3673d09`, le commit déployé à la bascule du 2026-09-29, et la-compagnie-maximus#157, fermée, dont les CGV sont publiées en tronc commun plus annexe Simpl-Résultat (annexe relue en production le 2026-09-30, plus aucune durée de 10 ans) ; côté serveur, `/v1/prices` ne vérifie pas qu'une machine est encore active (une machine désactivée garde les cours jusqu'à l'expiration de son jeton), issue maximus-api à ouvrir ; suites de #350 ouvertes le 2026-10-01 : maximus-api#82 (`status:triage` : identifiants machine bruts déjà stockés, lignes désactivées comprises ; à rehacher avant l'expiration des premiers jetons bruts, sinon une réactivation crée une seconde ligne) et la-compagnie-maximus#184 (`status:review`, voir ci-dessus) ; go-live clos (la-compagnie-maximus#141 fermée le 2026-10-10, maximus-api#62 le 2026-10-03) ; `spec-paiements` fermée ici 5/5 ; onboarding phase 2 (parcours guidé) **mergée** : milestone `planned-2026-10-06-onboarding-parcours-guide` fermée 6/6 le 2026-10-08 (#396 à #401, `ee17f31`), suivis **#408** et **#409** (`status:triage`) ; onboarding phase 1 **livrée** : milestone `planned-2026-10-03-onboarding-phase1` fermée 7/7 le 2026-10-04 (#351 à #357, mergées en avance rapide, `667e058`) ; suivis ouverts : **#384** (`status:ready`, suivis non bloquants des revues) et **#371** (`status:blocked`, hors `/autopilot` : en-têtes CSV BMO à fournir par Max depuis un compte réel, un par type de compte, chèques/épargne et Mastercard, avec des valeurs fictives) ; analyse d'origine dans `docs/analyse-onboarding-2026-09.md`, plan détaillé dans les `spec-*-onboarding-phase1.md` locaux, ignorés par git ; #271 absorbé par #301, livré ; `spec-ci-build-optimization` **fermée 4/4** le 2026-10-05 (#232 livrée le 2026-07-27 ; #234 close le 2026-10-05 avec ses quatre preuves : dispatch run 464, PR #386 run 480, run planifié 488, `actcache` à 999 Mo) ; **#376** (`status:triage` : Node 20, en fin de vie depuis le 2026-04-30, encore installé par `check-frontend.yml` et `audit.yml`, et commentaire `concurrency` de `check-rust.yml` démenti par `forgejo-ops.md` pour les runs de PR). Le suivi « glob `src-tauri/**` non prouvé » ouvert avec #232 est **levé** : la PR #344 est le cas test isolé attendu (`Cargo.lock` + 2 `.md` seulement) — `check-rust` a bien tourné, `check-frontend` a bien été sauté par sa denylist.
|
- Backlog ouvert : **vague `planned-2026-09-24-paiements` close 3/3** (milestone fermée le 2026-09-30) : #270 (PR #359) et #346 (PR #362) mergées le 2026-09-27, #347 (PR #364, ferme aussi #360) mergée le 2026-09-30 ; volet site **clos** (maximus/la-compagnie-maximus#153, redirection de `/simpl-resultat` en prod). **#365 fermée le 2026-10-03** après sa vérification manuelle. **Milestone `planned-2026-10-03-suites-licence` fermée 3/3 le 2026-10-05** (#373, #370, #367 mergées, voir Décisions ; suivi #389 en `status:triage`). Hors milestone, en `status:ready` : **#369** (réserver le fractionnement de transactions à l'édition Base) et **#372** (la liste complète des versions repousse le Journal en bas de Paramètres → Systèmes). **#350 fermée le 2026-10-04** (étape 3 vérifiée en production, voir Décisions) ; #363 fermée le 2026-10-10 sur décision de Max (ses tests, absorbés par #347, sont livrés dans la v0.16.0) ; réglés côté serveur et site : maximus-api#63 (clés de 100 ans) et maximus-api#70 (réactivation d'une machine désactivée), fermées et contenues dans `3673d09`, le commit déployé à la bascule du 2026-09-29, et la-compagnie-maximus#157, fermée, dont les CGV sont publiées en tronc commun plus annexe Simpl-Résultat (annexe relue en production le 2026-09-30, plus aucune durée de 10 ans) ; côté serveur, `/v1/prices` ne vérifie pas qu'une machine est encore active (une machine désactivée garde les cours jusqu'à l'expiration de son jeton), issue maximus-api à ouvrir ; suites de #350 ouvertes le 2026-10-01 : maximus-api#82 (`status:triage` : identifiants machine bruts déjà stockés, lignes désactivées comprises ; à rehacher avant l'expiration des premiers jetons bruts, sinon une réactivation crée une seconde ligne) et la-compagnie-maximus#184 (`status:review`, voir ci-dessus) ; go-live clos (la-compagnie-maximus#141 fermée le 2026-10-10, maximus-api#62 le 2026-10-03) ; `spec-paiements` fermée ici 5/5 ; onboarding phase 2 (parcours guidé) **mergée** : milestone `planned-2026-10-06-onboarding-parcours-guide` fermée 6/6 le 2026-10-08 (#396 à #401, `ee17f31`), suivis **#408** et **#409** (`status:triage`) ; onboarding phase 1 **livrée** : milestone `planned-2026-10-03-onboarding-phase1` fermée 7/7 le 2026-10-04 (#351 à #357, mergées en avance rapide, `667e058`) ; suivis ouverts : **#384** (`status:ready`, suivis non bloquants des revues) et **#371** (`status:blocked`, hors `/autopilot` : en-têtes CSV BMO à fournir par Max depuis un compte réel, un par type de compte, chèques/épargne et Mastercard, avec des valeurs fictives) ; analyse d'origine dans `docs/analyse-onboarding-2026-09.md`, plan détaillé dans les `spec-*-onboarding-phase1.md` locaux, ignorés par git ; #271 absorbé par #301, livré ; `spec-ci-build-optimization` **fermée 4/4** le 2026-10-05 (#232 livrée le 2026-07-27 ; #234 close le 2026-10-05 avec ses quatre preuves : dispatch run 464, PR #386 run 480, run planifié 488, `actcache` à 999 Mo) ; **#376** (`status:triage` : Node 20, en fin de vie depuis le 2026-04-30, encore installé par `check-frontend.yml` et `audit.yml`, et commentaire `concurrency` de `check-rust.yml` démenti par `forgejo-ops.md` pour les runs de PR). Le suivi « glob `src-tauri/**` non prouvé » ouvert avec #232 est **levé** : la PR #344 est le cas test isolé attendu (`Cargo.lock` + 2 `.md` seulement) — `check-rust` a bien tourné, `check-frontend` a bien été sauté par sa denylist.
|
||||||
- Suivis des advisories : **#312, #313 et #315 fermées le 2026-08-15** (PRs #321/#322 mergées). **#314 fermée le 2026-08-15, prémisse infirmée** — elle affirmait « zéro run `schedule` », or `audit.yml` tire tous les jours à 06:00 UTC (**19 runs `schedule` verts** du 07-28 au 08-15, sans trou) ; elle a été écrite le 07-27 vers 23:56Z, ~6 h avant le premier tir programmé possible, et décrivait donc une fenêtre trop courte, pas un scheduler en panne. Ces 19 runs confirment au passage que `.cargo/audit.toml` est bien lu en conteneur **sur `main`** — l'ADR 0018 ne l'avait vérifié que par un `workflow_dispatch` sur une branche. **#343 fermée le 2026-09-04** (PR #344) — RUSTSEC-2026-0258 sur `h2`, la seule vulnérabilité qui rougissait l'audit depuis le 08-19 ; l'audit est de nouveau vert sur `main`, prouvé par `workflow_dispatch` (run 393) et non déduit du run de PR. **#348 fermée le 2026-09-21** (PR #349) — RUSTSEC-2026-0285 sur `rustls`, seule vulnérabilité rougissant l'audit depuis le 09-15 (7 runs, 405→411) ; vert reprouvé par `workflow_dispatch` sur `main` (run 414 : 666 paquets, zéro vulnérabilité, 12 warnings autorisés). Deux advisories en cinq semaines sur le même chemin, celui de la mise à jour automatique. Restent **#317** (prémisse caduque depuis le 2026-09-26 : `react-router-dom` 7.18.2 et suivantes corrigent l'advisory par un bump de patch dans `^7.18.1`, sans migration v8 ; absorbée par #358, dont la PR la fermera), **#319** (déclencheur de retrait pour `rsa`, désormais **seule** entrée de `.cargo/audit.toml` — le garde-fou est passé à 2 vérifications) et **#345** (domicilier la contrainte `windows-sys 0.61.2` — analysée le 09-04 : le corps d'origine, écrit de mémoire en fin de revue, se trompait sur trois points. Le déclencheur n'est pas « n'importe quel `cargo update` » mais tout bump atteignant le sous-arbre réseau/TLS — mesuré : `-p anyhow` ne bouge rien, `-p hyper` fait descendre les 7 — soit précisément là où tombent les advisories. **Prémisse restreinte le 2026-09-21 par #348** : `-p rustls`, au cœur de ce même sous-arbre, n'en déplace **aucun** — le déclencheur tient à `hyper` et à ce qu'il tire, pas à la couche TLS en général, donc « sous-arbre réseau/TLS » prédit une dérive là où il n'y en a pas et ferait écrire une strophe à la main sans nécessité. D'où la suggestion portée en commentaire sur l'issue : formuler le garde-fou sur la **version résolue de `windows-sys`** plutôt que sur une liste de crates déclencheurs — la liste est ce qui vient d'être trouvé faux, la version est ce qui est protégé. #310 avait **bien** vu la dérive et l'avait jugée inoffensive *sur Linux*, où elle l'est ; son coût tombe sur le build Windows que personne ne mesurait : **3 versions de `windows-sys` compilées contre 5**. Aucun risque de correction — les 7 crates déclarent des bornes larges couvrant les deux états. Et cargo annonce « Locking 1 package » en écrivant 8 changements, donc le silence est le sien. Décision : garde-fou CI sur la version + ADR portant la condition de sortie. Le check croisé Windows depuis Linux a été **testé et écarté** — `cc-rs` s'arrête sur `lib.exe`, il faudrait `cargo-xwin`). Côté npm, **#358** ouverte le 2026-09-26 par `/analyse-vulnerabilite` : `npm audit` remonte 7 findings (4 high, 3 moderate) sur 4 dépendances racines, contre les 2 acceptés au 07-27, et chaque correctif tient dans la borne déjà déclarée ; le lock se régénère avec `npx npm@11` (npm 10 plante sur un bump de vitest 4.1.x).
|
- Suivis des advisories : **#312, #313 et #315 fermées le 2026-08-15** (PRs #321/#322 mergées). **#314 fermée le 2026-08-15, prémisse infirmée** — elle affirmait « zéro run `schedule` », or `audit.yml` tire tous les jours à 06:00 UTC (**19 runs `schedule` verts** du 07-28 au 08-15, sans trou) ; elle a été écrite le 07-27 vers 23:56Z, ~6 h avant le premier tir programmé possible, et décrivait donc une fenêtre trop courte, pas un scheduler en panne. Ces 19 runs confirment au passage que `.cargo/audit.toml` est bien lu en conteneur **sur `main`** — l'ADR 0018 ne l'avait vérifié que par un `workflow_dispatch` sur une branche. **#343 fermée le 2026-09-04** (PR #344) — RUSTSEC-2026-0258 sur `h2`, la seule vulnérabilité qui rougissait l'audit depuis le 08-19 ; l'audit est de nouveau vert sur `main`, prouvé par `workflow_dispatch` (run 393) et non déduit du run de PR. **#348 fermée le 2026-09-21** (PR #349) — RUSTSEC-2026-0285 sur `rustls`, seule vulnérabilité rougissant l'audit depuis le 09-15 (7 runs, 405→411) ; vert reprouvé par `workflow_dispatch` sur `main` (run 414 : 666 paquets, zéro vulnérabilité, 12 warnings autorisés). Deux advisories en cinq semaines sur le même chemin, celui de la mise à jour automatique. Restent **#317** (prémisse caduque depuis le 2026-09-26 : `react-router-dom` 7.18.2 et suivantes corrigent l'advisory par un bump de patch dans `^7.18.1`, sans migration v8 ; absorbée par #358, dont la PR la fermera), **#319** (déclencheur de retrait pour `rsa`, désormais **seule** entrée de `.cargo/audit.toml` — le garde-fou est passé à 2 vérifications) et **#345** (domicilier la contrainte `windows-sys 0.61.2` — analysée le 09-04 : le corps d'origine, écrit de mémoire en fin de revue, se trompait sur trois points. Le déclencheur n'est pas « n'importe quel `cargo update` » mais tout bump atteignant le sous-arbre réseau/TLS — mesuré : `-p anyhow` ne bouge rien, `-p hyper` fait descendre les 7 — soit précisément là où tombent les advisories. **Prémisse restreinte le 2026-09-21 par #348** : `-p rustls`, au cœur de ce même sous-arbre, n'en déplace **aucun** — le déclencheur tient à `hyper` et à ce qu'il tire, pas à la couche TLS en général, donc « sous-arbre réseau/TLS » prédit une dérive là où il n'y en a pas et ferait écrire une strophe à la main sans nécessité. D'où la suggestion portée en commentaire sur l'issue : formuler le garde-fou sur la **version résolue de `windows-sys`** plutôt que sur une liste de crates déclencheurs — la liste est ce qui vient d'être trouvé faux, la version est ce qui est protégé. #310 avait **bien** vu la dérive et l'avait jugée inoffensive *sur Linux*, où elle l'est ; son coût tombe sur le build Windows que personne ne mesurait : **3 versions de `windows-sys` compilées contre 5**. Aucun risque de correction — les 7 crates déclarent des bornes larges couvrant les deux états. Et cargo annonce « Locking 1 package » en écrivant 8 changements, donc le silence est le sien. Décision : garde-fou CI sur la version + ADR portant la condition de sortie. Le check croisé Windows depuis Linux a été **testé et écarté** — `cc-rs` s'arrête sur `lib.exe`, il faudrait `cargo-xwin`). Côté npm, **#358** ouverte le 2026-09-26 par `/analyse-vulnerabilite` : `npm audit` remonte 7 findings (4 high, 3 moderate) sur 4 dépendances racines, contre les 2 acceptés au 07-27, et chaque correctif tient dans la borne déjà déclarée ; le lock se régénère avec `npx npm@11` (npm 10 plante sur un bump de vitest 4.1.x).
|
||||||
|
|
|
||||||
|
|
@ -621,8 +621,8 @@ Déclenché par les tags `v*`. Un seul job, `build-and-release`, dans un contene
|
||||||
|
|
||||||
Fonctionnalités :
|
Fonctionnalités :
|
||||||
- Signature des binaires (clés TAURI_SIGNING_PRIVATE_KEY)
|
- Signature des binaires (clés TAURI_SIGNING_PRIVATE_KEY)
|
||||||
- JSON d'updater (`latest.json`) écrit par `scripts/build-latest-json.sh` à partir des assets ([#320](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/320)). `tauri-plugin-updater` cherche `{os}-{arch}-{installer}`, puis `{os}-{arch}` : le fichier porte `linux-x86_64-deb` et `linux-x86_64-rpm` (une clé par paquet Linux), `linux-x86_64` (le `.deb`, en repli : raison, lecteurs connus et condition de retrait dans `docs/qa-update-cycle.md`) et `windows-x86_64` (l'installeur NSIS). Le script échoue s'il ne trouve pas exactement un `.deb`, un `.rpm` et un `-setup.exe`, chacun avec un `.sig` non vide ; le JSON vient de `jq` seul (notes lues comme données par `--rawfile`), avec les noms de fichiers encodés par `@uri`, comme à l'envoi des assets. Testé par `scripts/build-latest-json.test.mjs` (vitest, lancé par `check-frontend`), qui l'exécute sous `bash -e -o pipefail` comme `release.yml`.
|
- JSON d'updater (`latest.json`) écrit par `scripts/build-latest-json.sh` à partir des assets ([#320](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/320)). `tauri-plugin-updater` cherche `{os}-{arch}-{installer}`, puis `{os}-{arch}` : le fichier porte `linux-x86_64-deb` et `linux-x86_64-rpm` (une clé par paquet Linux) et `windows-x86_64` (l'installeur NSIS). Pas de clé générique `linux-x86_64` depuis le 2026-10-11 : elle servait le `.deb` à des installations qui ne savaient pas l'installer (anciennes AppImage, binaire hors paquet), qui reçoivent désormais `TargetsNotFound` à la vérification (raisons et lecteurs dans `docs/qa-update-cycle.md`). Le script échoue s'il ne trouve pas exactement un `.deb`, un `.rpm` et un `-setup.exe`, chacun avec un `.sig` non vide ; le JSON vient de `jq` seul (notes lues comme données par `--rawfile`), avec les noms de fichiers encodés par `@uri`, comme à l'envoi des assets. Testé par `scripts/build-latest-json.test.mjs` (vitest, lancé par `check-frontend`), qui l'exécute sous `bash -e -o pipefail` comme `release.yml`.
|
||||||
- JSON publié sur `https://git.lacompagniemaximus.com/api/packages/maximus/generic/simpl-resultat/latest/latest.json` (registre de paquets, endpoint de `tauri.conf.json`). Avant le `DELETE` de l'ancienne version, le filtre `scripts/check-latest-json.jq` (version égale au tag, exactement les quatre clés, signatures non vides, extension de chaque URL) arrête le job si le fichier ne le passe pas : le registre reste intact. Le test du script applique ce même filtre à chaque PR et compare sa liste de clés à celles du script et de `verify-release.sh`, si bien qu'un écart se voit avant le tag.
|
- JSON publié sur `https://git.lacompagniemaximus.com/api/packages/maximus/generic/simpl-resultat/latest/latest.json` (registre de paquets, endpoint de `tauri.conf.json`). Avant le `DELETE` de l'ancienne version, le filtre `scripts/check-latest-json.jq` (version égale au tag, exactement les trois clés, signatures non vides, extension de chaque URL) arrête le job si le fichier ne le passe pas : le registre reste intact. Le test du script applique ce même filtre à chaque PR et compare sa liste de clés à celles du script et de `verify-release.sh`, si bien qu'un écart se voit avant le tag.
|
||||||
- Release Forgejo automatique avec assets et release notes extraites du CHANGELOG.md, transmises par `GITHUB_OUTPUT` sous un délimiteur aléatoire (une ligne du CHANGELOG égale à un délimiteur fixe terminait la valeur)
|
- Release Forgejo automatique avec assets et release notes extraites du CHANGELOG.md, transmises par `GITHUB_OUTPUT` sous un délimiteur aléatoire (une ligne du CHANGELOG égale à un délimiteur fixe terminait la valeur)
|
||||||
|
|
||||||
**Node.js 24** ([#376](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/376)), installé comme dans les trois autres workflows par le script NodeSource (`curl … | bash`). Ce script tourne en root dans le conteneur du job, et le Node.js qu'il installe lance ensuite `npx tauri build` avec `TAURI_SIGNING_PRIVATE_KEY` dans son environnement : le job confie à NodeSource (script et dépôt apt) la clé de signature de l'updater, et les jetons de publication des étapes suivantes. Risque accepté par Max le 2026-10-10, alternative écartée : un tarball Node.js épinglé. La chaîne Rust, installée de la même façon par `rustup`, est dans le même cas. Ce workflow ne tourne qu'au tag : la première release après #376 est la première sous Node 24, à vérifier par `node --version` dans le journal du run (étape 9 de `/release`).
|
**Node.js 24** ([#376](https://git.lacompagniemaximus.com/maximus/simpl-resultat/issues/376)), installé comme dans les trois autres workflows par le script NodeSource (`curl … | bash`). Ce script tourne en root dans le conteneur du job, et le Node.js qu'il installe lance ensuite `npx tauri build` avec `TAURI_SIGNING_PRIVATE_KEY` dans son environnement : le job confie à NodeSource (script et dépôt apt) la clé de signature de l'updater, et les jetons de publication des étapes suivantes. Risque accepté par Max le 2026-10-10, alternative écartée : un tarball Node.js épinglé. La chaîne Rust, installée de la même façon par `rustup`, est dans le même cas. Ce workflow ne tourne qu'au tag : la première release après #376 est la première sous Node 24, à vérifier par `node --version` dans le journal du run (étape 9 de `/release`).
|
||||||
|
|
|
||||||
|
|
@ -88,17 +88,14 @@ Les installations `.rpm` existantes n'ont rien à réinstaller : le binaire du `
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `linux-x86_64-deb` | `.deb` | les installations `.deb` |
|
| `linux-x86_64-deb` | `.deb` | les installations `.deb` |
|
||||||
| `linux-x86_64-rpm` | `.rpm` | les installations `.rpm` (#320) |
|
| `linux-x86_64-rpm` | `.rpm` | les installations `.rpm` (#320) |
|
||||||
| `linux-x86_64` | `.deb` | un binaire Linux sans marqueur de type de paquet, et les AppImage v0.4.2 à v0.4.5 (repli, voir ci-dessous) |
|
|
||||||
| `windows-x86_64` | `-setup.exe` | les installations NSIS, qui cherchent d'abord `windows-x86_64-nsis` |
|
| `windows-x86_64` | `-setup.exe` | les installations NSIS, qui cherchent d'abord `windows-x86_64-nsis` |
|
||||||
|
|
||||||
**Repli `linux-x86_64`.** Raison : un binaire sans marqueur de type de paquet ne cherche que cette clé ; sans clé à son nom, sa vérification échoue (`TargetsNotFound`) au lieu de répondre. Condition de retrait : quand aucune version supportée n'est antérieure au marqueur. Relevé le 2026-10-10 : toutes les versions qui embarquent l'updater (v0.2.1 et suivantes) ont été empaquetées par `@tauri-apps/cli` 2.10.0, d'après le `package-lock.json` de chaque tag, comme la v0.17.1 dont le `.rpm` porte le marqueur.
|
**Pas de clé générique `linux-x86_64`** (retirée le 2026-10-11, décision de Max sur #320). Toutes les versions qui embarquent l'updater (v0.2.1 et suivantes) verrouillent `tauri-plugin-updater` 2.10.0 et `tauri-utils` 2.8.2, et leurs paquets portent le marqueur de type (vérifié dans le `.deb` et le `.rpm` de la v0.17.1) : une installation `.deb` ou `.rpm` trouve sa clé avant de chercher `linux-x86_64`. Cette clé servait le `.deb`, et ses derniers lecteurs ne savaient pas l'installer :
|
||||||
|
|
||||||
Les lecteurs connus de cette clé ne savent pas installer le `.deb` qu'elle sert :
|
- les AppImage des v0.4.3 à v0.4.5, publiées sur Forgejo pour la v0.4.3 et sur le miroir GitHub pour les v0.4.3 à v0.4.5. Leur updater lit le registre et cherche `linux-x86_64-appimage`, absente, puis `linux-x86_64`. La v0.4.2 vise `…/releases/latest/download/latest.json`, qui répond 404 sur cette instance Forgejo, et les versions antérieures lisent GitHub ;
|
||||||
|
- un binaire lancé hors de son paquet, sans marqueur, qui ne cherche que `linux-x86_64`.
|
||||||
|
|
||||||
- un binaire sans marqueur, lancé hors de son paquet ;
|
Avec la clé, l'updater les traitait en AppImage (`install_appimage`) et écrivait les octets du `.deb` à la place du fichier lancé, ce qui cassait l'installation. Sans elle, leur vérification échoue avec `TargetsNotFound` et rien n'est installé : la carte Mises à jour affiche une erreur. La voie, pour ces installations, est de télécharger le `.deb` ou le `.rpm` de la dernière release.
|
||||||
- les AppImage des v0.4.2 à v0.4.5, publiées sur Forgejo pour les v0.4.2 et v0.4.3 et sur le miroir GitHub pour les v0.4.3 à v0.4.5. Leur updater lit déjà le registre, et elles cherchent `linux-x86_64-appimage`, absente, puis cette clé.
|
|
||||||
|
|
||||||
Pour les deux, l'updater traite le téléchargement comme une AppImage (`install_appimage`) et écrit les octets du `.deb` à la place du fichier lancé, ce qui casse l'installation. C'est l'état depuis la v0.4.2, que #320 ne change pas.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,16 +26,17 @@
|
||||||
# linux-x86_64-deb the .deb, for .deb installs.
|
# linux-x86_64-deb the .deb, for .deb installs.
|
||||||
# linux-x86_64-rpm the .rpm, for .rpm installs. Without this key they fell
|
# linux-x86_64-rpm the .rpm, for .rpm installs. Without this key they fell
|
||||||
# back on linux-x86_64, downloaded the .deb and refused it.
|
# back on linux-x86_64, downloaded the .deb and refused it.
|
||||||
# linux-x86_64 the .deb again: the fallback of a binary without a
|
|
||||||
# bundle-type marker, which looks up this key alone.
|
|
||||||
# Remove it once no supported version predates the
|
|
||||||
# marker. AppImage installs (v0.4.2 to v0.4.5) read it
|
|
||||||
# too, and neither they nor a marker-less binary can
|
|
||||||
# install a .deb: see docs/qa-update-cycle.md, "Les
|
|
||||||
# clés de latest.json".
|
|
||||||
# windows-x86_64 the NSIS installer. An NSIS install looks up
|
# windows-x86_64 the NSIS installer. An NSIS install looks up
|
||||||
# windows-x86_64-nsis first, then this key.
|
# windows-x86_64-nsis first, then this key.
|
||||||
#
|
#
|
||||||
|
# No generic linux-x86_64 key since 2026-10-11 (Max's decision on #320). Every
|
||||||
|
# version that ships the updater (v0.2.1 and later, tauri-plugin-updater
|
||||||
|
# 2.10.0) carries its bundle-type marker, so .deb and .rpm installs never
|
||||||
|
# reach that key. Its only readers were the AppImage installs v0.4.3 to
|
||||||
|
# v0.4.5 and binaries run outside a package, and the .deb it served overwrote
|
||||||
|
# them: they now get TargetsNotFound when checking, nothing installed. See
|
||||||
|
# docs/qa-update-cycle.md, "Les clés de latest.json".
|
||||||
|
#
|
||||||
# Each URL ends with the file name percent-encoded by jq's @uri, as the upload
|
# Each URL ends with the file name percent-encoded by jq's @uri, as the upload
|
||||||
# step of release.yml encodes it: the bundle names contain a space.
|
# step of release.yml encodes it: the bundle names contain a space.
|
||||||
|
|
||||||
|
|
@ -108,7 +109,6 @@ jq -n \
|
||||||
notes: $notes,
|
notes: $notes,
|
||||||
pub_date: $pub_date,
|
pub_date: $pub_date,
|
||||||
platforms: {
|
platforms: {
|
||||||
"linux-x86_64": asset($deb; $deb_sig),
|
|
||||||
"linux-x86_64-deb": asset($deb; $deb_sig),
|
"linux-x86_64-deb": asset($deb; $deb_sig),
|
||||||
"linux-x86_64-rpm": asset($rpm; $rpm_sig),
|
"linux-x86_64-rpm": asset($rpm; $rpm_sig),
|
||||||
"windows-x86_64": asset($exe; $exe_sig)
|
"windows-x86_64": asset($exe; $exe_sig)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@
|
||||||
* app reads to find its update. tauri-plugin-updater looks up
|
* app reads to find its update. tauri-plugin-updater looks up
|
||||||
* "{os}-{arch}-{installer}" first, then "{os}-{arch}". Before #320 the
|
* "{os}-{arch}-{installer}" first, then "{os}-{arch}". Before #320 the
|
||||||
* manifest only had linux-x86_64 (the .deb), so an .rpm install downloaded
|
* manifest only had linux-x86_64 (the .deb), so an .rpm install downloaded
|
||||||
* the .deb and refused it.
|
* the .deb and refused it. Since 2026-10-11 it has no linux-x86_64 key at
|
||||||
|
* all: its last readers (old AppImage installs, binaries run outside a
|
||||||
|
* package) could not install the .deb it served.
|
||||||
*
|
*
|
||||||
* Each test runs the script as release.yml does, under bash -e -o pipefail
|
* Each test runs the script as release.yml does, under bash -e -o pipefail
|
||||||
* (the shell of the runner's steps), on a temporary assets directory. The
|
* (the shell of the runner's steps), on a temporary assets directory. The
|
||||||
|
|
@ -106,7 +108,7 @@ afterEach(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("build-latest-json.sh", () => {
|
describe("build-latest-json.sh", () => {
|
||||||
it("writes the four keys, each with its own URL and its own asset's signature", () => {
|
it("writes the three keys, each with its own URL and its own asset's signature", () => {
|
||||||
writeAllAssets();
|
writeAllAssets();
|
||||||
|
|
||||||
const result = run();
|
const result = run();
|
||||||
|
|
@ -116,11 +118,9 @@ describe("build-latest-json.sh", () => {
|
||||||
expect(manifest.version).toBe("0.17.1");
|
expect(manifest.version).toBe("0.17.1");
|
||||||
expect(manifest.notes).toBe("### Fixed\n\n- Something (#320).");
|
expect(manifest.notes).toBe("### Fixed\n\n- Something (#320).");
|
||||||
expect(manifest.pub_date).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/);
|
expect(manifest.pub_date).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/);
|
||||||
|
// No generic linux-x86_64: an install without a key of its own must fail
|
||||||
|
// its check (TargetsNotFound) rather than receive the .deb.
|
||||||
expect(manifest.platforms).toStrictEqual({
|
expect(manifest.platforms).toStrictEqual({
|
||||||
"linux-x86_64": {
|
|
||||||
signature: "RWRkZWItc2lnbmF0dXJl",
|
|
||||||
url: "https://git.example.test/owner/Repo/releases/download/v0.17.1/Simpl%20Resultat_0.17.1_amd64.deb",
|
|
||||||
},
|
|
||||||
"linux-x86_64-deb": {
|
"linux-x86_64-deb": {
|
||||||
signature: "RWRkZWItc2lnbmF0dXJl",
|
signature: "RWRkZWItc2lnbmF0dXJl",
|
||||||
url: "https://git.example.test/owner/Repo/releases/download/v0.17.1/Simpl%20Resultat_0.17.1_amd64.deb",
|
url: "https://git.example.test/owner/Repo/releases/download/v0.17.1/Simpl%20Resultat_0.17.1_amd64.deb",
|
||||||
|
|
@ -209,7 +209,7 @@ describe("build-latest-json.sh", () => {
|
||||||
'"version": "9.9.9", "platforms": {}\n',
|
'"version": "9.9.9", "platforms": {}\n',
|
||||||
);
|
);
|
||||||
expect(manifest.version).toBe("0.17.1");
|
expect(manifest.version).toBe("0.17.1");
|
||||||
expect(Object.keys(manifest.platforms)).toHaveLength(4);
|
expect(Object.keys(manifest.platforms)).toHaveLength(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("fails without its four arguments", () => {
|
it("fails without its four arguments", () => {
|
||||||
|
|
@ -251,6 +251,7 @@ describe("check-latest-json.jq", () => {
|
||||||
it.each([
|
it.each([
|
||||||
["a missing key", (m) => delete m.platforms["linux-x86_64-rpm"]],
|
["a missing key", (m) => delete m.platforms["linux-x86_64-rpm"]],
|
||||||
["an extra key", (m) => (m.platforms["linux-x86_64-appimage"] = m.platforms["linux-x86_64-deb"])],
|
["an extra key", (m) => (m.platforms["linux-x86_64-appimage"] = m.platforms["linux-x86_64-deb"])],
|
||||||
|
["the generic linux-x86_64 key, removed on 2026-10-11", (m) => (m.platforms["linux-x86_64"] = m.platforms["linux-x86_64-deb"])],
|
||||||
["the .rpm key on the .deb", (m) => (m.platforms["linux-x86_64-rpm"] = m.platforms["linux-x86_64-deb"])],
|
["the .rpm key on the .deb", (m) => (m.platforms["linux-x86_64-rpm"] = m.platforms["linux-x86_64-deb"])],
|
||||||
["the .deb key on the .rpm", (m) => (m.platforms["linux-x86_64-deb"] = m.platforms["linux-x86_64-rpm"])],
|
["the .deb key on the .rpm", (m) => (m.platforms["linux-x86_64-deb"] = m.platforms["linux-x86_64-rpm"])],
|
||||||
["the Windows key on a .sig", (m) => (m.platforms["windows-x86_64"].url += ".sig")],
|
["the Windows key on a .sig", (m) => (m.platforms["windows-x86_64"].url += ".sig")],
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,8 @@
|
||||||
# (the file: field of the minisign trusted comment).
|
# (the file: field of the minisign trusted comment).
|
||||||
|
|
||||||
.version == $version
|
.version == $version
|
||||||
and (.platforms | keys) == ["linux-x86_64", "linux-x86_64-deb", "linux-x86_64-rpm", "windows-x86_64"]
|
and (.platforms | keys) == ["linux-x86_64-deb", "linux-x86_64-rpm", "windows-x86_64"]
|
||||||
and all(.platforms[]; (.signature | type) == "string" and (.signature | length) > 0)
|
and all(.platforms[]; (.signature | type) == "string" and (.signature | length) > 0)
|
||||||
and (.platforms["linux-x86_64"].url | endswith(".deb"))
|
|
||||||
and (.platforms["linux-x86_64-deb"].url | endswith(".deb"))
|
and (.platforms["linux-x86_64-deb"].url | endswith(".deb"))
|
||||||
and (.platforms["linux-x86_64-rpm"].url | endswith(".rpm"))
|
and (.platforms["linux-x86_64-rpm"].url | endswith(".rpm"))
|
||||||
and (.platforms["windows-x86_64"].url | endswith(".exe"))
|
and (.platforms["windows-x86_64"].url | endswith(".exe"))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue