Tuesday, April 7, 2009

Groovy CruiseControl Helper - part 1 RSS and Regex

I've been wasting entirely too much time deploying builds lately as our CruiseControl instance produces upwards of 35 builds, of which I only care about 4.   Not to mention that downloading each ear file is at least 3 page 'clicks'.   Ignoring for now that CruiseControl would happily deploy my ears for me (team's CruiseControl guru is overbooked right now),  I've started building a Groovy utility to leverage the RSS feeds produced by CruiseControl in order to run an automatic pull of the latest builds for my 4 target ears.

I started tinkering with examples found in "Groovy In Action" and in Netbeans, but moved over to Eclipse 3.4.1 when things were ready to implement as that's the standard at work.   Netbeans was more 'Groovyish' and very easy to start scripting with, whereas Eclipse is more 'Javaish' expecting you to produce classes rather than 'scripts'

In the end I built one Class  to handle  the RSS and information parsing  and one Script to act as my main and run my new process.

My Class simply opens an RSS feed, pulls data from the top item and parses out the stuff I need to find my assets for deployment.

/*
   For a specific RSS feed and project.   Get the key data for the latest build
*/
public class GetRss {
   private myBase;
   private myProject;
   private buildNo;
   private assetNo;

   GetRss (String base,  String project) {
     myBase = base;
     myProject = project;
  }

   void doRss()
   {
       //open the Rss Feed URL,  parse date into XML Document
       def items = new XmlParser().parse(myBase + myProject).channel[0].item
       //GPath notation to get to elements of interest
       // title tells me if this build passed or failed
       println items[0].title.text()
       //The link is to build HTML - I want only some of this info
       parseLink( items[0].link.text())
    }
    
/*
   parseLink uses regular expressions to pull out the two items I need from the link
   Build No is what I will use to identify the build to QA  ##.##.##.##  
   Asset No is what CruiseControl uses to uniquely identify build results - 14 digit number
*/
      void parseLink(String link)
     {
            //Link contains build #  - what the build will be know by in the real world
            // build number is pattern of 4 sets of digits separated by .
            def buildMatcher = ( link =~ /-\d+[.]\d+[.]\d+[.]\d+/ )
            buildNo = matcher[0]
            //link also contains CruiseControl build ID - 14 digit number
            def matcher = ( link =~ /\d{14}/ )
            assetNo = matcher[0]

      }

Part 1 - merely generates URLs for where each ear file is stored by the CruiseControl process.   So instead of many page clicks to download.  I can run the following script and get 4 URLs ready to download the assets from.   Stay tuned for Part2 where I will use AntBuilder and Groovy to automatically FTP these assets to where I need to stage them...

//The common paths set by cruisecontrol
def cruiseServer = 'http://mybuild.server.com:8081'
def allRSS = "$cruiseServer/cruisecontrol/rss/"
def allAsset = "$cruiseServer/crusiecontrol/artifacts"

//Read RSS for Project1 and get key data
GetRss uiservices = new GetRss( allRss, "Project1-BuildWar")
uiservices.doRss()

//Print the line with build No and URL to deployment asset
println " $uiservices.buildNo $allAsset$uiservices.myProject/$uiservices.assetNo/project1.war"

//... Repeated above for each additional project
The script outputs two lines, first the item title with time of build and status.  Then a second line with the build No and a link that I can cut and paste into browser to initiate the download of the deployment asset.

Example output for first project

Tue Apr 07 20:41:47 EDT 2009, passed   
-10.12.1.191  http://mybuild.server.com:8081/cruisecontrol/artifacts/Project1-BuildWar/20090403180111.project1.war


As mentioned, in part 2 I will develop the code to directly download the build assets using the URLs generated in part 1.