SNAK
SNAK is a series of NAnt tasks designed to streamline a continuous integration build/test/deploy cycle against VS2003/VS2005 solutions.

SNAK is unashamedly focussed on setting up the kind of build workflows that have worked well for us in the past. It's not a general purpose set of NAnt tasks; not a replacement for NAntContrib.

The SNAK project/solution has been moved to VS2005 primarily to give us IDE integration with Codeplex (previously we were working on it using the VSTS-SCC provider for VS2003). So SNAK is now .Net 2, however this doesn't prevent use within .Net1.1-targeting NAnt builds (you just need to have .Net 2 on your build box).

So what does it actually do?

Predominantly SNAK is about packaging the output from building a Visual Studio Solution under Continuous Integration. We get MSBuild / NAnt's solution task to do the build, and take it from there.

There are lots of ways to do this, but about the only one that does it right is Visual Studio's Deploy Web Project feature, and that assumes you want to deploy right then and there :-/. It's actually not as easy as it looks. SNAK:
  • Packages based on binaries + files marked as 'content' in VS projects (not dubious wildcard patterns)
  • Copes with the differing directory structure requirements for web and winforms/service apps (bin vs no bin)
  • Doesn't assume an output folder (loads bin\debug etc... from project files)
  • Doesn't assume a build configuration (uses the actual build config setup in the solution file, and doesn't assume name matching)

What we generate is what I call an 'xcopy ready' package. It's a series of folders for each web/exe project in your solution, that you could drop on a server somewhere and execute. We don't generate MSI's, because I've found folder packages easier to inspect, verify and - where required - fix on the fly. Zipping the folders would be a good idea though.

We spit these folders out into a 'drop' location, based on build number, and also maintain a Build_Current folder to facilitate file-based Enterprise Continuous Integration schemes (see http://confluence.public.thoughtworks.org/display/CCNET/Enterprise+Continuous+Integration+with+Binary+Dependencies+example).

Most of the above is wrapped up in our <packageOutputs> task, but the underlying functionality for working with Visual Studio projects and solutions can also be accessed in other ways:
  • In our <forEachProject> task
  • Via other .Net app
  • Via Powershell

The <foreachproject> task provides a loop over all the projects in a given build configuration for a VS solution. Tasks executing within the loop also have the benefit of a host of nant properties set up like ${project.outputPath} or ${project.outputType}, so it's easier to - say - point NUnit at the project outputs. Heck we even try and work out where the NUnit.config for that assembly is for you!

We have some other tasks too that we found made our build files more manageable, like a <tfsCheckInOut> which works like a try/catch checkin/out block.

Why SNAK not MSBuild?
Well we are using MSBuild - for the build. For the other parts of the process we're quite happy to use NAnt as the orchestrating engine. We were happy using NAnt, and there seemed a few early gotchas with using MSBuild as an all-singing-all-dancing scripting engine (like NAnt has become). And in 2005 the .SLN file was still not an MSBuild file, so there wasn't an obvious place to put this stuff even if we wanted to.
Frankly I think if I was to move away from using NAnt I'd start using Powershell instead. XML formats (like NAnt and MSBuild) are great for IDE's to work with, and so I'd always end up using MSBuild for the build, but for the rest of the 'glue' for a standard build/package CCNet project I think MSBuild just shares too many of my frustrations with NAnt. I think Martin Fowler's comment was along the lines of 'seemed like a good idea at the time'. You only have to look at the mess an average NAnt project descends into (and nothing to prevent MSBuild going the same way), and you realise that things like variable scope really do make a difference. XML just isn't a good scripting format.
That all having been said, if you keep it simple (hence SNAK), you will be fine.
PS: SNAK has been partitioned with half an eye on porting to MSBuild if really required.

Where are we at?
The source is in a good state, but I really need to pull my finger out and mark a stable release. I've been using it at work for over a year now, and it's about 6 months since anything but the most trivial modification (during which time it's done 10,000's of builds), so I think it's fairly well bedded in. There's always the odd edge-case however, project types that we haven't catered for yet (just doing BTS 2006 projects now). We also have a fairly strict 'one solution per build file' mentality, but I don't regard that as a limitation. VS2008 is not explicitly supported yet, but should be fairly straightforward.,

Update 2009 Source is essentially stable, but project has been dormant for about a year now. If I ever get round to setting up a similar process under TFS 2008 CI I'll work out how much of the code can be ported over, but for now this is mostly here for historical reference.

Last edited Apr 2, 2009 at 1:47 PM by piers7, version 8