Once you have your VS2005 solutions building, it's time to learn how to do an incremental build. Modify your TFSBuild.proj and insert these properties into your PropertyGroup:
This tells TFS to not reset your build directory and to only rebuild projects that need to be rebuilt. Personally incremental builds `scare` me, but Neil Enns ( MSFT program manager for Visual Studio ) personally assures me
"Incremental builds using MSBuild are 100% reliable for managed projects."
There is always the possibility that an incremental build would success when a full build would fail ( perhaps a deprecated component that doesn't go missing until you initialize the workspace ) so we will perform a redundant full build as a sanity check but discard the bits for deployment.
Now that we have incremental builds working, it sure would be nice to properly version them so Windows Installer costing patterns will work effeciently. Here is where Neil Enns comes to the rescue again. Neil wrote the AssemblyInfoTask community task. This task does a bunch of things, but one of the things it does well is to update the AssemblyInfo.cs files of only the projects that are out of date, or reference an out of date project. This means that during an incremental build, only the projects that get compiled will get versioned. Now isn't that exactly the sort of pattern that MSI costing needs?
To take advantage of this, we download the task and install it. Then we have to add a few lines to each of the projects in our solution to `subscribe` them to the pattern.
<Import Project="$(MSBuildExtensionsPath)\Microsoft\AssemblyInfoTask\Microsoft.VersionNumber.Targets" Condition="'$(BuildLabBuild)'=='true'"/>
By now you'll note that TFS `drops` the build ( stage the build to an archive location ) in a directory structure with it's build name. I like the `latest` pattern where each build drops the bits in a folder called LATEST so that a downstream build can consume it. In our TFSBuild.proj we'll do something like this:
<CreateItem Include="$(BinariesRoot)\**\*.*" >
<Output TaskParameter="Include" ItemName="AllLatestFiles"/>
<RemoveDir Directories="$(DropLocation)\LATEST" />
<Copy SourceFiles="@(AllLatestFiles)" DestinationFiles="@(AllLatestFiles->'$(DropLocation)\LATEST\\%(RecursiveDir)%(Filename)%(Extension)')"/>
Now when we drop the build we'll see the binaries get copied to a build specific folder, and a latest folder. It's time to move on to the InstallShield portion that will be in Part 3 of this article.