Maven Git Release
I need to start this post by stating that I’ve only started to work seriously with Git within the last year. Unfortunately, a lot of the projects that I work on are still using SVN or CVS, but I’m now finally starting in a few that use Git.
During the last few years, I’ve done a lot of software releases using Maven Release Plugin. I still remember that I’ve took a full week just to setup the plugin in one of my projects. It worked well most of the times, but if something went wrong you could spend the next few hours fixing the problem. Oh boy, what a nightmare!
Recently, I wanted to do the same operation with a Git project and I came across with the Maven JGit-Flow Plugin and I have to tell you that this is fantastic! Very easy to setup and worked flawlessly on the first try!
This plugin is based on the development model described in the post A successful Git branching model by Vincent Driessen. Take your time to read it, since it’s very interesting.
I’m going to show you how to perform a release using this plugin. I’ll use the project from my latest post about Spring Batch as Wildfly Module.
Setup
Setup is very easy, just add the following to your pom.xml
:
1 2 3 4 5 6 7 8 | <plugin> <groupId>external.atlassian.jgitflow</groupId> <artifactId>jgitflow-maven-plugin</artifactId> <version>1.0-m3</version> <configuration> <noDeploy>true</noDeploy> </configuration> </plugin> |
I’ve just added the noDeploy
configuration, because I’m not releasing to a Maven repository. That’s it!
Release
Let’s look at my project branches and version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | radcortez:wildfly-spring-batch radcortez$ git branch -avv * master 0b2364b [origin/master] Added documentation. remotes/origin/master 0b2364b Added documentation. radcortez:wildfly-spring-batch radcortez$ mvn help:evaluate -Dexpression=project.version [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-help-plugin:2.2:evaluate (default-cli) @ wildfly-spring-batch --- [INFO] No artifact parameter specified, using 'com.cortez.wildfly.batch:wildfly-spring-batch:war:1.0-SNAPSHOT' as project. [INFO] 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ |
Now, just run mvn jgitflow:release-start
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | radcortez:wildfly-spring-batch radcortez$ mvn jgitflow:release-start [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- jgitflow-maven-plugin:1.0-m3:release-start (default-cli) @ wildfly-spring-batch --- [INFO] ensuring origin exists... [INFO] (develop) Checking for SNAPSHOT version in projects... [INFO] (develop) Checking dependencies and plugins for snapshots ... What is the release version for "wildfly-spring-batch"? (com.cortez.wildfly.batch:wildfly-spring-batch) [1.0]: [INFO] ensuring origin exists... [INFO] (release/1.0) adding snapshot to pom versions... [INFO] (release/1.0) updating poms for all projects... [INFO] turn on debug logging with -X to see exact changes [INFO] (release/1.0) updating pom for wildfly-spring-batch... What is the development version for "wildfly-spring-batch"? (com.cortez.wildfly.batch:wildfly-spring-batch) [1.1-SNAPSHOT]: [INFO] (develop) updating poms with next development version... [INFO] (develop) updating poms for all projects... [INFO] turn on debug logging with -X to see exact changes [INFO] (develop) updating pom for wildfly-spring-batch... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ |
You get an interactive menu to pick the version numbers you want to release, the same way as Maven Release Plugin. I’m developing on the master
branch, but during this process a release
branch is created with the release versions and development
branch with the new development versions.
1 2 3 4 5 | radcortez:wildfly-spring-batch radcortez$ git branch -avv develop 728856a [origin/develop] updating poms for 1.1-SNAPSHOT development master 0b2364b [origin/master] Added documentation. * release/1.0 9f88a42 updating poms for branch '1.0' with snapshot versions remotes/origin/master 0b2364b Added documentation. |
Now the cool thing about this, is that everything is still in your local environment! If you are not happy with the changes, you can get rid of the branches and start over. No build was performed at this point.
If we want to release, just run mvn jgitflow:release-finish
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | radcortez:wildfly-spring-batch radcortez$ mvn jgitflow:release-finish [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- jgitflow-maven-plugin:1.0-m3:release-finish (default-cli) @ wildfly-spring-batch --- [INFO] ensuring origin exists... [INFO] running jgitflow release finish... [INFO] ensuring origin exists... [INFO] (release/1.0) Updating poms for RELEASE [INFO] (release/1.0) removing snapshot from pom versions... [INFO] (release/1.0) updating poms for all projects... [INFO] turn on debug logging with -X to see exact changes [INFO] (release/1.0) updating pom for wildfly-spring-batch... [INFO] (release/1.0) Checking for RELEASE version in projects... [INFO] (release/1.0) Checking dependencies and plugins for snapshots ... [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building wildfly-spring-batch 1.0 |
In this step, the release
branch is going to get merged as described in A successful Git branching model and create the tag. Remember, nothing has been pushed yet, so you can always revert the process.
Let’s have a look into the branches and tags now:
1 2 3 4 5 6 | radcortez:wildfly-spring-batch radcortez$ git branch -avv * develop a8e762b [origin/develop] Updating develop poms back to pre merge state master b6fbda0 [origin/master: ahead 3] Merge branch 'release/1.0' remotes/origin/master 0b2364b Added documentation. radcortez:wildfly-spring-batch radcortez$ git tag 1.0 |
Now you’re a push away to complete your release and ready to keep developing in your new updated development
branch. How easy was that?
Conclusion
Looking into some differences between the original release plugin and jgitflow:
- You don’t have to worry about stage commits. Everything is local until you push.
- No more problems with other people changing pom.xml during the process.
- Your project is only built once, saving release time.
- Very easy to setup. Everything is picked from your Git configuration.
When I was investigating / writing, I’ve found this very interesting post, about an alternative way to perform the release. It’s worth reading: http://axelfontaine.com/blog/final-nail.html by Axel Fontaine