Continuous Integration with Hudson
06 Oct 2010
After hours spent painfully integrating existing projects in our automatic build automation process at work, it is a good time to spend a couple of words on the topic of continuous integration. A good time for me to help keeping my sanity in this jungle of project dependencies that the compiler is resolving without any issues on the original developer’s machine
, but fails miserably on a neutral environment, yet at the same time an opportunity to revisit the good old principles of continuous integration.
What’s continuous integration, anyway?
In software engineering, continuous integration (CI) implements continuous processes of applying quality control - small pieces of effort, applied frequently. Continuous integration aims to improve the quality of software, and to reduce the time taken to deliver it, by replacing the traditional practice of applying quality control after completing all development.
The concept of continuous integration has its roots in the Extreme Programming
community and is based on several practices
describing the key objectives to strive for in order to achieve continuous integration:
- Maintain a single source repository
- Automate the build
- Make your build self-testing
- Everyone commits to mainline every day
- Every commit should build the mainline on an integration machine
- Keep the build fast
- Test in a clone of the production environment
- Make it easy for anyone to get the latest executable
- Everyone can see what’s happening
- Automate deployment
While most of them are self explanatory, lots of different tools are available nowadays to help a team implement these practices. Quite obviously, you won’t find a tool that magically materializes automated tests out of thin air for your existing code base: however, one can come a long way in just a matter of minutes, having a build automation software set up in just a couple of clicks.
I will tell you how we did that for our .NET projects using Hudson
Meet Hudson the butler
Hudson is an open-source continuous integration server that can be set up in no time. It
can be easily tested thanks to Java Web Start at the following address: https://hudson.dev.java.net/hudson.jnlp
Once the Java Web Start application has launched, point your browser to http://localhost:8080
and you will be promptly presented with Hudson’s dashboard.
That’s it! We can already start configuring our first job: as an example, we are going to build Prism
. As noted in the source code page, Prism’s SVN URL for the latest release is https://prism.svn.codeplex.com/svn/V4
we will just write it down for the moment.
Let’s click on New Job and select Build a free-style software project
from the next page. Don’t forget to set a name for the project before clicking ok, I just named it (drum roll…) Prism. We are now welcomed by the job configuration page! We are going to focus on the Source Code Management section: as a start, we want to check out the project from the SVN repository. In order to do so, click on Subversion and enter the repository URL that we previously found:
At this point, we can Save our configuration and click on Build Now in the project’s page. Notice the Workspace item in the menu and on the dashboard of the project: there you will see the whole project structure once Prism has finished downloading.
While Prism is downloading you can actually have a look at Prism’s website
if you don’t know what you’re downloading.
Prism (formerly known as Composite Application Guidance for WPF and Silverlight) provides guidance and a re-usable code library for building modular, flexible WPF and Silverlight applications.
When the download is complete, we can go on with the project configuration. If we look under the Build section of the configuration page and try to add a build step clicking on the relative button, we find a couple of options: since this is a .NET project and we have no batch file set up to build it for us, we have to use MSBuild, that is not supported out of the box. But fear not! There’s a plugin for that. It is sufficient to go back to Hudson’s dashboard, to click on Manage Hudson and finally Manage Plugins. From here you can easily install the MSBuild plugin and restart Hudson. One thing is left to do: set the local MSBuild path, so that Hudson can find it.
Under Manage Hudson –> Configure System you will find a section named MSBuild Builder
where you can add the path to your local MSBuild.exe, for instance C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe.
We’re finally ready to build! We’re going to add a build step in the Prism project configuration page, choose our local MSBuild version we just configured and point it to the solution to build.
Just a word of caution: if you are using an express edition of visual studio you’re not going to be able to compile the MSTest projects inside the solution. In this case, just remove these projects from the solution.
Once the configuration has been saved you can again click on Build Now and Hudson will try to build our Prism solution. In case the build failed, you’ll notice that your last build in the Build History
area has a red icon instead of a blue one. What I suggest you to do is to go to that build’s page and click on Console Output which will show you exactly what went wrong.
That’s fine, but where’s the “continuous” part of it?
We have laid the foundations of our continuous integration process. You probably already noticed that the configuration page contains lots of different settings, for example the Build Triggers
one. Here you can specify when the build should be started. Every night at 4 AM? Every hour but only if changes in the repository were detected? You name it.
How are you supposed to notice if the build breaks? For starters, there’s a built in support for email notifications: that means you can send an email to the developers who broke the build, so that they can notice right away when something is not right. Alternatively you could notify your Nabaztag
or publish the results to a Google Calendar or whatever.
The possibilities are almost endless, thanks to Hudson’s extensibility. The list of plugins
is indeed impressive: you can keep track of your unit test results having them published on your project’s page as a graph, you can track the TODOs in your source code, publish your project artifacts so that they are ready for release and much more.
All you have to do is configure everything once: it will take some time, especially for legacy projects needing some dependency cleanup, nevertheless it is a pain you have to suffer just one time. And this is of course only the tip of the iceberg; from here on, the roads of continuous integration are open to you.