Third of a four-part series on creating a continuous deployment pipeline using Liberty and open source software: Setting up a continuous integration server.

So far, we’ve created a development environment for the AcmeAir application. This development environment allows us to automatically publish changes to our local development server, and uses Maven to build and run the tests locally.

In the next two articles, we’re going to create our automated pipeline. When finished, it will look a bit like this:

Machine Setup

After committing to GitHub, a Jenkins instance running on a Virtual Machine (VM) will build and test the changes before deploying to another VM running AcmeAir on Liberty.

This time, we’re going to use Chef to set up a Jenkins continuous integration server. This will poll the Git repository every two minutes and automatically start a build if any changes are detected. The build will checkout the application code from Git, compile it, execute the tests, and publish the build artifacts.

Before we begin, we need to install a few things:

If you aren’t familiar with Chef, Vagrant, or Jenkins, you may want to read up about about what they do.

Create a cookbook to install and configure Jenkins

Chef configures machines using cookbooks. We’re going to create our own cookbook, which will provision a machine by installing and configuring Jenkins, and everything else we need to run a build.

On Windows, open your command prompt as an Administrator.

  1. Create a directory named cookbooks.
  2. Inside that directory, create a cookbook template at <cookbooks>/acmeair_ci by running:
    $ berks cookbook acmeair_ci
  3. Since our cookbook will be relying on some other cookbooks to do the heavy lifting for us, we need to tell Chef about these dependencies. To do this, simply add to the bottom of <cookbooks>/acmeair_ci/metadata.rb:
    depends 'apt'
    depends 'jenkins'
    depends 'git'
    depends 'maven'
    depends 'wlp'
  4. Next, we need to modify the default recipe in our cookbook. Open <cookbooks>/acmeair_ci/recipes/default.rb, and add the following to the bottom of the file:
    include_recipe 'apt'
    include_recipe 'git'
    include_recipe 'wlp'
    include_recipe 'maven'
    include_recipe 'jenkins::master'
    jenkins_plugin 'scm-api'
    jenkins_plugin 'git-client'
    jenkins_plugin 'git'
    jenkins_plugin 'ssh'
  5. Save the files, then commit the changes by running:
    $ git add .
    $ git commit -m "Configure dependencies"
  6. If you’re on Windows, run:
    $ set SSL_CERT_FILE=C:opscodechefdkembeddedsslcertscacert.pem
  7. Then download the cookbooks we need by running:
    $ berks install
  8. We’ve now created our cookbook and downloaded all the dependencies. The last thing we need to do is download the following jar files from IBM WASdev and save them in <cookbooks>/acmeair_ci/:
    • Liberty Profile Runtime
    • Liberty Profile Extended Content

Create the Jenkins VM

Let’s now create a virtual machine to run the cookbook. To make this as smooth as possible, we’re going to use a Vagrant plugin to integrate with Berkshelf (part of ChefDK).

  1. Install this by running (omit the plugin-version parameter on Windows):
    $ vagrant plugin install vagrant-berkshelf --plugin-version 2.0.1
  2. Be patient. It’ll get there.

  3. Once that’s done, we need another plugin to integrate with Chef:
    $ vagrant plugin install vagrant-omnibus
  4. We also need to make some changes to the Vagrantfile, Vagrant’s configuration file. The config.vm.provision block should look as below:
        config.vm.provision :chef_solo do |chef|
          chef.json = {
            "wlp" => {
              "archive" => {
                "accept_license" => "true",
                "base_url" => "file:///vagrant/"
          chef.run_list = [

    Here we’re just setting some attributes for the wlp cookbook to accept the license agreement and set the location of the Liberty jar file.

  5. Before we provision the VM, we need to set up VirtualBox for our network:
    $ VBoxManage dhcpserver remove --netname HostInterfaceNetworking-vboxnet0
  6. Now, bring up the VM by running the following in <cookbooks>/acmeair_ci:
    $ vagrant up
  7. That will take a good few minutes the first time as it downloads the VM image.

  8. Once it’s finished, we need to find out the IP of the VM. Do this by running:
    $ vagrant ssh -c ifconfig
  9. The output should be something like:
    eth1      Link encap:Ethernet  HWaddr 08:00:27:96:c6:e2  
              inet addr:  Bcast:  Mask:
  10. We want the IP address with the form: 172.28.128.x, in this case Make a note of it, from here onwards I’ll be referring to this as Jenkins IP.

  11. Open up your favourite web browser and go to <Jenkins IP>:8080. You should see Jenkins running.


Create a build job for AcmeAir

Next, we’re going to use Jenkins to create and run a build job for the AcmeAir application. The job will check out the application code from GitHub, compile the application, execute the tests, and publish the build artifacts. Jenkins will poll the GitHub repository every two minutes and automatically start a build if any changes are detected.

Inside Jenkins:

  1. Click on New item.
  2. Type in AcmeAir tests as the item name.
  3. Select Build a free-style software project.
  4. Click OK.

First thing we need to do is tell Jenkins where to get the AcmeAir source from. You can find the clone URL on your GitHub repository homepage:

Clone github

Note: If you have two-factor authentication enabled in your GitHub account, you should use SSH to clone and authenticate, rather than HTTPS.

  1. Under Source Code Management choose Git.
  2. In the Repository URL field, enter<your GitHub ID>/sample.acmeair.git. You can find this on your GitHub repository’s homepage.
  3. Under “Credentials”, click Add. Enter your GitHub username and password in the appropriate fields.
  4. Click Add.
  5. Select your new credentials from the list.
  6. For Branches to build, replace master with lab.

Next, set up the build trigger to poll the Git repository every two minutes:

  1. Scroll down until you find Build Triggers.
  2. Select Poll SCM.
  3. Under Schedule enter H/2 * * * *.

Now we need to set up our build:

  1. Under Build click on Add build step button and choose Invoke top-level Maven targets.
  2. Under Goals type in clean install.
  3. Click on Advanced.
  4. Under Properties enter wlpInstallDir=/opt/was/liberty/wlp

Finally, add a post-build action to save the built artifacts, and also allow us to see the JUnit test results:

  1. Under Post-build Actions click on Add post-build action button and choose Archive the artifacts.
  2. Under Files to archive enter acmeair-webapp/target/*war, acmeair-itests/src/main/resources/servers/acmeair/*, acmeair-itests/target/usr/shared/**.
    Click on Add post-build action button again and choose Publish JUnit test result report
  3. Under Test report XMLs enter acmeair-itests/target/failsafe-reports/*.xml
  4. Click Save.

After a minute or two a build should automatically start. It will appear in the Build History table. If not, click on the Build Now link.

Examine the build job results

In the AcmeAir tests project, click on the build under Build History table.

Once the build completes and is successful you should see the screen below. The acmeair-webapp-1.0-SNAPSHOT.war file should appear under Build Artefacts and Test Result should indicate no failures:

Jenkins success

If the build is still running you can click on Console Output to see the live output of the build job.

Click on Test Result to examine the results of the integration tests.

Triggering a build on commit

We configured Jenkins to poll the Git repository for any changes every two minutes. If any changes are detected, Jenkins will start a new build job. Let’s test this by committing and pushing the change we made in the Update AcmeAir step to trigger a new build.

In Eclipse:

  1. Right click on the acmeair project and select Team > Commit….
  2. Type in Fix welcome page refresh on logout as the commit message.
  3. Under Files ensure only the acmeair-webapp/src/main/webapp/js/acmeair-common.js file is selected.
  4. Click Commit and Push.
  5. On the Push Results window press OK.
  6. Switch to your web browser and go to <Jenkins IP>:8080/job/AcmeAir tests/.

Within two minutes a new build should appear under the Build History table. Click on the new build and verify that the right commit message appears under Changes.

That’s it for today. We’ve implemented continuous integration to automatically build and test our application whenever we commit code. Next time we’ll be finishing off our continuous deployment pipeline by automatically deploying AcmeAir after a successful build. See you then!

4 comments on"DevOps with Liberty, Maven, and Chef (Part 3)"

  1. The config.vm.provision doesnt work as it give a Run List error where it is not able to identify the default cookbook file to load all the dependency.

  2. AmirBarkal July 13, 2016

    I thinks there’s something broken with the failsafe reports. I cannot get the maven goal ‘clean install’ to create acmeair-itests/target/failsafe-reports/failsafe-summary.xml.

    Please see the output of ‘mvn install’ command here:

  3. Jeremy Hughes July 07, 2016

    Hi, you should just be able to add that snippet to the default Vagrantfile you have.

  4. Hi and thanks for a great article!

    In step 4, where do I get the complete Vagrantfile?

Join The Discussion

Your email address will not be published. Required fields are marked *