Surface des commandes
Référence de chaque sous-commande : flags, entrées, sorties, codes de sortie. Pour le découpage en environnements et le calcul de version, voir environnements-et-versioning.md.
Toutes les commandes acceptent --help / -h et --verbose. Les codes de sortie sont décrits dans le README.
Commandes locales
init
Génère .release-it.json à la racine du dépôt. À lancer une fois par projet après git init, ou avant la première release sur un dépôt existant.
release-util init [--force]| Flag | Description |
|---|---|
--force | Écrase un .release-it.json existant. |
Ordre de détection du trunk :
git symbolic-ref refs/remotes/origin/HEAD— la branche par défaut du remote.git config init.defaultBranch— le défaut local de l'opérateur.- Repli :
master.
Le fichier généré est une base de travail pour le flux release-it que pilote la CLI. Deux clés comptent pour l'outil lui-même : trunkBranch (la branche sur laquelle release exige d'être) et le reste (git/github/gitlab/npm/plugins) transmis tel quel à release-it. Voir configuration.md.
doctor
Rapporte l'état des préconditions sous forme de checklist verte/rouge. Strictement en lecture seule — aucun commit, pas de création de branche.
release-util doctor [--verbose]Vérifications effectuées (dans l'ordre) :
- La branche courante est
trunkBranch. - L'arbre de travail est propre (rien d'indexé, de non-indexé ni de non-suivi).
trunkBranchcorrespond à la branche par défaut d'origin— protège contre une expédition depuis une branche obsolète si le défaut distant a été renommé.- Le trunk local est synchronisé avec
origin/<trunk>— lancegit fetchpuis inspecte ahead/behind. En retard / divergé → échec. En avance seulement → avertissement mais succès (ces commits partiront via la MR de release).
Sortie 0 si tout est vert, sortie 3 au moindre échec (sentinelle). Plus rapide que release --dry-run car il saute le calcul de version et le balayage des tags.
next-version
Affiche la version que release couperait, puis sort. Aucun effet de bord.
release-util next-version --env <staging|prod|feature> [--verbose]| Flag | Description |
|---|---|
--env <staging|prod|feature> | Requis. Choisit le flux de release. |
--verbose | Journalisation git verbeuse (sur stderr). |
La chaîne de version va sur stdout ; tout le reste (bannière, logs) va sur stderr. C'est la convention qui rend possible la capture en CI :
VER=$(release-util next-version --env prod)Pour staging, le compteur de suffixe est calculé depuis l'union des tags locaux + distants, donc des invocations répétées entre machines restent monotones. Pour prod, la sortie est un X.Y.Z nu. Pour feature, doit être lancé depuis une branche feature/<name> et affiche la prochaine version de preview (X.Y.Z-<slug>.N). S'il n'y a aucun commit publiable depuis le dernier tag prod, la commande sort en non-zéro.
release
La commande phare. Selon --env, coupe une release staging/prod depuis le trunk, ou un preview de feature depuis une branche feature/<name>.
release-util release --env <staging|prod|feature> [--bump] [--dry-run] [--verbose]| Flag | Description |
|---|---|
--env <staging|prod|feature> | Requis. staging coupe release/X.Y.Z-staging.N ; prod coupe release/X.Y.Z ; feature produit un preview en place. |
--bump | Staging uniquement. Balaie origin à la recherche de branches orphelines release/X-staging.N, les supprime, et fait avancer le compteur au-delà. À utiliser après une tentative échouée qui a laissé une branche de release sur origin. |
--dry-run | Lance toutes les vérifications + rend le plan, sort 0. Aucun effet de bord. |
--verbose | Journalise chaque invocation git. |
Les préconditions sont les mêmes que doctor, mais ici un échec sort 1 (et non 3). La CLI ne fait jamais de pull ni de merge à votre place ; si le trunk est en retard, c'est à vous de git pull --ff-only puis de relancer.
Flux staging/prod, en cas de succès :
- Branche :
git checkout -b release/X.Y.Z[-staging.N]depuis le HEAD du trunk. - Changelog + commit : invoque release-it, qui (en prod) préfixe une section à
CHANGELOG.mdet crée un commit unique avec le sujetchore(release): X.Y.Z[-staging.N]. La MR ne porte que ce commit — c'est l'invariant à un seul commit. Le staging saute le changelog (il est régénéré au cut prod). - Push + MR :
git push -o merge_request.create -o merge_request.label=release -o merge_request.label=<staging|production> origin release/.... La MR est ouverte via les push options GitLab — aucun token. - Nettoyage :
git checkout <trunk>puisgit branch -D release/.... Au mieux — si le nettoyage échoue, la release est tout de même réussie et un indice manuel est affiché.
Flux feature : voir environnements-et-versioning.md. Le preview commit la montée de version (sans changelog) directement sur la branche feature/<name> et la pousse en place — pas de nouvelle branche, pas de MR. Le job tag de la CI tague le HEAD.
Autorisation pour les agents : ne pas lancer
release-util releasede façon non interactive sans autorisation explicite de l'utilisateur. La commande pousse une branche et ouvre une MR — visible par l'équipe. Préférer--dry-runounext-versionpour l'inspection.
hotfix
Corrige un bug de production sans livrer le travail non-released du trunk. Trois phases sur une seule commande — exactement une par invocation.
release-util hotfix --start [--dry-run] [--verbose]
release-util hotfix --apply [--sign|--no-sign] [--dry-run] [--verbose]
release-util hotfix --finish [--dry-run] [--verbose]| Flag | Description |
|---|---|
--start | Branche hotfix/<X.Y.Z+1> depuis le dernier tag de production (le X.Y.Z le plus haut connu en local ou sur origin). Exige un arbre propre. |
--apply | Sur la branche hotfix/* : calcule la prochaine version patch depuis les tags atteignables sur la branche, fait le commit chore(release): X.Y.Z (changelog via release-it si package.json existe, commit-marqueur vide sinon), tague HEAD et pousse le tag uniquement. |
--finish | Pousse la branche et ouvre (ou rafraîchit) la MR squash de retour vers le trunk (-o merge_request.squash, GitLab ≥ 17.2). Labels release + hotfix. Revient sur le trunk et supprime la branche locale (au mieux). |
--sign / --no-sign | --apply uniquement. Force/désactive la signature du commit de release (sinon la config git décide). |
--dry-run | Vérifications + plan, sort 0. Aucun effet de bord. |
--verbose | Journalise chaque invocation git. |
Pourquoi le tag seul dans --apply ? GitLab ne traite les push options que si le push met à jour une ref. Pousser la branche dès --apply rendrait le push de --finish vide (« Everything up-to-date ») et la MR ne serait jamais créée ni rafraîchie. Le push d'un tag annoté transporte de toute façon les commits — et déclenche le pipeline de tag (un tag hotfix est un tag prod ordinaire : detect le classe production).
Boucle de re-fix. Fix non validé → committer sur la même branche, relancer --apply (la base devient le tag précédent : 1.2.4 → 1.2.5) puis --finish (la MR existante est rafraîchie, son titre passe à chore(release): 1.2.5). Le nom de branche est une étiquette figée au --start — jamais renommé.
Garde-fous. --apply refuse : aucun commit depuis la base ; une release prod plus récente existe ailleurs (lignée périmée → rollback) ; une branche release/<version> ouverte sur origin vise la même version. --finish refuse si des commits ne sont pas couverts par un tag poussé (faire --apply d'abord).
Pousser le tag X.Y.Z exige le droit de créer des tags protégés (Maintainer par défaut, ou assouplir le réglage projet). Après le merge (squash), le job release-tag retrouve chore(release): X.Y.Z dans le sujet du commit squash et saute idempotemment — le tag existe déjà.
Autorisation pour les agents : comme
release, ne pas lancer sans autorisation explicite de l'utilisateur —--applypousse un tag qui déclenche un déploiement en production. Préférer--dry-runpour l'inspection.
cleanup
Démantèle une feature longue durée abandonnée (ou fusionnée) : supprime la branche feature/* sur origin et chaque tag de preview correspondant à *-<slug>.* (local et sur origin). En avant seulement — les numéros de tag supprimés sont perdus définitivement.
release-util cleanup <slug> [--dry-run] [--yes] [--verbose]| Argument / Flag | Description |
|---|---|
<slug> | Le slug de la feature (ex. client_indecis). Comparé aux suffixes de tag et aux branches feature/* via leur slug dérivé. Ne doit pas contenir de /. |
--dry-run | Liste les refs qui seraient supprimées, puis sort. Aucune suppression. |
--yes, -y | Saute la confirmation interactive (ex. en CI). |
Par défaut, affiche ce qui sera supprimé et demande confirmation (défaut : non). Chaque suppression est au mieux : un échec (tag protégé, etc.) n'empêche pas le reste. Si vous êtes sur une branche qui va être supprimée, la commande bascule d'abord sur le trunk.
Aides CI
tag
Le pivot du flux de publication. Inspecte le sujet de HEAD à la recherche de chore(release): X.Y.Z[-staging.N] ; si HEAD est un commit de merge (MR synthétisée par GitLab), scanne la plage HEAD^1..HEAD^2 — les commits introduits par la MR, du plus récent au plus ancien. Les commits déjà sur le trunk (dont les chore(release): des releases antérieures) sont exclus par construction, et le commit de release est trouvé même enfoui sous un merge de résolution de conflits (« Merge branch 'main' into release/X.Y.Z »). Jamais de tag preview via ce chemin. Si trouvé, crée un tag annoté à HEAD et le pousse sur origin.
release-util tag [--no-push] [--strict] [--print version|env|tag] [--verbose]| Flag | Description |
|---|---|
--no-push | Crée le tag localement ; saute le push. |
--strict | Sort 1 (au lieu de 0) quand aucun commit de release n'est détecté sur HEAD. Par défaut il saute silencieusement, ce qui permet de garder le rules: du job publish étroit sans qu'il échoue sur des pushs parasites. |
--print <key> | Affiche uniquement l'un de version, env, tag. Saute le dotenv. |
Sortie stdout par défaut (forme dotenv, prête pour eval) :
RELEASE_VERSION=0.1.0-staging.1
RELEASE_ENV=staging
RELEASE_TAG=0.1.0-staging.1Usage canonique en CI :
git remote set-url --push origin "https://gitlab-ci-token:${RELEASE_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
eval $(release-util tag)
echo "Tagué $RELEASE_TAG ($RELEASE_ENV)"tag est idempotent : si le tag calculé existe déjà localement ou sur origin, il saute la création/le push et émet quand même le dotenv. C'est ce qui rend le job publish rejouable. Authentification : nécessite un Project Access Token au scope write_repository, exposé en variable CI protégée + masquée. CI_JOB_TOKEN ne peut pas pousser sur des refs protégées.
detect
Pour les pipelines de tag (déclenchés par $CI_COMMIT_TAG), pas le job publish. Lit le tag, décide le canal et le type de release, et écrit un dotenv que les jobs en aval consomment via artifacts:reports:dotenv.
release-util detect [--out <file>] [--verbose]| Flag | Description |
|---|---|
--out <file> | Chemin de sortie. Défaut : release.env dans le cwd. |
Sortie (staging / production) :
VERSION=0.1.0-staging.1
CHANNEL=staging # staging | production
RELEASE_TYPE=major # major | minor_patchSortie (preview de feature) :
VERSION=1.2.3-client_indecis.1
CHANNEL=preview
PREVIEW_SLUG=client_indecis
RELEASE_TYPE=minor_patchLes tags de preview obtiennent leur propre canal + slug et sautent l'analyse de bump majeur (sans objet pour un build qui ne touche jamais le trunk). Les tags doivent correspondre à X.Y.Z, X.Y.Z-staging.N ou X.Y.Z-<slug>.N ; tout le reste sort en non-zéro.
badge (alias : badges)
Récupère des badges shields.io basés sur les derniers tags de release. Le mode est choisi par la présence de --env ; les noms badge et badges pointent sur la même commande.
Mode badge unique (--env fourni) — coupe un seul badge personnalisable pour le flux choisi (prod lit le dernier X.Y.Z, staging le dernier X.Y.Z-staging.N) :
release-util badge --env <prod|staging> [--out <file>] [--label <text>] [--message <text>] [--color <color>] [--style <name>] [--verbose]| Flag | Description |
|---|---|
--env <prod|staging> | Flux à badger. Coupe un seul badge. |
--out <file> | Fichier de sortie. Défaut : badges/production.svg (prod) ou badges/staging.svg (staging). Le nom par défaut dépend de l'env, pas du --label, pour garder les URL d'artefacts stables. |
--label <text> | Texte de gauche. Défaut : production / staging. |
--message <text> | Texte de droite. Défaut : le dernier tag de l'env (ou none). |
--color <color> | Couleur de droite. Défaut : brightgreen (prod) / yellow (staging). |
--style <name> | Style de badge shields.io : flat, flat-square, plastic, for-the-badge, social. Défaut : flat-square. Une valeur inconnue émet un avertissement et retombe sur le défaut. |
Mode hérité (--env omis) — comportement d'origine, conservé pour ne casser aucun pipeline existant. Écrit les deux badges dans un répertoire :
release-util badges [--out <dir>] [--style <name>] [--verbose]Écrit <dir>/production.svg et <dir>/staging.svg (défaut <dir> = badges/). --label/--message/--color y sont refusés (ambigus entre les deux badges).
Dans les deux modes, si aucun tag correspondant n'existe, le badge affiche none. Exposer la sortie en artefact de job avec expire_in: never pour qu'un lien de badge projet GitLab de la forme …/-/jobs/artifacts/<branche-defaut>/raw/badges/production.svg?job=publish reste stable entre les releases.

