Tuesday, September 30, 2014

My Gradle Wildfly Plugin, 'Continued'

I have been toying around with a custom gradle plugin to perform some basic administrative activities against a local wildfly application server.   This project is more of a learning experience for me, but it could be useful to others.   I have the basic stuff working and it is free for the taking at this github repo.

Recently I decided to add more stuff to it and make it a bit more general purpose and configurable.   While doing some of this work; I also wanted to practice some 'contentious delivery' stuff.

IRL, I am involved in a project that "does CD".   In a nutshell, the project's application CD pipeline does:
  1. merged pull-requests trigger a jenkins pipeline
  2. gradle builds and runs unit and integration tests 
  3. gradle makes an RPM that is pushed to nexus
  4. an infrastructure pipeline merges into this application pipeline
  5. cucumber does acceptance tests over the RPM artifact
  6. puppet automates the build out of whole new application stacks for testing and then to production.  
So I wanted to approximate some of this stuff with my toy plugin.  This is what I did.

The code for this post is github at https://github.com/fwelland/gradle-wildfly-plugin.

spock

So after I got something working and I decided to evolve it some, I also thought it would be good to practice keeping up a good set of tests for the plugin.  Since SPOCK has been on my short list of things to checkout and the inspiration for this plugin, gradle-cargo-plugin , uses it; I decide to take the plunge.

In brief, spock is a groovy based testing framework.   It can act like JUNIT tests and it also is a bit BDD like.  In this post, I am focusing on the CD stuff so I will not go into details of spock.  Go read about it here and check out the little bits of spock I have in this plugin.

bintray

Here is the old way 'client' gradle projects were using this plugin.
buildscript {
    repositories {
        flatDir {
            dirs '../gradle-wildfly-plugin/build/libs'
        }
    }    
    dependencies {
        classpath name: 'gradle-wildfly-plugin'
    }
}
But what I really wanted was something like this:
buildscript {
    repositories {
        maven {
            url 'http://some.place.com/SomeRepo'
        }
    }    
    dependencies {
        classpath 'org.fhw:gradle-wildfly-plugin:0.2'
    }
}
I turned to BinTray as a place to set up my own maven like repo.   After some playing around with BinTray and the help of the bintry/gradle plugin, I was able to land on this bit of gradle to publish builds:
bintray {
    user = uzer
    key = creds

    filesSpec { 
        from 'build/libs'
        into "org/fhw/gradle-wildfly-plugin/$version"
        include '*.jar'
    }
    
    dryRun = false 
    publish = true 
    pkg {
        repo = 'FredsStuff'
        name = 'gradle-wildfly-plugin'
        desc = 'simple gradle plugin for basic jboss manipulation on a workstation!'
        websiteUrl = 'http://stupidfredtricks.blogspot.com/2014/08/a-simple-gradle-plugin-for-wildfly-and.html'
        vcsUrl = 'https://github.com/fwelland/gradle-wildfly-plugin.git'
        licenses = ['Apache-2.0']
        labels = ['gradle', 'wildfly', 'java', 'jboss']             
    }
}

travis-ci

travis-ci is a CD service for github projects (and some other things too).  Here are the basics steps to 'do' travis:

  1. make a travis account  and log in
  2. in travis-ci turn on CI for the github repo 
  3. put a yaml file in root of github repo
  4. push code to github repo
Most of this is document in more detail here.     What is most interesting is my .travis.yml.

language: groovy
jdk:
- oraclejdk7 
after_success: 
- ./gradlew  bintrayUpload -PbtIdentity="${btIdentity}" -PbtIDCreds="${btIDCreds}"
env:
  global:
  - secure: e1ChIoTY48SBhN.......
  - secure: Uxp73loI5NIIhB.......

Here is a quick break down of what's going on:
  1. its a groovy project
  2. its using oracle jdk 7
  3. it invokes the bintrayUpload task after a successful build
  4. it has some encrypted environment variables
So to make that encrypted environment variable stuff you'll need to have ruby installed and use gem to install the travis cli.    Here is a quick example:

travis encrypt btIDCreds=gook-to-encrypt-here --add

Here is more documentation on this process.    Notice the '--add' switch will hammer this into your .travis.yml for you.  Why encrypt?   Well, the .travis.yml sits in the root of my repo which is public.   

Finally the after_success block, re-runs gradle executing the bintrayUpload task.    Notice, that I had to add -P arguments to gradle command-line to 'resubmit' build properties from the .travis.yml environment.

One other little piece of magic

So when running and/or testing the gradle.build locally, the natural way to handle and provide user specific gradle build parameters is NV pairs in $HOME/.gradle/gradle.properties.   In travis, there really isn't $HOME/gradle/gradle.properties; so these values need to be provided in another way.   As implied above, travis-ci will provide environment to the gradle.build.   So one can either always use environment variables or provide simple groovy expression to see if there is a gradle properties value or fall back on the environment variables
def uzer = hasProperty('btIdentity') ? btIdentity : System.getenv('btIdentity')
def creds = hasProperty('btIDCreds') ? btIDCreds : System.getenv('btIDCreds')

No comments:

Post a Comment