Build Version Maven Plugin for Git
Written by Fernando Dobladez
For all artifacts we build on our projects (
.war files, packaged installers,
.jar archives, etc.) we always want to include precise and descriptive
information about the build: time stamps, version number, commit hash and
whether it’s a final/pre/internal release.
We include all build information inside the artifacts themselves for programmatic consumption (e.g. for showing the current build version at the bottom of a some web pages or “about” screens) and also for humans: to know exactly what build each artifact is in, for reporting and reproducing defects, for troubleshooting dependency issues and so forth. Even the naming of some artifacts (like, RPM packages) depend on build information.
We are using Maven for many of our projects. We started using the existing
to extract build information from git; unfortunately, it does not provide all we
need. So, we later started cooking simple groovy scripts (via
git describe and other
git commands to obtain the information
we wanted and set it as project properties.
This approach worked for awhile. However, the script started to get complicated and was not easy to reuse across projects.
Our current solution
With that in mind, I wrote buildversion-plugin: a simple Maven plugin that provides the functionality we need. It extracts build info from the current git branch, including timestamp, commit hash, tag name and number of commits since the last tag.
The problem with git-describe
We initially relied on calling
git describe to obtain a descriptive version
number, which includes the most recent tag and the number of commits since such
Unfortunately, the logic behind
git describe searches for the closest tag back
in history following all parent commits on merges. This means it may select
tags you originally put on another branch. So, if you are working on a
development branch and merge back a fix made on a release branch, calling
describe on the development branch may shield a description that includes a tag
you placed on the release branch.
run into the same problem. There’s
discussion on GIT’s mailing list
git describe’s logic and the need for adding a
option. And there’s even a
working patch to add
git describe accepts a
--first-parent argument, this plugin implements
its own logic, which basically leverages
git log --first-parent and traverses
the history on the current “line of development”, parsing the tag names and counting
the number of commits as it goes.
Don’t repeat yourself
One of the reasons why we started writing this plugin was to obtain the version
number from git in order to “inject” it into the Maven project. That is, we
wanted to stop having to maintain the version number inside the
given that the information was already managed by git. We couldn’t (yet?)
achieve this: apparently, Maven reads the version from the pom before invoking
the plugins; so, even after we set the version number most of Maven’s operations
continue using the version originally set in the
Notes about the implementation
It’s a really simple plugin. However, I coded it in Clojure as an exercise and to prove its Java “interoperability”. Luckily, Hugo Duncan did all of the hard work already, so it was quite simple.
I hope the plugin is useful for others. If you try it, let us now if you find issues or have ideas to improve it.
Acknowledgment: thanks to José Rozanec who implemented the first prototype trying to inject the project version. He’s also the first one to seriously test the current buildversion-plugin.