Troubleshooting du flow release Spektrum
Symptômes courants et leurs causes habituelles. Indexé par ce qu'on observe d'abord côté pipeline.
Le pipeline release-tag / publish-docker ne se déclenche pas après merge de la MR de release
Cause #1 : squash a été activé au moment du merge. Le titre du commit a été réécrit en Merge branch 'release/…'-style et a perdu le numéro de version, donc les rules: ne matchent plus.
Vérifier : regarder le titre exact du commit sur trunk. S'il ressemble à Update <something> ou Merge branch 'release/foo' into … sans numéro de version, c'est probablement un squash.
Fix :
- Désactiver squash pour les MR
release/*(setup.md). - Re-cuter la release localement :
npx @spektrum/release-util release --env <env>. - Merger sans squash.
Cause #2 : le titre du commit a une casse ou un format inattendu. Les rules: matchent strictement ^chore\(release\): ou ^Merge.*release\/. Vérifier qu'il n'y a pas de typo dans le titre.
release-tag échoue avec could not push to protected ref
RELEASE_TOKEN est manquant, mal configuré, ou n'a pas le bon scope.
Vérifier :
- Settings → CI/CD → Variables :
RELEASE_TOKENest présent ET coché Protected ET Masked. - Settings → Access Tokens : le token utilisé a le scope
write_repository. - La branche par défaut est protégée (
setup.md) — sinon les variables Protected ne sont pas exposées. - Les tags sont protégés.
Si tout est correct côté GitLab et que le push échoue quand même : c'est probablement que le token a expiré (les Project Access Tokens ont une date d'expiration).
publish-docker échoue avec denied: requested access to the resource is denied
Le runner n'est pas authentifié au registry. Les composants publish-docker ne font pas de docker login — ils supposent un ~/.docker/config.json provisionné au niveau machine sur le runner.
Fix : contacter Sysadmin pour vérifier la config Docker du runner qui a fait tourner le job, ou bien :
- Identifier le runner (Settings → CI/CD → Runners → cliquer sur le job).
- Vérifier
~/.docker/config.jsonsur la machine du runner.
release-detect ne tourne pas après le push de tag
Cause #1 : le format du tag ne match pas. Le composant est gated sur /^[0-9]+\.[0-9]+\.[0-9]+(-staging\.[0-9]+)?$/. Si le tag a un préfixe v ou un autre format, il est ignoré.
Vérifier : git tag --list localement après fetch, ou la liste des tags dans GitLab. Le tag créé par release-util tag n'a normalement jamais de préfixe v.
Cause #2 : le tag a été poussé mais aucun pipeline n'a été créé. Vérifier dans CI/CD → Pipelines qu'un pipeline de tag est apparu. Sinon, c'est peut-être que :
- les tags ne sont pas dans les triggers du projet (Settings → CI/CD) ;
- une
workflow:règle exclut les tag pipelines.
Un job aval ne reçoit pas les variables de release-detect
Le job aval doit déclarer needs: avec artifacts: true :
my-downstream-job:
needs:
- job: release-detect
artifacts: true
# …Sans artifacts: true, GitLab attend release-detect mais ne charge pas son dotenv → $VERSION, $CHANNEL, $RELEASE_TYPE sont vides.
Je veux gater un job sur RELEASE_TYPE=major dans rules: — ça ne marche pas
C'est une limitation GitLab. Les rules: sont évaluées à la création du pipeline, avant que release-detect ne tourne et n'émette le dotenv.
Pattern à utiliser : gater le rules: sur le format du tag (toujours connu à la création du pipeline) et court-circuiter en début de script :
major-only-job:
rules:
- if: $CI_COMMIT_TAG =~ /^[0-9]+\.[0-9]+\.[0-9]+(-staging\.[0-9]+)?$/
needs:
- job: release-detect
artifacts: true
script:
- |
if [ "$RELEASE_TYPE" != "major" ]; then
echo "Skip — RELEASE_TYPE=$RELEASE_TYPE"
exit 0
fi
# … vrai travail iciLe runtime gate (RELEASE_TYPE) court-circuite proprement les bumps mineurs et patches. Le job apparaît comme success dans GitLab dans tous les cas — c'est OK, c'est l'idiome standard.
La version dans l'artefact publié est obsolète (reflète le release précédent)
L'étape de rebuild après le bump de version est manquante. Certains bins (notamment les CLIs npm qui embarquent leur propre version au build) doivent être re-buildés après npm version pour que --version retourne la nouvelle valeur.
Pattern dans le job publish :
script:
- eval $(npx --yes @spektrum/release-util@latest tag)
- npm version "$RELEASE_VERSION" --no-git-tag-version --allow-same-version
- npm run build # ← rebuild ICI, après le bump
- npm publishcommit-lint (si présent) échoue sur la MR de release
C'est attendu si la MR contient un commit chore(release): et que la config commitlint du projet est très stricte (par exemple : interdit le scope release ou des messages spécifiques).
Fix : ajouter release aux scopes autorisés dans commitlint.config.js, ou bien scoper le job commit-lint pour exclure les MR release/* :
commit-lint:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME !~ /^release\//Le badge dans le README pointe vers une URL 404
L'artefact qui contient le SVG a expiré. Vérifier que le job qui produit les badges (release-badges ou publish-docker-*) déclare bien artifacts.expire_in: never. C'est obligatoire pour que l'URL reste stable d'une release à l'autre.
Les composants Spektrum le font par défaut — donc si tu vois un 404, c'est qu'un override projet a réduit l'expire_in.
Voir aussi
release-flow.md: le modèle mental, utile pour comprendre pourquoi tel job tourne dans tel pipeline.setup.md: checklist initiale — un problème de setup oublié est la cause #1 des pipelines cassés.

