Thursday, February 28, 2013

User friendly Git revision numbers

As you know Git keeps the number of the revision in SHA1 and if you need to show the revision number somewhere in the application you'll have to look for some better solutions. In this post I will investigate the possibilities to display pretty revision numbers.

As a first approach I'd like to mention Maven Buildnumber plugin. It is designed to get a unique build number for each time you build your project. Here is the example snippet from pom.xml:
...
<build>
 <plugins>
  <plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>buildnumber-maven-plugin</artifactId>
   <version>1.0</version>
   <executions>
       <execution>
    <phase>validate</phase>
    <goals>
        <goal>create</goal>
    </goals>
       </execution>
   </executions>
   <configuration>
       <doCheck>false</doCheck>
       <doUpdate>false</doUpdate>
   </configuration>
  </plugin>
 </plugins>
...
</build>
You'll need also to configure the connection to your git repository:
<scm>
 <connection>scm:git:https://YOUR_CONNECTION</connection>
 <url>scm:git:https://YOUR_URL</url>
 <developerConnection>scm:git:https://YOUR_DEV_CONNECTION</developerConnection>
</scm>
Now you can acces ${buildNumber} within your pom.xml. E.g.:
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 <version>2.1</version>
 <configuration>
     <webResources>
  ...
     </webResources>
     <archiveClasses>false</archiveClasses>
     <archive>
  <manifest>
      <addClasspath>true</addClasspath>
      <classpathPrefix/>
  </manifest>
  <manifestEntries>
      <Implementation-Revision>${buildNumber}</Implementation-Revision>
      ...
  </manifestEntries>
     </archive>
 </configuration>
</plugin>
But the ${buildNumber} is too long so it would be better to use additional configuration to use only the beginning N characters. So for example if you will set length of ${buildNumber} to 5 you will get not 6b4017bf51257db678c75732d48121a0997dc19e but 6b401. Here is the configuration for pom.xml:
<configuration>
   <shortRevisionLength>5</shortRevisionLength>
</configuration>
To take ${buildNumber} not only within pom.xml you should use Maven Resources plugin filtering or Maven properties plugin with Spring PropertyPlaceholderConfigurer(For details check here).

The second approach for pretty build number is to use git tag and git describe (for details read here). This is the standard solution for the pretty revision number issue, but if you use CI tools such as Jenkins or Hudson I don't recommend giving to such tools write permissions to your repository. But if CI tool does not have write permissions it cannot create tags and git describe will not give you the result that you expected.

The third approach that you can use in Maven if you have configured resource filtering (the command is for Linux, but I think something similar should work for Windows and Mac):
mvn clean install -DbuildNumberEnv=$(git rev-list HEAD | wc -l)
And now you can use ${buildNumberEnv} to get the numeric value of the revision. But be careful with this approach since your local ${buildNumberEnv} may be the same with another developer's one while you'll have different revision list.
And of course you can use some kind of composition of presented approaches.