Maven versioning in GitFlow

Viewed 9213

Git Flow has been around for a long time and lots of people seem to be adopting it for as their favourite git workflow.

When it comes down to implementing Git Flow in a Java / Maven setting, I was wondering how one should approach versioning the software modules that live on all the branches below.

enter image description here

In a simplistic Maven world,

  • developers always work on SNAPSHOT versions (ex: 0.0.1-SNAPSHOT)
  • some release process create a release (0.0.1)
  • A new snapshot version is made available for developers to develop on (0.0.2-SNAPSHOT).

If all you had was a Develop and Master branch this would be ok, but how do you handle maven versioning in GitFlow.

The versions on the master are pretty easy to define, as they will be the versions that are ultimately created and released from the Release branch.

But as soon as code goes to a release branch, what versioning strategy do you deploy here ?

  • I guess we need to reserve a new version number on the release branch to avoid conflicts with Develop ? And how will that version number relate to whatever is on the develop branch.
  • I assume that on the release branch there can also be multiple commits before the release goes into production. As we cannot re-use non-snapshot versions, do we increment fixed versions here with each commit, or also work with release-snapshot versions before finalising and pushing to master ?
  • When we merge changes back from the release to the develop branch do we start a new snapshot version ?
3 Answers

For release branch we should following 0.0.1-RC-SNAPSHOT naming convention. Also please explore the mvn jgitlfow plugin. Which will provide all the above discussed features .

Please include the following depedency.

   <plugin>
                <groupId>external.atlassian.jgitflow</groupId>
                <artifactId>jgitflow-maven-plugin</artifactId>
                <version>${jgitflow-maven-plugin.version}</version>
                <configuration>
                    <enableSshAgent>true</enableSshAgent>
                    <noDeploy>true</noDeploy>
                    <noReleaseBuild>true</noReleaseBuild>
                    <noFeatureBuild>true</noFeatureBuild>
                    <noHotfixBuild>true</noHotfixBuild>
                    <enableFeatureVersions>true</enableFeatureVersions>
                    <releaseBranchVersionSuffix>RC</releaseBranchVersionSuffix>
                    <allowSnapshots>true</allowSnapshots>
                    <pushReleases>true</pushReleases>
                    <pushHotfixes>true</pushHotfixes>
                    <pushFeatures>true</pushFeatures>
                    <flowInitContext>
                        <versionTagPrefix>v</versionTagPrefix>
                    </flowInitContext>
                </configuration>
            </plugin>

Example cammands

mvn jgitflow:release-start

creates a release branch with RC and updates develop branch pom to next version

 mvn jgitflow:release-finish

Mergers relaese to master and develop and creates a tag : Mostly this branch goes Integration testing any bug fix are commited to the release branch, when it is closed develop also get the updates as it is merged.

creates a release branch with also updates the develop pom ie before (devlop 0.1-SNAPSHOT) After devlop 0.2-SNAPSHOT and a release branch of 0.1-RC-SNAPSHOT is create

https://bitbucket.org/atlassian/jgit-flow/wiki/Home

In our application , we had we were using the maven-release-plugin to update the version in the pom file. When we are using tools like Jenkins , whenever we configure a Job , we also have the provision to trigger downstream jobs. So in our case , we had the following setup :

  1. A pull request from release to master was made and the build will run on release and of success it enables the merge.
  2. When the merge occurs jenkins job was triggered to update the version in the pom to a snapshot one. After this a down-stream job was triggered to update the same snapshot version in the develop branch as well .

So , in our case whenever a release went through two version updates happened , that in one when the release version was cut and the other when the snapshot version is cut after release when merging to master and develop. So, in our master and develop after a release , the final version will always be a snapshot one. For some teams, I have seen that they only update the snapshot version in develop and push the release version directly to master (that is they merge to master from release without version change to snapshot and in down stream job change the version to snapshot when merging to develop).

For your question : I assume that on the release branch there can also be multiple commits before the release goes into production. As we cannot re-use non-snapshot versions, do we increment fixed versions here with each commit, or also work with release-snapshot versions before finalising and pushing to master ?

In an ideal case the release branch won't have direct commits to it. It will have to go through the develop to happen.So, yes the version needs to be incremented whenever you merge from develop to release as it is setup as a process.It's also easier to track bugfixes and features if you increment the version with each release.

I find that it is important to keep the areas of source control (managed by Git) and of building (managed by Maven) separate. In other words, managing versioning and branches should happen outside of your pom.xml files. It can still be achieve by means of some Maven plugin, but this plugin should not be a part of build process - it should be a tool external to this process.

Having this said, take a look at this description of Maven versions. You are right that when a release branch is created, a version X.Y.Z is "reserved" for this release (and develop branch atomically gets incremented snapshot version X.Y.(Z+1)-SNAPSHOT or X.(Y+1).Z-SNAPSHOT etc. depending on what kind of release is planned to be next). In meantime, your release branch will be existing for some time and you may need to change the version of your artefact between builds to avoid conflicts. This can be done by using build numbers or qualifier and a build number together. For example, you may start from X.Y.Z-alpha-0 and proceed till you change to X.Y.Z-beta-0 and onwards. You increment build number every time you need to deploy a "pre-release" artefact to your repository. Eventually, when release is made, your version X.Y.Z will be considered by Maven "greater" than all versions with build numbers and modifiers.

Related