Pages

Showing posts with label versioning. Show all posts
Showing posts with label versioning. Show all posts

Wednesday, January 9, 2013

Versioning a webapp using SVN revision as build number with maven

Versioning a webapp is useful for keeping track of bugs fixed, upgrades, libraries versions modifications, etc.

In this article I will show how to use SVN revision number as part of the version number of a webapp using the buildnumber-maven-plugin. Using that number makes things a lot easier in case you have to downgrade your application, reproduce a bug in a particular previous version, etc.

Here I will use the version format Major.Minor.SVNRevision. Major is a number manually assigned, Minor is a sequential number that is incremented automatically after every build, and SVNRevision is the revision number obtained from the SVN repository, you can easily modify this format to suit your needs. The whole number is generated by maven in the build process, ie when you execute mvn install on your project.

For this to work first of all you have to configure the scm section in your pom.xml:


<scm>
    <connection>scm:svn:https://svnserver/projectname/trunk</connection>
    <developerConnection>scm:svn:https://svnserver/projectname/trunk</developerConnection>
    <tag>HEAD</tag>
    <url>https://svnserver/projectname/trunk</url>
</scm>


Then, you must add the buildnumber plugin to the plugins section inside <build> tag

<plugin>

<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>generate-buildnumber</id>
<phase>prepare-package</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<doUpdate>true</doUpdate>
<providerImplementations>
<svn>javasvn</svn>
</providerImplementations> 
<useLastCommittedRevision>true</useLastCommittedRevision>
<buildNumberPropertyName>buildRevision</buildNumberPropertyName>
</configuration>
</execution>
<execution>
<id>generate-sequential</id>
<phase>prepare-package</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<buildNumberPropertiesFileLocation>src/main/resources/buildNumber.properties</buildNumberPropertiesFileLocation>
<format>{0,number,1'.'00}</format>
<items>
   <item>buildNumber0</item>
</items>
<buildNumberPropertyName>buildSequential</buildNumberPropertyName>
</configuration>
</execution>
</executions>
</plugin>

The plugin has two executions configured.

The first one is responsible for getting the svn revision number from the repository, the 
create goal is executed upon the prepare-package phase, that phase is reached automatically when you issue a build command on maven (install, package, release); the <buildNumberPropertyName> tag value creates a variable name that hold the revision number, later we'll see how it is used.

The second execution creates the sequential part of the version number, it references the
buildNumber.properties file that hold the last number used, which is automatically incremented by 1 after every build. The item tag indicates the name of the variable inside the properties file. The format of the generated number is 1.XX, where XX is the number obtained from the properties file, the plugin uses java.text.MessageFormat to format the number using {0,number,1'.'00} format in this case. Note that we use <buildNumberPropertyName> again to store the sequential number in a new variable.


Using the generated version number

Now that we already have the pom.xml configured to generate the version number, it's time to use it. I'll show you here how to put it in your application's home page but you can reference it elsewhere.

First, I'll declare two variables in the pom.xml that references the two variables created by the buildnumber plugin:

<properties>
    ...
    <webapp.version>${buildSequential}</webapp.version>
    <webapp.revision>${buildRevision}</webapp.revision>
</properties>

Then I'll add another plugin to my pom, maven-war-plugin that is responsible for the packaging and generation of the web application archive.

<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>index.html</include>
</includes>
</resource>
</webResources>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildRevision}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>

In the configuration of the plugin I indicate to filter index.html in order to replace variables included there by values computed from this pom. You can find more information about filtering in the plugin's site. I also added a default MANIFEST.MF file indicating the generated revision number as Implementation-Build value. That file is included inside the META-INF folder of the webapp.

Then, inside the index.html you can reference the variables declared earlier in the pom:

<html>
  <head>
    <title>Webapp's Name ${webapp.version} (Revision: ${webapp.revision})</title>
    ...
  </head>
  ...
</html>

That's all, when your application is packaged and deployed, you'll see in your home page the title indicating the version number, for example: Webapp's Name 1.23 (Revision: 4567)

Hope it helps. Comment if you have any problem using this approach.