Getting Started With CI Using Hudson For Your .NET Projects
In this post, I will explore installing and configuring Hudson as a continuous integration server for .NET projects. Why Hudson? This is good question. I know other CI servers exist, however, Hudson happens to already be an accepted solution at work. Hudson is a web application that allows you to monitor your build process. Hudson is extendable via plug-ins.
For more information about Hudson visit their website.
Installing Hudson
Hudson is a Java web application that is packaged and distributed in a ‘war’ file. This allows Hudson to be installed and running rather quickly. The only pre-requisite is that you have Java installed. Here are the links to the files:
- Java
- Hudson
Once the Hudson war file has been downloaded, you can finish the install and start Hudson by doing the following: open up a console window, navigate to the folder containing the ‘hudson.war’ file and issuing the following command:
java -DHUDSON_HOME=c:Hudson -jar hudson.war
For the purposes of this tutorial, I am unpacking the Hudson war file to the ‘c:Hudson’ folder. When configuring Hudson keep in mind that it will need disk space to pull code from source control, perform builds, and maintain a workspace. The folder selected should have the capacity required and some thought should be put into your backup strategy.
Now you should see something like the following in your console window:
Hudson is now running and can be accessed via your web browser at http://localhost:8080/
Hudson is “internet aware” and uses the web to fetch plug-ins and updates. Here is an update:
You probably don’t want to run Hudson via the command line in your production environment. To install Hudson as a Windows service use the “Install as Windows Service” option on the “Manage Hudson” page and follow the instructions.
Now you should have Hudson listed as a Service in your service panel.
Configuring Hudson
Configuration of Hudson is done using the “Manage Plugins” and “Configure System” options on the Manage Hudson page.
First visit the “Manage Plugins” option and click on the “Available” tab to display a list of plug-ins that can be installed. Again, Hudson is “internet aware” and will fetch these from the interwebs so a network connection is required. There are an ever growing number of plug-ins as the Hudson eco-system continues to evolve. Explore the list, and search the internet for possible extensions. I will focus on plug-ins to get .NET projects into the Hudson CI environment.
Select the following Hudson plug-ins and click ‘Install’:
- MSBuild Plugin – This plugin allows you to use MDBuild to build .NET projects.
- MSTest Plugin – This plugin converts MSTest TRX file metadata into a format that it can be integrated into the Hudson’s JUnit features. This will make the test reports available as build output.
I am using Subversion for source control. Hudson has built in support for Subversion. Other source control libraries may require a plugin to be selected to access your code.
These are the bare minimum to get your .NET projects built and automated tests run using Hudson. After the install, be sure to restart your Hudson service.
Now we need to configure the MSBuild plugin. Select the “Configure System” option and look for the “MSBuild Builder” section. Configure it to look like the following and click the ‘Save’ button (not shown…at the bottom of the page):
Notice that you can have multiple MSBuild configurations. This might be handy for building projects using the different versions of the .NET Framework.
Add A Build Job
Build jobs are added via the “New Job” option on the Hudson main page. Select a name and the “Build a free-style software project” option as shown below. Then click “OK”.
Now a ‘job’ will appear in the main Hudson page.
To manage the new project, click the link for the project you just created. You will get a page similar to the following:
Click the ‘Configure’ link in the list on the left. First select the “Discard Old Builds” option and configure the policy for limiting disk consumption.
Then configure your “Source Code Management” options. I am using Subversion so my configuration looks like the following:
Notice the period in the “Local module directory (optional)” field. That will force Hudson to check out the project directly into the workspace rather than into a subdirectory.
To setup the build select the “Add a Visual Studio project of solution using MSBuild” option from the “Add build step” drop down list.
After selecting the “MS Build Version” that we configured before and adding other configuration information, we have something like:
This will get the solution built. Now we want Hudson to execute the unit tests for the project. We can add a “Windows batch command” to call MSTest. Previously, I posted on using MSTest to run your .NET tests via a command line. After we add this batch command you will have something like the following:
Finally, select the “Publish MSTest test result report” from the “Post Build Actions” section and configure as follows:
This will take the ‘trx’ test results metadata file (XML), transform it into HTML and make it available as part of the build output.
Click “Save” at the bottom and the project should be ready to build manually. I found that I need to restart Hudson for the configuration to take effect.
Kick Off A Manual Build
On the main Hudson page you will see a list of all the jobs. On the right-hand side there is a button that allows you to schedule a job. Clicking that button will start the build process.
Hudson will show you a progress bar for your build…
And finally make available the build results:
This build happened to fail. To determine the cause of the failure take a look at the “Console Output” using the link on the left hand side.
In my case I see the following.
I include this error in this guide because I had the hardest time trying to fix this issue. I finally stumbled upon a post that helped. So after removing PLATFORM from my environment variables and restarting Windows the build results look like the following:
The job failed again, because 3 tests failed. This is exactly what we want. If the source code doesn’t build, the job fails and if any test doesn’t pass the job fails. Hudson provides a wealth of information. The “Console Output” window shows the commands that were issued by Hudson and the results. So I see the Hudson checking out my code from subversion….
…you see Hudson calling MSBuild to build the solution…
…you see the build succeeded and Hudson calling MSTest to start the tests…
…finally you can see the results of the tests.
As indicated above I have 3 tests that failed and the job fails as a result.
On the build status page, there is also a link to a “Test Result” report that provides a list of failed tests and links to more details.
From here you can dig right down to the stack trace information for the failed tests.
Continuous Integration
To kick off a build we can also navigate to the following URL:
http://YOURHOST/job/PROJECTNAME/build
where YOURHOST is your server / port and PROJECTNAME is the project name. You can get these parameters by looking at the URL in Hudson when your project is selected.
So in my instance I can trigger a build for this project by requesting the following URL:
http://hppav1:8080/job/Cron%20Project/build
This knowledge is key to having the source control system trigger Hudson to build a project.
Having Hudson perform builds based upon changes in the source code, requires that we install a post commit hook into the source control repository (Subversion) in my case. This will vary depending upon your source control system. For VisualSVN, I add a hook by right clicking on the repository and selecting the “All Tasks” – “Manage Hooks…” option.
I then configure a post commit hook to execute a Ruby script.
Notice in the above configuration the escape sequence for the percent sign. This took me hours to figure out. Please learn from my blood, sweat and tears.
The Ruby script takes an argument for the project name. Here is the Ruby script:
# Push a notice to the hudson server to initiate a build. # Ensure the required libs are present require "net/http" require "uri" # Get the project name hudsonProject = ARGV[0] # Create the uri and issue the request uri = URI.parse("http://hppav1:8080/job/" + hudsonProject + "/build/") Net::HTTP::get_print uri
Now whenever code is checked in, Hudson will be triggered to build and run the tests for the project.
Summary
Now we have Hudson configured to kick off a build whenever changes are committed to source control. Hudson has many other features worth exploring. For instance, the next step may be to setup email or IM notification of build results.
Awesome post, I went through a similar process (although slightly different implementation) a while ago and blogged most of it, you might find it useful: http://www.refactor.co.za/2009/12/04/continuous-integration-with-hudson-and-net/. Let me know what you think, I could not find many .NET implementations of Hudson out there and it would be nice to bounce ideas off someone…
Rick–
Glad you liked the post. We are mostly a Java shop at work, but use Hudson for build system. I would consider myself a Hudson noobie. So far, I have found it to be quite easy to set up. I intend on exploring a bit what it offers to .NET developers. As you have enumerated on your site, there are quite a few plugins for Hudson. I do intend on exploring these a bit and I may post again on Hudson. Please feel free to contact me at bob DOT cravens AT gmail DOT com.
how to fetch Jenkins build details like build number,build status from .net application
Very nice post. I have been using Hudson for Java builds for the last few years. It really is a good CI tool.
One thing though, I am not sure you need that script to kick of the build automatically after code is checked in. I have my Hudson server set up with an SVN polling option, which allows Hudson to pull SVN for changes every so many seconds. The nice thing about that is you can also set timings for a slight delay so that the build will wait another 1 minute before it builds in case there are more changes. (Someone broke up their commit.)
Thanks for the post though. I didn’t know if anyone was using Hudson for .NET.
I did try to configure Hudson to poll SVN for changes. I could not getting it so that it only did a build when there were actual changes. Maybe a communication issue between Hudson and VisualSVN…or maybe a configuration issue by me. In either case, the build was occurring at the interval that I specified even if no changes were present. I decided to leverage Hudson’s ability to kick off a build via a web request.
If anyone has experience setting up Hudson to poll from VisualSVN and only build when changes are present please share. I could not get that working.
Nice post. I’ve used Hudson for several years on both Java and .Net projects. I’ve used the NUnit framework (with a nice plug-in) to run the tests. One question, though. Why did you choose to use a post-commit trigger instead of having hudson poll the repository? Not a criticism, just curiousity since we’ve used SVN polling for many years without any problems (just have to adjust the polling interval appropriately).
Russ–
I was not able to get Hudson and VisualSVN to communicate via SVN polling. Hudson always got the "repository is dirty" signal, pulled all the code and kicked off a build job. As a result, I implemented the post-commit trigger. I have recently started using trunksapp.com for my SVN repo. I have not setup Hudson yet, but will try the SVN polling again.
Thank you for another great article. Where else could anyone get that kind of information in such a perfect way of writing? I have a presentation next week, and I am on the look for such information.
Great write up.
The only thing I’ve have done differently and thought is worth mentioning is our builds have an "exit 0" at the end of the test batch job. This means that if the tests fail, the job doesn’t see it as a failure.
Hudson then thinks that the job succeeded (the build worked and the test step returns an zero errorcode). It is however clever enough is see that some or all of the tests failed and marks the build as "unstable" (with a yellow ball icon).
I prefer this unstable designation and it allows users to easily see if they have broken the build or merely broken the expected functionality.
Does hudson supports .NET framework 4 and visual studio 2010. I’m able to build a solution but reports are not getting displayed in the page. The report (unit tests and fxcop) xml files are getting generated.
I have not had the opportunity to try Hudson on a .NET 4 project. However, I don’t think that the .NET 4 framework would cause any issues. Hudson is just spawning out to MSBuild. I suspect (from the info that you provided) that the XML format for the reports has changed and the XML to HTML (or other) conversion is broken. You can try getting in touch with the plug-in devs to see if there are issues.
Bob
Hi
Can anyone help me?
I can’t configure gmail with Hudson.
Hudson doesn’t send emails to the configured gmail account. What should be added to the hudson.xml?
Sorry for the delay. To get Hudson (I am actually running the latest Jenkins build) to send emails on our local exchange server I just entered the SMTP Server address. I have not configured Jenkins to send email via GMail. I found this on Server Fault (http://serverfault.com/questions/144360/sending-email-using-smtp-gmail-from-hudson-ci). Don’t know if that helps.
Bob
i have taken a log file from Svn and made a changes for that one and i am running from command prom it was showing the Svn revision no ,date ,file name……..like that how we can run by using the Hudson and one have the idea means post the steps
Hey Bob,
Very nice write-up! Thanks for taking the time to document this and put it online. I found various pieces of information scattered all over the web, but this one is by far the most complete tutorial I found.
Just got everything setup and it’s working like a charm. Your article probably saved me a good day of trying to figure it out on my own.
Thanks much!
Hi,
Can someone help me in publishing/copying the code to a location? Then I need to move the code to a server for deploying the code. I am able to build the code successfully. I am working on .Net projects with SVN and Jenkins.
Thanks,
Vijay.