Tuesday, November 5, 2013

Creating a Release using the Maven Release plugin

What is a Release

I spent some time tutoring a junior on configuring the Maven Release plugin to create Milestone and Release artefacts. We were not making much ground up until I took a few steps back and discussed what exactly a Release process is.

Here is a simple Release process. I am pretty sure that if you understand this basic process, you will be able to extend and modify this process for your organisation's specific requirements:
  1. The Latest set of code exists in a Source Code repository, has been tested successfully and is ready to be promoted.
  2. We need to Tag the repository so that we have a way of knowing that something special happened at this point in time. A tag is simply a Snapshot of the code at a particular point in time. This tag gives us a reference point so that we can compare code before and after the release.
  3. We build or create our deployment artefact(s).
  4. We store our artefact(s) in a secure location so that it can be retrieved at a later date for rollback or auditing purposes.

What do I want the Maven Release Plugin to do for me

The Maven Release Plugin is by no means a One-Trick-Pony. It has the ability to Build Code, Tag Code, Change Version Numbers, Branch Code, Rollback what its done and Stage artefacts. I guess if you really want know want it does, please visit http://maven.apache.org/maven-release/maven-release-plugin/.

The cool part of this Plugin is that you do not have use all of these features. You can choose what suits your release process and only use that.

I want the Maven Release to automate this process:
  • Build the Code
  • Tag the code
  • Change the code Version from a Snapshot to a Milestone or Release version
  • Build an Artefact
  • Change the code Version from a Milestone or Release version back to a Snapshot version
  • Deploy the Artefact to a Maven Repository

The 2 Parts to configure the Maven Release Plugin

There are two parts to focus on in order to get the Maven Release Plugin to achieve the goals mentioned above:
  1. Configuration in the POM file
  2. How to Run the Plugin

Configuration in the POM file

Make sure that every POM file in the Project has a Version, Artefact ID & Group ID Tag.

The Parent or Main POM file needs to have these 3 settings configured:

1.) The SCM tag must be configured.
  <scm>  
     <connection>scm:git@<host_name>:test-repository/test-project.git</connection>  
     <url>scm:git:git@<host_name>:test-repository/test-project.git</url>  
     <developerConnection>scm:git:git@<host_name>:test-repository/test-project.git</developerConnection>  
   </scm>  

The syntax changes slightly between the Source Code repositories. Fill it out with caution and consult the maven user guide as this can throw a very cryptic error. This section is used by the plugin to connect and Tag the Code in the Repository.

2.) The Distribution Management Tag Must be configured.
 <distributionManagement>  
     <snapshotRepository>  
       <id>SNAPSHOTS</id>  
       <url>http://<host_name>/nexus/content/repositories/snapshots</url>  
     </snapshotRepository>  
     <repository>  
       <id>RELEASES</id>  
       <url>http://<host_name>/nexus/content/repositories/releases</url>  
     </repository>  
   </distributionManagement>   

The Plugin deploys the generated artefact to the Artefact Repository configured in this Tag. 

3.) Add the Maven Release Plugin to the POM.
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-release-plugin</artifactId>  
         <version>2.4.1</version>  
       </plugin>  

How to Run the Plugin

1:  mvn -Dtag=<Release_Tag>  
2:    
3:  -Dproject.rel.<POM_1_Group_id>:<POM_1_Artifact_id>=<Release_version> -Dproject.dev.<POM_1_Group_id>:<POM_1_Artifact_id>=<NextDevelopmentVersion>   
4:    
5:  -Dproject.rel.<POM_2_Group_id>:<POM_2_Artifact_id>=<Release_version> -Dproject.dev.<POM_2_Group_id>:<POM_2_Artifact_id>=<NextDevelopmentVersion>  
6:    
7:   .  
8:   .  
9:   .  
10:    
11:  -Dproject.rel.<POM_1_Group_id>:<POM_1_Artifact_id>=<Release_version> -Dproject.dev.<POM_1_Group_id>:<POM_1_Artifact_id>=<NextDevelopmentVersion>  
12:    
13:  release:clean  
14:  release:prepare  
15:  release:perform   
(The Script to Execute this Plugin should be run on a single line. I am only adding line breaks for illustrative purposes.)

Let us try and understand each line:
   mvn -Dtag=<Release_Tag>  
The general way to execute Maven and the message which we want to Tag the Code Repository with.
 -Dproject.rel.<POM_1_Group_id>:<POM_1_Artifact_id>=<Release_version>  
 -Dproject.dev.<POM_1_Group_id>:<POM_1_Artifact_id>=<NextDevelopmentVersion>   
This needs to be configured for each POM file in the project. In essence, each Module is Built with the relevant Release version and the next Development version is set and committed to the Repository. The output artefact of each module is deployed to the Artefact Repository.
 release:clean  
This plugin creates temporary files during its execution. The temporary files keep the previous state or version of the POM files. This is used if or when a Rollback is executed. The clean deletes these files.
 release:prepare  
This is the heart of the Plugin. This is responsible for changing the versions, tagging the code and committing to the Code Repository.
 release:perform  
This deploys the generated Artefact to the Artefact Repository.

Suggestions and Hurdles to Look out for


  • The error or exceptions thrown by the plugin is very cryptic and often misleading.
  • Use the Maven -X option at the end of the script for the maven script to be run in verbose mode.
  • First try and get the script working locally in interactive mode before automating or deploying the job to Jenkins or some Build server.
  • Omit the release:perform step, up until you get the script to run up to and including the release:prepare step.
  • When working with a GIT repository, the plugin will commit and push the code.
  • Use the --batch-mode option to run in non-interactive mode.
  • Create a profile in the POM and use variables rather than hard coding the distribution management tag. In this way you can use the Plugin to create Milestones and Releases by merely changing the profile which reference the different locations in the Artefact Repository.

 -Darguments="-Pmilestones"  
   <distributionManagement>  
     <snapshotRepository>  
       <id>${snapshot.repository.id}</id>  
       <url>${snapshot.repository.url}</url>  
     </snapshotRepository>  
     <repository>  
       <id>${releases.repository.id}</id>  
       <url>${releases.repository.url}</url>  
     </repository>  
   </distributionManagement>  

Conclusion

The Maven Release plugin is often seen to be a pain and very difficult to use but if you do manage to get it working, I guarantee that you will be saving yourself hours. Follow my instructions and tips and please contact me if you feel that I have missed something important. I will gladly add it in.

As always; please send through your comments, suggestions or questions and I will try to address them. I can also assist you if you require technical assistance from my side in developing scripts for your organisation.


No comments:

Post a Comment