Nous avons une exigence de workflow qui signifie essentiellement que nous devons avoir la version d'artefact d'un module défini en externe à partir de la branche actuelle dans git.
C'est à dire. si nous sommes sur la branche master dans git, j'ai besoin de <version>master-...</version>
et si nous sommes sur la branche bugfixX, j'ai besoin de <version>bugfixX-....</version>
pour l'artefact généré pour ce pom.xml.
J'ai précédemment constaté que https://github.com/koraktor/mavanagaiata peut fournir le hachage SHA-1 en tant que propriété et il ressort de la documentation qu'il peut également fournir la branche, donc peut-être si il pourrait être exécuté assez tôt dans le processus, nous pourrions définir la propriété et simplement mettre <version>${our.version}</version>
dans le pom. Si cela est possible, j'aimerais beaucoup voir un pom.xml fonctionnel (et récompenser une prime de 500 points pour cela aussi).
Sinon, je suppose que nous sommes soit en prétraitement, soit en "git checkout", faire de la magie supplémentaire avec certains des hooks (que je n'ai pas encore essayés, le code de travail serait super aussi).
Nous avons un pom de niveau supérieur, qui peut être exécuté pour générer un fichier de propriétés dans ".." avant de construire les modules où cette fonctionnalité que je demande doit aller.
Des suggestions sur la façon de résoudre ce problème?
En effet, Maven ne peut pas changer la version de son propre projet en une seule fois avec d'autres objectifs. De plus, pour autant que je sache, Maven ne prend pas en charge les propriétés arbitraires dans le <version>
tag. Par conséquent, une exécution distincte est requise pour exécuter un objectif qui changera la version du POM. Il existe différents plugins qui peuvent le faire - dans ce cas, on pourrait utiliser le versions:set
objectif du versions
plugin - http://mojo.codehaus.org/versions-maven-plugin/set-mojo.html
Ainsi, on pourrait l'exécuter comme suit par exemple:
mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$branch-SNAPSHOT
où le $branch
la variable doit contenir le nom de la branche Git actuelle; il peut être extrait avec git rev-parse
, comme ça:
branch=$(git rev-parse --abbrev-ref HEAD)
Mais encore faut-il l'exécuter d'une manière ou d'une autre. Vous pouvez le faire manuellement, mais c'est lourd. Donc, je suppose que la solution la plus robuste serait en fait d'approcher Git. C'est - un crochet Git. Voici le Git complet post-checkout
hook qui fera le travail (même code que ci-dessus avec un certain filtrage pour exécuter le hook uniquement lorsque la branche est extraite, pas seulement les fichiers individuels):
#!/bin/bash
echo 'Will change the version in pom.xml files...'
# check if the checkout was to checkout a branch
if [ $3 != '1' ]
then echo 'git checkout did not checkout a branch - quitting';exit
fi
# get current branch name
branch=$(git rev-parse --abbrev-ref HEAD)
version=$branch-SNAPSHOT
# run maven versions plugin to set new version
mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$version
echo 'Changed version in pom.xml files to $version'
Mettez ce contenu dans le fichier PROJECTDIR\.git\hooks\post-checkout
fichier. Notez que le fichier hook doit être exécutable pour l'exécuter (chmod +x post-checkout
).
Quelques notes sur le plugin versions
- il est assez flexible et prend en charge de nombreuses options et a peu d'autres objectifs qui pourraient être utiles, selon la structure de votre projet (utilisez-vous ou non des poms parent, les enfants ont-ils leurs propres versions ou dérivent-ils d'un parent, etc.). Ainsi, le crochet ci-dessus peut être légèrement modifié pour prendre en charge votre cas spécifique en utilisant d'autres objectifs du plugin versions
ou en spécifiant des paramètres supplémentaires.
Avantages:
Les inconvénients:
[~ # ~] mise à jour [~ # ~]
Ci-après se trouve la version la plus compliquée du hook, qui non seulement définira la version sur le nom de la branche, mais préservera également le suffixe de l'ancienne version. Par exemple, fourni l'ancienne version master-1.0-SNAPSHOT
, passer à feature1
branch changera la version du projet en feature1-1.0-SNAPSHOT
. Ce script bash souffre de quelques problèmes (nécessite des noms de branche sans symbole de tiret (-
) dans le nom, et ne prend que la version du pom racine), mais peut donner une idée de la façon dont le hook peut être étendu: étant donné un mélange de commandes mvn et bash, vous pouvez extraire et mettre à jour un grand nombre d'informations dans le POM.
#!/bin/bash
echo 'Will change the version in pom.xml files...'
# check if the checkout was to checkout a branch
if [ $3 != '1' ]
then echo 'git checkout did not checkout a branch - quitting';exit
fi
# get current branch name
branch=$(git rev-parse --abbrev-ref HEAD)
# get current version of the top level pom
current_version=$(mvn help:evaluate -Dexpression=project.version | grep -v '\[.*')
# extract version suffix
suffix=$(echo $current_version | cut -d \- -f 2)
# build new version
version=$branch-$suffix
# run maven versions plugin to set new version
mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$version
echo 'Changed version in pom.xml files to $version'
Désolé de relancer cette question et de poster très récemment une autre solution mais il est en effet possible de changer dynamiquement la version de maven et d'utiliser certaines fonctionnalités de git, un peu comme git describe
ferait.
Le projet qui fait cela est jgitver-maven-plugin (mentions légales; je suis l'auteur), il utilise jgitver une bibliothèque basée sur jgit afin de dériver la version du projet maven à partir des informations git.
Il est très facile à utiliser comme extension maven
...
<build>
<extensions>
<extension>
<groupId>fr.brouillard.oss</groupId>
<artifactId>jgitver-maven-plugin</artifactId>
<version>0.1.0</version>
</extension>
</extensions>
...
</build>
...
L'extension peut également être utilisée comme une extension de plugin, puis permet plus de configuration, par exemple au cas où vous ne souhaiteriez pas utiliser SNAPSHOTS. Voir la page projet pour une description des scénarios d'utilisation complète.
Il existe également un plugin gradle qui fait plus ou moins la même chose.
[edit 1]: réponse au commentaire de Thorbjørn Ravn Andersen
Le plugin ne modifie pas les fichiers pom d'origine ou les fichiers build.gradle.
Pour le plugin maven, les modifications sont effectuées à la fois en mémoire dans le modèle d'objet maven et écrites dans un fichier temporaire dans le répertoire temp. Le calcul est basé uniquement sur les métadonnées git (tags, commits, ...).
Cette non modification permet de ne pas polluer l'historique git. Lorsque vous êtes satisfait d'un git commit, marquez-le git tag -a x.y.z
et mvn deploy
: c'est tout.
La version de vos fichiers de projet est désormais inutile et peut être mise à 0 par exemple.
À ce jour, et en raison de IDEA-1557 seules les versions EAP récentes d'IntelliJ fonctionnent avec le plugin maven. Eclipse et Netbeans n'ont aucun problème.
Avertissement: je suis l'auteur
Mon extension de base maven définira virtuellement la version en fonction de la branche ou de la balise actuelle. Vous pouvez configurer des modèles de format de version personnalisés à votre guise.
S'il suffit de définir la balise git et les informations de version dans le nom du fichier d'artefact, vous pouvez utiliser maven-jgit-buildnumber-plugin :
<build>
<finalName>${artifactId}-${git.buildnumber}</finalName>
<plugins>
<plugin>
<groupId>ru.concerteza.buildnumber</groupId>
<artifactId>maven-jgit-buildnumber-plugin</artifactId>
<version>1.2.7</version>
<executions>
<execution>
<id>git-buildnumber</id>
<goals>
<goal>extract-buildnumber</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
<!-- more plugins -->
</plugins>
</build>
Avez-vous essayé d'utiliser ce plugin?: https://github.com/ktoso/maven-git-commit-id-plugin . Vous pouvez le configurer pour générer un fichier de propriétés avec toutes les informations pertinentes sur l'état de votre référentiel:
- branche
- décrire
- commitId
- buildUserName
- buildUserEmail
- temps de construction
- commitUserName
- commitUserEmail
- commitMessageShort
- commitMessageFull
- commitTime
À partir de maven-3.5.0 , les propriétés $ {revision}, $ {sha1} et $ {changelist} sont prises en charge dans les propriétés version tag. Cette fonctionnalité peut être suffisante pour votre objectif si, par exemple, vous souhaitez incorporer le nom de la branche Git dans la version d'un travail de génération de CI. Voir Versions compatibles Maven CI
Fondamentalement, dans votre pom.xml, remplacez la version fixe par:
<version>${revision}${changelist}</version>
Définissez les valeurs par défaut pour révision et liste des modifications dans le répertoire racine du projet en créant un fichier .mvn/maven.config
contenant:
-Drevision=1.2.3
-Dchangelist=-SNAPSHOT
Vérifiez ce fichier dans le contrôle de version, mettez-le à jour lorsque vous augmentez la révision de votre projet.
Dans votre système CI, vous pouvez ensuite remplacer la variable changelist en utilisant une représentation nettoyée du nom de la branche Git, par exemple.
BRANCHNAME=$(git rev-parse --abbrev-ref HEAD | sed -E -e 's@[^0-9A-Za-z.-]+@-@g')
mvn clean install -Dchangelist="-${BRANCHNAME}"
(Vous préférerez peut-être git symbolic-ref --short HEAD
pour récupérer le nom de la branche, YMMV)
Votre artefact créé par le système CI pour la branche feature/branchname
aura alors un suffixe de branche versionnée comme:
yourproject-1.2.3-feature-branchname.jar
tandis que les développeurs qui n'utilisent aucune substitution le construiront toujours comme:
yourproject-1.2.3-SNAPSHOT.jar
Avez-vous vérifié le buildnumber-maven-plugin qui vous donne la possibilité d'utiliser le numéro de révision de git. Mais vous aviez besoin de quelque chose de différent. De plus, je suggérerais de faire quelque chose comme:
1.0.0-SNAPSHOT
1.0.0-SNAPSHOT
être maître
sur une branche, vous pouvez simplement changer la version
1.0.0-BF-SNAPSHOT