Creating a Custom Link Tab for your TFS Work Item

Each work item in TFS contains an All Links Tab where you can see all the links to this work item grouped by relationship type.

There are other tabs that just show specific links like Implementation, Change Requests, Test Cases. These tabs are filtered to only show certain types of relationships and the work items that can have this relationship.

It’s very easy to create your own Tab that shows specific links and the work item types that you want the user to include.

As an example lets create a Review Tab on the Requirement work item in the CMMI Process Template so we can see the Design Reviews associated to this requirement.

Open up the CMMI process template using the Process Template editor that comes with the TFS Powertools.

Lets create a custom link type to be used for Reviews. From the Process Editor select Methodology | Work Item Tracking | Link Types and click the new Button. Fill in the New Link type to represent a  Reviewed By/Reviews relationship.

Save the Link Type and open the Requirement Work Item type editor.

In the Layout tab right click on the TabGroup node and select New Tab Page from the context Menu. You can right click on that new tab page and select Move Up or Move Down to change it’s order in the Tab control.

Change the Label on the New Tab Page to Reviewed By.

Right click on the Tab Page – Reviewed By and select New Control. Fill in the Control property grid with label, name and type information.

Now select the Control Settings field and click on the button in that field with the ellipses.

From here you can control the links that can be added and viewed with this control.

There are three filters that can be applied.

Work Item Type Filters: Allows you to select the type of work items the can be selected. You can choose to Include All work item types or Include/Exclude a subset of them. For our example we will select Include and check the Review Work item Type.

Work Item Link Filters: Allow you to force a specific work item link type. You can include/exclude all or include/exclude a subset. For our example we’ll Include the new Reviewed By link type we created.

External Link Filters: These are for the non work item links. You can include or Exclude the following external link types.

Fixed in Changeset
Result Attachment
Source Code File
Test Result
Workitem Hyperlink

See my blog entry on Requirements in TFS for an example on using the External Links.

For our example we will set this to Exclude All this way none of the external links will be allowed.

You can also select what columns you would like to show in the list of related work items. I’ll add Called By and Called Date to the selected Columns.

Now with a project created from this process template the Requirement will have a Reviewed By tab that allows users to add Reviews with the link type Reviewed By.


Metro Toronto User Group February 2012


Come out to the Metro Toronto User Group on February 15th. Colin Bowern and I will be showing you how to customize your build process with TFS 2010 and use MS Deploy to automate your web app deployment.

Customizing the TFS Build process and automatically deploying your web app.

When: Wednesday February 15, 2012 at 6:00pm

Where: KPMG, 333 Bay Street, 46th Floor, Toronto

See you there.

Create a Master Build that calls other Builds

Have you ever wanted to have a build that kicks off a bunch of other builds. I recently had such a need, we wanted to have independent build definitions for a bunch of apps. However when you are responsible for deployment you just want to run a bunch of builds at once. If every app is a .net application it’s easy to create one build that builds all the apps.

However in this instance we have two different build process’s. One for .net apps and one for VB6 COM applications. So we created a master build that can kick off multiple build definitions each having a different build process.

First thing is to strip down the Default build Process to it’s bare minimum. Here is what the Build Process looks like.

If you are familiar with the default build process you will recognize the first few items.

The ForEach is the new part. I will explain that in a minute. First we need a new Argument to the build process that will hold the build definitions you want to queue.

Name – BuildDefinitions
Direction – In
Type – String[ ] (Array of Strings)

and a new Variable for the output.

Name – BuildRetVal
Type – IQueuedBuild
Scope– RunOnAgent

You will need to get the Community TFS Build Extensions from Codeplex. If you don’t know how to get started using these, there is plenty of help on that subject here.

To Queue up a bunch of builds drag in a ForEach and iterate over the BuildDefinitions parameter you added.

Inside the ForEach drop in a QueueBuild from the community TFS Build Extensions.

Here is how you fill in the paramaters of the QueueBuild Activity.

Build Controller - BuildDetail.BuildController
BuildDefinition - BuildDetail.BuildServer.GetBuildDefinition(BuildDetail.TeamProject, item)
BuildServer - BuildDetail.BuildServer
Priority - Microsoft.TeamFoundation.Build.Client.QueuePriority.Normal
Process Parameters - Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers.SerializeProcessParameters(New Dictionary(Of String, Object) From {{"AgentSettings", AgentSettings}, {"Verbosity", Verbosity}})
Result - BuildRetVal

In my example I pass the Agent settings and verbosity through to the called definition. That way I can control them from the master build. In our case we wanted each child build to run on the same agent as the master build so we can accomplish that by passing in the AgentSettings to override those defined in the build definition.

We also passed in the Drop Location and used it in the child so that the child builds each dropped their binaries under the master builds drop folder. Again a choice we made for our situation.

Once you have the process we can define a build definition for the master build. Add all the Build Definition Names you want and the Master build will kick them all off for you. It should look like this.

Set the AssemblyFileVersion to match the build number

If you are not sure why you need to set the AssemblyFileVersion and AssemblyVersion read this first.

First thing to do is to change the build number format to include the version number of a build Major.Minor.Build.Revision.

Something like this $(BuildDefinitionName_{Major}.{Minor}.$(DayOfYear)$(Rev:.r) will usually do the trick. The Build number could also be a date $(Date:MMdd)

The above build number format will will result in a build number similar to: Calculator.Main.QA_5.3.321.1

For the Major and Minor numbers create two string arguments in your Build process one for each.

Find the Invoke For Reason activity named “Update Build Number for Triggered Builds” in your build process and add an Assign activity right before the Update Build Number activity. This will include your Major and Minor build numbers in the Build Number Format.

Assign activity
Value: String.Format(BuildNumberFormat, Major, Minor)

Now we want to put the version number from the build into the AssemblyInfo.cs file in our projects so the assemblies have the same version number as the build.

There are 3 build activities we can use to get the job done.

We will need the following variables defined:

  1. FileVersion as string
  2. FilesToVersion as IEnumerable<String>

Then add these four activities into a sequence right after initialize Workspace.

  1. 1. Extract the Version Number from the Build Number
  2. Assign activity (From the Primitives group in your Workflow tool box)
  3. To: FileVersion
  4. Value: BuildDetail.BuildNumber.Substring(BuildDetail.BuildNumber.IndexOf("_") + 1)

2. Get all the AssemblyInfo.cs files
FindMatchingFiles activity (from the Team Foundation Build Activities in your Workflow tool box)
Match Pattern: String.Format("{0}\**\Assemblyinfo.cs", SourcesDirectory)
Result: FilesToVersion

  1. 3. Change the AssemblyFileVersion
    File activity (from the TFS Build Extensions project)
  2. Action: Replace
  3. Fail Build on Error: True
  4. Files: FilesToVersion
  5. Regex Pattern: "AssemblyFileVersion\(""(.*)""\)"
  6. Replacement: String.Format("AssemblyFileVersion(""{0}"")", FileVersion)
4. Change the AssemblyVersion

File activity (from the TFS Build Extensions project)
Action: Replace
Fail Build on Error: True
Files: FilesToVersion
Regex Pattern: "AssemblyVersion\(""(.*)""\)"
Replacement: String.Format("AssemblyVersion(""{0}.{1}.0.0"")", Major,Minor)

When you queue a build set the Major and Minor numbers on the build definition and let the build process do the rest.

The result will be an AssemblyFileVersion that looks like 5.3.321.1 and an AssemblyVersion that looks like

The TFS Build Extensions has a TFSVersion Activity that is great and helps to simplify this. However it currently has a problem with a BuildNumberFormat that is different from the default. When that gets fixed i will repost how to do this using TFSVersion.

Test Case Customization

The Test Case Work item has a tab that lists Tested Requirements or User Stories (depending on the canned process template CMMI or Agile) that this Test Case tests.

When a bug is found you should write a test case so everyone knows how to validate that Bug once it’s fixed. Therefore why have a tab that just shows Tested Requirements/User Stories.

Lets use the Agile template as an example. The Tested User Stories tab will only allow you to add User Stories. Even though you could add a Bug with the tests relationship under All Links if you wanted.

It’s very easy to change this tabs behaviour to allow for Bugs also. Here’s how.

Open up the Test Case in the WIT editor that comes with the TFS 2010 Power Tools. Under the Layout tab find the TabGroup > TabPage – Tested User Stories > Control – User Stories tested by this Test Case and select it.

Select the Control Settings property and click on the ellipsis button. Leave Work Item Type Filters as Include. However in the drop down list to the right of that change it to also include Bug, then click OK,

Now change the Label from User Stories tested by this Test Case to something more appropriate like Tested by this Test Case.

Then switch focus to the Tab Page and change it’s label to something more appropriate  like Tested User Stories and Bugs or just Tests.

Save the work item type.

You should now be able to select Bug as a work item type tested by this test case.

Quality Assurance in Mixed Technology Environments


I am doing a webcast today on the subject Quality Assurance in Mixed Technology Environments.

This is one in a series of Web Casts MS and partners like us are doing leading up to the TesTrek conference in Toronto. Where Deb Forsyth and I will be leading a workshop on Experience and Overcome the Challenges of Exploratory Testing.

Test Configurations


I’m sure you have noticed that when you create a new TFS project in 2010 there are a couple of default Test Configurations created.

Operating System - Windows 7
Browser – Internet Explorer 8.0

Like most people you will go into Test Manager and add the configurations you really need. Then you create another project and those default configurations are back. Unfortunately there is no way in the UI to add the configurations you added in the first project to other projects. Not without writing some code.

However if you look at the process template those defaults are in there, however they are not made available for edit through the Process editor UI.

Of course you can edit the file, and add your Test Configurations manually. The file you are looking for is testconfiguration.xml and it can be found in the Test Management folder of the downloaded process template.

<?xml version="1.0" encoding="utf-8" ?>
    <TestConfiguration name="Windows 7 and IE 8"
                        description="Default operating system and browser for testing" state="active" isdefault="true">
                        name="Operating System" value="Windows 7" />
                        name="Browser" value="Internet Explorer 8.0" />

If you want to add test configurations to a new project edit this file in your process template first. The defaults you put in here will be created in your new project.

Windows Explorer

This is a very interesting Blog post on the history and future of Windows Explorer.

Figure 1 - MS-DOS Executive in Windows 1.0

Figure 9 - Home tab

Filtering Assigned To

Team Foundation Server work items have an assigned to field that defaults to the Valid Users Group. The problem is this group includes service accounts also.


You can easily change the list to contain just the groups you want.

Open up the work item with the Process Editor you get when you install the TFS 2010 Power Tools.

Open the field definition for the Assigned To field in the work item and switch to the Rules Tab.

Remove any rules that are there now. and add Allowed Values and Default.


Edit Allowed Value and set it to the following to get all the project administrators and Contributors along with an unassigned value. Make sure you exclude Groups.


Under Default set the value to be Unassigned.


Now you are all set all that will show up in the AssignedTo drop down is Unassigned along with Project Administrators and Contributors.

Requirements in TFS

Customers are often asking about storing requirement documents with their requirement work item. Specifically what is the best way to do this? I always tell them they have 3 options. Before we talk about that keep in mind there are third party requirement management tools out there that integrate with TFS. Therefore there is a 4th option. Which is to use that tool and have it push requirements into TFS as a work items but store the full fidelity of the requirement in the requirement management tool itself. If you don’t have such a tool here are 3 other options.


The simplest is to just attach your requirement document to the Work item using the attachments tab on the work item. The document is stored in the Database with the requirement and is easily found by others. This is difficult to version though. If you changed the requirement in another release you would have to alter the document and attach it again to another Work item so you can maintain the previous requirement as it was in the previous version.

Versioned Items

If you want to keep versions of the Requirement document you could store it in source control and create a link to it from the work item using a Versioned Item. Then you can point the Work item to a particular version of the document in source control using the Link Type Versioned Items.


The third solution is to store the document in SharePoint. Where you can easily apply workflow to it and version it. Then link it to the Work Item via a Hyperlink link type.

Along the same lines, I was recently asked what if I wanted to change my requirement work item so there was a tab on the Requirement just for Hyperlinks to SharePoint, and remove the Attachments tab so documents can’t be added to the work item.

I’m not sure I would remove the attachments tab it can be handy for many things. However it’s easily removed from the UI. Adding a Tab just for Hyperlinks is a little trickier.

I’ll explain how to do this using the process editor that comes with the TFS power tools. Then also include the XML for the control.

Open the work item type using the process editor, and go to the layout tab.

Add a new Tab under the Tab Group and name it SharePoint Documents or something appropriate.

Create a new control on that Tab and change the control type to a LinksControl

On the Control Settings property click the ellipses button to open the editor. 

In the filter section there are three fields set them like this:

  • Work Item Type Filters – Exclude - Select all Work Item Types
  • Work item Link Filters – Exclude - Select all Work Item Filter Types
  • External Link Filters – Include – Workitem Hyperlink

Might as well remove all the columns except for Title and System.Links.Comment

Once you apply this change to your Project you will have a new tab that only allows Hyperlinks to be added.

As promised here is the XML for the new Tab with Links Control

<Tab Label="SharePoint Documents">
            <Control Type="LinksControl" Label="" LabelPosition="Left">
                  <LinkColumn LinkAttribute="System.Links.Comment" />
                  <LinkColumn RefName="System.Title" />
                <WorkItemLinkFilters FilterType="exclude">
                  <Filter LinkType="Microsoft.VSTS.Common.Affects" />
                  <Filter LinkType="System.LinkTypes.Hierarchy" />
                  <Filter LinkType="System.LinkTypes.Dependency" />
                  <Filter LinkType="System.LinkTypes.Related" />
                  <Filter LinkType="Microsoft.VSTS.TestCase.SharedStepReferencedBy" />
                  <Filter LinkType="Microsoft.VSTS.Common.TestedBy" />
                <ExternalLinkFilters FilterType="include">
                  <Filter LinkType="Workitem Hyperlink" />
                <WorkItemTypeFilters FilterType="exclude">
                  <Filter WorkItemType="Bug" />
                  <Filter WorkItemType="Issue" />
                  <Filter WorkItemType="Shared Steps" />
                  <Filter WorkItemType="Task" />
                  <Filter WorkItemType="Test Case" />
                  <Filter WorkItemType="User Story" />