Using the Maven Release Plugin in a GitLab Pipeline
The Maven Release Plugin can be used to release a Maven project. There are two important goals:
release:prepare
that changes the version in all POMs to the supplied release version, commits those changes to SCM, creates a tag, changes the version in all POMs to the supplied next development version and commits those changes as well.release:perform
pushes the released and packaged Maven project to a remote repository.
My project uses Semantic Versioning, i.e. Major.Minor.Patch[-SNAPSHOT]
. While there is a SemVer Policy for the Maven Release Plugin, it only increases the minor element for the next development version. My goal was to automate the execution of this plugin and the release process for all three version components within my GitLab pipeline. There should be three jobs in a Release stage that can be triggered manually:
release-major
: releases the next major version, e.g. for a current version2.3.1-SNAPSHOT
:- Release version should be
3.0.0
- Development version should be
3.0.1-SNAPSHOT
- Release version should be
release-minor
: releases the next minor version, e.g. for a current version2.3.1-SNAPSHOT
:- Release version should be
2.4.0
- Development version should be
2.4.1-SNAPSHOT
- Release version should be
release-patch
: releases the current patch version, e.g. for a current version2.3.1-SNAPSHOT
:- Release version should be
2.3.1
- Development version should be
2.3.2-SNAPSHOT
- Release version should be
For this process we need to extract what the current and next major, minor and patch components are. Maven Build Helper Plugin offers the build-helper:parse-version
goal that does just that. Our full Maven command to release the patch version looks like this:
mvn build-helper:parse-version release:prepare release:perform \
--batch-mode \
-DreleaseVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion} \
-DdevelopmentVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion}-SNAPSHOT \
-Dusername=$USER \
-Dpassword=$PASSWORD \
-Darguments=-Dmaven.test.skip \
For our GitLab pipeline we need to tell the runner to checkout the exact commit. By default the GitLab runner would checkout the detached HEAD of our branch which is just a pointer without the ability to commit. It is also necessary to set git user.name
and user-email
as the runner will commit to our branch. Our three jobs in .gitlab-ci.yml
are defined as follows:
.release-setup:
script:
- git checkout -B "$CI_COMMIT_REF_NAME"
- git config user.name "..."
- git config user.email "..."
release-patch:
stage: release
when: manual
script:
- !reference [.release-setup, script]
- >
mvn build-helper:parse-version release:prepare release:perform
--batch-mode
-DreleaseVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion}
-DdevelopmentVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion}-SNAPSHOT
-Dusername=$USER
-Dpassword=$PASSWORD
-Darguments=-Dmaven.test.skip
release-minor:
stage: release
when: manual
script:
- !reference [.release-setup, script]
- >
mvn build-helper:parse-version release:prepare release:perform
--batch-mode
-DreleaseVersion=\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0
-DdevelopmentVersion=\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.1-SNAPSHOT
-Dusername=$USER
-Dpassword=$PASSWORD
-Darguments=-Dmaven.test.skip
release-major:
stage: release
when: manual
script:
- !reference [.release-setup, script]
- >
mvn build-helper:parse-version release:prepare release:perform
--batch-mode
-DreleaseVersion=\${parsedVersion.nextMajorVersion}.0.0
-DdevelopmentVersion=\${parsedVersion.nextMajorVersion}.0.1-SNAPSHOT
-Dusername=$USER
-Dpassword=$PASSWORD
-Darguments=-Dmaven.test.skip
This GitLab pipeline setup is very convenient and helps to automize the versioning and release process in your CI/CD process.