quest'n'click 4.5.0 · r1

Construite pour quest'n'click 4.5.0, révision r1. Si elle est publiée, et laquelle est la courante, est dit par publication.json.

Publier une release

English · Type : procédure · Public : contributeur · Contexte : dépôt du moteur · Statut : prête · S'applique depuis : 4.2.0

Comment une version de quest'n'click se fabrique, pour le mainteneur : un candidate run sur main, un tag signé qui le nomme, une release qui publie les fichiers de ce run sans rien reconstruire, puis une relecture. Les commandes sont npm run ship -- … (tools/release/ship.mjs) ; chacune écrit son PID dans .cache/pids/ship-<commande>.pid (SHIP_PIDS choisit le dossier) : pour en arrêter une, on arrête ce PID, pas un motif.

Ce que vous obtenez

Une release GitHub v<version> publiée et immuable, construite depuis le commit que la CI et le candidat ont testé, avec ses archives, manifestes, SBOM, sommes et attestations de provenance, relue par ship verify ; à partir de la 4.5.0, sa documentation publiée après cette relecture.

Contexte et versions

Dans le dépôt du moteur, par le mainteneur (il faut l'accès en écriture, la clé de signature et les réglages du dépôt). La chaîne est celle de la 4.1.20 « Last Mile » (plan §11) ; les tags sont signés depuis la 4.2.0. Cette page vaut à partir de la 4.2.0.

Prérequis

Où lancer les commandes

Dans le dépôt du moteur, sur la machine du mainteneur, sur un main à jour. La release elle-même tourne sur GitHub Actions (.github/workflows/release.yml), lancée par le run ci du tag.

Étapes

La chaîne

  1. Un candidat sur main. On le lance à la main sur main pour le SHA complet :

    # dans le dépôt du moteur
    gh workflow run candidate --ref main -f sha=<full sha>
    

    Il joue toutes les familles lourdes sur ce SHA, le profil de qualification complet sur ses propres archives et son image, les trois charges et la répétition de signature. Sa gate (candidate-gate) écrit et atteste candidate-manifest.json, avec chaque fichier que la release publiera (tools/release/artifacts.mjs). Lire la gate et sa conclusion. Seul un run lancé à la main (workflow_dispatch) sur main peut être nommé par un tag ; une pull request avec le label full-ci le lance aussi, pour information seulement.

  1. Un tag qui le nomme.

    # dans le dépôt du moteur
    npm run ship -- tag <version> <sha> --candidate=<run> --sign --now
    

    Le tag stable précédent doit être un ancêtre du SHA. --candidate=<run id> est obligatoire depuis la 4.1.17 : le run doit être vert et son manifeste nommer ce SHA et ce run ; l'annotation du tag le nomme, et release.yml publie les fichiers de ce run. --now n'attend pas le run ci de main (le run ci du tag, la même suite sur le même commit, est celui que release.yml vérifie). --sign signe le tag avec la clé SSH (plus bas). ship tag refuse de taguer tant que les releases immuables sont désactivées. Il attend ensuite comme ship watch.

  1. La release, depuis ce run. Le run ci du tag, une fois vert, lance release.yml. Il vérifie que le tag est bien le commit testé par la CI, que le tag stable précédent est un ancêtre, et que le candidat nommé est un run vert de candidate lancé à la main sur main. Il télécharge les fichiers du run et vérifie chaque SHA-256 contre le manifeste. Il rejoue les vérifications de release (npm run release-check:ci), prouve les catalogues Remix, et copie ce que le candidat a fait : il ne reconstruit rien de ce que le candidat a produit (archives, image, SBOM, le site, les surfaces). Il crée alors la release en brouillon, téléverse chaque fichier, la publie et la relit (ship verify). Depuis la 4.1.20, il lui faut aussi la répétition de signature du run : un candidat antérieur à la PR 3b de cette version ne peut pas être publié, il faut en lancer un nouveau. Un seul run de release par tag à la fois : le second attend, puis trouve la release du premier.
  1. Relecture.

    # dans le dépôt du moteur
    npm run ship -- verify <version>
    

    La commande télécharge la release et vérifie les sommes, chaque attestation de provenance et la liste des fichiers contre le manifeste ; depuis la 4.1.20, elle lance aussi gh release verify et gh release verify-asset pour chaque fichier. release.yml la lance comme dernière vérification.

Limite · published-never-changed Une release publiée ne change jamais. Un run sur une release déjà publiée s'arrête avant de rien faire. Un brouillon laissé par un run qui a échoué avant la publication n'a jamais été public : il est supprimé (son tag reste) et refait depuis le même candidat. Une RC ratée ne se corrige pas : elle devient une rc.N+1.

Ce que porte une release

Chaque release est construite depuis le commit que la CI a testé, porte ses licences dans l'archive, et joint : le jeu construit (dist), son manifeste d'assets, les archives des cinq paquets npm (quest-n-click, create-quest-n-click, quest-n-click-bridge, quest-n-click-connectors, quest-n-click-studio-server ; Paquets npm), un SBOM CycloneDX par paquet et un pour l'image du Bridge (cinq SBOM en 4.1.19, six depuis le paquet du Studio Server en 4.2.1), l'image du Bridge, les preuves des catalogues Remix, un speedrun complet du chapitre de référence vérifié par speedrun:verify, les runs du candidat, sa baseline, les fichiers de son site, ses surfaces et sa répétition de signature, le manifeste du candidat, des sommes SHA-256 et une attestation de provenance de build (gh attestation verify <file> -R wanoo/quest-n-click) ; à partir de la 4.5.0, l'archive de la documentation. Elle n'est jamais remplacée une fois publiée. Ce que seuls des gens et de vrais appareils vérifient est rapporté dans ses notes (Passes de terrain).

Une pré-version (4.1.8-rc.1) se tague de la même façon ; release.yml la marque comme pré-release sur GitHub.

La documentation, après la relecture

S'applique depuis la 4.5.0

À partir de la 4.5.0, le job docs-publish de release.yml dépend (needs) du job de release : il ne démarre donc qu'une fois ship verify passé. Il appelle .github/workflows/docs-publish.yml avec le tag, le SHA, le candidate run et le sha256 de l'archive de documentation, promeut cette archive (celle du candidat, vérifiée de nouveau), l'inscrit dans publication.json et pousse le wiki ; une rc ne publie que /docs/<v-rc>/. Il n'est jamais lancé par release: published, qu'une release publiée avec GITHUB_TOKEN ne déclenche pas. Seule la clé de déploiement du wiki, WIKI_DEPLOY_KEY, lui est passée. Voir Écrire la documentation.

Ce que le mainteneur active, une fois (après la PR 3b de la 4.1.20)

Signer les tags

Les tags 4.1.x restent annotés (D30). À partir de la 4.2, ils sont signés avec la clé SSH du mainteneur :

# dans le dépôt du moteur
git config gpg.format ssh
git config user.signingkey ~/.ssh/id_ed25519.pub
npm run ship -- tag 4.2.0-rc.2 <sha> --candidate=<run> --sign --now

Limite · signature-not-approval Avec id_ed25519, la signature prouve l'usage de la clé, pas l'accord du mainteneur : un accord est consigné explicitement (D37).

Le préflight stable

# dans le dépôt du moteur
npm run ship -- preflight-stable --candidate=<run> [--version=4.2.0]

Il ne signe rien, ne publie rien et ne change aucun réglage (tools/release/preflight.mjs). Il dit, vérification par vérification, ok, missing (une étape encore à faire) ou blocked (quelque chose ne va pas) :

Il ne sort en 1 que sur un blocked.

Toutes les commandes ship

CommandeCe qu'elle fait
ship checks <pr>Attend les vérifications de la pull request ; relance une fois un job en échec ; sort en 1 s'il échoue encore
ship merge <pr>checks, puis fusionne (un commit de fusion, la seule méthode que le ruleset permet) ; affiche le SHA
ship main <sha>Attend que le run ci de main sur ce SHA soit vert (relancé une fois)
ship tag <version> <sha> --candidate=<run> [--now] [--sign [--key=<file>]]Tague (plus haut), pousse, puis watch
ship watch <version>Attend le run ci du tag, puis le run release ; sort selon sa conclusion
ship verify <version>La relecture (plus haut)
ship preflight-stable --candidate=<run> [--version=<x.y.z>]Le préflight stable (plus haut)
ship chain <pr> <version>fusion → tag → watch → verify ; refusée depuis la 4.1.17, dont les tags demandent un candidate run du commit de fusion (fusion, candidat, puis tag)

Chaque commande est idempotente et dit ce qu'elle attend.

Résultat attendu, et comment le vérifier

ship watch sort en 0 avec le succès du run de release ; ship verify <version> affiche chaque fichier vérifié et sort en 0 ; la page de la release montre les fichiers et « Immutable » ; gh attestation verify <file> -R wanoo/quest-n-click passe pour n'importe lequel de ses fichiers.

Erreurs fréquentes

SymptômeCauseCorrection
release.yml : « names no candidate run »Le tag a été fait sans --candidateTaguer la version suivante (ou rc.N+1) avec --candidate : le ruleset refuse de supprimer un tag
release.yml : « run … is not a green candidate started on main »Le run est celui d'une pull request, d'une autre branche, ou rougeLancer candidate à la main sur main pour ce SHA
release.yml : « has no candidate-site » (ou -surfaces, -signing, -pack, -sbom, -image)Un candidat antérieur à l'étapeLancer un nouveau candidat
« is published: a published release is never changed »Une relance sur un tag publiéRien à faire ; une nouvelle version est un nouveau tag
ship tag refuse : releases immuables désactivéesLe réglage n'est pas activéL'activer (plus haut), puis taguer
Une RC ratée—Taguer rc.N+1 depuis un nouveau candidat

Fichiers ou données modifiés

Un tag v<version> (signé), une release GitHub avec ses fichiers et attestations, .cache/pids/ship-*.pid en local ; à partir de la 4.5.0, le wiki et publication.json (par docs-publish). Avant cela, la branche de release modifie CHANGELOG.md, docs/dev/LOG.md et docs/dev/passes/<version>.md.

Revenir en arrière

Une release publiée ne peut être ni changée ni retirée : un défaut se corrige dans une nouvelle version. Un brouillon est supprimé par le run de release suivant. Un tag pas encore publié peut rester tel quel, et un nouveau candidat être tagué sous le numéro de pré-version suivant.

Références


Modifier la source de cette page · Signaler une erreur