Maven Releaes Plugin
This blog post covers information about the maven-release-plugin.
Introduction to how the Maven Release Plugin works
Based on information at https://maven.apache.org/guides/mini/guide-releasing.html
The maven release plugin is used when you have code that is in SCM (Software Configuration Management) such as git or Subversion (svn) and you want to create a release of a JAR file (aka a maven package) that can be used by others.
Other developers can use your library by including a dependency on a release you’ve created in maven. The maven dependency syntax is:
<dependency>
<groupId>com.steranka.play</groupId>
<artifactId>liblog</artifactId>
<version>3.1.7</version>
</dependency>
Development Workflow
Below is a quick explaination of how you would use maven release plugin.
- Start with a repo. Say it has
main
branch for releases, anddev
for the development teams branch. All code gets merged todev
branch tested and released. When it is known to work it is merged tomain
. At least that’s the spirit of the rest of this example. a. At the start of this example, the main branch has version1.3.0
, the dev branch has version1.5.2-SNAPSHOT
and the user’s branch is at version1.4.0-SNAPSHOT
. *In the following table, each column represents a branch, time flows from top to bottom.**
main dev feature/ticket-123-fix-it Note
1.3.0-SNAPSHOT
1.3.0 mvn release:prepare release:perform are run to create a release
1.4.0-SNAPSHOT
1.3.0
1.4.0-SNAPSHOT A developer starts working on a ticket/fix/task
1.4.1-SNAPSHOT
1.5.0-SNAPSHOT
1.5.1-SNAPSHOT
1.5.2-SNAPSHOT
1.5.2.SNAPSHOT Developer merges latest `dev` to local branch before submitting pull request
1.5.2-SNAPSHOT feature branch is merged to dev
1.5.3 maven release:prepare is run to create release
1.5.4-SNAPSHOT
1.5.3 dev branch tag 1.5.3 is merged to main
-
In the above example, no code changes are ever made on main (when everything is done correctly, :-)).
- A developer starts working on a task (aka JIRA ticket, github issue, or the like) and creates a
feature/ticket-123-fix-xyz
branch. At the time the user started, thedev
branch was at version1.4.0-SNAPSHOT
so that is what the developer starts with. - Before declaring the branch complete, the developer merges (or rebases) the latest version
dev
branch changes to their branch and issue a pull request. Depending on how the developer merges the developers branch pom.xml might be updated to1.4.0-SNAPSHOT
(aka thedev
branch’s current version), this is desirable so that when the merge todev
occurs, thedev
branch POM version is not adversely affected. - The pull request is merged into the dev branch and the code is tested.
- After it’s known to work a maven release is created for version
1.4.0
and thedev
branch is changed to version1.5.0-SNAPSHOT
. - The tag associated with version 1.4.0 is merged to the
main
branch so that main points to the latest working release.
I’m going from memory on how I did this years ago, so it might be subject to change if I’m reminded to remember it differently. :-)
Important Notes when using Maven Release Plugin
- It forces you do follow some best practices such as not depending on other code that is labled as a SNAPSHOT. This might seem like a pain but it is there to make sure that your releases are stable and based on other code that is not changing.
- You can’t have any dependencies on libraries that have a snapshot version.
- Your unit tests
mvn test
need to run without any failures - You can’t have any code checked out
- You can create snapshot releases but this is problematic (IMO) and should be avoided until you know how maven snapshot dependencies are resolved for all developers.
- Please bump the major version whenever you change the signature of a function. This is called a breaking change as it requires users of your library to change their code.
- When working on multiple branches remember to check that you don’t merge versions on branches that move the version to a lower number! For example, if your main development branch is at version 2.4.0-SNAPSHOT and a developer finishes a branch named
feature/hard-one
that started at version1.18.0-SNAPSHOT
, don’t change the main development branch to 1.18.0-SNAPSHOT just because you are merging that branch. Either come up with a strategy or manually back out the change if it was accidently committed. - See troubleshooting tips below for what to do if the maven release plugin fails to publish your release to your maven release repository (aka Maven Central or your companies NEXUS server).
Versioning
Many tools in the maven ecosystem expect semantic versioning to be used in order to determine the compatability of a library. While I would recommend you follow the semantic release numbering approach to versioning. Such as 3.1.7-SNAPSHOT prior to the release becomes 3.1.7 after the release. The plugin doesn’t require this but it’s a good practice. See Software Versioning for other approaches.
Maven Release Plugin Documentation
The maven release plugin documentation is at http://maven.apache.org/maven-release/maven-release-plugin/plugin-info.html.
Docs for release:perform goal. http://maven.apache.org/maven-release/maven-release-plugin/examples/perform-release.html - pretty useless.
https://maven.apache.org/guides/mini/guide-releasing.html - A pretty good guide on how to use the maven release plugin.
Creating an sample hello world application to experiment with
From https://maven.apache.org/archetypes/maven-archetype-quickstart/ If you’re new to maven or just want to create a sandbox to experiment with, the following command is useful:
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
For myself, I create packages under steranka.com
domain so my command would be
mvn archetype:generate -DgroupId=com.steranka.play -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Creating a new release
If you’re following the workflow supported by the maven release plugin you run:
mvn release:prepare release:perform -Darguments="-DskipTests=true -Dmaven.javadoc.skip=true -Dadditionalparam=Xdoclint:none -DadditionalJOption=-Xdoclint:none -DgenerateReports=false"
The various arguments are used to work around problems that exist when running tests or prducing Javadocs.
Some of my FAQs
(Q) How can I update all of the POMs under a directory to be the same version?
(A) You can use the maven release plugin as follows:
mvn release:update-versions -DautoVersionSubmodules=true
See https://maven.apache.org/maven-release/maven-release-plugin/examples/update-versions.html
(Q) The push to NEXUS (or Maven Central) failed, how do I just do that step?
I did the following. In this example, version 1.5.1 was built and tagged but not pushed to NEXUS.
- Checkout version 1.5.1 from the tag.
- Build the code
mvn clean install
- Create a package and push it to NEXUS
mvn release:perform
- Verify the package was released/pushed to NEXUS.
(Q) What are all of the steps that the maven release plugin does when you run prepare and release?
Prepare
The mvn release:prepare
does the following:
- Check that there are no uncommitted changes in the sources
- Check that there are no SNAPSHOT dependencies
- Change the version in the POMs from x-SNAPSHOT to a new version (you will be prompted for the versions to use)
- Transform the SCM information in the POM to include the final destination of the tag
- Run the project tests (preparation goals) against the modified POMs to confirm everything is in working order. If tests are failing I use the ` -DskipTests=true` option to skip this step.
- Commit the modified POMs
- Tag the code in the SCM with a version name (this will be prompted for)
- Bump the version in the POMs to a new value y-SNAPSHOT (these values will also be prompted for)
- Eventually run completion goal(s) against the project (since 2.2)
- Commit the modified POMs
The above is from the Maven documentation at https://maven.apache.org/maven-release/maven-release-plugin/examples/prepare-release.html
Release
The mvn releaes:perform
does the following
- Checkout from an SCM URL with optional tag to workingDirectory (target/checkout by default)
- Run the perform Maven goals to release the project (by default, deploy site-deploy), eventually with release profile(s) active
In english, the release:perform action
- checks out the code to be released (as specified by the SCM URL in the pom or on the command line)
- builds the code
- Deploy’s or pushes the JAR artifcats to NEXUS or maven central (configured in your pom)
Articles, Questions and Answers I found useful
- https://stackoverflow.com/questions/58210926/maven-release-without-pushing-to-nexus-aka-maven-central