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:
- Subversion as source control
- Artifactory as internal Maven repository
- Jenkins for Continious integration
- Java source code as Maven projects
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:
And in Artifactory it will show the following:
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:
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:
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:
Now with this plugin in place I get an extra menu option to start your Release Build:
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:
The final step is to make the Jenkins release build to use this settings.xml file. You can so this like this:
Now I can run the Maven release build in Jenkins like it runs on my local machine.
Hi,
Could I ask you, how do the testers know which revision they deployed on their environment ?
Thank you,
K
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?