If you've used Nexus for development and you've perfected the art of continuous integration, you may have noticed that Nexus does more than just support development. Once you've mastered complex assemblies and created Matrix jobs to publish release artifacts to Nexus, you start to see Nexus as a central part of your approach to deploying software to various environments.
Deployment Scripts: What to write them in
The production automation and deployment space has thousands of options from Puppet to ControlTier to OSGi-based solutions to approaches that involve a series of custom scripts. While there are many options, I would argue for something closer to Puppet or a custom script. Deploying software to production networks is very often a responsibility shared by two separate teams: Development and Operations with an Operations group owning much of the process.
This newly emerging space is often called Devops and it is a particularly interesting part of the modern IT department. While you could write a custom Java application to interact with Nexus using the Aether library, if you did so you would be creating a system that would need to maintained by a group of Java developers. For this reason, I often suggest bash coupled with a set of "lowest common demoninator" tools that are going to be available on almost every Linux distribution. This set of tools is: bash, curl, md5sum.
If you standardize your deployment scripts on bash then there is very little training needed for your sysadmins. If you are trying to operationalize deployment, it makes sense to use the same tools you would expect your sysadmins to use: a simple bash script that can download artifacts from either your snapshots or releases repository on a Nexus instance.
Interacting with Nexus REST from a bash script
Luckily Nexus provides a straightforward REST interface that makes it easy to interact with the system using something like curl. While the full picture of your deployment approach is beyond the scope of this blog post, you may have wondered if anyone had a simple bash script that could be used to download artifacts from Nexus. Here's an example of just such a bash script that uses curl to interact with Nexus REST services to query and download an artifact from a Nexus instance.
The first few lines of this script simply point the script at your Nexus installation. You are supplying the Nexus BASE URL and the paths for the Nexus REST services (Note: uncomment the shopt command if you want debug output).
Lines 11-75: Most of this script is dedicated to command line option parsing. As you can see, we're using getopts to parse an option string and then we're checking to see if groupId, artifactId, and version have been supplied. For convenience, we are also defining some defaults - the packaging defaults to jar in this particular script.
Lines 79-85: If the version supplied ends in SNAPSHOT, this script will download the latest SNAPSHOT version from the snapshots repository. If the version supplied does not end in SNAPSHOT, the artifact will be downloaded from the releases directory.
Lines 87-102: This section crafts the request to the Maven artifact redirect service. We create two arrays one is the GET parameters expected by the REST service, and the other is an array of potential values. We loop through these arrays and test for the presence of a particular option to create the properly request URL.
Line 105: Once we have the URL, call curl. Note that this script sends to artifact to STDOUT.
Sure, you can do all of this in Ruby, Perl, Python, or Java, but you couldn't do it with tools that are going to already be present on all Linux installations. You would also need to train people on whatever scripting language you selected. In this, you use bash to interact with Nexus, you can script your deployment and then hand off responsibility to a sysadmin who doesn't need to understand the finer points of a scripting language.
Notes / Possibilities for Improvement
Here are some directions you could take this script (since this is a Gist at GitHub you can fork the Gist and improve it):
- It would be nice if this script automatically downloaded and verified the SHA1 or MD5 hash for a downloaded artifact. Throwing an error if there is a problem.
- Sending the artifact to STDOUT may not always be the desired behavior. Just like curl provides the option to save output to a file, so should this script.