Team Foundation Server’s build system serves as the “heartbeat” for your development lifecycle. It automatically creates relationships between code changes, work items, reports, and test plans.
But once in a while I’m asked, “What if we don’t use TFS Build for building our application, but we still want to have builds in TFS so we can track and associate work?” Besides the biased question of “Why NOT use TFS Build, then?!”, there is sometimes the need to leverage the benefit of having empty/fake builds in TFS that don’t do anything more than create a build number/entry in TFS.
There are a couple scenarios where this makes some sense, but the most common one I hear is this:
Without builds in TFS, it’s near impossible (or at least very inconvenient) to tie test plans (accurately) to the rest of the lifecycle.
Luckily, TFS 2010’s build system is incredibly flexible: flexible enough to allow us to “fake” builds without actually performing build actions (get source, compile, label, etc.). It’s surprisingly simple, actually; and it doesn’t require writing any code.
In my example (which I’ll detail below), I define a build which doesn’t do much more than craft a build number and spit out some basic information to the build log.
First, create a new build process template, based on the default process template, using the steps described in this MSDN article.
Once you have the process template created and registered in TFS, open the new template (.xaml file) in Visual Studio. It will look (collapsed) something like this:
Here’s where it gets fun. Inside the outermost sequence, delete every sequence or activity except for “Get the Build”.
Drag an UpdateBuildNumber activity from the toolbox into the sequence, after “Get the Build”.
(optional) Rename “Get the build” to “Get Build Details” so there’s no implication that an actual build will take place".
Now expand the Arguments section (at the bottom of the XAML Designer window). Delete all arguments except for BuildNumberFormat, Metadata, and SupportedReasons.
At the bottom of the now-shorter list, use “Create Argument” and create the following arguments:
“MajorBuildName” and “MinorBuildName” will be used to help manually name each build. “Comment” will be used to capture any notes or comments the builder wants to include for a given build. “IncludeBuildDetails” will be used to determine if additional summary information about the build will be written to the build log.
To provide users with means to set values to these arguments, create parameters in Metadata. Click the ellipsis (…) in the Default value column for Metadata. This will bring up the Process Parameters Metadata editor dialog. Add each of the following parameters:
A couple notes about setting the above parameters:
Your dialog should now look something like the one at right.
Next, open the expression editor for the Value property of the BuildNumberFormat argument and edit the value to read: “$(BuildDefinitionName)_$(Date:yyyyMMdd)_$BuildID)”. Including the BuildID will help ensure that there is always a unique build number.
Now, Click “Variables” (next to Arguments) and create a new variable named ManualBuildName of type String, scoped to the Sequence, and enter the following as the Default:
If(String.IsNullorEmpty(MinorBuildName), MajorBuildName, MajorBuidName & “.” & MinorBuildName)
This variable will be used to provide a manual build name using the supplied MajorBuildName and MinorBuildName arguments.
Now we have all the variables, arguments, and parameters all ready to go. Let’s put them into action in the workflow!
Drag a WriteBuildMessage activity into the main sequence, before Get Build Details, with these settings:
Next, add an “If” activity below “Get Build Details” to evaluate when to include additional details in the build log, with the following properties:
In the “Then” side of the “If” activity, add a WriteBuildMessage activity for each piece of information you may want to include in the build log. In my example, I included 3 activities:
Your “If” activity will look like this:
The last thing to do is to add an UpdateBuildNumber activity as the last element in the main sequence, with the following properties:
This last activity will actually create the build number which will be stored back into TFS. Your completed workflow should look like this:
Now go back to Source Control Explorer and check this template back into TFS.
Go create a new build definition, opting to use your new template on the process tab. You’ll notice that your options are dramatically simplified:
Specify a value for Major Build Name and save your new definition.
Queue the build and you’ll see the following on the Parameters tab:
Enter some basic information and click “Queue” to run the (fake) build.
What you end up with is a build that completes in just a couple seconds, does pretty much nothing, but includes your specified information in the build log:
And just to be clear, my example adds more “noise” into the build than you may find necessary, with additional build information, comments, etc. You could streamline the build even more by removing the “Include Build Details If Chose” activity (and all its sub-activities).
Given the overall flexibility TFS 2010 has with incorporating Windows Workflow into the build system, there are undoubtedly other ways to accomplish variations of this type of build template. But I had fun with this one and thought I should share. I’ve posted my sample template’s xaml file on SkyDrive here:
I’m all ears for feedback!
The fact that you need to do all that just to push the data back into TFS or just to have an empty build definition is a good answer to why NOT use TFS.