Gestion des versions dans Maven: SNAPSHOT ou pas SNAPSHOT?

Introduction

MAVEN est un outil qui permet de gérer le cycle de vie d’un projet d’une manière portable. Parmi les fonctionnalités les plus importantes, on peut citer :

  • la structure du projet qui est normalisée et indépendante du langage et de la plateforme utilisés (Java, PHP, FLEX…);
  • l’incitation à utiliser un dépôt central abritant les librairies utilisées par nos projets et assurant le stockage des ces derniers pour une utilisation tierce (livraison à un client ou bien utilisation par un autre projet).

Un aspect important dans l’utilisation de MAVEN est la gestion des numéros de version d’un projet et de ses dépendances. En effet, avec MAVEN, j’ai découvert la notion de SNAPSHOT et l’objectif de ce billet est de partager mon retour d’expérience concernant :

  • La mise en place d’une pratique commune de versionning.
  • La mise en place d’un déploiement continu.
  • L’automatisation de la distribution d’un projet.

Concepts

REPOSITORY

C’est un espace permettant de stocker tous les artefacts qui représentent  : 
  • les projets (binaires, code source, documentation…)
  • les librairies utilisées dans nos projets
MAVEN définit deux types de repository : 
  • SNAPSHOT REPOSITORY : on y stocke les versions SNAPSHOT
  • RELEASE REPOSITORY : on y stocke les versions non-SNAPSHOT

RELEASE

L’absence du mot SNAPSHOT signifie qu’il s’agit d’une version de type RELEASE du projet et que ce dernier est dans un état stable et qu’il peut être utilisé hors développement (tests d’intégration, qualification client, pré-production…).

Une version de type RELEASE est unique : l’exécution de la commande mvn deploy déploiera notre projet dans Artifactory. Une exécution ultérieure de la même commande sur le même projet portant la même version se soldera par un échec. En effet, Artifactory verra que l’artefact qu’on tente de déployer existe dans son RELEASE REPOSITORY. Comme cette dernière, par définition, n’autorise pas la mise à jour des artefacts, Artifactory nous renverra un message d’erreur.

SNAPSHOT

Quand le numéro de version d’un projet se termine par le mot SNAPSHOT, cela signifie que le projet est « en cours de développement ». Ce genre de version doit être visible uniquement par les développeurs. Il peut y avoir une infinité de SNAPSHOT d’une version donnée.

Si la version de notre projet web com.netapsys:foo est 5.3-SNAPSHOT, alors chaque exécution de la commande mvn deploy produira un fichier foo-5.3-SNAPSHOT.war différent (la différence est assurée par un timestamp). Il est très important de comprendre que la version SNAPSHOT est une image instantanée du projet et qu’au stade de développement, on peut déployer notre projet dans Artifactory (ou NEXUS) à l’infini

Quand MAVEN build un projet dont la version est de type SNAPSHOT, alors il tentera de mettre à jour dans le repository local toutes les dépendances du projet qui sont de type SNAPSHOT (la fréquence de mise à jour peut être personnalisée). Cela permet la parallélisation des développements de plusieurs composants du même projet. En effet, le build se fera à l’aide de la dernière version d’une dépendance, ce qui permet par exemple de détecter tôt une anomalie dans un composant (dépendance) utilisé par notre projet et bien sûr de bénéficier des dernières versions des fonctionnalités en cours de développement.

Cela suppose que les dépendances SNAPSHOT d’un composant soient régulièrement déployées dans ARTIFACTORY, mais par qui? 

  1. Par les développeurs : cela rallonge la durée du build et gaspille la bande passante du réseau.
  2. Par Hudson : cette solution est préférable car elle permet de centraliser le processus de déploiement et ainsi de le normaliser.

SNAPSHOT vers RELEASE

A un moment donné et pour des raisons contractuelles (échéance projet), on peut être amené à livrer une version stable du projet. Une bonne pratique consiste à concevoir la construction du livrable comme étant un processus automatique et reproductible. Pourquoi?
Parce qu’un client peut demander de livrer à nouveau un projet déjà livré par le passé et qui représente une spécificité technique (par exemple projet compatible Weblogic 8.1 car le client a migré vers Weblogic 9, mais souhaite faire marche arrière). Un tel processus doit respecter les conditions suivantes : 
  • Le projet ne doit contenir aucune dépendance de type SNAPSHOT (les dépendances doivent être stables).
  • Le projet fait une référence explicite (via son POM) à son repository SVN ou CVS (trunk ou bien une branche/tag spécifique) permettant de reconstruire le projet à partir de ses sources.
Un processus de construction de livrable peut être résumé de la manière suivante : 
  • Récupération du code source
  • Vérification de l’absence de dépendance de type SNAPSHOT
  • Vérification de la présence d’un lien vers le repository SVN/CVS
  • Build complet du projet 
  • Passage du numéro de version dans les POM de SNAPSHOT vers RELEASE (RELEASE ici signifie absence de SNAPSHOT : 5.3-SNAPSHOT vers 5.3 par exemple)
  • Commit du projet avec les POM modifiés
  • Création d’un TAG SVN (version CVS)
  • Build complet du projet
  • Déploiement sur Artifactory
  • Incrémentation du numéro de version (de 5.3 vers 5.4)
  • Transformation du nouveau numéro de version en SNAPSHOT (de 5.4 vers 5.4-SNAPSHOT)
  • Commit des POM ainsi modifiés

Conclusion

SNAPSHOT est mon quotidien et RELEASE est l’aboutissement.

Références

Maven Release Plugin :  http://maven.apache.org/plugins/maven-release-plugin/

Introduction to repositories : http://maven.apache.org/guides/introduction/introduction-to-repositories.html


2 commentaires

  1. Salut,

    billet clair et instructif mais j’ai une question :

    qu’entends-tu par « Le projet fait une référence explicite (via son POM) à son repo SVN ou CVS »

    il y a un champ spécifique dans le pom?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

1 + = deux

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>