bug: les utilisateurs installes en .rpm ne peuvent pas se mettre a jour (latest.json ne sert que le .deb) #320

Closed
opened 2026-07-28 01:29:38 +00:00 by maximus · 1 comment
Owner

Planification du 2026-10-10 (/plan-run, milestone planned-2026-10-10-release-deps) : les sections ci-dessous, à partir de « Dépendances », priment sur le texte d'analyse en cas d'écart.

Analyse /analyze du 2026-10-10, lue sur main 87920ec. Corps d'origine archivé en commentaire.

Contexte

src-tauri/tauri.conf.json:26 bundle ["nsis", "deb", "rpm"] et release.yml publie les trois. Mais latest.json n'a qu'une entrée linux-x86_64, construite depuis le .deb (release.yml:104-122).

Vérifié en analyse (tauri-plugin-updater 2.10.0, tauri-utils 2.8.2)

  • Le plugin cherche déjà une clé par installeur. get_urls (updater.rs:568-598) essaie {os}-{arch}-{installer} puis {os}-{arch} (commentaire L579, format! L584 et L586). Installer::Rpm.name() = "rpm" (L63), donc une installation rpm cherche linux-x86_64-rpm en premier.
  • Détection du bundle : __TAURI_BUNDLE_TYPE (tauri-utils/src/platform.rs:349-360), remplacé par le bundler dans chaque paquet ; installer_for_bundle_type (updater.rs:1426-1433).
  • Symptôme réel : une installation rpm voit une mise à jour proposée (repli sur linux-x86_64), télécharge le .deb, puis install_rpm (L1058-1063) refuse les octets (infer::archive::is_rpm → InvalidUpdaterFormat). Une mise à jour proposée, puis un échec.
  • Le correctif tient dans release.yml : aucune modification Rust.
  • Coût CI du rpm marginal : même tauri build (release.yml:50, --bundles deb,rpm), une étape d'empaquetage et environ 9,7 Mo d'upload.
  • Textes faux : notes de release release.yml:158 (« .deb ou .AppImage », aucun AppImage construit, rpm absent) ; README.md:44-45 (AppImage). Le site (la-compagnie-maximus) ne propose que le .deb : rien à changer.

Décision (Max, 2026-10-10)

Ajouter la clé linux-x86_64-rpm (et linux-x86_64-deb) à latest.json, garder le rpm. Écarté : retirer le rpm (couperait Fedora/openSUSE pour un gain CI négligeable).

Travail à faire

  • Extraire la génération de latest.json dans scripts/build-latest-json.sh (voir « Décisions prises en planification »), appelé par release.yml : écrire linux-x86_64-rpm et linux-x86_64-deb ; garder linux-x86_64 sur le .deb (repli, voir décisions).
  • release.yml:158 : notes « Linux : .deb (Debian, Ubuntu) ou .rpm (Fedora, openSUSE) », sans AppImage.
  • README.md:43-45 : retirer l'AppImage.
  • .claude/skills/release/scripts/verify-release.sh (L44-51) : exiger linux-x86_64, linux-x86_64-deb, linux-x86_64-rpm et windows-x86_64, et vérifier que l'URL de chaque clé Linux finit par la bonne extension (.deb / .rpm). Mettre à jour .claude/skills/release/SKILL.md:46 en conséquence.
  • docs/qa-update-cycle.md:65-69 : la section « RPM — cassé, connu » devient une procédure de test du cycle rpm (à dérouler sur la prochaine release) ; :32 inchangé (toujours pas d'AppImage). docs/architecture.md:617 : mentionner les clés de latest.json.
  • CHANGELOG.md / CHANGELOG.fr.md : Fixed / Corrigé, « les installations .rpm reçoivent les mises à jour automatiques ». Corrigé aussi pour les installations rpm existantes : vérifié le 2026-10-10, le binaire du .rpm v0.17.1 publié porte le marqueur __TAURI_BUNDLE_TYPE_VAR_RPM, donc il lira linux-x86_64-rpm dès que la release suivante le publie, sans réinstallation.

Fichiers concernés

  • .forgejo/workflows/release.yml
  • .claude/skills/release/scripts/verify-release.sh, .claude/skills/release/SKILL.md
  • README.md, docs/qa-update-cycle.md, docs/architecture.md
  • CHANGELOG.md, CHANGELOG.fr.md

Surface de test

  • Test de régression (type:bug) : scripts/build-latest-json.test.mjs (vitest), voir « Critères d'acceptation (planification) ».
  • verify-release.sh : le lancer sur un latest.json factice sans linux-x86_64-rpm → échec ; avec → succès.
  • À confirmer à la prochaine release : verify-release.sh vert sur les quatre clés ; un cycle de mise à jour réel depuis une installation rpm reste à faire quand une machine Fedora/openSUSE est disponible (hors PR, à noter dans qa-update-cycle.md).

Critères d'acceptation

  • Le latest.json généré porte linux-x86_64, linux-x86_64-deb, linux-x86_64-rpm et windows-x86_64, chacun avec la bonne URL et sa signature.
  • verify-release.sh échoue si une de ces clés manque ou pointe vers la mauvaise extension.
  • Notes de release et README sans AppImage, rpm mentionné.
  • CHANGELOG FR/EN.

Complexité estimée

Simple.

Liens

Relevé pendant #315 / #312 ; docs/qa-update-cycle.md §3.


Dépendances

Depends on

Fichiers concernés (complet)

  • scripts/build-latest-json.sh (nouveau), scripts/build-latest-json.test.mjs (nouveau)
  • .forgejo/workflows/release.yml (appel du script, délimiteur, assertion avant DELETE, notes de release L158)
  • .forgejo/workflows/check-frontend.yml (ajouter jq à l'apt-get install)
  • .claude/skills/release/scripts/verify-release.sh (chemin exact), .claude/skills/release/SKILL.md (L46 et checklist)
  • README.md (L43-45), docs/qa-update-cycle.md (L32, L65-69), docs/architecture.md (réécrire tout le paragraphe release.yml, L610-617 : il décrit encore deux jobs dont windows-latest, alors qu'un seul job Ubuntu cross-compile avec cargo-xwin ; ajouter scripts/ et son test)
  • CHANGELOG.md, CHANGELOG.fr.md

Critères d'acceptation (planification)

  • scripts/build-latest-json.sh (entrées : dossier d'assets, version, fichier de notes, URL de base ; sortie : latest.json) sort en erreur s'il ne trouve pas exactement un .deb, un .rpm et un -setup.exe, chacun avec son "$asset.sig" non vide.
  • Le JSON est produit uniquement par jq (--arg, --rawfile pour les notes) ; noms de fichiers encodés @uri dans les URL, comme l'étape d'upload.
  • latest.json porte linux-x86_64 (.deb), linux-x86_64-deb, linux-x86_64-rpm et windows-x86_64, chaque URL avec la bonne extension, chaque signature lue du .sig de son propre asset.
  • Test scripts/build-latest-json.test.mjs (vitest, lance le script avec bash -e -o pipefail comme release.yml, sur un dossier temporaire) : cas nominal (quatre clés, extensions, signatures appariées) ; .rpm absent → code de sortie non nul ; .sig vide → non nul ; deux .deb → non nul ; notes contenant ", \ et une ligne CHANGELOG_EOF → JSON valide et notes intactes.
  • check-frontend installe jq ; le test passe dans la CI de la PR (journal lu).
  • release.yml : délimiteur GITHUB_OUTPUT aléatoire pour les notes ; avant le DELETE du paquet latest du registre, une assertion jq (version = tag, quatre clés, signature non vide, bonne extension) qui arrête le job sinon.
  • verify-release.sh sort en 1 si une des quatre clés manque, si une URL Linux n'a pas la bonne extension, ou si le file: du commentaire de confiance minisign (signature décodée en base64) ne correspond pas au nom de fichier de l'URL. Prouvé sur un latest.json factice (cas vert et cas rouges) dans la PR.
  • Notes de release et README sans AppImage, rpm mentionné ; CHANGELOG Fixed / Corrigé.

Review caveats

  • 🔴 ARCHITECTURE/TECHNIQUE (résolu) : jq absent de check-frontend → ajouté (décision).
  • 🔴 SECURITE (résolu) : script en échec fermé → critère ci-dessus.
  • 🟡 SECURITE (résolu) : signature par asset, notes en données, délimiteur aléatoire, validation avant DELETE, contrôle minisign → critères ci-dessus.
  • 🟡 ARCHITECTURE : la clé de repli linux-x86_64 doit avoir sa raison et sa condition de retrait écrites (commentaire du script + qa-update-cycle.md) : repli pour les binaires sans marqueur de bundle ; à retirer quand aucune version antérieure au marqueur n'est plus supportée.
  • 🟢 TECHNIQUE : tsconfig n'inclut que src ; le test est en .mjs pour ne pas laisser croire qu'il est vérifié par tsc.
  • 🟢 TECHNIQUE : la modification de release.yml n'est exercée qu'au prochain tag. Ajouter à .claude/skills/release/SKILL.md : lire le journal de l'étape de génération de latest.json et lancer verify-release.sh (désormais bloquant) avant d'annoncer la release.

Décisions prises en planification

  • Clé linux-x86_64-rpm ajoutée, rpm gardé (Max, 2026-10-10).
  • jq ajouté à check-frontend + test vitest .mjs (Max, 2026-10-10).
  • Tout le lot de durcissement de la revue sécurité intégré (Max, 2026-10-10).
  • Installations rpm existantes : corrigées sans réinstallation (vérifié sur le .rpm v0.17.1), à écrire dans qa-update-cycle.md et le CHANGELOG.

Spec source

spec-plan-release-deps.md (local, ignoré par git)

> **Planification du 2026-10-10** (`/plan-run`, milestone `planned-2026-10-10-release-deps`) : les sections ci-dessous, à partir de « Dépendances », **priment** sur le texte d'analyse en cas d'écart. > Analyse `/analyze` du 2026-10-10, lue sur `main` `87920ec`. Corps d'origine archivé en commentaire. ## Contexte `src-tauri/tauri.conf.json:26` bundle `["nsis", "deb", "rpm"]` et `release.yml` publie les trois. Mais `latest.json` n'a qu'une entrée `linux-x86_64`, construite depuis le `.deb` (`release.yml:104-122`). ### Vérifié en analyse (tauri-plugin-updater 2.10.0, tauri-utils 2.8.2) - **Le plugin cherche déjà une clé par installeur.** `get_urls` (`updater.rs:568-598`) essaie `{os}-{arch}-{installer}` puis `{os}-{arch}` (commentaire L579, `format!` L584 et L586). `Installer::Rpm.name()` = `"rpm"` (L63), donc une installation rpm cherche `linux-x86_64-rpm` en premier. - **Détection du bundle** : `__TAURI_BUNDLE_TYPE` (`tauri-utils/src/platform.rs:349-360`), remplacé par le bundler dans chaque paquet ; `installer_for_bundle_type` (`updater.rs:1426-1433`). - **Symptôme réel** : une installation rpm voit une mise à jour proposée (repli sur `linux-x86_64`), télécharge le `.deb`, puis `install_rpm` (L1058-1063) refuse les octets (`infer::archive::is_rpm` → `InvalidUpdaterFormat`). Une mise à jour proposée, puis un échec. - **Le correctif tient dans `release.yml`** : aucune modification Rust. - Coût CI du rpm marginal : même `tauri build` (`release.yml:50`, `--bundles deb,rpm`), une étape d'empaquetage et environ 9,7 Mo d'upload. - Textes faux : notes de release `release.yml:158` (« `.deb` ou `.AppImage` », aucun AppImage construit, rpm absent) ; `README.md:44-45` (AppImage). Le site (`la-compagnie-maximus`) ne propose que le `.deb` : rien à changer. ## Décision (Max, 2026-10-10) **Ajouter la clé `linux-x86_64-rpm`** (et `linux-x86_64-deb`) à `latest.json`, garder le rpm. Écarté : retirer le rpm (couperait Fedora/openSUSE pour un gain CI négligeable). ## Travail à faire - [ ] Extraire la génération de `latest.json` dans `scripts/build-latest-json.sh` (voir « Décisions prises en planification »), appelé par `release.yml` : écrire `linux-x86_64-rpm` et `linux-x86_64-deb` ; **garder** `linux-x86_64` sur le `.deb` (repli, voir décisions). - [ ] `release.yml:158` : notes « **Linux** : `.deb` (Debian, Ubuntu) ou `.rpm` (Fedora, openSUSE) », sans AppImage. - [ ] `README.md:43-45` : retirer l'AppImage. - [ ] `.claude/skills/release/scripts/verify-release.sh` (L44-51) : exiger `linux-x86_64`, `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64`, et vérifier que l'URL de chaque clé Linux finit par la bonne extension (`.deb` / `.rpm`). Mettre à jour `.claude/skills/release/SKILL.md:46` en conséquence. - [ ] `docs/qa-update-cycle.md:65-69` : la section « RPM — cassé, connu » devient une procédure de test du cycle rpm (à dérouler sur la prochaine release) ; `:32` inchangé (toujours pas d'AppImage). `docs/architecture.md:617` : mentionner les clés de `latest.json`. - [ ] `CHANGELOG.md` / `CHANGELOG.fr.md` : Fixed / Corrigé, « les installations `.rpm` reçoivent les mises à jour automatiques ». Corrigé aussi pour les installations rpm existantes : vérifié le 2026-10-10, le binaire du `.rpm` v0.17.1 publié porte le marqueur `__TAURI_BUNDLE_TYPE_VAR_RPM`, donc il lira `linux-x86_64-rpm` dès que la release suivante le publie, sans réinstallation. ## Fichiers concernés - `.forgejo/workflows/release.yml` - `.claude/skills/release/scripts/verify-release.sh`, `.claude/skills/release/SKILL.md` - `README.md`, `docs/qa-update-cycle.md`, `docs/architecture.md` - `CHANGELOG.md`, `CHANGELOG.fr.md` ## Surface de test - Test de régression (type:bug) : `scripts/build-latest-json.test.mjs` (vitest), voir « Critères d'acceptation (planification) ». - `verify-release.sh` : le lancer sur un `latest.json` factice sans `linux-x86_64-rpm` → échec ; avec → succès. - **À confirmer** à la prochaine release : `verify-release.sh` vert sur les quatre clés ; un cycle de mise à jour réel depuis une installation rpm reste à faire quand une machine Fedora/openSUSE est disponible (hors PR, à noter dans `qa-update-cycle.md`). ## Critères d'acceptation - [ ] Le `latest.json` généré porte `linux-x86_64`, `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64`, chacun avec la bonne URL et sa signature. - [ ] `verify-release.sh` échoue si une de ces clés manque ou pointe vers la mauvaise extension. - [ ] Notes de release et README sans AppImage, rpm mentionné. - [ ] CHANGELOG FR/EN. ## Complexité estimée Simple. ## Liens Relevé pendant #315 / #312 ; `docs/qa-update-cycle.md` §3. --- ## Dépendances ## Depends on - #376 ## Fichiers concernés (complet) - `scripts/build-latest-json.sh` (nouveau), `scripts/build-latest-json.test.mjs` (nouveau) - `.forgejo/workflows/release.yml` (appel du script, délimiteur, assertion avant DELETE, notes de release L158) - `.forgejo/workflows/check-frontend.yml` (ajouter `jq` à l'`apt-get install`) - `.claude/skills/release/scripts/verify-release.sh` (chemin exact), `.claude/skills/release/SKILL.md` (L46 et checklist) - `README.md` (L43-45), `docs/qa-update-cycle.md` (L32, L65-69), `docs/architecture.md` (réécrire **tout** le paragraphe `release.yml`, L610-617 : il décrit encore deux jobs dont `windows-latest`, alors qu'un seul job Ubuntu cross-compile avec `cargo-xwin` ; ajouter `scripts/` et son test) - `CHANGELOG.md`, `CHANGELOG.fr.md` ## Critères d'acceptation (planification) - [ ] `scripts/build-latest-json.sh` (entrées : dossier d'assets, version, fichier de notes, URL de base ; sortie : `latest.json`) sort en erreur s'il ne trouve pas **exactement** un `.deb`, un `.rpm` et un `-setup.exe`, chacun avec son `"$asset.sig"` non vide. - [ ] Le JSON est produit **uniquement** par `jq` (`--arg`, `--rawfile` pour les notes) ; noms de fichiers encodés `@uri` dans les URL, comme l'étape d'upload. - [ ] `latest.json` porte `linux-x86_64` (`.deb`), `linux-x86_64-deb`, `linux-x86_64-rpm` et `windows-x86_64`, chaque URL avec la bonne extension, chaque signature lue du `.sig` de son propre asset. - [ ] Test `scripts/build-latest-json.test.mjs` (vitest, lance le script avec `bash -e -o pipefail` comme `release.yml`, sur un dossier temporaire) : cas nominal (quatre clés, extensions, signatures appariées) ; `.rpm` absent → code de sortie non nul ; `.sig` vide → non nul ; deux `.deb` → non nul ; notes contenant `"`, `\` et une ligne `CHANGELOG_EOF` → JSON valide et notes intactes. - [ ] `check-frontend` installe `jq` ; le test passe dans la CI de la PR (journal lu). - [ ] `release.yml` : délimiteur `GITHUB_OUTPUT` aléatoire pour les notes ; **avant** le DELETE du paquet `latest` du registre, une assertion `jq` (version = tag, quatre clés, signature non vide, bonne extension) qui arrête le job sinon. - [ ] `verify-release.sh` sort en 1 si une des quatre clés manque, si une URL Linux n'a pas la bonne extension, ou si le `file:` du commentaire de confiance minisign (signature décodée en base64) ne correspond pas au nom de fichier de l'URL. Prouvé sur un `latest.json` factice (cas vert et cas rouges) dans la PR. - [ ] Notes de release et README sans AppImage, rpm mentionné ; CHANGELOG Fixed / Corrigé. ## Review caveats - 🔴 ARCHITECTURE/TECHNIQUE (résolu) : `jq` absent de `check-frontend` → ajouté (décision). - 🔴 SECURITE (résolu) : script en échec fermé → critère ci-dessus. - 🟡 SECURITE (résolu) : signature par asset, notes en données, délimiteur aléatoire, validation avant DELETE, contrôle minisign → critères ci-dessus. - 🟡 ARCHITECTURE : la clé de repli `linux-x86_64` doit avoir sa raison et sa condition de retrait écrites (commentaire du script + `qa-update-cycle.md`) : repli pour les binaires sans marqueur de bundle ; à retirer quand aucune version antérieure au marqueur n'est plus supportée. - 🟢 TECHNIQUE : `tsconfig` n'inclut que `src` ; le test est en `.mjs` pour ne pas laisser croire qu'il est vérifié par `tsc`. - 🟢 TECHNIQUE : la modification de `release.yml` n'est exercée qu'au prochain tag. Ajouter à `.claude/skills/release/SKILL.md` : lire le journal de l'étape de génération de `latest.json` et lancer `verify-release.sh` (désormais bloquant) avant d'annoncer la release. ## Décisions prises en planification - Clé `linux-x86_64-rpm` ajoutée, rpm gardé (Max, 2026-10-10). - `jq` ajouté à `check-frontend` + test vitest `.mjs` (Max, 2026-10-10). - Tout le lot de durcissement de la revue sécurité intégré (Max, 2026-10-10). - Installations rpm existantes : corrigées sans réinstallation (vérifié sur le `.rpm` v0.17.1), à écrire dans `qa-update-cycle.md` et le CHANGELOG. ## Spec source `spec-plan-release-deps.md` (local, ignoré par git)
maximus added the
status:ready
type:bug
source:analyste
labels 2026-07-28 01:29:38 +00:00
Author
Owner

Archive avant réécriture par /analyze (2026-10-10, lu sur main 87920ec). Le corps est réécrit avec les décisions de Max du jour ; le texte d'origine est conservé ci-dessous.

Corps d'origine

src-tauri/tauri.conf.json bundle trois cibles : ["nsis", "deb", "rpm"]. release.yml construit et publie bien les trois. Mais l'entree linux-x86_64 de latest.json est construite uniquement a partir du .deb :

.forgejo/workflows/release.yml:104   for f in release-assets/*.deb.sig; do
.forgejo/workflows/release.yml:107   for f in release-assets/*.deb; do
.forgejo/workflows/release.yml:122   '. + {"linux-x86_64": {"signature": $sig, "url": $url}}'

latest.json n'a pas de notion de format de paquet : il y a une entree par cible, et Linux pointe sur le .deb.

Consequence

Un utilisateur installe depuis le .rpm qui lance une verification de mise a jour telecharge des octets .deb. Cote tauri-plugin-updater, le format d'installeur est resolu depuis le marqueur __TAURI_BUNDLE_TYPE grave dans l'artefact : le binaire rpm resout Installer::Rpm, qui verifie la signature magique du payload avant de le passer au gestionnaire de paquets, et rejette les octets deb.

Donc : les utilisateurs rpm recoivent un echec de mise a jour, pas une mise a jour silencieusement cassee — mais ils n'ont aucun chemin de mise a jour automatique, alors qu'on leur livre un artefact. La mise a jour automatique etant une fonctionnalite Base+, ce sont des utilisateurs payants.

Incoherence connexe

Le texte des notes de release annonce le mauvais format :

.forgejo/workflows/release.yml:158   **Linux** : Telechargez le fichier `.deb` ou `.AppImage` ci-dessous.

Aucun AppImage n'est construit. Le .rpm, lui, existe et n'est pas mentionne.

Pistes

  • Le plus simple : ne plus bundler le .rpm s'il n'a pas d'utilisateur connu — un artefact sans chemin de mise a jour est un piege.
  • Sinon : servir un latest.json distinct par format, ou basculer Linux sur l'AppImage (le seul format que tauri-plugin-updater sait reellement extraire lui-meme, via install_appimage — c'est aussi le seul chemin qui exercerait tar, cf. #315).
  • Dans tous les cas, corriger le texte des notes de release.

Releve pendant #315 / #312.

Archive avant réécriture par `/analyze` (2026-10-10, lu sur `main` `87920ec`). Le corps est réécrit avec les décisions de Max du jour ; le texte d'origine est conservé ci-dessous. <details><summary>Corps d'origine</summary> `src-tauri/tauri.conf.json` bundle **trois** cibles : `["nsis", "deb", "rpm"]`. `release.yml` construit et publie bien les trois. Mais l'entree `linux-x86_64` de `latest.json` est construite **uniquement a partir du `.deb`** : ``` .forgejo/workflows/release.yml:104 for f in release-assets/*.deb.sig; do .forgejo/workflows/release.yml:107 for f in release-assets/*.deb; do .forgejo/workflows/release.yml:122 '. + {"linux-x86_64": {"signature": $sig, "url": $url}}' ``` `latest.json` n'a pas de notion de format de paquet : il y a **une** entree par cible, et Linux pointe sur le `.deb`. ## Consequence Un utilisateur installe depuis le `.rpm` qui lance une verification de mise a jour telecharge des octets `.deb`. Cote `tauri-plugin-updater`, le format d'installeur est resolu depuis le marqueur `__TAURI_BUNDLE_TYPE` grave dans l'artefact : le binaire rpm resout `Installer::Rpm`, qui verifie la signature magique du payload avant de le passer au gestionnaire de paquets, et **rejette** les octets deb. Donc : les utilisateurs rpm recoivent un echec de mise a jour, pas une mise a jour silencieusement cassee — mais ils n'ont **aucun** chemin de mise a jour automatique, alors qu'on leur livre un artefact. La mise a jour automatique etant une fonctionnalite Base+, ce sont des utilisateurs payants. ## Incoherence connexe Le texte des notes de release annonce le mauvais format : ``` .forgejo/workflows/release.yml:158 **Linux** : Telechargez le fichier `.deb` ou `.AppImage` ci-dessous. ``` Aucun AppImage n'est construit. Le `.rpm`, lui, existe et n'est pas mentionne. ## Pistes - Le plus simple : **ne plus bundler le `.rpm`** s'il n'a pas d'utilisateur connu — un artefact sans chemin de mise a jour est un piege. - Sinon : servir un `latest.json` distinct par format, ou basculer Linux sur l'AppImage (le seul format que `tauri-plugin-updater` sait reellement extraire lui-meme, via `install_appimage` — c'est aussi le seul chemin qui exercerait `tar`, cf. #315). - Dans tous les cas, corriger le texte des notes de release. Releve pendant #315 / #312. </details>
maximus added this to the planned-2026-10-10-release-deps milestone 2026-10-10 23:22:29 +00:00
maximus added
status:in-progress
and removed
status:ready
labels 2026-10-11 00:26:24 +00:00
maximus added
status:review
and removed
status:in-progress
labels 2026-10-11 00:56:31 +00:00
maximus added
status:approved
and removed
status:review
labels 2026-10-11 23:02:29 +00:00
maximus removed the
status:approved
label 2026-10-12 19:33:42 +00:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

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