web-dev-qa-db-fra.com

Quelle est la méthode Maven pour les versions de projet automatiques lors d’une livraison continue?

J'ai une application Web où nous déployons en production chaque fois qu'une fonctionnalité est prête, parfois plusieurs fois par jour, parfois plusieurs semaines. 

Actuellement, nous n'augmentons pas les numéros de version de notre projet, et tout est en place depuis la version 0.0.1-SNAPSHOT depuis plus d'un an .. Je me demande quelle est la façon la plus simple de proposer la livraison continue d'une application Web. Il semble exagéré de surpasser le numéro de version sur chaque commit, et ne jamais écraser le numéro de version comme nous le faisons actuellement semble également erroné.

Quelle est la meilleure pratique recommandée pour ce type d'utilisation de Maven?

Le problème est en réalité un double:

  • Avancer le numéro de version du projet dans un fichier pom.xml individuel (et il peut y en avoir beaucoup).
  • Mise à jour du numéro de version dans tous les composants dépendants pour utiliser les derniers l'un par rapport à l'autre.
44
ams

Je recommande la présentation suivante qui traite des réalités pratiques de la livraison continue avec Maven:

La clé à retenir est que chaque version est une version potentielle, évitez donc d'utiliser des instantanés.

38
Mark O'Connor

Ceci est mon résumé basé sur la vidéo liée par la réponse de Mark O'Connor.

  • La solution nécessite un DVCS tel que git et un serveur CI tel que Jenkins. 
  • N'utilisez pas de génération d'instantané dans le pipeline de livraison continue et n'utilisez pas le plug-in maven release.
  • Les versions d'instantané telles que 1.0-SNAPSHOT sont transformées en versions réelles telles que 1.0.buildNumberbuildNumber est le numéro du travail Jenkins. 

Étapes de l'algorithme:

  1. Jenkins clone le repo git avec le code source et dit que le code source a la version 1.0-SNAPSHOT
  2. Jenkins crée une branche git appelée 1.0.JENKINS-JOB-NUMBER afin que la version de l'instantané soit transformée en une version réelle 1.0.124
  3. Jenkins appelle le plugin maven versions pour changer le numéro de version dans les fichiers pom.xml de 1.0-SNAPSHOT à 1.0.JENKINS-JOB-NUMBER 
  4. Jenkins appelle mvn install
  5. Si le mvn install est un succès, Jenkins validera la branche 1.0.JENKINS-JOB-NUMBER et une version réelle non instantanée sera créée avec une balise appropriée dans git pour une reproduction ultérieure. Si le mvn install échoue, Jenkins supprimera simplement la branche nouvellement créée et échouera à la construction.

Je recommande fortement la vidéo liée à la réponse de Mark.

34
ams

À partir de Maven 3.2.1, les versions respectueuses de la livraison continue sont prises en charge immédiatement: https://issues.Apache.org/jira/browse/MNG-5576 Vous pouvez utiliser 3 variables prédéfinies dans la version:

${changelist}
${revision}
${sha1}

Donc, ce que vous faites fondamentalement est: 

  1. Définissez votre version sur, par exemple. 1.0.0-${revision}. (Vous pouvez utiliser mvn versions:set pour le faire rapidement et correctement dans un projet multi-module.)
  2. Mettez une propriété <revision>SNAPSHOT</revision> pour le développement local.
  3. Dans votre environnement CI, exécutez mvn clean install -Drevision=${BUILD_NUMBER} ou quelque chose comme ceci ou même mvn clean verify -Drevision=${BUILD_NUMBER}.

Vous pouvez par exemple utiliser https://wiki.jenkins-ci.org/display/JENKINS/Version+Number+Plugin pour générer des numéros de construction intéressants.

Une fois que vous avez découvert que la construction est stable (par exemple, réussir les tests d’acceptation), vous pouvez transmettre la version à Nexus ou à un autre référentiel. Toutes les constructions instables vont juste à la poubelle.

14
Piotr Gwiazda

Il existe d'excellentes discussions et propositions sur la manière de traiter le numéro de version Maven et la distribution continue (CD) (je les ajouterai après ma partie de la réponse).

Alors d’abord mon avis sur les versions SNAPSHOT. En maven, un SNAPSHOT indique qu’elle est en cours de développement pour la version spécifique avant le suffixe SNAPSHOT. Pour cette raison, des outils tels que Nexus ou le plug-in maven-release-plug ont un traitement spécial pour SNAPSHOTS. Pour Nexus, ils sont stockés dans un référentiel séparé et il est autorisé à mettre à jour plusieurs artefacts avec la même version de SNAPSHOT. Donc, un instantané peut changer sans que vous le sachiez (parce que vous n'incrémentez jamais un nombre dans votre pom). Pour cette raison, je ne recommande pas d'utiliser les dépendances SNAPSHOT dans un projet, en particulier dans un monde CD, car la construction n'est plus fiable. 

SNAPSHOT en tant que version du projet poserait un problème lorsque votre projet est utilisé par d'autres projets, pour les raisons susmentionnées.

Un autre problème de SNAPSHOT pour moi est qu’il n’est plus vraiment traçable ni reproductible. Lorsque je vois une version 0.0.1-SNAPSHOT en production, je dois effectuer quelques recherches pour savoir quand elle a été construite à partir de quelle révision elle a été construite. Lorsque je trouve une version de ce logiciel sur un système de fichiers, je dois consulter le fichier pom.properties ou MANIFEST pour savoir s’il s’agit d’une vieille saleté ou de la dernière et meilleure version.

Pour éviter le changement manuel du numéro de version (en particulier lorsque vous créez plusieurs versions par jour), laissez le serveur de construction le modifier à votre place. Donc, pour le développement, j'irais avec un 

<major>.<minor>-SNAPSHOT

version, mais lors de la création d’une nouvelle version, le serveur de compilation pourrait remplacer le SNAPSHOT par quelque chose de plus unique et traçable.

Par exemple un de ceci:

<major>.<minor>-b<buildNumber>
<major>.<minor>-r<scmNumber>

Ainsi, les nombres majeur et mineur peuvent être utilisés pour des problèmes de marketing ou simplement pour montrer qu'un nouveau grand jalon est atteint et peuvent être modifiés manuellement lorsque vous le souhaitez. Et le buildNumber (numéro de votre serveur d'intégration continue) ou le scmNumber (Révision de Subversion ou GIT) rendent chaque version unique et traçable. Lors de l'utilisation de la révision buildNumber ou Subversion, les versions du projet sont même triables (pas avec les numéros GIT). Avec le buildNumber ou le scmNumber, il est également un peu facile de voir quels changements ont été apportés dans cette version.

Un autre exemple est le contrôle de version de stackoverflow qui utilise

<year>.<month>.<day>.<buildNumber>

Et voici les liens manquants:

9
mszalbach

NE FAITES PAS CELA!

<Major>.<minor>-<build>

vous mordra dans le dos parce que Maven traite n'importe quoi après un trait d'union comme LEXIQUE. Cela signifie que la version 1 sera lexicalement supérieure à 10.

C'est mauvais, car si vous demandez la dernière version de quelque chose dans maven, alors le point ci-dessus gagne.

La solution consiste à utiliser un point décimal au lieu d'un trait d'union précédant le numéro de build.

FAIRE CECI!

<Major>.<minor>.<build>

Il est correct d’avoir les versions SNAPSHOT localement, mais dans le cadre d’une construction, il est préférable d’utiliser

mvn versions:set -DnewVersion=${major}.${minor}.${build.number}

Il existe des moyens de dériver la version majeure/mineure du pom, par exemple en utilisant help: evaluer et diriger vers une variable d'environnement avant d'appeler les versions: set. C'est sale, mais je me suis vraiment égratigné la tête (et les autres membres de mon équipe) pour simplifier les choses, et (à l'époque), Maven n'était pas assez mûr pour gérer cela. Je pense que Maven 2.3.1 pourrait avoir quelque chose qui aiderait cela, alors cette information pourrait ne plus être pertinente.

Il est normal qu'un groupe de développeurs publie la même version majeure.minor - mais il est toujours bon de garder à l'esprit que les modifications mineures sont ininterrompues et que les modifications de version majeures entraînent des modifications de dernière minute de l'API ou la dépréciation de fonctionnalités/comportements.

Du point de vue de la livraison continue, chaque build est potentiellement libérable. Par conséquent, chaque enregistrement doit créer un build.

6
user924272

Comme point de départ, vous pouvez jeter un oeil à Maven: la référence complète. Versions du projet.

Ensuite, il y a un bon post sur la stratégie de versioning.

2
dmitri

Dans mon travail pour les applications Web, nous utilisons actuellement ce modèle de versioning: 

<jenkins build num>-<git-short-hash> 

Exemple: 247-262e37b9. 

C'est bien parce que cela vous donne une version toujours unique et traçable jusqu'à la version de build et git de jenkins qui l'a produite.

Dans Maven 3.2.1+, ils ont finalement éliminé les avertissements concernant l'utilisation d'une $ {propriété} en tant que version, ce qui facilite grandement leur construction. Changez simplement tous vos poms pour utiliser <version>${revision}</version> et construisez avec -Drevision=whatever. Le seul problème avec cela est que, dans vos poms publiés, la version restera à ${revision} dans le fichier pom réel, ce qui peut causer toutes sortes de problèmes étranges. Pour résoudre ce problème, j'ai écrit un simple plugin maven ( https://github.com/jeffskj/cd-versions-maven-plugin ) qui effectue le remplacement de la variable dans le fichier.

1
Jeff S