Tuesday, January 31, 2017

Grails plugins on Hudson

Grails plugins on Hudson


Yesterday I spent some time setting up Hudson continuous integration build for my various Grails plugins. It was pretty straightforward but Ive been asked to document the steps involved.

Each plugin has one or more test applications under test/projects each of which has grails.plugin.location.whatever = "../../.." in BuildConfig.groovy. So each plugin CI build needs to run not only the plugins own unit tests but any integration and/or functional tests included in the test apps as well.

Hudson plugins

I installed the essential plugins I would need:
  • The Grails plugin makes building Grails projects much easier and allows you to build against multiple versions of Grails.
  • The Git plugin enables Hudson to pull from a Git repository such as GitHub.
  • The GitHub plugin adds links to the GitHub project in the Hudson build.
  • The Chuck Norris plugin encourages you to keep your tests from failing.

Configuring Grails

Under Manage Hudson -> Configure System there is a Grails Builder section where I entered the name and path of the various versions of Grails installed on the build box.

Connecting to GitHub

In the project configuration:
  • I pasted the GitHub project URL in the Github project field (shown if you have the GitHub plugin installed).
  • Under Source Code Management I selected Git then pasted the read-only repository URL into the URL of repository field.
  • I entered master in the Branch Specifier field as Ive seen Hudson do odd things picking up changes from other branches before. I dont really need this behaviour and havent had time to investigate it further yet.
  • I ticked Poll SCM under Build Triggers then set a cron expression of */5 * * * * so Hudson will poll GitHub every 5 minutes.

Grails build steps

  • Select Build with Grails from the Add build step drop down, then:
    • Select the Grails Installation you want to use.
    • Enter the Targets to run. These are the Grails commands that Hudson will execute. For example, I entered "test-app unit: -clean --non-interactive" package-plugin for the to run unit tests then package the plugin. The quotes allow arguments to be passed to individual targets so Im telling the test-app phase to build clean and run non-interactively (i.e. Grails wont ask about things like installing or uninstalling plugins).
    • The other fields can be left blank for now.
  • Add further Grails build steps for test applications. The only difference in configuring these is that the targets will likely be different and Project Base Directory needs to be set to the relative path where the test apps lives, e.g. test/projects/content-caching

Isolating each build

One thing I found is that its probably a good idea to specify separate working directory for each build. I found that simultaneous builds would stomp over each others compiled classes otherwise. This is particularly an issue for me where I have a build for the Selenium RC plugin whilst one of the test apps for the Springcache plugin uses the latest Selenium RC release to run tests.

Hudson provides various environment variables so I just set grails.work.dir to /tmp/.grails/${JOB_NAME} in every case.

The other consideration is the port that Grails applications will use. If you are running any kind of functional tests the Grails application will start and it each Hudson job needs to use a separate server port or simultaneous jobs will experience port contention. The server port is also configured in the Grails build step. Ive just assigned a different one to each job but I couldnt think of a particularly clever way to automate the port assignment.

Test reports

Under Post-build Actions I ticked Publish JUnit test result report then entered a comma-separated set of paths to the XML reports generated by each build step. For example, the Springcache plugin has the following reports configured:
target/test-reports/*.xml,test/projects/springcache-test/target/test-reports/*.xml,test/projects/content-caching/target/test-reports/*.xml

Thats picking up the root plugins unit test reports and the reports generated by the springcache-test and content-caching test applications. Hudson does a good job of merging these together into a unified test report.

Running tests that need a browser

Some of my tests use Selenium RC which drives a real browser. Given that Hudson is running on a headless box I had to get the display exported to a box with an X Windows environment.

Still to do

Right now all the plugins are building against Grails 1.2.1 only so the next task is to set up parallel builds using Grails 1.3-RC1. Ideally I would like to use Hudsons multi-configuration project capability to do that but I havent had a chance to look into it yet. Id also like to use Gradle to build the various project with one build step but Id lose the convenience in switching Grails versions that the Hudson Grails plugin gives me.

Available link for download