Getting maven artifact version from git branch

We have a requirement for data flow, which essentially means that we need to have a module artifact version externally defined from the current branch in git.

those. if we are on the main branch in git, I need <version>master-...</version> , and if we are on the bugfixX branch, I need <version>bugfixX-....</version> for the generated artifact for this pom.xml.

Earlier, I discovered that https://github.com/koraktor/mavanagaiata can provide a SHA-1 hash as a property, and the documentation shows that it can also provide a branch, so it’s possible if it could be started early enough, we could set the property and just put <version>${our.version}</version> in pom. If possible, I would really like to see a working pom.xml (and reward 500 points for it).

If not, I assume that we are either pre-processing or "git checkout" doing extra magic with some of the hooks (which I haven't tried yet, working code would be nice too).

We have a top-level pom that can be run to create a properties file in ".." before creating modules, where I ask for this functionality.

Any suggestions on how to solve this?

+56
git maven mavanagaiata
Nov 27 '12 at 12:08
source share
7 answers

Indeed, Maven cannot change the version of its own project in one go with other goals. Also, as far as I know, Maven does not support arbitrary properties in the <version> . Therefore, to achieve the goal, a separate execution is required, which will change the version of POM. There are various plugins that can do this - for this case, you can use the versions:set target from the versions plugin - http://mojo.codehaus.org/versions-maven-plugin/set-mojo.html

So, you can execute it, for example, as follows:

 mvn versions:set -DgenerateBackupPoms=false -DnewVersion=$branch-SNAPSHOT 

where the $branch variable should contain the current Git branch name; it can be extracted using git rev-parse , for example:

 branch=$(git rev-parse --abbrev-ref HEAD) 

But still, you need to somehow fulfill it. You can do it manually, but it is cumbersome. So, I think the most reliable solution would be to get closer to this from Git. That is - a Git hook. Here is the full Git post-checkout hook that will do the job (the same code as above, with some filtering to trigger the hook only when the branch is checked, not just individual files):

 #!/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' 

Put this content in the file PROJECTDIR\.git\hooks\post-checkout . Note that the hook file must be executable to run it ( chmod +x post-checkout ).

A few notes about the versions plugin - it is quite flexible and supports many parameters and has several other goals that can be useful, depending on the structure of your project (whether you use parent pumps or not, the children have their own versions or they come from the parent and etc.). Thus, the above hook can be slightly modified to support a specific case, using other goals from the versions plugin or specifying additional parameters.

Pros:

  • Robust
  • There is no need to change anything in the pom.xml files to make this work.
  • This "functionality" can be disabled simply by deactivating the hook (delete or make it not executable) - again, no changes are required in pom.xml

Minuses:

  • You cannot force others to use the hook - it must be installed manually after cloning the repo (or you can provide a script to set the hook if it is assumed that Git users are afraid to touch the material inside .git).

UPDATE

In the future, this is a more complex version of the hook, which will not only install the version in the name of the branch, but also retain the suffix of the old version. For example, with the old version of master-1.0-SNAPSHOT switching to the feature1 branch will change the project version to feature1-1.0-SNAPSHOT . This bash script suffers from several problems (it requires a branch name without a dash ( - ) character in the name and accepts only the version of the root pump), but it can give an idea of ​​how to increase the hook: given the combination of the mvn and bash commands, you can extract and update quite a lot of information in 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' 
+43
Dec 20 2018-12-12T00: 12
source share

Sorry to revive this question and recently published a different solution, but you can really change the version of maven dynamically and use some git functions a bit like git describe .

The project that does this is the jgitver-maven-plugin (disclaimer, I'm the author), it uses the jgit -based jgitver library to get the version of the maven project from git.

enter image description here

It is very easy to use as a maven extension

 ... <build> <extensions> <extension> <groupId>fr.brouillard.oss</groupId> <artifactId>jgitver-maven-plugin</artifactId> <version>0.1.0</version> </extension> </extensions> ... </build> ... 

The extension can also be used as a plug-in extension, and then allows more configuration, for example, if you do not want to use SNAPSHOTS. See page for full use cases.

There is also a gradle plugin that does more or less the same.




[edit 1] : Response to Thorbjorn Ravn Andersen's comment

The plugin does not modify the pom source files or build.gradle files.
For the maven plugin, modifications are performed both in memory in the Maven Object Model and written to a temporary file in the temp directory. The calculation is based only on git metadata (tags, commits, ...).
This non-modification allows you not to pollute the git history. If you are satisfied with the git commit, tag the git tag -a xyz and mvn deploy : with everything.
The version in your project files is now useless and can be set, for example, to 0.

To date, and thanks to IDEA-155733 , only the latest versions of EAP IntelliJ work with the maven plugin. Eclipse and Netbeans have no problems.




+10
Jun 24 '16 at 7:41
source share

Disclaimer: I am the author

My Maven kernel extension will actually install the version based on the current branch or tag. You can customize custom version format templates as you like.

https://github.com/qoomon/maven-branch-versioning-extension

Version format example enter image description here

+7
Oct 16 '17 at 4:59 on
source share

If you just specify the tag and version of git in the artifact file name, you can use 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> 
+4
Aug 22 '14 at 16:51
source share

Have you tried using this plugin ?: https://github.com/ktoso/maven-git-commit-id-plugin . You can configure it to create a properties file with all the necessary information about the status of your repo:

  • branch
  • describe
  • commitId
  • buildUserName
  • buildUserEmail
  • buildTime
  • commitUserName
  • commitUserEmail
  • commitMessageShort
  • commitMessageFull
  • commitTime
+2
Dec 20 '12 at 15:37
source share

You checked the buildnumber-maven-plugin , which gives you the option to use the git version number. But you needed something else. Also, I would suggest doing something like:

  1.0.0-SNAPSHOT 1.0.0-SNAPSHOT 

beeing on master

on a branch you can just change the version to

  1.0.0-BF-SNAPSHOT 
+1
Nov 27 '12 at 15:02
source share

Starting with maven-3.5.0, the version tag has support for the $ {revision}, $ {sha1} and $ {changelist} properties. This function may be sufficient for your purposes if, for example, you want to include the Git brand name in the version to specify the CI assembly. View Maven CI Friendly versions

Essentially, in your pom.xml, replace the fixed version with:

 <version>${revision}${changelist}</version> 

Set the default values ​​for the revision and change list in the root .mvn/maven.config project by creating a .mvn/maven.config containing:

 -Drevision=1.2.3 -Dchangelist=-SNAPSHOT 

Check this file in version control, update it when you raise the revision of your project.

On your CI system, you can then override the change list variable using a cleared representation of the Git branch name, for example.

 BRANCHNAME=$(git rev-parse --abbrev-ref HEAD | sed -E -e 's@[^0-9A-Za-z.-]+@-@g') mvn clean install -Dchangelist="-${BRANCHNAME}" 

(You may prefer git symbolic-ref --short HEAD for branch extraction, YMMV)

Your artifact created by the CI system for the feature/branchname branch will have a version branch suffix, for example:

 yourproject-1.2.3-feature-branchname.jar 

while developers who do not use overrides will still create it as:

 yourproject-1.2.3-SNAPSHOT.jar 
0
Sep 22 '18 at 15:51
source share



All Articles