Painless Maven project releases with Maven GitFlow Plugin

November 9, 2013

Update

Since the time of this writing, this plugin was merged into https://bitbucket.org/atlassian/jgit-flow/, so please read https://bitbucket.org/atlassian/jgit-flow/wiki/goals.wiki for the latest configuration options.

Intro

We recently moved all our code repositories from Atlassian's hosted SVN to BitBucket and took the opportunity to revisit our deployment process. We had been operating using SVN trunk for ongoing development and stabilizing it whenever we wanted to cut releases. This approach worked well in the early days but started to show its' challenges as we added developers to the team and worked on parallel tracks. So the move to Git presented the perfect time to consider a development process that would be a better fit for a DVCS. Enter Git-Flow.

Git-Flow

Git-Flow is a popular branching model for Git that is aimed at structuring and streamlining the development process in a DVCS setting. If you've been living under a rock and haven't read the original article by Vincent Driessen, you should drop what you are doing right now and go read it. Do it now! I'll wait... ;-)

A successful Git branching model

Back? So, just to recap, the main highlights are:

All this branching may feel like a lot of overhead but in practice, it really isn't. Plus it pays whenever there are several team members working concurrently on different features. And thankfully, Vincent Driessen released some Git extensions to help automate some of the branching tasks.

We had been familiar with this model for a while, so moving to Git was the perfect time to implement it. We don't find it necessary to create feature branches 100% of the time. For instance, for quick maintenance tasks, we tend to develop on the development branch. But for features that may take more than a week to develop, we do branch off as it helps us avoid stepping on each other's toes.

Git-Flow with Maven and maven-jgitflow-plugin

If you work with Java and Maven, you are probably familiar the maven-release-plugin which performs a variety of release tasks and most importantly for multi-module projects (of which we have many), takes care of bumping the sub-module versions together with the parent project version.

It is possible to use the maven-release-plugin together with a tool like Git-flow but for a smoother, more streamlined experience, the maven-jgitflow-plugin by Atlassian's Jonathan Doklovic is definitely the way to go. This plugin is designed to make the Maven/Git-Flow combo experience as painless as possible. To quote from Jonathan's own blog post about the plugin, here is how it improves on the stock maven-release-plugin for git-flow projects:

Unless you want to keep cleaning up all of the above manually, using this plugin is a no-brainer.

Configuration

The following is the configuration we have been using internally for our own deployments, annotated to explain the various flags:

[...]
<plugin>
  <groupId>com.atlassian.maven.plugins</groupId>
  <artifactId>maven-jgitflow-plugin</artifactId>
  <version>1.0-alpha20</version>
  <configuration>
    <!-- Enable this to push to origin using SSH keys -->
    <enableSshAgent>true</enableSshAgent>
    <!-- Keep your maven submodules at the same version as the parent POM -->
    <autoVersionSubmodules>true</autoVersionSubmodules>
    <!--
      Pusing in-development features to origin allows all devs to see what each other
      are working on
    -->
    <pushFeatures>true</pushFeatures>
    <!--
      This allows the CI server (e.g. Jenkins) to automatically push new releases to
      origin; you can then either manually deploy them or, if you are doing Continuous
      Deployments, auto-deploy them to prod
    -->
    <pushReleases>true</pushReleases>
    <!--
      Hot Fixes should be pushed to origin as well so that any dev can pick them up
    -->
    <pushHotfixes>true</pushHotfixes>
    <!--
      Prevents deployments from dev workstations so that they can be done by a CI
      server
    -->
    <noDeploy>true</noDeploy>
    <flowInitContext>
      <!--
        You can customize your development branch name. Why? Because it's faster to type
        'git push origin dvlp'
        than
        'git push origin develop'
        ;-)
      -->
      <developBranchName>dvlp</developBranchName>
      <!-- You can also customize your tag prefixes -->
      <versionTagPrefix>rev-</versionTagPrefix>
    </flowInitContext>
  </configuration>
</plugin>
[...]

More configurations options exist. You can read about them on the plugin's wiki.

Usage

The main plugin commands are:

When a release branch is started the plugin prompts for the release version. E.g. if the development branch version was 5.1-SNAPSHOT it will assume that the release is 5.1 (the users can override this). When the release branch is merged back into master, the plugin automates several things:

Conclusion

If you are using Maven and Git, I have hopefully convinced you to give the maven-jgitflow-plugin plugin a try. Fell free to drop a comment or email me with any questions.

comments powered by Disqus
Fork me on GitHub