Thursday, August 07, 2008

Continuous Integration in TFS 2008: Part 2

Ok so in Part I I missed two important features due to a schoolboy cut-and-paste error:

The association of a build with the changesets that triggered it - fantastic for trouble shooting

Automatically raising a 'bug' work item for 'he who broke the build' to fix it. Sweet.

Maybe I'll go into those in more detail another time, maybe not. They are cool. But here's the not-cool stuff:

Stupid default working directory / issues with path lengthStraight out of the box many of my builds failed with excessive path length errors. Unfortunately the build agent starts with its default working directory of C:\Documents and Settings\NetworkService\Local Settings\Temp\ so I've got 61 extra chars on my path before I've even started, and we were already skating pretty close to the 255 chars limit (think BizTalk, over-zealous namespacing, auto-generated code etc...). Easily fixed, but seemed like a silly place to start.

Ok, it's going to be a bit less under Vista / Server 2008: still too long. Is C:\Buildsso wrong?

Binaries deployed to shared Staging folderMore problematically, the folder structure created on the staging share is a complete mess, totally useless to use as the source for xcopy deployment to testing environments and the like. I'll show you what I mean:

Pretty disappointing. All the binaries from all of the different applications have been dumped in the same folder. At least the websites have also been spat out in 'xcopy ready' form, but god help me if I wanted to Xcopy the console app one place and the WinForms app somewhere else.

What I'm looking for is more or less what I get out of SNAK right now:

...with any deployable asset (exe, website) neatly packaged to be copied off somewhere.

Same-name content files overwrittenOk, I guess I could just accept the above and copy everything, only using the EXE that I want, but that's icky, and it does rather suppose there aren't any naming conflicts between the deployable artefacts.

For example: I added some files marked as Content in my HelloWorldConsole app, but they got completely ignored by the deployment process. I had to also mark them as 'Copy to Output Directory' before TFS build stuck them anywhere (which I'm not convinced is correct behaviour, but there you have it), and then it stuck them in the 'right' relative location to the build root folder:

...becomes...

But there are two 'Subfolder1's above, and I only got one out at the end. Predictably, one of them got overwritten.

When would this be a problem? When could different projects possibly have a content file with the same name?! I can think of some examples:

We always use a file 'log4net.config' to host our logging configuration, so we can change it on the fly without recycling app pools and the like. Only one project would have got the right configuration.

Bundled licence files (Licence.lic) would get mixed up

I'm sure you can think of some more. And yes, using Embedded Resources works fine, but they're not always an answer (eg: log4net.config).

There is a fix. There's some changes you can make to your *proj files to make them preserve the output path hierarchy when deployed to the build drop folder. But it's a per-project fix, and that's - frankly - a bit lame. I know you don't add new project to your solution on a daily basis, but it's just one more thing that needs to be kept on top of, or things start falling apart. And that's just not how all this is supposed to work.

(Alternatively you could customize everyone's project templates. I guess you could fix it on all their PCs, or you could just put a fixed template on a share somewhere and tell people to use it. Since it's one of the default project types you're amending I guess you probably have to remove the original from their machine too. And hope they don't have to re-install VS anytime...)

ConclusionsGetting VSTS to perform Continuous Integration on your project is now really easy. To be fair, this on it's own was pretty easy with CCNet too, but it's even easier now, and we don't have to fight over the CCNet.config file.

But the staged output from the build strikes me as limited in use. It's possible to go and hack about with the generated MSBuild files that actually perform the build and stage, and bend it to my will, but that's just what I don't want to have to do. I want it to 'just work' and I don't think we're there yet.

1 comment:

Anonymous
said...

i have spent many a day setting up automated CI builds in both ccnet/nant and team build. i have found that when it comes to deployment, i really like using a WIX project. the msi output can be automatically and silently run in a QA environment as part of the build. when you need more than just an xcopy it is readily available. you can easily "promote" the msi from Integration to QA to Production automatically with other team builds. you can map wix file elements back to the original project directory instead of the OutDir that gets redirected eliminating most problems with the redirected OutDir (which sounds like it will go away in rosario :) When it comes to config settings WIX has custom actions that make updating the settings a snap or you can choose to maintain multiple config files and conditionally deploy the correct one based on which environment you are installing too.