For a while now, we had been operating in the wild west when it comes to building our applications and deploying to production. Builds were typically done straight from the developer’s IDE and manually deployed to one of our app servers. We had a manual process in place, where the developer would do the following steps.
- Check all project code into Subversion and tag
- Build the application.
- Archive the application binary to a network drive
- Deploy to production
- Update our deployment wiki with the date and version number of the app that was just deployed.
The problem is that there were occasionally times where one of these steps were missed, and it always seemed to be at a time when we needed to either rollback to the previous version, or branch from the tag to do a bugfix. Sometimes the previous version had not been archived to the network, or the developer forgot to tag SVN. We were already using Jenkins to perform automated builds, so we wanted to look at extending it further to perform release builds.
The Maven Release plug-in provides a good starting point for creating an automated release process. We have also just started using the Nexus Maven repository and wanted to incorporate that as well to archive our binaries to, rather than archiving them to a network drive.
The first step is to set up the project’s pom file with the Deploy plugin as well as include configuration information about our Nexus and Subversion repositories.
The Release plugin configuration is pretty straightforward. The configuration takes the subversion URL of the location where the tags will reside for this project.
The next step is to configure the SVN location where the code will be checked out from.
The last step in configuring the project is to set up the location where the binaries will be archived to. In our case, the Nexus repository.
<name>Lynden release repository</name>
The project is now ready to use the Maven release plug-in. The Release plugin provides a number of useful goals.
- release:clean – Cleans the workspace in the event the last release process was not successful.
- release: prepare – Performs a number of operations
- Checks to make sure that there are no uncommitted changes.
- Ensures that there are no SNAPSHOT dependencies in the POM file,
- Changes the version of the application and removes SNAPSHOT from the version. ie 1.0.3-SNAPSHOT becomes 1.0.3
- Run project tests against modified POMs
- Commit the modified POM
- Tag the code in Subersion
- Increment the version number and append SNAPSHOT. ie 1.0.3 becomes 1.0.4-SNAPSHOT
- Commit modified POM
- release: perform – Performs the release process
- Checks out the code using the previously defined tag
- Runs the deploy Maven goal to move the resulting binary to the repository.
Putting it all together
The last step in this process is to configure Jenkins to allow release builds on-demand, meaning we want the user to have to explicitly kick off a release build for this process to take place. We have download and installed the Release Jenkins plug-in in order to allow developers to kick off release builds from Jenkins. The Release plug-in will execute tasks after the normal build has finished. Below is a screenshot of the configuration of one of our projects. The release build option for the project is enabled by selecting the “Configure release build” option in the “Build Environment” section.
The Maven release plug-in is activated by adding the goals to the “After successful release build” section. (The –B option enables batch mode so that the Release plug-in will not ask the user for input, but use defaults instead.)
Once the release option has been configured for a project there will be a “Release” icon on the left navigation menu for the project. Selecting this will kick off a build and then the Maven release process, assuming the build succeeds.
Finally a look at SVN and Nexus verifies that the build for version 1.0.4 of the Siesta-Framework project has been tagged in SVN and uploaded to Nexus.
The next steps for this project will be to generate release notes for release builds, and also to automate a deployment pipeline, so that developers can deploy to our test, staging and production servers via Jenkins rather than manually from their development workstations.