Friday, December 4, 2009

Grail Projects in Hudson, Pt 2.

I just recently concluded a first sprints worth of work using Grails for the first time. We delivered.

While cutting the release, I found one additional gotcha in our CI environment. The grails application.properties file holds several key pieces of information including the version number, grails plugin versions and the last build date. This means the file must be checked into source control, but is also modified locally every build by CI (Hudson, nudge, nudge, wink wink). This caused our build to fail while bumping our project version.

  1. CI will fail a grails+maven project if you change the version number of the project in the application.properties file.
    • Workaround: 1) Have your CI project perform a clean checkout instead of an update for you build. 2) At the end of your build, add a custom hook to delete the locally modified application.properties file.
    • Fix: I think have the build timestamp in this file may be a mistake as Grails grows more mature. As an improvement, it should be removed.

Friday, November 20, 2009

Grail Projects in Hudson

Here is a quick reference for adding a Grails project to Hudson. I'm assuming the webtest plugin is installed becuase there is no reason not to use it. It rocks. Also note that for integration into my existing maven build, I'm using the built-in Grails v1.1.1 maven integration. The project structure was created via the maven archetype:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:generate \
-DarchetypeGroupId=org.grails \
-DarchetypeArtifactId=grails-maven-archetype \
-DarchetypeVersion=1.1 \
-DgroupId=com.black -DartifactId=grails-project

With that, here is what works so far:

General sequence (these are also the steps for keeping a development team in synch):
  1. svn up
  2. grails upgrade --non-interactive
  3. mvn clean install -DnonInteractive=true

Notes:
  • Step 2 above: This upgrades the grails project to include all core grails plugins and also creates some important files under web-app/WEB-INF (applicationContext.xml, ...). We would rather run mvn grails:exec -Dcommand=upgrade -DnonInteractive, however, this fails with an error: Embedded error: java.lang.reflect.InvocationTargetException
    /home/black/dev/branches/parent/grails-project/null/src/war not found.
    Anybody have an idea on this?
  • Step 3 above: This step will upgrade all non-core plugins added/modified/removed since the last checkout. Since grails will ask the "are you sure" question, make sure in CI to add the non-interactive switch as above, which will have the effect of cheerfully answering "Y" to all of grails questions.

Problems you may run into:

  1. As part of a big maven multiproject build, grails may consume enough memory to produce an out of memory error.
    • Fix: Set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=150m


  2. Adding new grails plugins to the build will freeze the CI build due to the "are you sure" prompt. The same will happen when removing a grails plugin.
    • Fix: Add the non-interactive switch to the build (mvn -DnonInteractive=true or grails --non-interactive)


  3. Webtest launches a window during the test run that needs a display, so CI may need to run the webtests headless.
    • Fix: Add non-interactive switch to the build (mvn -DnonInteractive=true or grails --non-interactive)


  4. Webtest starts the jetty server on port 8080 by default which may clash with other services on your CI box using that port.
    • Fix: Use the switch mvn -Dserver.port=8183. Note: The webtest.properties file property wt.config.port seems to be used if the code under test were already hosted on another running server besides the provided jetty.


  5. A maven multiproject build that includes a grails project with webtests will look for /test/webtest/conf/webtest.properties in the wrong directory. That is, it will not look in ${basedir}, but always in the root project where you invoked maven to start with.
    • Workaround: Create a hudson job that only builds the grails war/webtest project. Create a downstream dependency on your main CI hudson job to trigger this one to build.

    • Fix: ?? Anyone have an answer for this one?



I hope this helps. For the few items above that have lingering questions, I would be interested in hearing if you have solved these. Let me know.

Thursday, September 24, 2009

"Shipping is a feature."

Another good variation on Perfect is the Enemy of Very Good:

"A 50%-good solution that people actually have solves more problems and survives longer than a 99% solution that nobody has because it’s in your lab where you’re endlessly polishing the damn thing. Shipping is a feature. A really important feature. Your product must have it."
-- http://www.joelonsoftware.com/items/2009/09/23.html

Wednesday, June 24, 2009

Hudson Gadget For Google Desktop v1.0

For all you developers that rely on Hudson for continuous integration build status, I have released version 1.0 of the Hudson Status Gadget for Google Desktop. The code is part of the Hudson project itself, so it is open source.

More information can be found on its home page.
Release note highlights for version 1.0:
  • In addition to monitoring the multiple main hudson dashboards, any tabbed view can be also be monitored
  • A scrollbar shows for a large number of jobs that would take more space then the gadget allows
  • Views can be collapsed to a single line with all jobs statuses of that view aggregating their status to the single view line
  • A refresh button has been added for manual status refreshes
  • Blinking build statuses are now animated

Enjoy and let me know how it works out for you.

Sunday, November 23, 2008

The Supply Chain of Continuous Integration

When I was first introduced to Continuous Integration, I viewed it as a black box with a well defined interface. It was the same kind throw-it-over-the-wall mentality that some people have with testing: When the code is "done", give it to the testing shop and mark the checkbox complete. It may or may not return with feedback attached.

I got a different perspective of how CI should work, however, while working on a CI team. More than a little of this new perspective is probably due to working in a company that believes in and practices agile development and scrum management. With agile, we are much better at involving testers into day-to-day activities rather than the cold baton hand-off as sprint review time rolls near.

What got me thinking about a CI supply chain concept was the story from The Earth is Flat about how UPS has evolved from a package delivery company to an integral part of many companies day-to-day business operations. They started with a core business of picking up and shipping packages. But it turns out, there are inefficiencies to this bolted on approach. In order for the shipping to be efficient for both UPS and the contracting company, the entire supply chain had to be prepped in advance. This includes both pre and post shipment. The visibility into business processes had to be bidirectional.

I think the same is true with continuous integration. It is based on the old computer adage, GIGO, Garbage In Garbage Out. So a team that writes plenty of code, but no tests. What is the value of CI for them? The feedback is minimal. To get the most value out of an automated build system, there must be some forethought into what kind of quality feedback you want to see, and then what teams can do to define and integrate the right reporting tools into the build.

For example, even after automated tests written and incorporated into the build, you may want to get feedback on some quality measures on your code. In our case, we wanted Checkstyle and PMD reporting on our Java code. We use maven as our build tool, so adding the reporting into our builds was simple. But then the question becomes, what coding standards do we want to compare to? What PMD rulesets represent a sane minimum that teams can deal with and learn from at the same time?

So now, a team dedicated to providing CI services is recommending quality reports to both developers and stakeholders AND helping to define the rules that code should be compared against. My first take on this approach, deviating from a traditional CI definition was a sense of invasiveness. Upon further reflection, I have embraced the blurred lines between teams for several reasons. Firstly, it breaks artificial team boundaries and keeps communication lines open. CI is no longer a black box, it is a visible, value contributing component of system development. Secondly, developers won't (at least consistently across an organization) take the time to inject QA into their processes. A CI team, however, does have the time to take the first steps and get the ball rolling. The conversation is more constructive when you have something in place actually working then just a bunch of talking going on about what could be.

I think a simple diagram emphasizes the point. If "A" is a development team, "B" is a CI team, and "C" represents the stakeholders of the solution being developed, then the shaded areas pinpoint a missed opportunity unless you adopt the supply chain analogy. These are not hard control points, but juicy overlap, waiting to be optimized by as AB and BC working together.

So far, I've talked about the pre-shipment benefit leading into CI. I also now believe the supply chain post-CI is equally important. That is, where does the feedback go and how do you make is so easy, there is no reason not to use it. In our case, this encompassed two audiences with two different needs.

1) Developers. They need the low level test results, test coverage, Checkstyle and PMD reports.

2) Stakeholders (Project Managers, Solution Owners, Scrum Masters). They need to know that the developer teams are using the system. What is the source control commit frequency? How long do CI builds stay broken? How long are the automated builds taking? In short, the interest is around are they getting their monies worth on CI investment and knowing if the teams "get it". It provides them with just enough information to start asking the right questions to the right people.

So the supply chain from CI into management visibility, in our case, ended up being a enterprise level portal aggregating project CI metrics together into an at-a-glance view of how well their agile teams are performing. This could be stop light charts on current CI conditions or simple graphs of build times or number of tests as plotted over the last 30 days.

As always seem to be the case, the benefit of this proposed supply chain approach is inceased communication.

Again, this initially seemed to stray from traditional core CI functionality, but in reality it is simply providing the visibility into the process that scrum promises. Warts and all.

Wednesday, June 4, 2008

Hudson Status Google Gadget on Linux

Google has just announced gadget support for the linux version of Google Desktop. This is exciting news for me as that means the Hudson Status gadget is now cross-platform. For all you developers out there that rely on Hudson, this means you don't have to visit your Hudson site or check your email or your feed reader to get the latest job statuses.

The dots are right there on your desktop!

For you existing users out there, make sure you upgrade to the newest gadget version, which has some important bug fixes. More information about the latest release, v0.9.5, can be found on the Hudson wiki.

Monday, April 21, 2008

Maven SNAPSHOT Traceability

So your scrum team is creating non-unique SNAPSHOT versioned artifacts throughout your sprint. How do trace that SNAPSHOT version back to a baseline that is of any QA relevance (build number, subversion revision, datetime stamp)?


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<configuration>
<tasks>
<tstamp>
<format property="now" pattern="MM/dd/yyyy hh:mm" unit="hour" />
</tstamp>
<property name="build.version" value="${version} (private-${now}-${user.name})" />
<property name="hudson.build" value="hudson-${BUILD_NUMBER}, subversion-${SVN_REVISION}" />

<!-- put the version file -->
<echo message="The build id is: ${build.version}" />
<mkdir dir="target/${project.build.finalName}/" />
<echo file="target/${project.build.finalName}/version.properties">version=${build.version} ${hudson.build}
</echo>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

...

<profiles>
<profile>
<id>release</id>
<properties>
<!-- for releases, just use the POM version. -->
<build.version>${version}</build.version>
<hudson.build></hudson.build>
</properties>
</profile>
</profiles>


This little piece of magic creates a version.properties file that contains some valuable information.

version=1.1.0-SNAPSHOT (private-04/21/2008 02:23-jblack), hudson-453, subversion-1124

When you do a formal release, specify the -Prelease profile to have this file simply hold the pom version.

For the plugin configuration above, this file gets put in a war project root webapp directory, suitable for immediate viewing from your browser!

The mad props for this idea go to Kohsuke. :)