Balaji Vajjala's Blog

A DevOps Blog from Trenches

JBoss, Selenium, Maven, Hudson, M2 Extra Steps & Files Found Trigger plugins playing well together

JBoss, Selenium, Maven, Hudson, M2 Extra Steps & Files Found Trigger plugins – how do all these work together in a continuous build + Integration test life-cycle ?

The Story – The Use Case:

We have two projects with two war artifacts which need to be deployed to a JBoss Application Server, whilst both webapps share a common base configuration, although the release life-cycle of each war have no correlation to the other.

In production both application servers are running & serving one another thus, Integration test should cover both JBoss instances & test their web services.

We are using selenium tests for both webapps and they need to run straight after a continuous build of each of the servers mentioned above. That said a change in project A or in project B should trigger the Integration tests job, whilst if either project A or project B are running the integration test plugin shouldn’t run (at least until both projects / one of them is complete).

The “work around” – forcing the “native Hudson” configuration (which we didn’t go with naturally):

Create a Job which builds Project A and Project B then as a downstream job will run ITest job. The problems with this method was –

1. Project A and Project B do not have the same release life-cycle therefore, I would be forced to have a separate build process for their release / chain the release of these webapps.

2. I would be building one of the projects for nothing (~ 10 minuets penalty) – if nothing changed in Project A / B why build the other for

nothing?

As a matter fo fact Project A doesn’t change much, our consideration was – Project A will change once in two weeks whilst Project B will change on a daily basis – that is why we needed a smarter solution:

A more Creative Solution:

Step 1 – configure m2 “extra steps” post-build action for Project A & B:

Project A – build a.war, and as a post build task it would copy the a.war into a shared location. For example purposes lets call it /sharedfolder, in Project B we would do the same.

Upon a successful build of Project A and Project B we will result with /sharedfolder with a & b war files in it. Let me point out these are two standard maven jobs which have the mvn clean install (or deploy) life-cycles and with M2 extra steps plugin you can run a shell / bash which will just copy a & b wars to the /sharedfolder.

Please note: if running in distributed Hudson make /sharedfolder a location both the servers building a, b & ITest Jobs can write to (NFS, SMB mount if you must).

Step 2 – Add Files Found Trigger & M2 Extra steps:

1. Manage Hudson >> Manage plugins.

2. Install the missing plugins (will be under the available tab if not installed already)

3. Reload / Restart Hudson

_Step 3 – create / configure ITest Job:
_

Create a freestyle (or maven depends on selenium configuration) job named Itest which has a Files Found Trigger (SCM should be configured to checkout the selenium test – may it be Maven / Ant or whatever executes it for you :), in the Files found configuration have /sharedfolder and a.war, b.war (note the “,” delimiter) watched for changes and configure the trigger to run every 5 / 10 minuets according to your preference – so the Files Found Trigger will test /sharedfolder every $n minuets for changes in the filesystem and trigger a build accordingly.

I thought I was finished but The only problem was if either Project A or Project B was running I didn’t want ITest to run until the Upstream project (either Project a or b completes) and the built in upstream / downstream doesn’t support “wait for either Project A or Project B to complete”.

So:

Step 4 – Add m2 “extra steps” pre-build action for Project A & B:

I went back to Project A and Project B configuration and added a pre build snippet which removed /sharedfolder/a.war for Project A and /sharedfolder/b.war for Project B.
**

Now I have achieved – **The Final result**:

1. No parallel building of Project A,B or ITest

2. ITest will be triggered wither if a.war or b.war will change (that is where the Files Found Trigger comes in)

3. I can still keep Project A & Project B in their regular continuous life-cycle.

Alsonote that: The FS-SCM (File System SCM) plugin (which seemed a good candidate at first) – will not work for you in this case, for on each change the Itest project will run. So even if Project A removed a.war this will be treated as a SCM change in the FS, and will trigger a new ITest build.

Hope you find this tip helpful.