Running the Maven Release Plugin with Jenkins

jenkins
Recently I started to implement our release process in Jenkins. Until then I just ran the release plugin of Maven on my local machine which did the job. As I said we decided to move this task to Jenkins. The build/release toolstack was:

To show my Jenkins configuration I have setup a very basic Maven module named ‘myapp’ with the following pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>net.pascalalma.demo</groupId>
	<artifactId>myapp</artifactId>
	<packaging>pom</packaging>
	<version>1.0.1-SNAPSHOT</version>
	<name>${project.artifactId}</name>
	<properties>
		<jdk.version>1.7</jdk.version>
	</properties>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
					<encoding>${project.build.sourceEncoding}</encoding>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-release-plugin</artifactId>
                <version>2.4.2</version>
			</plugin>
		</plugins>
	</build>
	<scm>
		<developerConnection>scm:svn:https://svn.4synergy.nl/sandbox/myapp/trunk</developerConnection>
	</scm>
	
	<distributionManagement>
		<repository>
			<id>ec2-arti</id>
			<url>http://artifactory.4synergy.nl/artifactory/libs-release-local</url>
		</repository>
		<snapshotRepository>
			<id>ec2-arti</id>
			<url>http://artifactory.4synergy.nl/artifactory/libs-snapshot-local</url>
		</snapshotRepository>
	</distributionManagement>
</project>

As you can see not much special here: I have included the release plugin of Maven, the SCM developers connection so it can check-in and out the code of the SVN repository and Artifactory as repositories to deploy to.

And of course not to forget the following Maven settings file:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <servers>
    <server>
      <username>admin</username>
      <password>password</password>
      <id>ec2-arti</id>
    </server>
  </servers>
  <mirrors>
    <mirror>
      <mirrorOf>*</mirrorOf>
      <name>remote-repos</name>
      <url>http://artifactory.4synergy.nl/artifactory/remote-repos</url>
      <id>remote-repos</id>
    </mirror>
  </mirrors>
</settings>

With this setup I can run the Maven release plugin locally like this:
mvn -B release:clean release:prepare release:perform

This will do all the stuff the Maven release plugin should do and results in SVN with the following structure:
Screen Shot 2014-05-06 at 14.55.44

And in Artifactory it will show the following:
Screen Shot 2014-05-06 at 14.58.48
So that works. Now let me show you what steps I needed to make it work on a separated Jenkins server.

With the following config in Jenkins I can check-out and build my Maven module:
Screen Shot 2014-05-06 at 16.47.34

The next step is to run the release plugin of Maven. For this I use the following Jenkins plugin that I added to the Jenkins configuration:
Screen Shot 2014-05-06 at 16.56.36

After installing this plugin you can configure the Maven Release Plugin in your module configuration. It will generate some extra options in the module configuration:
Screen Shot 2014-05-07 at 21.00.45

Now with this plugin in place I get an extra menu option to start your Release Build:
Screen Shot 2014-05-07 at 21.03.17

After I made sure the OS user that is running Jenkins could execute SVN on the Jenkins server and had access to the SVN repository I ran into the following issue:

[INFO] [INFO] Uploading: http://54.216.254.98/artifactory/libs-release-local/net/pascalalma/demo/myapp/1.0.3/myapp-1.0.3.pom
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [INFO] BUILD FAILURE
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [INFO] Total time: 40.501 s
[INFO] [INFO] Finished at: 2014-05-07T18:45:13+00:00
[INFO] [INFO] Final Memory: 12M/30M
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project myapp: Failed to deploy artifacts: Could not transfer artifact net.pascalalma.demo:myapp:pom:1.0.3 from/to ec2-arti (http://54.216.254.98/artifactory/libs-release-local): Failed to transfer file: http://54.216.254.98/artifactory/libs-release-local/net/pascalalma/demo/myapp/1.0.3/myapp-1.0.3.pom. Return code is: 401, ReasonPhrase: Unauthorized. -> [Help 1]
[INFO] [ERROR] 
[INFO] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[INFO] [ERROR] Re-run Maven using the -X switch to enable full debug logging.
[INFO] [ERROR] 
[INFO] [ERROR] For more information about the errors and possible solutions, please read the following articles:
[INFO] [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:05 min
[INFO] Finished at: 2014-05-07T18:45:14+00:00
[INFO] Final Memory: 9M/21M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.4.2:perform (default-cli) on project myapp: Maven execution failed, exit code: '1' -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
[JENKINS] Archiving /opt/bitnami/apps/jenkins/jenkins_home/jobs/my-app/workspace/pom.xml to net.pascalalma.demo/myapp/1.0.3-SNAPSHOT/myapp-1.0.3-SNAPSHOT.pom
channel stopped
Finished: FAILURE

In my local environment I have defined the necessary username and pasword for the Artifactory instance in my Maven settings.xml but it is missing this info when running the Maven job in Jenkins. Now we can add this settings.xml also to the user running Jenkins and see if that works but a cleaner approach is to use a plugin for this. In this case the Config FileProvider Plugin. After adding this plugin to Jenkins you can define any config file in it, in our case a Maven settings.xml file:
Screen Shot 2014-05-10 at 10.21.03

The final step is to make the Jenkins release build to use this settings.xml file. You can so this like this:
Screen Shot 2014-05-12 at 17.59.55

Now I can run the Maven release build in Jenkins like it runs on my local machine.

Advertisement

About Pascal Alma

Pascal is a senior IT consultant and has been working in IT since 1997. He is monitoring the latest development in new technologies (Mobile, Cloud, Big Data) closely and particularly interested in Java open source tool stacks, cloud related technologies like AWS and mobile development like building iOS apps with Swift. Specialties: Java/JEE/Spring Amazon AWS API/REST Big Data Continuous Delivery Swift/iOS
This entry was posted in Jenkins, Maven and tagged , , , . Bookmark the permalink.

2 Responses to Running the Maven Release Plugin with Jenkins

  1. Hi,
    Could I ask you, how do the testers know which revision they deployed on their environment ?
    Thank you,
    K

    • Pascal Alma says:

      Hi K,

      In our case it are not the testers that deploy the releases but the ‘Operations’ department. So you could ‘solve’ it by setting up a procedure.
      Another more dynamic option would be to create a web page (or in case of Mule ESB a http inbound endpoint) that shows the version + build number of the current deployed release so the testers could easily see what version they are testing against.
      Is that the kind of info you were looking for?

Comments are closed.