MSBuild, SDC Tasks, VS 2008, VSS 2005 and WSPBuilder

Whew! That’s a long headline. As an IT Architect I get thrown curve balls from clients looking for all manner of solutions. I’m fortunate enough to work with some sharp people who like to invest time researching what they need and are about to ask for in advance so no complaining here. The task itself from this particular client I am sitting with today (and for the immediate future) was fourfold.

  1. On a dedicated MOSS server get the latest solution code from the Source Repository
  2. Build said code and log output to a defined folder
  3. Secondary build of finished code to WSP solutions using WSPBuilder
  4. Deploy built WSPs and code to MOSS

All of the above had to be run from a single command that can be batched and scheduled to accomodate nightly and adhoc builds. Now I don’t normally get involved in this end of the development process although after completing this task it’s a gaurantee I will in future.

I’ve had some familiarity with MSBuild in the past but never really took advantage of the possibilities I’ve just recently realized were available to me. However I started by asking a fairly simple question to the client:

“Where is your Team Foundation Server hosted?”

I’d made the assumption that things would be easy, that I could use Team Foundation Build and via the UI create the steps necessary for getting, building and so on. Unfortunately I was out of luck. No TFS today but maybe in a few months. So this was not going to be a walk in the park.

First things first: When in doubt – SPAM. I sent a mail around to some of the brighter guys I work with asking for input. Responses, those I got, varied but one in particular contained a simple little url to the SDC tasks project that got the ball rolling. For those that don’t know the SDC Tasks library is used to make the lives of those who use MSBuild on a regular basis much easier. It contains over 300 tasks covering a range of product technologies and platforms. The documentation is complete and the Installation guidelines, spartan as they are, give a good compass bearing on where to head.

I downloaded the latest release and created a folder named Buildtools on the root of the c: drive. I’m a structure freak so I spent some time organizing the contents the way I wanted them ala Binaries here, documents there, task descriptor another place and so on.

I started where everyone starts at the Documentation and the Installation pdf. The installation guide shows the 3 potential ways for using SDC tasks. I decided to go with the COMMON / SHARED INSTALLATION option. I won’t go into more detail than that but you can read up about it on the site or download it and try it out for yourself.

PROJ file
I now had the BuildTools in place so the next step was to put them to use. I fired up VS 2005 and created a simple proj file (basically just XML like all configs these days) and added what I found in the install guidelines. I expected to get a lot of help by adding the schema definition for MSBuild but oddly enough elements like CleanFolder and TasksPath threw errors on validation.

At this point I have to admit that there aren’t that many examples of project files for MSBuild floating around the web. Not surprisingly though I quickly discovered the project file is identical to the kind of project file you would find in Visual Studio like a csproj file. Taking my inspiration from here I put a project file together that resembles the following:

<Project DefaultTargets="Latest;Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TasksPath>C:\BuildTools\bin\</TasksPath>
</PropertyGroup>
<Import Project="C:\BuildTools\tasks\Microsoft.Sdc.Common.tasks"/>
<Target Name="Latest">
<SourceSafe.Get
UserName="*******"
Password="*******"
Database="\\SourceControl\VSS\"
Project="$\CMS2002\Development"
WorkingDirectory="C:\Projects\CMS2002\Development\">
</SourceSafe.Get>
</Target>
<Target Name="Build">
<MSBuild Projects="C:\Projects\CMS2002\Development\CMSApp7834.sln" Properties="Configuration=Debug">
</MSBuild>
</Target>
</Project>

Now I had a project file to use in tandem with MSBuild. I went straight to the command line and got my first error. It was along the lines of “this version of MSBuild can only read solution files between versions 7-9″. I realized right away that I was trying to compile a VS 2008 solution file with the MSBuild executable in the v2 framework.

Having made the modification to point to the correct framework (v3.5 – damn mixed environments) I was successfully getting the latest code from source safe and almost successfully building it.

Almost you say?
Well it seems that the SDC tasks extensions are lacking an important property for the Source.Get method: AutoResponse=”True”. Basically what happens is that on first source GET everything works fine and the solution compiles as it should. However if the build output of the VS project is incorrect, pointing to bin instead of bin\release, or there is a file that is writable within the folder structure MSBuild will return an error with “a writable copy of ##### already exists” and stop the build for that particular project.

This is isn’t an optimal error, none are, but I understand that it’s by design – VSS shouldn’t overwrite files that are currently being worked on without prompting first. This essentially is what the AutoResponse property did when using VSSGet in older versions of VSS:

<vssget vsspath="/toplevel"
localpath="C:\dev\control\java"
login="${login}"
ssdir="${ssdir}"
serverpath="${serverPath}"
recursive="true"
autoresponse="Y"/>
</target>

It’s a small gripe and I’m sure there’s a reason for the omission of overwrite and autoresponse functions. More testing ironed out any other problems I faced. One thing I also discovered was that the CleanFolder method works intermittently – I’m investigating this further to see if some of the methods I have added overlap each other.

WSPBuilder
I can’t take credit for formulating the WSP build and deploy process here as the client Architect I work with beat me to the punch. He created post build events for each of the projects where they would either deploy via stsadm or do a manual file copy to the 12 hive. Anyone familiar with WSPBuilder should already be aware of how to work with post build events in Visual Studio.

To tidy everything up I created 2 simple batch files that run the msbuild command and point to the respective project files. Now the client can login in remotely to the build server and with one action get the latest code from source, build it, pipe the output into a datetime named log file for later debugging and deploy the solutions to MOSS. All of which takes less than 2 seconds!

Conclusion
A few hours legwork and investigation into a new technique for solution deployment and we now have a process that is fast, efficient and removes the element for human error. And once you know how it’s hard to stop. I’ve already applied the same methodology to a CMS 2002 project which I hope we can use for the production environment.

Leave a Reply