What I am trying to do here is to automate the Gitflow release actions (release-start, release-finish, hotfix-start, and hotfix-finish) for a mavenized project.
Lets take a look at the basic workflows:
(Note: have a look at the Gitflow diagramm again before continuing)
The Release Workflow
Suppose the pom.xml of the “develop” branch has version 1.5.0-SNAPSHOT (in my case, the second part contains the release version, and the third part contains the build or hotfix number).release-start should create the branch “release/1.5” (based on “develop”) and bump the “develop” version to 1.6.0-SNAPSHOT. Next it performs a release-prepare on the release branch, which means:
- setting the version to 1.5.0 and tagging it
- building and publishing to the Maven releases-repository
- bumping the version to 1.5.1-SNAPSHOT
release-finish first checks if the HEAD of the "release/1.5" branch is tagged (to make sure there are no commits after the most recent release plugin execution), then merges it to “master” as well as back to “develop”, and finally deletes the release branch.
The Hotfix Workflow
Now our release (let's say it has version 1.5.3) is in production, and (whilst development on version 1.6.0-SNAPSHOT proceeds) we must apply an hotfix.hotfix-start would create the branch “hotfix/1.5.3” (based on “master”) and bump its version from 1.5.3 to 1.5.4-SNAPSHOT. All hotfix changes are now applied to this branch.
Every time we think we are ready for release, we again use the a Release plugin to build a new version.
hotfix-finish is similar to release-finish: it cehcks if the HEAD of the hotfix branch is tagged, then merges it to “master” and “develop”. Furthermore, if the next release has already been started, the hotfix branch must also be merged to “release/1.6.0”. At the end, the branch is deleted.
Showstoppers
- On both release-finish and hotfix-finish, the merge back to “develop” will ultimately fail, because both branches have modified the version number in the pom.xml file.
- Besides this conflict, there is always the possibility of other merge conflicts, which prevents the release-finish and hotfix-finish steps from being executed non-interactive (e.g. on a CI server).
- The merge from a hotfix branch to any pending release branch is not included in Gitflow (or maybe I have missed something?)
Workaround: Scripting
There is some discussion, but no real solution to these problems: Some suggest to always use SNAPSHOT versions to avoid the release merging conflict, or even reverting the versionnumber before merging, but most seem to avoid the Gitflow commands in these cases and use the corresponding Git commands directly.So I wrote my own wrapper scripts for release-start, release-finish, hotfix-start, and hotfix-finish that bypass the showstoppers mentioned above:
- Before merging a release or hotfix back to “develop”, the version is set to the version of the target branch (e.g. on branch "release/1.5", after merging to "master", I use "mvn version:set -DnewVersion=1.6.0-SNAPSHOT", commit this, and then do the merge.
- Generally, if a merge back to “develop” fails, the script will carry on, but it won’t delete the branch and will raise an alert – now the developer nows that there is a dangling release (or hotfix) branch that needs a manual merge.