fix(release): refuse an empty or multi-document latest.json, test the Publish step #464
No reviewers
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/Simpl-Resultat#464
Loading…
Reference in a new issue
No description provided.
Delete branch "issue-419-latest-json-check-followups"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Resolves #419
Follow-ups of the review of PR #418 (comment 22774). Point 1 had to land before the next tag.
Changes
latest.jsonrefused.scripts/check-latest-json.jqnow wants exactly one document (length == 1 and (.[0] | ...)), and the Publish step ofrelease.ymlcalls it with-s. Reproduced before the fix with the official jq 1.6 static binary (sha256af986793...a124c44, the version ofubuntu:22.04): an empty file passed with rc 0, while jq 1.7 refused it with rc 4. Two new tests cover it: an empty file, and two documents whose last one is valid (also two valid documents).check-frontend.ymlno longer ignores.claude/**or.forgejo/workflows/release.yml. The test readsverify-release.shand now runs the Publish step, so a PR that touches only one of them must run it. This widens the trigger set. REVIEW.md puts anypaths-ignorechange in the CI zone at the high level, so it is named here.REVIEW.md(the CI-and-guards rule and the commands table),CLAUDE.mdanddocs/architecture.mdfollow. Cost: about 2.5 min of runner time on PRs touching project skills orrelease.yml.release.yml:104: the stale ".deb fallback" comment is replaced by the three keys. This was also item 3 of #461.build-latest-json.test.mjsextracts the exactrun:text of "Publish latest.json to package registry" and runs it underbash --noprofile --norc -e -o pipefail, in a directory laid out like the checkout, with a fakecurlon PATH. A valid manifest givesDELETEthenPUTwith the expected URLs and file. On the generic key, a wrong version, an empty file or two documents, the step exits 1 with the error line and makes no request. The extracted text was compared to a PyYAML parse of the step: identical (46 lines). A guard asserts it has no workflow expression, and a comment at the top of the step says so. The guard matters because the runner substitutes those expressions, even in comments, and the test would not see that.docs/qa-update-cycle.md: anpm run tauri devbuild on Linux showsTargetsNotFoundin the Updates card on every check. This is expected since #418, not a regression. Added to the existing bullet. The stalerelease.yml:217-219reference now names the step.Outside this repo:
la-compagnie-maximus/docs/forgejo-ops.md, commit9a8e3f5pushed tomain./actions/tasksreadslimitonly withpage. Re-measured on 2026-10-18 over 654 tasks:?limit=5returns 654,?limit=5&page=1returns 5,?page=2returns 30,?limit=100&page=1returns 50.cancel-in-progressdid not cancel a running PR job.Skill
/release(step 9 text plus a dated history entry) updated. No CHANGELOG entry: nothing user-facing.Verification
npm run buildgreen;npm testunder jq 1.6: 134 files, 2256 tests (2248 before, +8). Probe first: a deliberately red test exits 1.build-latest-json.test.mjs: 36/36 under jq 1.6 and under jq 1.7.python3 scripts/review-levels.py --check: ok.Mutations: one at a time, on the committed tree, restored by git. The table gives red tests out of 36.
-edropped from the Publish call-sdropped from the Publish callexit 1after the refusal replaced bytruelength == 1 anddropped from the filter-sanywhere)M5 matches the review's claim: without the fix, the new tests are red under jq 1.7 only for two documents, and under jq 1.6, the CI's, for the empty file too.
Review level
High per
REVIEW.md. The diff touchesrelease.yml(the job that holds the signing key and the guard before the registryDELETE), thepaths-ignoreofcheck-frontend.ymland.claude/skills/release/.🤖 Generated with Claude Code
Niveau : haut —
.forgejo/workflows/release.yml(Release et mise à jour), aussiscripts/check-latest-json.jq,scripts/build-latest-json.test.mjset.claude/skills/release/SKILL.mdMax doit lire avant le merge.
Verdict : APPROVE
Le point 1 de #419 est fermé : avec
-setlength == 1, le filtre refuse un fichier vide et un fichier à deux documents sous jq 1.6 comme sous 1.7. L'étape « Publish » est exécutée telle quelle par le test, et ce test sait échouer sur chaque garde que la PR ajoute.Ce qui a été rejoué
Tout a tourné sur une copie hors dépôt (
git archive c859405,node_moduleslié), le dépôt n'a pas été modifié.af986793…a124c44, identique à celui du corps de la PR).build-latest-json.test.mjspasse à 36/36 sous jq 1.6 et sous jq 1.7.publishStepScript()est identique, à l'octet, àrunlu par PyYAML (46 lignes).jq (1.6-2.1ubuntu3.2)est installé,jq-1.6affiché,build-latest-json.test.mjs (36 tests)passe, 134 fichiers et 2256 tests.closesvenant de #464, et #461 n'en porte aucun (cité seulement,none).Mutations du relecteur, une à la fois, restaurées puis comparées à l'original. Le tableau donne les tests rouges sur 36, sous jq 1.6 / sous jq 1.7 :
length == 1→length >= 1length == 1 and .[0]→.[-1](dernier document seul)jqdéplacé après leDELETE(avant lePUT)${GITHUB_REF_NAME#v}→${GITHUB_REF_NAME}# tag ${{ github.ref_name }}ajouté dans lerun:> /dev/null || truesur l'appel du filtreUne première version de R4 a muté la ligne 84 (
TAG=de l'étape de création de la release) au lieu de l'étape Publish, et la suite est restée verte. C'est attendu : seul le texte de « Publish » est exécuté, et le corps de la PR le dit (« le reste derelease.ymlne s'exerce qu'au tag »).Passe sécurité (niveau haut)
Aucun constat.
fake-tokenest un littéral de test.FORGEJO_TOKEN: ${{ secrets.PACKAGE_TOKEN }}était déjà là.mkdtemp, avec uncurlfactice en tête duPATH. Aucun appel réseau.paths-ignoredecheck-frontend.ymlest élargi, pas restreint : la CI tourne sur plus de PR.check-frontend.ymlne référence aucunsecrets, et il n'y a pas depull_request_target. Aucun manifeste ni lock ne change.DELETEéchoue toujours fermée.REVIEW.md(hors de la section « Niveaux »),CLAUDE.mdetdocs/architecture.mdsuivent le nouveau déclencheur, comme l'exige « Règles de revue ».Suggestions (non bloquantes)
scripts/**, donc son run ne montre pas qu'une PR qui ne touche que.claude/**ourelease.ymllance biencheck-frontend(piège « un filtrepaths:n'est pas prouvé par une PR qui touche le chemin exact »). La preuve viendra de la première PR de ce type : le noter sur #419 ou dansSTATE.md.release.yml:104) est réglé ici. Un commentaire sur #461 après le merge évitera de le refaire.release.yml, donc l'étape 10 de/releasereste due à la prochaine release. Elle l'est déjà pour #376 et #447 : rien de nouveau.Actions faites
scratchpad/pr464, les sauvegardesorig-*et le script de mutation supprimés en fin de revue.status:review→status:approved.