Automating Visual Studio 2010 builds and deployments with Nant.Builder

Part 2 in my Visual Studio 2010 Turbo series

  1. Visual Studio 2010 Workflow
  2. Automating Your Builds with Nant.Builder
  3. DIY AppHarbor – Deploying Your Builds onto Windows Azure

In this post I look at using Nant and my Nant.Builder nuget package to quickly get your builds automated, from here it should be simple for you to integrate with a CI tool of your choice.

Update (27/07/12) – Anoop Shetty has put together an awesome post on using Nant.Builder here.  Thanks Anoop 🙂

Nant and Nant.Builder

I’ve been using Nant for years now, it’s a great tool for scripting and automating tedious build and deployment tasks.  Some might say it’s getting a bit long in the tooth, and it’s not as hip as rake etc.  However, I find it perfectly usable, with a learning curve that’s not too steep, it’s very well documented and it’s updated usually once or twice a year.

I’ve recently been doing more and more with Nuget, and I’m increasingly finding it a very powerful way of quickly setting up new projects.  One task that always takes a bit of time is setting up a build script for the new project.  Usually I’d cut and paste an existing script and hack out the bits that needed changed.  This was painful, and I wanted to get rid of this boring step, so Nant.Builder was born.

Installing and Integrating Nant

Hopefully you’ve followed part 1 of this enthralling series, so if you haven’t get Nant installed, download the latest stable build and extract it c:\dev\tools\nant-0.91.  If like me you’re trying to do more from the command line, add the bin directory into your Path environment var, ie C:\dev\tools\nant-0.91\bin

Open powershell and type nant you should see something like this, don’t worry about the Failure message for now:

NAnt 0.91 (Build 0.91.4312.0; release; 22/10/2011)
Copyright (C) 2001-2011 Gerry Shaw
http://nant.sourceforge.net

Nant can also be launched from Visual Studio.  Go to the Tools | External Tools menu option, click Add and complete as per screenshot, ensure you tick the Use Output Option.   You can now launch Nant from VS.

Install Nant.Builder

If you followed the first installment of this series you should have your new Solution in your workspace.  Now lets setup Nant.Builder:

  • Add a new empty project and name it  <yoursolutionname>.Build, ensure you save it in the src directory.  We’ll use this project to hold our build scripts.

  • We don’t want the compiler to build this project so click Build | Configuration Manager.  Untick build on any configurations

  • Now we can install Nant.Builder from Nuget run the following command, from the package manager command line:
install-package nant.builder -projectname <yoursolutionname>.Build
  • We now have Nant.Builder installed into your .Build project 🙂

Configure Nant.Builder for your solution

I’ve tried to keep configuration to the bare minimum, as the whole point is to keep things fast.

  • Open the Nant.Build file.
  • Set the solution.name property to the name of your solution, in our example SampleSolution
  • If you’ve set up your workspace as described in the Workspace blog, you won’t need to edit solution.src.dir.  If you don’t save your projects in a source dir, and save them in the same directory as the .sln file, edit this property to blank, ie “”
  • Set the solution.projects property to a comma separated list (no spaces) of all the projects contained in your solution, in our example SampleSolution.Services,SampleSolution.Tests,SampleSolution.Web
  • Set the release.configuration property to the configuration you want the solution to be compiled under, default is Release
  • If you’re not using CI, you can manually set the version number.  Nant.Builder will then version all your dlls with the version number you specify.  If you are using CCNet, Nant.Builder will pick up the version number from CCNet
  • Set the company.name property to the name of your company, this will also be added to the Assembly.Info, so users can see who created the dll
  • So in our sample we have this:
<!--The name of your solution, please overwrite the default -->
<property name="solution.name" value="SampleSolution"/>

<-- If your projects reside in a different directory from the .sln file specify here, or leave empty if not -->
<property name="solution.src.dir" value="src" />

<!-- Comma seperated list of projects contained in your solution -->
<property name="solution.projects" value="SampleSolution.Services,SampleSolution.Tests,SampleSolution.Web" />

<!-- Set the configuration for compilation, typically release, but may be custom -->
<property name="release.configuration" value="Release" />

<!-- Manually set version, if using CCNet this will be overwritten later -->
<property name="version.tag" value="1.0.0.1"/>
<property name="company.name" value="iainhunter.wordpress.com" />

If you’ve followed the first tutorial you shouldn’t need to change anything in GlobalBuildSettings.xml.  However, if you have a different workspace, buildspace, or have msbuild4 located in a non-standard location, set the values appropriately or you’ll get errors.

Running Nant

We can now run Nant from the command line by opening powershell, navigate to your Build directory, eg C:\dev\work\SampleSolution\src\SampleSolution.Build  then type Nant.  Your solution should build, or throw errors if you have warnings etc.

Alternatively in Visual Studio open the Nant.Build file, then in Tools  run your new Nant tool you created above.

Now if you navigate to your builds directory C:\dev\builds\SampleSolution you should see your build, and if you look at one of the Dlls you should see it has been versioned according to your instructions

Next steps

Nant.Builder is available on github here, so feel free to fork or send me a patch if you think it can be improved.  I’m planning to add a few enhancements like a msdeploy task etc, we’ll see how time allows.

Next time

We alter Nant.Builder to automatically deploy your solution onto Windows Azure

Visual Studio 2010 Turbo – Workflow

Recently I’ve been attempting to streamline my workflow, to help me Get Things Done 🙂  So I thought I’d share some of that work, in a mini-series of blog posts:

  1. Visual Studio Workflow
  2. Automating Your Builds with Nant.Builder
  3. DIY AppHarbor – Deploying Your Builds onto Windows Azure

Tool Up

I won’t spend much time expounding on the tools that I use, as excellent guides are but a Google search away, but I’d recommend installing and using the following:

  • Powershell – Yeah it’s a bit clunkier than bash, but it’s extremely powerful and lets you easily automate your day to day life
  • Console2 – A nice way of working on the CommandLine and Powershell- read Hanselman’s excellent guide
  • Git – As a looooong time SVN user and aficionado I was reluctant to move to Git, but now I have I have to confess I’m enjoying the experience
  • PoshGit – Work with Git in Powershell, read Haack’s excelent guide to getting it set up here and here.
  • Nant – My build tool of choice, I’ll talk about it a bit more in follow up posts.
  • Nuget – Jump start your projects with this excellent package manager, and then upload some packages of your own 🙂

Configure your workspace

I’d encourage all dev teams to configure their workspace in the same way.  That way you can jump onto a colleague’s machine and you’ll know where to go to find the code if pairing etc.  Also it makes it easy to share buildscripts around the team.  I set up my workspace as follows:

C:\dev 
    \builds 
    \releases 
    \tools 
    \work

So all work is done in the C:\dev dir.  We then create 4 subdirs:

  • builds – used solely by your build tool to copy files into for compilation, running unit tests etc
  • releases – used by your build tool to copy your solution in a format that can be easily released, ideally any subfolders here would be dated or versioned
  • tools –  contains any tools you use to help with developing code, ie Nant, NUnit etc
  • work – the main event, contains all your various solutions

So for example we might have:

C:\dev 
	\builds 
		\DemoApp1 
	\releases 
		\DemoApp1-Build-120508-0915 
		\DemoApp1-Build-120508-1115 
		\DemoApp2-Build-120507-1506 
	\tools 
		\Nant-0.91 
		\Nunit-2.6 
	\work 
		\DemoApp1 
		\DemoApp2

Creating a new empty solution

A number of years ago I read the excellent Code Leader, the author advised using a tool called TreeSurgeon to set up a new solution.  This tool is slightly long in the tooth now and could do with being updated, but you can follow the guide below to quickly define a new solution in the same style:

  • Create a new blank solution in c:\dev\work and name it after your project  – eg SampleSolution

  • Your solution will open in Visual Studio and will contain only the solution file.  Now you can add projects to your solution you might want to add a Web project a Services project and a Tests project.
  • So right-click on the solution file and select Add | New Project
  • As per .Net convention you should call the various projects <solutionname>.<projecttype>.  So we’ll add SampleSolution.Web, SampleSolution.Tests, SampleSolution.Services.
  • When you add the project ensure you set the location of the project to the /src folder within your solution

  • Right-click on the solution file again and select Enable Nuget Package Restore.   Click Yes when you get the pop-up about wanting Nuget to manage packages restores for you.  A couple of nuget files will be added to the root of your solution.

We should now have a nice neat solution, with all projects saved in the src dir, eg:

Next Steps

Now to test if Nuget is working lets add a package to see if all is working as expected, lets add the awesome Twitter Bootstrap.  So if we run the command in the Package Manager console

install-package TwitterBootstrap

Twitter Bootstrap will be installed successfully, and if we now look at our Solution dir, you’ll see we now have a new packages dir, containing Bootstrap and its dependencies

Now that we’re happy you can add your solution to the source code management tool of your choice, I’d recommend checking out Git.  BTW with nuget installed, you do NOT add the Packages directory to Source Control.

Next time

I’ll look at using Nant, to quickly build our solution.