36

In maven projects the version of a project is contained in the <version> attritbute of the pom.xml file. When creating a new release in the git flow model I need to bumb the version number. This article explains how this is done (without maven):

  1. Create a release branch
  2. Change the version number and commit
  3. Merge the release branch both to develop and master

Additionally it says:

It is exactly at the start of a release branch that the upcoming release gets assigned a version number—not any earlier. Up until that moment, the develop branch reflected changes for the “next release”, but it is unclear whether that “next release” will eventually become 0.3 or 1.0, until the release branch is started. That decision is made on the start of the release branch and is carried out by the project’s rules on version number bumping.

I see two problems in conjunction with maven here:

  1. The version under development in maven would be [next version]-SNAPSHOT. So we cannot really postpone the decision which version is next up to the moment we create a release branch. Of course if we can change our mind later, but we already need to enter /some value/ here earlier.
  2. Before creating our release the version in the pom.xml was let's say 1.1-SNAPSHOT. Now we have changed that to simply 1.1 on the release branch and merged that to master. Fine. But we should also merge that branch back to develop and for that we need to adapt the version to e.g. 1.2-SNAPSHOT. And probably we should not have done that on the release branch because that commit should not be part of the release. Actually we probably should have made this change right after branching off develop because all future commits on develop will be for the next version.

When googling for the problem I found some articles about maven-plugins that can automate the process, which may be interesting, but this question is really on how the git graph should look like and where the version bump commits should be and not how I can automate this using a maven-plugin.

yankee
  • 38,872
  • 15
  • 103
  • 162
  • 1
    1) Just ++ to version. 2) Merge to develop then change version. And use some gitflow maven plugin it would be much better than doing it by hand. – Aleksandr M Mar 27 '15 at 14:13

4 Answers4

12

For normal releases, just do the snapshot version bump after merging the release branch:

  1. Create the release branch off develop and remove the snapshot from the version
  2. Merge it into master
  3. Merge it into develop
  4. Change the version on develop to the next snapshot version
  5. Push both master and develop

As you push all the changes at the same time, the team will only see the snapshot version increase.

For hotfixes, this is not possible as you create it off the master branch. There is a workaround for this scenario, here's an example using the raw git commands.

Example: You have 1.0.0 on master and want to create a 1.0.1 hotfix version. Your develop is already at 1.1.0-SNAPSHOT.

  1. git checkout master
  2. git checkout -b hotfix/1.0.1
  3. Make your hotfix!
  4. mvn versions:set -DnewVersion=1.0.1
  5. git commit -a -m "hotfix release 1.0.1"
  6. git checkout master
  7. git merge hotfix/1.0.1 (easy, because we created the branch off master)
  8. git checkout develop
  9. mvn versions:set -DnewVersion=1.0.0
  10. git commit -a -m "workaround to avoid merge conflicts"
  11. git merge hotfix/1.0.1 (will work because of the commit before)
  12. mvn versions:set -DnewVersion=1.1.0-SNAPSHOT
  13. git commit -a -m "set version back to 1.1.0-snapshot"

Not very nice but it works. This solution is also used by jgitflow (a Maven plugin to support you with git flow).

A nice alternative is to not ever commit the version bumps in the pom.xml and to set it before your build is run on the CI server. Example CI Pipeline:

  1. Checkout the branch
  2. Derive release version from the branch name and enrich it with a build number or timestamp, e.g. for build 42 of release/1.0.1 it would be 1.0.1-42
  3. Set the version using mvn versions:set -DnewVersion=1.0.1-42
  4. Build the release and publish it

The version number will not be as pure, but you'll never have merge conflicts anymore and you can always track a version back to it's build.

chris
  • 2,467
  • 2
  • 25
  • 25
  • hi @chris and what about in during the release we need to make small changes because of things detected on the environment... i mean, in sthis URL explains that during release maybe it is needed to do changes: https://stackoverflow.com/questions/37010535/how-does-git-flow-handle-hotfix-to-older-release-or-point-release-of-older-relea/37038972. If in nexus for example is configured that a version can not be redeploy, how we should procedd? thanks in advance – Gabriel García Garrido Feb 05 '20 at 17:42
  • You can just build a new version with a new version number. The *nice alternative* described above also works around your Nexus problem. – chris Feb 11 '20 at 06:50
3

Keep in mind that Git was developed for the Linux kernel which has it's own version rules.

For Maven, you should create a release branch which gets the snapshot version of the next release. This change should be a single commit (i.e. just the change of the version number in pom.xml). When merging that, checkout master and use git merge --strategy=ours <release-branch>

--strategy=ours means: Make a merge by saying "everything in master has been correctly merged with the release branch"; no changes are being made to master. Afterwards, Git will treat the branches as merged (i.e. having no changes) despite the different version number in both branches.

To avoid all kinds of problems when building master with Maven, use an odd or very high version number which never changes like 99.DEV-SNAPSHOT.

When you make the release, strip the -SNAPSHOT from the version in the release branch and commit. Afterwards, you checkout master and merge once more with --strategy=ours.

Note: If you do this, you must not make any other changes on the release branch but changing the versions. Any other hotfixes will be lost! You can only cherry pick them.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 1
    word of warning... you have to merge (or cherry pick) any bug fixes to master before doing the maven release. The only difference between the release-branch and the master must be the version numbers. – David W Apr 21 '15 at 16:26
  • I think the `--strategy=ours` is a bad idea. With gitflow you do hotfix on master branch (by merging hotfix branch on develop and master...) so you can loose hotfix modification! – Thibaud Sowa Nov 13 '18 at 18:21
1

With Maven, you should not change the version number manually.

You should add the "scm" information to your pom, in order to let Maven commit and push the version change directly.

Then, use the "release plugin". It will do the work for you. Suppose that your current version is "1.1-SNAPSHOT", the "release:perform" maven task will:

  • Change the version to 1.1, commit, tag this version and push it.
  • Change the version again to 1.2-SNAPSHOT (or 1.1.1-SNAPSHOT, 2.0-SNAPSHOT… you can choose the next version), commit and push it.

Here is an extract of a git history on a project where the Maven release plugin is used:

* 2345678 - Normal developpement commit (on branch 1.2-SNAPHOT).
* 5678901 - [maven-release-plugin] prepare for next development iteration
* 8901234 - (tag: 1.1) [maven-release-plugin] prepare release 1.1
* 1234567 - Normal developpement commit (on branch 1.1-SNAPHOT).

Note 1: At the release moment, you have to provision the next version (1.2 in this example). If you change your mind, you can change it later. The Maven "version:set-version" plugin let you reassign the version of all the project hierarchy. You will just have to commit this version change before the next release.

Note 2: At the release moment, you can also change the release version. Even if the current version is 1.1-SNAPSHOT, you can decide that the release is the 2.0 version and the next development version the 2.1-SNAPSHOT.

Benoit Courtine
  • 7,014
  • 31
  • 42
  • 5
    Maven release plugin doesn't do gitflow. – Aleksandr M Mar 27 '15 at 14:27
  • 1
    When using Maven, version naming conventions are a big constraint (when used with an intern artifact repository). So I prefer using the Maven conventions/plugins to manage the project, and adapting the gitflow to fit these Maven constraints. After testing several posible options, I think this is the best compromise. – Benoit Courtine Mar 27 '15 at 15:01
  • @BenoitCourtine how do we use the release plugin for hotfix. So for hotfix we take a new branch from master bump up the version and merge to master. The same branch is merged onto dev and the dev pom.xml version is bumped up manually. – unnik Jan 08 '20 at 12:38
1

You can use jgitflow-maven-plugin: goals jgitflow:release-start and jgitflow:release-finish.

numéro6
  • 3,921
  • 1
  • 19
  • 18