Skip to content

Module — Releases & CI/CD

Pipeline GitLab + @spektrum/release-util pour la SemVer + génération de changelog. Deux flavours de release : staging et prod, avec des tags d'image disjoints.

Cette page complète RELEASING.md à la racine du repo. Pour la procédure stepwise détaillée et les variables CI requises, voir ce fichier. Cette page donne le « pourquoi » et le mapping avec le reste du knowledge base.

Flow général

feature MR ──merge──► master ──cut release──► release/X.Y.Z MR ──merge──► master ──publish CI fires

Deux releases possibles :

TypeBranche releaseTag gitTags Docker pushés
Stagingrelease/X.Y.Z-staging.NX.Y.Z-staging.N:X.Y.Z-staging.N + :latest-staging
Prodrelease/X.Y.ZX.Y.Z:X.Y.Z + :latest

Promouvoir :latest ne touche pas :latest-staging, et vice-versa.

Cutter une release

Deux chemins équivalents :

Depuis GitLab (sans setup local)

  1. Pipeline master → clic manuel sur trigger-release-staging ou trigger-release-prod.
  2. Le job exécute npx @spektrum/release-util release --env <staging|prod> qui :
    • Incrémente SemVer en fonction des commits conventional commits.
    • Régénère CHANGELOG.md.
    • Crée le commit chore(release): X.Y.Z[-staging.N].
    • Push la branche release/X.Y.Z[-staging.N].
    • Ouvre une MR vers master.
  3. Review + merge.
  4. Pipeline trunk sur master détecte le subject du commit de release → fire publish-staging ou publish-prod.

Depuis un poste dev

sh
npx @spektrum/release-util release --env staging
# ou
npx @spektrum/release-util release --env prod

Même résultat : branche + MR.

Ce que fait publish-staging / publish-prod

Tous deux étendent .publish-base dans .gitlab-ci.yml. Pipeline :

  1. git remote set-url --push origin "https://gitlab-ci-token:${RELEASE_TOKEN}@…" — utilise le token de release (write_repository + api) plutôt que CI_JOB_TOKEN.
  2. eval $(npx @spektrum/release-util tag) — exporte RELEASE_VERSION, RELEASE_ENV, etc., crée + push l'annotated git tag (X.Y.Z ou X.Y.Z-staging.N).
  3. docker build avec :
    • --build-arg VERSION_TAG=${RELEASE_VERSION} → exposé sur /.
    • --build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") → idem.
  4. docker tag + docker push :
    • Tag versionné :X.Y.Z ou :X.Y.Z-staging.N.
    • Tag flottant :latest ou :latest-staging.
  5. npx @spektrum/release-util badges --out badges — génère staging.svg et prod.svg (artefact CI, expire never).

Variable CI obligatoire

VariableScopePourquoi
RELEASE_TOKENwrite_repository + apiPush de la branche/tag de release sur un protected ref + création de MR via l'API GitLab

Doit être Protected + Masked. CI_JOB_TOKEN ne suffit pas (pas de push protected, pas d'API MR).

Settings GitLab projet

  • Default branch : master. Doit matcher trunkBranch dans .release-it.json.
  • Merge method (Settings → Merge requests) : Merge commit ou Fast-forward.
  • Squash on merge : désactivé pour les MR release/*. Squasher réécrit le subject chore(release): → la regex de publish-* ne match plus → pas de publish.

Mapping conventional commits → bump SemVer

@release-it/conventional-changelog avec preset conventionalcommits (cf. .release-it.json) :

CommitBump SemVer
feat: …minor
fix: …patch
chore: …, docs: …, ci:pas de bump
feat!: … ou BREAKING CHANGE: dans le footermajor

Conventions du repo

  • Conventional commits sur master.
  • Pas de fast-forward direct sur master (toujours via MR).
  • release-it (@release-it/conventional-changelog) régénère CHANGELOG.md à chaque release. Ne pas l'éditer à la main — il est dérivé.
  • Les commits chore(release): X.Y.Z sont émis automatiquement et matchés par les regexes du CI. Ne pas modifier le format sans mettre à jour les rules dans .gitlab-ci.yml (sections publish-staging.rules et publish-prod.rules).

Tester localement avant cut

sh
# Voir la prochaine version qui serait calculée
npx @spektrum/release-util release --env staging --dry-run
# ou
npx @spektrum/release-util release --env prod --dry-run

(Vérifier la sortie ; ne fait rien côté git.)

Procédure de rollback

Image

Re-déployer l'image avec un tag immuable précédent : :X.Y.Z ou :X.Y.Z-staging.N. Les tags flottants :latest / :latest-staging sont des pointeurs mobiles, à éviter pour un rollback ciblé.

sh
# Côté serveur prod
docker pull registry.internal.spektrum-suisse.ch/buchsearch:3.1.0
# Modifier le compose pour pointer ce tag
# docker compose up -d

Tag git

@spektrum/release-util push des tags annotés. Pour rollback un tag git mal envoyé (cas rare) :

sh
git tag -d 3.2.0
git push origin :refs/tags/3.2.0   # delete remote

Attention : si le pipeline publish-* est déjà passé, l'image est déjà en registry — la suppression du tag git n'enlève pas l'image.

DB

yoyo n'a pas de rollback automatique sur ce projet (cf. modules/migrations.md). Restaurer depuis backup si une migration cassée est appliquée en prod.

Pannes courantes

SymptômeCause typique
publish-staging / publish-prod ne tourne pas après merge de la MR releaseSquash on merge activé → subject du commit réécrit → la regex rules: ne match plus. Désactiver squash, re-cut.
eval $(... tag) plante avec "could not push to protected ref"RELEASE_TOKEN manquant, ou scope insuffisant (write_repository), ou git remote set-url --push mal formé.
trigger-release-* plante en créant la MRRELEASE_TOKEN manque le scope api.
Endpoint / affiche encore l'ancienne version après release--build-arg VERSION_TAG=... pas passé, OU le déploiement pull encore le digest précédent (cache). Forcer un pull.
publish-staging ET publish-prod tournent sur le même pipeline trunkNe devrait pas arriver (regexes disjointes). Si oui, vérifier que le subject de commit ne match qu'une seule forme.

Suivi des releases

  • Tags git : visibles sur GitLab (Settings → Tags).
  • Images Docker : registry.internal.spektrum-suisse.ch → repo buchsearch.
  • Changelog : CHANGELOG.md à la racine.
  • Badges : artefacts du job publish-*badges/staging.svg et badges/prod.svg. Inclus dans le README typiquement.

Workflow recommandé pour les modifs de schéma

Quand une PR contient une migration (migrations/*.sql) :

  1. Merge sur master (la migration est appliquée sur la DB de test en CI).
  2. Cut une release staging.
  3. Déployer staging → la migration tourne sur la DB staging au boot via entrypoint.sh.
  4. Tester quelques jours sur staging.
  5. Cut une release prod → idem en prod.

Pour les migrations destructives (DROP COLUMN, etc.), prévoir une migration en deux temps : (1) ajouter le nouveau, (2) après une release qui consomme le nouveau, supprimer l'ancien. Évite les reverts en urgence.

Contributors

No contributors

Changelog

No recent changes