Ruminations of J.net idle rants and ramblings of a code monkey

Debugging TFS Build

TFS

If nothing else, this is one of the coolest things in TFS 2010. But I am not, unfortunately, afforded the luxury at this time of working with TFS 2010 in my current gig. Though I won’t complain too loudly as it is 2008 and not 2005.

I’m currently working on the build process. As simple as that may sound (and some builds are simple), I do have some pretty high goals. Let me explain. The Team Project is a collection of solutions and projects that are certainly related and tied together in a single software project, but there are 10-15 of them. We have, in Source Control, branches for each release environment and thus, will need to have builds for each environment as well. My ideal scenario would be to pass the environment into TFS Build as a command line argument and have it pull the project from the correct branch, label the project from the correct branch and then create the drop directory with the correct name from the correct branch. And then zip it as well, but that getting that to have the correct branch/environment name is pretty easy as it’s a task that I’m adding in, not changing the behavior of Team Build.

While there is a build debugger in TFS 2010, such a beastie does not come out-of-the-box with TFS. There is, however, MSBuild Sidekick out there that lets you edit and debug MSBuild projects. Since TFS Build projects are MSBuild projects, I figured that this would be a good place to start. So I downloaded the trial with high hopes. I started with simply opening the MSBuild project that TF Build creates when you kick off a build. You’ll find this in the BuildType folder that’s right under the working directory for the Build Agent. It defaults to the Temp folder, but I like to put it in it’s own spot. On the Build Server that I’m working on, it’s F:\Build so you will find your TFSBuild.proj file in F:\Build\BuildType. Simple enough, right? No. When you fire up the debugger, it starts with CanonicalizePaths, then BeforeCompile and then CallCompile. And there it fails.

Digging in a bit, you’ll see a second file in the folder with TFSBuild.proj – TFSBuild.rsp. Hmmm … interesting. Upon opening that up in Notepad, you’ll find a list of stuff that looks remarkably like a series of command-line switches. Guess what? That’s exactly what they are. These are all of the command-line arguments that are passed into MSBuild when the build is kicked off. There are a slew of properties, some loggers and a couple of other things – like the initial target for the build. That’s a little important. Next step – add these into MSBuild Sidekick. You do this in the Properties screen for the build project. First, under project properties, you need to add in ALL of the properties that TFBuild is passing in. Then you have to specify the initial target for MSBuild. They’ll look like this:

Build Properties Initial Target

When you run it now, it hits CanonicalizePaths and then jumps right to the end and happily informs you that “Build succeeded”. Oh boy. What’s up with this? As it turns out, the first target in the chain for TF Build is “CheckSettingsForEndToEndIteration”. There’s a condition on this - $(IsDesktopBuild)'!='true'. So, let’s now add a property to the command line in our build options: IsDesktopBuild with a value of False. And … here we go again. We get past “CheckSettingsForEndToEndIteration” and go into the “InitializeBuildProperties” target, which calls the GetBuildProperties task. Which then promptly fails with the message:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(267,5): error MSB4018: The "GetBuildProperties" task failed unexpectedly.
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(267,5): error MSB4018: Microsoft.TeamFoundation.Build.Client.BuildNotFoundForUriException: TF214007: No build was found with the URI vstfs:///Build/Build/34. Either the URI does not exist, or TFSTEST\Administrator does not have permission to access it.
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(267,5): error MSB4018:    at Microsoft.TeamFoundation.Build.Client.BuildServer.GetBuild(Uri buildUri, String[] informationTypes, QueryOptions queryOptions)
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(267,5): error MSB4018:    at Microsoft.TeamFoundation.Build.Tasks.Task.get_BuildDetail()
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(267,5): error MSB4018:    at Microsoft.TeamFoundation.Build.Tasks.GetBuildProperties.get_BuildAgentName()
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(271,15): error MSB4028: The "GetBuildProperties" task's outputs could not be retrieved from the "BuildAgentName" parameter. TF214007: No build was found with the URI vstfs:///Build/Build/34. Either the URI does not exist, or TFSTEST\Administrator does not have permission to access it.

And that, my friends, is where I am now. BUT … at least MSBuild Sidekick allowed be to look at all of the properties as they are when it starts up. And it’s also shown me what the entire process is that TF Build actually goes through. I haven’t done much editing with MSBuild Sidekick (yet) but the debugging … even if I cannot get TFBuild to cooperate fully … is priceless.

UPDATE:

I’ve gotten it working from beginning to end, soup to nuts. :-) Here’s what I did: First, I logged in as the user that the Build Server runs under (don’t lecture me about security; it’s a test environment). I did this because I remember seeing an error message when I tried to change the Build Server’s account about access to some URL or another (I don’t remember the details … I just switched back to the previous account). That still didn’t work. Therefore, I knew that it wasn’t security permissions; that account would need those permissions of Team Foundation Build was going to work at all. So now I’m looking at “No Build Found”. Time to fire up Sql Server Management Studio to see what’s in the TfsBuild database. When I opened up the tbl_Build table (what’s with the “tbl” prefix??? That’s sooo pre-Y2K!), I noticed that there was no build number 34 (look at the URI … it’s in there). BUT … there was a 33 and a 35. Changing the BuildUri property in the BuildOptions (above) did the trick and I was happily stepping through the entire TFS Build process.