RessourcesDEVOPS · VERSIONING

Stratégie de versioning et tagging pour les releases

Semantic versioning, Git tags et automatisation pour que chaque version soit identifiable et déployable sans confusion.

STRALYA15 min de lecturejuillet 2026

Pourquoi le versioning structuré est essentiel dans un pipeline de release

Lorsqu'une infrastructure cloud atteint une certaine maturité, les déploiements manuels laissent place à des pipelines automatisés. Or, sans convention de versioning claire, l'équipe perd rapidement le contrôle: quelle version exactement tourne en production? Pourquoi ce déploiement en staging ne correspond pas à celui en dev? Quel artefact doit être promu vers le prochain environnement?

Un versioning release structuré répond à ces questions en établissant des conventions que l'ensemble du pipeline respecte. Chaque build génère un numéro ou un tag prévisible. Chaque environnement sait quoi déployer et à partir de quel artefact. Les logs, les alertes et les rollbacks deviennent traçables parce que tout repose sur des identifiants cohérents. Pour une scale-up ou une ETI qui opère sur AWS avec une dette technique d'architecture, cette structuration n'est pas un luxe: c'est le fondement qui permet aux platform engineers de reprendre la main sur un système qui aurait dérivé, et d'accélérer les déploiements sans multiplier les incidents.

Semantic versioning: la convention majeure.mineure.patch expliquée

Le semantic versioning (SemVer) reste la convention la plus largement adoptée pour le versioning release, notamment pour les applications distribuées et les microservices. Son principe est simple mais puissant: MAJEUR.MINEUR.PATCH (ex: 2.5.3).

La version MAJEURE augmente lors d'un changement incompatible qui affecte l'API ou le contrat exposé aux clients. Si vous mettez à jour votre base de données d'une manière qui casse la compatibilité en arrière, ou si vous supprimez un endpoint, c'est un changement de version majeure. La version MINEURE augmente quand vous ajoutez une nouvelle fonctionnalité, compatible avec ce qui existait. Un nouveau paramètre optionnel, un nouvel endpoint, une optimisation interne, c'est du MINEUR. La version PATCH augmente pour un correctif de bug qui ne change rien à l'interface ou à la fonctionnalité globale.

En pratique, dans un pipeline CI/CD structuré, vous automatisez ces incrémentations. Un commit qui contient le mot clé [BREAKING] dans son message déclenche un bump majeur. [FEAT] déclenche un bump mineur. [FIX] déclenche un patch. Des outils comme conventional commits et des scripts dans votre pipeline font cette détection et générent automatiquement le numéro de version. Cela signifie qu'aucun développeur n'a à éditer manuellement un fichier de version: tout repose sur la convention des messages de commit, que vous validez avec un linter.

Le semantic versioning apporte aussi une clarté implicite aux consommateurs. Un utilisateur qui voit passer votre version 2.5.0 sait qu'il peut mettre à jour vers 2.5.3 sans peur. S'il doit passer de 1.x à 2.0, il sait qu'il doit réviser son code, sa configuration ou ses intégrations. Sur AWS, ce qui inclut souvent des dépendances de lambdas, de couches, de runtimes différents, cette sémantique fait gagner du temps lors du déploiement.

Git tags et la relation entre branches et versions en release

Le semantic versioning définit quoi numéroter, mais le git tagging définit où et comment. Un tag Git est simplement une étiquette immobile qui pointe sur un commit précis de l'historique. C'est l'artefact fondamental qui lie une version logique à un état exact du code source.

Dans un pipeline bien structuré, chaque version sémantique correspond à exactement un tag Git, nommé selon une convention: généralement v1.2.3 ou release-1.2.3 (le préfixe v est conventionnel). Ce tag est créé sur la branche de production ou sur une branche de release dédiée (souvent main ou release/*) au moment où la version est validée et prête à être construite en artefact.

L'intérêt du tagging est multiple. D'abord, c'est immuable: si vous devez enquêter sur un problème en production avec v2.3.1, vous checkoutez exactement ce tag et vous obtenez le code source d'alors, bit pour bit. Deuxièmement, c'est automatisable: votre pipeline peut déclencher un build dès qu'un tag est créé ou poussé. Troisièmement, c'est lisible dans les interfaces: GitHub, GitLab ou Bitbucket affichent les tags comme des jalons visuels de votre histoire de release.

Une pratique courante est de combiner branches et tags: vous gardez une branche main ou develop, et une branche release/1.2.x pour chaque version majeure.mineure. Quand vous décidez de faire une release depuis release/1.2.x, vous créez un tag v1.2.3 sur le dernier commit de cette branche. Si un correctif urgent est nécessaire en production (hotfix), vous travaillez depuis le tag précédent, validez le correctif, puis créez immédiatement le tag v1.2.4. Cette structure garantit que chaque environnement peut se demander: sur quel tag suis-je exactement? Et la réponse est non ambiguë.

Tagging les artefacts et métadonnées pour la traçabilité en environnements multiples

Le tagging Git établit la version du code source, mais dans un pipeline multiEnvironnement qui déploie sur AWS, vous créez aussi des artefacts: images Docker, packages, fichiers binaires. Ces artefacts ont besoin d'étiquettes aussi, et c'est là que le versioning de release prend toute sa dimension opérationnelle.

Imaginez un stage dans votre pipeline qui construit une image Docker à partir du code correspondant au tag Git v1.2.3. Cette image doit être taggée et stockée dans un registre (ECR sur AWS, par exemple). La convention la plus lisible est de taguer l'image avec le même numéro: my-service:1.2.3 ou my-service:v1.2.3. Certaines équipes ajoutent aussi un alias my-service:latest, mais cela rend le déploiement ambigu: quel commit exactement est dans "latest"? Mieux vaut éviter latest en production et rester explicite.

Lorsque vous promotez l'artefact vers un nouvel environnement (validation en staging, puis déploiement en prod), vous gardez le même tag. Cela signifie que tout le monde sait qu'en production tourne my-service:1.2.3, qu'il s'agit du code du commit pointé par le tag Git v1.2.3, et que cet artefact a probablement traversé toutes les validations requises (tests unitaires, tests d'intégration, scan de sécurité) au moment du build.

Un niveau de traçabilité plus avancé consiste à enrichir les métadonnées de l'artefact. Beaucoup d'équipes utilisent les labels Docker ou les annotations Kubernetes pour stocker des métadonnées: le hash du commit source, le numéro du build pipeline, la date, l'auteur. Quand vous inspectez un pod en production (ou un conteneur ECS sur AWS), vous pouvez immédiatement retrouver d'où cet artefact provient sans aller creuser les logs du pipeline. Cela accélère les investigations lors d'incidents.

Automatiser l'incrémentation de version et la création de tags dans le pipeline

Gérer les versions manuellement, c'est pédagogique mais ça ne scale pas. Un stage du pipeline automatise cette incrémentation. Les étapes typiques sont les suivantes.

D'abord, le pipeline scrute les commits depuis la dernière version taguée. Un outil comme gitversion, semantic-release, ou même des scripts custom utilisant git log examine les messages de commit pour déterminer quel type de bump est nécessaire. Si tous les commits contiennent [FIX], c'est un bump PATCH. S'il y a au moins un [FEAT], c'est un bump MINEUR. S'il y a un [BREAKING], c'est un bump MAJEUR.

Ensuite, le pipeline calcule le prochain numéro de version (par exemple: actuellement en v1.2.3, si c'est un PATCH, le prochain sera v1.2.4). Il crée le tag Git pointant vers le commit actuel, puis pousse ce tag vers le dépôt distant (GitHub, GitLab, etc.).

Cette création de tag peut déclencher une série d'événements: immédiatement après le push du tag, un webhook peut relancer le pipeline pour construire l'artefact et le tagger avec ce numéro de version. Certains pipelines utilisent une étape que GitOps appellent "release commit": écrire le numéro de version dans un fichier de configuration, faire un commit avec ce numéro, puis tagger ce commit. D'autres systèmes calculent la version à chaque fois, sans la stocker nulle part, en la dérivant uniquement du tag Git.

La clé est la cohérence: peu importe la méthode, tous les stages du pipeline doivent utiliser la même logique de versioning. Si le stage build injecte la version v1.2.4 dans l'artefact, le stage deploy doit lire exactement la même version depuis le tag ou depuis le fichier de configuration, sans la recalculer indépendamment.

Sur AWS, cela signifie souvent: une étape CodePipeline qui utilise CodeBuild pour exécuter un script de versioning, qui écrit la version dans un fichier artifact ou dans les variables d'environnement transmises aux stages suivants (ECR, ECS, etc.).

Validation et promotion des artefacts entre environnements avec le versioning release

Une fois que vos artefacts sont correctement taggés selon le versioning release, la promotion entre environnements devient prédictible et auditée. La question "quel artefact promouvoir de staging vers prod?" a une réponse claire: celui qui porte le tag my-service:v1.2.4.

Dans un pipeline multiEnvironnement structuré, chaque environnement (dev, staging, prod) utilise une déclaration explicite de la version à déployer. Cela peut être un fichier environment.yaml par environnement, ou un système GitOps où le repo contient un manifeste Kubernetes pour chaque environnement spécifiant quelle image deployer. Quand il est temps de promouvoir une version de staging vers prod, l'équipe ou le pipeline mets à jour ce manifeste avec le nouveau tag d'image, commit et push ce changement. Le pipeline GitOps détecte ce push et redéploie automatiquement.

L'avantage est que chaque promotion est un commit traçable dans Git. Un auditeur peut suivre exactement quand v1.2.4 a transitionné de staging vers prod, qui a approuvé ce changement, et revenir au commit précédent si une rollback est nécessaire. Si un incident survient, vous ne vous demandez pas "quel code tourne?", la réponse est dans le tag d'image et dans l'historique Git.

Cette approche s'intègre naturellement avec les validations entre environnements. En staging, vous pouvez exécuter une suite de tests d'intégration, de charge ou de sécurité. Si tous les tests passent, un approvisionnement humain ou un critère automatisé approuve la promotion. Le pipeline alors pousse le tag de l'image de l'artefact vers la prod, et le système GitOps ou le service de déploiement (ECS, Kubernetes sur EKS, etc.) redéploie avec ce tag versionnél précis.

Gestion des préversions et versions de développement dans le versioning release

Le semantic versioning strict couvre les versions stables (1.0.0, 1.1.0, etc.), mais dans un pipeline réel, vous avez besoin de numéroter aussi les versions de développement, les candidats à la release ou les builds non validés. C'est là que les suffixes de préversion entrent en jeu.

Le format de SemVer inclut un suffixe optionnel après le PATCH: par exemple, 1.2.3-alpha.1, 1.2.3-beta.2, ou 1.2.3-rc.1 (release candidate). Chaque suffixe indique le statut de maturation: alpha signifie une version très instable à titre exploratoire, beta signifie fonctionnellement complète mais non validée, rc signifie prête à être release si les tests de validation passent. Le .1, .2, etc. vous permet de créer plusieurs versions alpha ou beta successives sans tourner la version majeure.mineure.patch.

Dans un pipeline ci-cd, cela se traduit ainsi: chaque build depuis une branche de développement (main, develop, ou une feature branch) génère un tag comme v1.2.3-alpha.5. Ce tag crée un artefact my-service:1.2.3-alpha.5. Cette version peut être déployée en environnement de dev ou de test, mais pas en production. Quand tous les tests passent et que l'équipe est prête pour une candidature à la release, le pipeline crée v1.2.3-rc.1. Après un dernier round de tests, il devient v1.2.3 (une version stable, sans suffixe). À ce moment, la version est prête à être poussée en production.

La gestion des préversions nécessite un peu de discipline: votre pipeline doit savoir distinguer un tag "alpha" d'un tag "rc" ou d'une version stable, et appliquer des règles différentes (ex: les artefacts alpha peuvent être supprimés rapidement du registre pour économiser l'espace, tandis que les versions stables sont archivées). Beaucoup d'équipes utilisent des dépôts séparés ou des tags distincts pour les candidatures: un registre "snapshots" pour les préversions, un registre "releases" pour les stables.

Audit et traçabilité: retrouver l'origine d'une version en production

Tout le travail de versioning structuré aboutit à un objectif clé: l'auditabilité. Lorsqu'une dégradation de performance ou un bug critique apparaît en production, vous devez pouvoir répondre immédiatement: quelle version tourne? Quel code source? Qui a approuvé ce déploiement? Quand?

Grâce aux conventions de versioning et tagging décrites plus haut, ces réponses sont à portée de commande. Vous interrogez votre système de déploiement (ECS, Kubernetes, CloudFormation sur AWS, etc.) pour savoir quelle image tourne: my-service:v1.2.4. Ensuite, vous allez dans votre dépôt Git et cherchez le tag v1.2.4. Vous accédez au commit pointé par ce tag et vous voyez exactement quels fichiers ont changé, qui a écrit le code et quels messages de commit expliquent pourquoi. Vous consultez l'historique de promotion dans votre manifeste GitOps ou votre historique de déploiement: qui a approuvé cette promotion de staging vers prod? Quand?

Cet audit complet est possible uniquement si chaque couche (code source, artefacts, déploiements) utilise les mêmes numéros de version ou des références mutuelles claires. Si v1.2.4 du code génère une image Docker taggée autrement, cette traçabilité se perd. C'est pourquoi les conventions de versioning release ne sont pas des détails mineurs: ce sont des briques fondamentales d'une infrastructure cloud mature qui permet aux équipes d'opérer en confiance.

Pour les scale-ups et ETI sur AWS, où l'équipe interne est souvent restreinte, cette traçabilité accélère les diagnostics d'incident. Au lieu de passer des heures à creuser les logs ou à essayer de reconstituer "qu'est-ce qui a changé?", vous avez une chaîne claire de commit en commit, de build en build, de déploiement en déploiement. Un partenaire comme Stralya peut vous aider à mettre en place cette structure dans votre pipeline existant, en automatisant les étapes de versioning et en veillant à ce que les conventions soient respectées à chaque stage du build et du déploiement.

Exemple concret: versioning d'une application multiservices sur AWS

Pour concrétiser, imaginons une startup qui gère trois microservices (api-service, worker-service, frontend) sur ECS (Elastic Container Service). Chacun est dans son propre dépôt Git.

Chaque service suit le semantic versioning. Un développeur commit un correctif pour une fuite mémoire dans worker-service, avec un message "[FIX] mémoire leakage dans la tâche d'archivage". Le pipeline détecte ce [FIX] et incrémente la version de v2.3.5 à v2.3.6. Un tag Git v2.3.6 est créé. Un webhook déclenche un stage CodeBuild qui construit l'image Docker et la pousse vers ECR avec le tag worker-service:v2.3.6.

En parallèle, un autre développeur ajoute un nouvel endpoint à api-service, avec un message "[FEAT] endpoint de migration batch". Le pipeline incrémente api-service de v3.1.2 à v3.2.0. L'image résultante est api-service:v3.2.0.

Maintenant, les trois services ne sont pas en même version, et c'est normal: chacun avance à son rythme. Un fichier docker-compose.yml ou un ensemble de manifestes Kubernetes (ou un template CloudFormation) définit quelles versions déployer en dev, staging et prod. En staging, peut-être que la config spécifie api-service:v3.2.0 (nouvelle), worker-service:v2.3.5 (ancienne), frontend:v1.4.3 (ancienne). Cette config est un commit Git, donc chaque changement est auditablement traçable.

Quand l'équipe de QA a validé que api-service:v3.2.0 et worker-service:v2.3.6 fonctionnent bien ensemble en staging, la config est mise à jour pour prod, et le pipeline l'applique. En production, vous pouvez alors consulter exactement quelle image de quel service tourne, et remonter jusqu'au commit source et à l'approbation du déploiement, tout automatiquement.

TEARDOWN AWS · GRATUIT

Recevez le Teardown AWS : où part vraiment votre facture.

Le guide qui liste les 12 postes de coût qui fuitent le plus chez les scale-ups, et comment les colmater. Gratuit, par mail, sans engagement.