Publier une version
Publier, c’est produire des tags cohérents sur les six dépôts en une seule commande, depuis l’espace de co-développement.
Ce que chaque dépôt versionne
Section intitulée « Ce que chaque dépôt versionne »| Dépôt | Source de vérité | Règle |
|---|---|---|
darkone-nixos-framework | VERSION | Référence du train |
dnf-generator | Cargo.toml | Version propre, épinglée par le framework |
dnf-fleet-update | package.json | Version propre, empaquetée par le framework |
dnf-doc | package.json | MAJEUR.MINEUR du framework, correctif propre |
dnf-boilerplate, dnf-example | dernier tag | Miroir du framework |
Les six dépôts tiennent un CHANGELOG.md généré, modèles compris.
Le projet privé consommateur n’est jamais taggué : il reste en co-développement et sert de banc d’intégration permanent.
Le vocabulaire de commit
Section intitulée « Le vocabulaire de commit »Le changelog est généré à partir des messages de commit. Un type hors liste
disparaît silencieusement des notes de version, donc le format est vérifié :
une seule ligne <type>(<scope>): <sujet>, 80 caractères max, type de la liste
suivante.
feat fix perf refactor docs test build ci chore security revertLe même script, scripts/check-commit-msg.sh, contrôle chaque push vers
main et chaque pull request dans l’intégration continue, et chaque commit
en local via le hook commit-msg, à installer une fois par clone :
ln -s ../../scripts/check-commit-msg.sh .git/hooks/commit-msgUn scope n’est jamais un type : feat(matrix): …, jamais matrix(admin): ….
| Type | Section du changelog |
|---|---|
feat | Added |
fix | Fixed |
security | Security |
perf, refactor, revert | Changed |
docs | Documentation |
chore(deps) | Dependencies |
sujet en drop ou remove | Removed |
autres chore, ci, test, build | non publié |
chore(deps) est le commit d’épinglage du train : l’entrée du framework
nomme ainsi le générateur et le fleet-update qu’elle embarque.
Les recettes
Section intitulée « Les recettes »| Recette | Effet |
|---|---|
just versions | Version, dernier tag et branche de chaque dépôt |
just changelog | Aperçu de la prochaine entrée, n’écrit rien |
just bump [niveau] | Version, changelog, commit et tag d’un dépôt |
just release [niveau] | Le train complet sur les six dépôts (+ la racine) |
just version | Version, révision et générateur épinglé du framework |
Le niveau vaut auto par défaut : git-cliff 🡕 déduit
le numéro suivant des commits. patch, minor, major ou un X.Y.Z littéral
forcent la décision. Des commits non publiés seuls (un chore(deps), par
exemple) donnent un correctif.
just bump ne pousse jamais : il affiche la commande de poussée. Il refuse de
publier si HEAD porte déjà le dernier tag v*. Trois drapeaux passent au
script :
--dry-run: montre l’entrée puis restaure le fichier, sans rien commiter ;--yes: enchaîne sans confirmation ni passage dans$EDITOR;--next: affiche la version que prendrait la release, puis s’arrête.
Écrire à la main dans une entrée
Section intitulée « Écrire à la main dans une entrée »Le bloc généré ne contient que des messages de commit. Un préambule, un tableau
de versions compagnes ou une note de migration s’écrivent sous
## [Unreleased] dans le CHANGELOG.md : à la publication, le script vide
cette section et replie son contenu en tête de l’entrée, avant les rubriques
générées. Le train ne s’arrête pas pour éditer : ces notes s’écrivent
avant de le lancer.
Le train de release
Section intitulée « Le train de release »just release s’exécute à la racine de l’espace de co-développement, qui doit
contenir les six dépôts. Chaque dépôt part dans l’ordre de ses dépendances, et
seulement s’il a bougé depuis son dernier tag.
-
Contrôles préalables : outils présents (
git-cliff,jq,nix-update), dépôts propres, surmain, à jour deorigin. Rien de long ne tourne avant. -
Plan : version actuelle et prochaine de chaque dépôt, aperçu des entrées de changelog, puis une seule confirmation. Refuser n’écrit rien. Ensuite, tout est automatique.
-
Barrière globale :
just check(code et tests unitaires). -
Générateur, s’il a bougé :
just gen-test, release et poussée. Il possède le schémaetc/config.yaml, donc il part avant ce qui en dépend. Son tag est ensuite épinglé dansdnf/flake.nix(commitchore(deps)), pour que le contrat entre framework et générateur se lise dans un diff. Le générateur épinglé régénère enfindnf/config/config.schema.json, le schéma que les projets lisent par leur liendnf/(commitchore(schema)s’il change). -
fleet-update, s’il a bougé : barrières
cietauditavec l’outillage de sonnix develop, release et poussée. Son tag est ensuite épinglé dansdnf/pkgs/fleet-updateparjust pkg-update, et le paquet est construit (commitchore(deps)). -
Framework :
just simulate alltourne après les épinglages, donc sur les dépendances réellement livrées. Ces scénarios ne tournent pas dans l’intégration continue : un scénario rouge arrête le train ici. PuisVERSION, l’épinglage du modèle de projet (templates/project/flake.nix),CHANGELOG.md, commit, tag et poussée. -
Documentation :
just codegenrégénère la référence, puis traduction et normalisation. S’il y a quelque chose à publier, le site est construit (avant le tag, pour qu’un lien cassé bloque), la version s’aligne sur la ligneMAJEUR.MINEURdu framework, puis le site est déployé. -
Boilerplate et exemple : le boilerplate est d’abord recopié depuis
templates/project/au tag du framework (CHANGELOG.mdetflake.lockconservés), avec un bandeau « copie publiée » sous le titre de ses README. On ne le modifie donc jamais à la main. Puis, pour les deux, le tag du framework est écrit dans leurflake.nix, leflake.lockest commité (c’est lui qui rend un clone reproductible), puis changelog et tag identique à celui du framework. Chaque hôte de l’exemple est évalué jusqu’àsystem.build.toplevelcontre le nouveau framework, matériel et secrets remplacés par des bouchons (dnf/just/scripts/eval-template-hosts.nix) : un modèle n’a ni l’un ni l’autre. Le boilerplate, livré sansvar/generated/, n’a rien à évaluer avantjust generate. -
Racine :
just update-dnf, commit du seulflake.lock, puis poussée de la branche courante (sans tag), en tout dernier : son verrou pointe sur les releases publiées juste avant. La racine n’est jamais tagguée.
Seul le framework suit le niveau passé à la recette. Générateur et
fleet-update restent en auto, la documentation suit la ligne du framework,
les modèles son numéro.
Chaque dépôt est poussé avec son tag seul (git push --atomic origin main refs/tags/vX.Y.Z), jamais avec --tags : les tags locaux de travail
restent locaux.
Les garde-fous d’intégration continue
Section intitulée « Les garde-fous d’intégration continue »Sur un tag v*, release.yml refuse de publier si :
- le fichier
VERSIONne correspond pas au tag ; CHANGELOG.mdne contient pas de section pour cette version ;- le verrou pointe un
dnf-generatorpris sur une branche plutôt que sur une release publiée.
Les trois contrôles de ci.yml (tests unitaires, évaluation, lint) sont
rejoués via workflow_call, puis la section du changelog devient les notes de
la release GitHub.
Test de l’installeur
Section intitulée « Test de l’installeur »Le workflow installer-test.yml joue darkone new de bout en bout dans une
VM QEMU (KVM du runner, vrai réseau) : l’ISO générique démarre,
l’assistant est piloté par sa console série (pexpect), puis le système installé
redémarre et se contrôle par SSH. Deux scénarios, en parallèle, environ
25 minutes chacun :
- scripté : fichier de réponses,
--non-interactive, disque en clair, phrase de passe de la sauvegarde dans un fichier ; - interactif : chaque question répondue à la console, disque chiffré, clé USB de sauvegarde débranchée puis rebranchée (QMP), premier démarrage déverrouillé par le sshd d’initrd.
Contrôles : lancement automatique sur tty1, système running sans unité en
échec, /etc/nixos propre, page d’accueil installée, seconde sauvegarde par
just backup-admin depuis le système installé (la première gardée sous sa
date), sauvegarde ouverte depuis l’hôte. Le journal série est joint au run.
Trois déclenchements :
- tag : appelé par
release.yml, un échec retient l’ISO hors de la release ; - chaque lundi, sur
main: une casse venue de nixpkgs unstable se voit avant le tag suivant ; - à la main :
gh workflow run installer-test.yml --ref <branche>, avant une release ou après un changement de l’ISO.
Même test en local, sur l’ISO de l’arbre courant ou une autre :
just test-installer # les deux scénariosjust test-installer interactive /chemin/de/l.isoDisques et journaux : ~/.cache/dnf-installer-test/<scénario>/, environ
25 Go par scénario. Le code : dnf/tests/installer/.
Pour essayer l’arbre courant à la main, dans une fenêtre QEMU :
just try # disque gardéjust try reset chemin/de/dnf-generator # disque neuf, générateur localÀ la différence de nix run …#try, le projet écrit par l’assistant est
épinglé sur le framework de l’ISO (path:) et non sur la release du
template : le système installé porte le code non publié. Disque :
~/.local/share/dnf-try-local.
Le store de la machine sert de cache de paquets (nix-serve-ng sur
127.0.0.1:5000, lancé par just try si le port est libre). L’ISO fixe
DNF_URL et DNF_CACHE : une relance de darkone new dans la VM les garde.
Configuration partagée
Section intitulée « Configuration partagée »Un seul git-cliff 🡕 pour les six dépôts, dans
dnf/just/scripts/cliff.toml. Le script dnf/just/scripts/bump.sh découvre la
source de version du dépôt (VERSION, Cargo.toml, package.json, ou à
défaut le dernier tag), assemble le fichier autour du bloc généré et préserve
l’historique écrit à la main.