Saturday, 30 April 2011

Building the Build (first .NET Build)

Apologies for the delay this week…(I’ll blame the Easter holiday mode I was in). Getting back to it:

Creating and configuring a build in Jenkins is known (at least in my neck-of-the-woods) as “Building the Build”

When you first look at that configuration page (especially as you start adding more and more plugins, which, trust me, you will) it can seem daunting. When I think back to when I started playing with H^%#$& three plus years ago it would take me hours to get even the simplest bits working.

Many a long night was spent (entire weekends in fact) trying to first, simply understand the mechanisms but then; to actually get an execution environment that would actually work.

(When I refer to the “simplest bits” I am talking about the unit and selenium tests – it was a bit of a pain to figure it out).

It might sound cruel but I would not recommend short cutting this “understanding process”. I feel personally that I am able to “run” given that I have already “crawled” and “walked” first.

That said I will try and cover some useful things.

Configuring a Jenkins job is very much a process of constructing a build process (I would encourage you to view it in this way). The goal should be to automate ALL the steps that need to happen to create a production-ready system, with the starting point being the core source code. The process may or may not be a simply linear sequence (Step 1, Step 2, Step 3, complete), there may be some steps that depend on more than one previous step (like a stateflow diagram), the build pipeline can start getting complicated (but I digress, and that’s a topic for another post).

Very quickly you should start to see what you can do with Jenkins and before long your build process has a large number of steps. These steps need to be “built up” step-by-step, layer-upon-layer hence the term “Building the Build”.

The temptation is to dive in and start filling out fields. That’s what I did. But don’t.

Take a second to consider the high level goals of Jenkins:

  1. Check out the source code
  2. Do builds and/or tests
  3. Record results
  4. Notify people

Have a look at that list again. EVERYTHING, ALL the plugins fit into these 4 categories. That’s right, only 4. It’s worth keeping these in mind as you progress to maintain perspective.

Hopefully by now I have whetted your appetite to some examples. Let’s get started.

Alas, .NET does not currently have an analogous tool for Maven (a build lifecycle out of the box). UPDATE: NuGet these days provides the dependency management aspect of Maven but not the "build lifecycle out of the box" aspect of Maven.

Microsoft has MSBuild, which is basically just ANT (essentially just batch scripting where you start with a proverbial blank piece of paper and have to tell the computer what to do step by step).

This means that for the time being we have to choose “Build a free-style software project” when creating a new job to build a .NET project.

(To all those who are using Java, is anyone still using ANT? Seriously? When you have Maven why would you consider ANT anymore? Surely ANT is dead. In a previous life we mavenised all our legacy ANT application whenever we could.)

I already have a menagerie of plugins installed so my config may look a bit different in the screenshots but I will focus on the plugins and settings that we need to concern ourselves with. Once we have created the job, the first basic setting:

  • I like to keep the last 5 jobs as general rule. I think it keeps a nice balance between managing disk space and being able to see trends in the graphs that we will set up to be produced.

First thing the job needs to do as per number 1 above is check out the source code. (Note: a job does not always have to checkout source code, in fact in some circumstance you do not want to do this at all. We might get to this in later posts).

As I am using VisualSVN I am yet to bother with repository browsing (that and I just spent an hour trying to get any of the Jenkins-supported ones to work and couldn’t on my Windows box.)

  • Once the code is checked out we need to start defining what this freestyle build will do. Do that by Selecting the Add Build Step button and select ‘Build a Visual Studio project or solution using MSBuild
  • Select the MSBuild version defined in Manage Jenkins > Configure System page.
  • Define the target you want MSBuild to run.

I run /t:Clean and /t:Rebuild

Nearly all the remaining Build Steps are achieved using ‘Execute Windows batch command

Running Tests

Assuming the code compiles the next thing you are going to need to do is run Unit Tests, and then functional web tests.

To do this you need to install NUnit and write some tests in C#.

Executing a Windows Batch command, you specify the command:

"<Installed Path to NUnit>\nunit-console.exe" trunk\<TestProjectName>\bin\Debug\<TestProjectName>.dll /xml=nunit-testresult.xml

exit %%ERRORLEVEL%%

This should run your Unit tests. Same approach is taken with Selenium tests:

"C:\Program Files\NUnit 2.5.9\bin\net-2.0\nunit-console.exe" trunk\<SeleniumTestProjectName>\bin\Debug\<SeleniumTestProjectName>.dll /xml=selenium-testresult.xml

exit %%ERRORLEVEL%%

This should run your Selenium tests.

Currently I have most of my steps in one Job. One improvement I could make is to separate out the Selenium Step (as they take a long time to run on the one machine I have at home) into its own job, according to the principle that CI should fail fast to speed up feedback.

Next Week: Further along the build process: Static Analysis for .NET projects

Come visit my other site at fullcirclesolutions.com.au. All my best ideas are distilled into commercial tools and made available for purchase.

Till next time....

3 comments:

  1. We've done a similar thing, but all our build steps are wrapped up into an Ant script. This is because our build process includes multiple applications (some .NET, some not-.NET). It was easier to have a single script that does everything, and have jenkins setup to "ant compile", then "ant test:unit" or "ant test:integration".

    ReplyDelete
  2. Can you please explain what means /xml=selenium-testresult.xml

    exit %%ERRORLEVEL%% and how to set it on current project. Thanks in advance

    ReplyDelete
  3. Hi Sanja,

    The commands I refer to in the post should be entered into Windows Batch command build steps in your Jenkins job configuration.

    ReplyDelete