Introduction
Vous avez sûrement déjà vu des numéros de version comme 4.2.1, 1.0.0-beta.3 ou ^2.0.0 dans un fichier package.json. Ces numéros ne sont pas arbitraires : ils suivent une convention précise appelée versioning sémantique (Semantic Versioning ou SemVer), définie par Tom Preston-Werner, cofondateur de GitHub.
Comprendre SemVer, c'est comprendre quand une mise à jour est sans risque et quand elle peut casser votre application.
Le format : MAJEUR.MINEUR.CORRECTIF
Un numéro de version SemVer se compose de trois chiffres séparés par des points :
2.4.1
│ │ └── CORRECTIF (patch) : corrections de bugs
│ └──── MINEUR (minor) : nouvelles fonctionnalités rétrocompatibles
└────── MAJEUR (major) : changements incompatiblesVersion CORRECTIF (patch)
Incrémentée pour des corrections de bugs qui ne modifient pas le comportement attendu de l'API.
Exemples :
- Correction d'un calcul erroné
- Correction d'une fuite mémoire
- Correction d'une erreur de typo dans un message d'erreur
Passer de 1.2.3 à 1.2.4 ne devrait jamais casser votre code.
Version MINEURE (minor)
Incrémentée pour des nouvelles fonctionnalités qui restent rétrocompatibles.
Exemples :
- Ajout d'une nouvelle fonction à une bibliothèque
- Ajout d'un nouveau paramètre optionnel
- Dépréciation d'une fonctionnalité (qui reste disponible)
Passer de 1.2.3 à 1.3.0 ajoute des possibilités mais ne casse rien. Le correctif est remis à zéro.
Version MAJEURE (major)
Incrémentée pour des changements incompatibles (breaking changes).
Exemples :
- Suppression d'une fonction publique
- Modification du type de retour d'une fonction
- Changement du comportement par défaut
- Renommage de paramètres obligatoires
Passer de 1.2.3 à 2.0.0 signifie que vous devrez peut-être modifier votre code. Le mineur et le correctif sont remis à zéro.
Le cas spécial de la version 0.x.y
Avant la version 1.0.0, le projet est considéré comme en développement initial. Les règles sont plus souples :
- Tout peut changer à tout moment
- L'API publique n'est pas considérée comme stable
- Les changements incompatibles peuvent survenir en version mineure
C'est pourquoi de nombreuses bibliothèques restent en 0.x longtemps : elles ne veulent pas s'engager sur la stabilité de leur API.
Les pré-versions et les métadonnées
SemVer permet aussi d'indiquer des pré-versions :
2.0.0-alpha.1
2.0.0-beta.3
2.0.0-rc.1 (release candidate)Et des métadonnées de build (ignorées dans la comparaison de versions) :
2.0.0+build.123
2.0.0-beta.1+20250115L'ordre de priorité : 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-rc.1 < 1.0.0.
SemVer dans la pratique : les gestionnaires de paquets
Les opérateurs de plage dans npm/yarn
Le fichier package.json utilise des opérateurs pour spécifier quelles mises à jour sont acceptables :
| Opérateur | Exemple | Versions acceptées |
|---|---|---|
| Exact | 1.2.3 |
Uniquement 1.2.3 |
Tilde ~ |
~1.2.3 |
≥1.2.3 et <1.3.0 |
Caret ^ |
^1.2.3 |
≥1.2.3 et <2.0.0 |
| Plage | >=1.2.0 <2.0.0 |
Comme indiqué |
| Joker | 1.2.* |
≥1.2.0 et <1.3.0 |
Le caret (^) est le défaut de npm. Il autorise les mises à jour mineures et correctives mais bloque les majeures. C'est un bon compromis entre sécurité et mise à jour.
Le rôle du lock file
Le package-lock.json (npm) ou yarn.lock fige les versions exactes installées. Même avec ^1.2.3 dans le package.json, le lock file garantit que toute l'équipe utilise la même version 1.2.7 (par exemple).
C'est pourquoi il faut toujours versionner le lock file dans Git.
Quand SemVer ne suffit pas
Le problème des « breaking changes silencieux »
Parfois, une correction de bug modifie un comportement dont votre code dépendait — même si ce comportement était un bug. C'est une zone grise de SemVer.
La dépendance humaine
SemVer repose sur la rigueur des mainteneurs. Rien n'empêche techniquement de publier un changement incompatible dans une version corrective. Des outils comme semantic-release automatisent la gestion des versions à partir des messages de commit (convention Conventional Commits).
Les alternatives
- CalVer (Calendar Versioning) : basé sur la date, utilisé par Ubuntu (24.04 = avril 2024), pip, certains projets
- Versioning interne : certains projets (Chrome, Firefox) utilisent un compteur simple incrémenté à chaque release
Bonnes pratiques
- Commencez à 0.1.0 pour un nouveau projet et passez à 1.0.0 quand l'API est stable
- Documentez les changements dans un fichier CHANGELOG.md
- Utilisez Conventional Commits pour automatiser le versioning
- Testez les mises à jour majeures dans une branche séparée
- Lisez le CHANGELOG avant de mettre à jour une dépendance majeure
- Verrouillez les versions en production avec un lock file
Conclusion
Le versioning sémantique est une convention simple mais puissante qui facilite la gestion des dépendances et la communication entre développeurs. Trois chiffres suffisent à indiquer le niveau de risque d'une mise à jour — à condition que tout le monde joue le jeu.
