Tuesday, November 6, 2012

Continuous delivery with Jenkins and Gradle


www.ignite.ee


  To my mind, continuous delivery is a great thing that gives real value. However, it seems that setting up a proper build pipeline to support it is not a trivial task.

  My first attempt to make a build pipeline was based on Maven. I was using FOSS Jenkins instance, provided by CloudBees.

  Pipeline steps that interested me were:
  1. snapshot - runs unit tests and creates build artifact (WAR in my case)
  2. REST integration tests - deploys WAR and tests it's REST interfaces
  3. UI tests - deploys WAR and tests it's UI in different browsers
  4. release - updates versions and puts tags in SCM
  5. ... endless amount of other pipeline tasks
Some other requirements were:
  1. Use same SCM code version for all steps in pipeline
  2. Use only those Jenkins plugins which are available for free on CloudBees
  It was pretty easy to compile all required tasks in Maven life cycle and run them in sequence. However, as soon as I've started configuring jobs in Jenkins, it became clear that Maven life cycle does not match my pipeline. Simple "mvn install" turned into "mvn clean deploy -DskipITs" and "mvn failsafe:integration-test -P selenium". It was especially hard to configure jobs in the middle on the pipeline, because Maven tends to execute all preceding life cycle phases.

  You can find some of my attempts here: https://reference.ci.cloudbees.com/. In the end, I got it working but it did not feel right for sure.

  On June 14th I've visited conference called GeekOut, where Hans Dockter was showing Gradle. At first it seemed pretty much like Maven, but it had some features that looked quite promising to me:
  1. Gradle plugins provide Maven simplicity
  2. At the same time, it's incredibly easy to customize life cycle
  3. Incremental builds
  Here are my attempts to make a pipeline with Gradle: https://reference.ci.cloudbees.com/view/gradle/. Thanks to flexibility of Gradle I was able to fix life cycle according to my needs and incremental builds took care of skipping preceding steps. "mvn failsafe:integration-test -P selenium" becomes "gradle cleanUiTest uiTest". Now it does feel right!

  Some hints:
  1. If you want to start incremental build in one Jenkins job and resume it in other - make sure that absolute path to workspace stays the same. Otherwise, Gradle will start build all over. For example, if first job uses workspace /scratch/jenkins/workspace/1-snapshot-gradle and the second one uses /scratch/jenkins/workspace/2-rest-test-gradle, second job will not resume incremental build.

2 comments:

  1. Hi Aleksandr,

    thanks for the interesting post. Unfortunately the link to the description of the Gradle CD pipeline is broken. Could you fix that?

    Thanks, Thomas

    ReplyDelete
    Replies
    1. Hi, it's online now. It hibernates if nobody uses it.

      Delete