TFS Work Item Hierarchy
Team Foundation Server doesn't natively support work item hierarchy, we all know that. So the question is, how can you create a reasonable workaround to get a work item hierarchy?
Of course, all of these techniques require custom reporting, either some fancy SQL Report MDX code, or your own reporting app. And there isn't easy editing built into Team Explorer or Excel, but it is relatively easy to add the infrastructure to the work item types, then write your own little app to display the hierarchy.
Here are some ideas...
Note: This is not a "best practice" or "supported scenario", it is a workaround. The next version of VSTS may very well support this scenario. Until then...
Create Specific Work Item Types
This is what we use internally for our "Feature Directory" TFS Project. We have completely different work item types (WITs) that implicitly derive a hierarchy by linking the different WITs together. We have a "Value Proposition", an "Experience", and a "Feature" WIT. The hierarchy goes Value Proposition are at the top, the next level are Experiences, then Features are at the bottom.
Add a "Parent ID" Field to the Work Item
This requires a small edit to your WITs. You can simply add a "Parent ID" field to your WIT. Then when you create a new work item, just put the ID of it's parent in the "Parent ID" field. This is the common self-referring one-to-many relational database trick.
Link Work Items Together
This doesn't require any changes to your WITs. If you have a single "Root" work item, then you can link the 2nd tier of work items to that one, the 3rd tier to the 2nd tier, etc. It may look like a flat list of links in the work item, but it makes a nice hierarchy when you print it out. Here is the code to do just this, but with a list of root nodes.
Sample Code: ListLinkedWorkItems.zip
// Note: Look for output in the Output window
using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace ListLinkedWorkItems
{
class Program
{
static void Main()
{
// Opperational parameters
string server = "https://somevstsserver01:8080";
string RootList = "158627,158637,158638,158642,158645";
// Create a list of IDs out of the string
List<int> root = new List<int>();
foreach (string id in RootList.Split(',')) root.Add(int.Parse(id));
// Obtain a reference to the server factory
TeamFoundationServer tfs =
TeamFoundationServerFactory.GetServer(server);
// Obtain the work item store
WorkItemStore store =
tfs.GetService(typeof(WorkItemStore)) as WorkItemStore;
// List to maintain which work item IDs have been visited
List<int> chain = new List<int>(root);
// Iterate through a list of work item IDs
foreach (int id in root)
ShowFullHierarchy(store, id, chain, 0);
}
private static void ShowFullHierarchy(
WorkItemStore store, int parent, List<int> chain, int level)
{
// List of the current work item's linked work items
List<int> subitems = new List<int>();
// Placeholder for a link that is a related work item
RelatedLink link;
// Obtain the current work item from its ID
WorkItem root = store.GetWorkItem(parent);
// Show the user the current work item
WriteWorkItem(root, level);
// Obtain all linked WIs that haven't been visited yet
foreach (Link wiLink in root.Links)
if ((link = wiLink as RelatedLink) != null)
if (!chain.Contains(link.RelatedWorkItemId))
subitems.Add(link.RelatedWorkItemId);
// Add the newly linked items to the list that's been touched
chain.AddRange(subitems);
// Show all newly linked items
foreach (int id in subitems)
ShowFullHierarchy(store, id, chain, level + 1);
}
private static void WriteWorkItem(WorkItem wi, int indent)
{
// Display a work item in a formatted way
System.Diagnostics.Trace.WriteLine(
String.Format("{0}{1,7} {2}",
"".PadLeft(indent * 2), wi.Id, wi.Title));
}
}
}
This produces a list that looks something like this. Note that this list has been modified from it's original state and is now just a sample report.
158627 Figure out a way to make Debugger messaged more visible to the user
161457 Suggestion: Remote Debugging Setup Wizard
113967 Make the options on the 'exception thrown' dialog more descriptive
158637 Debugger Visualizers
114004 Additional hex/text visualizer would be useful
158638 Remove Customer Dissatisfiers
171879 Modify managed symbol provider to locate static members for interop debugging.
112589 DTS: SRX060227603615 - Error: symbol 'i' not found' for a local static
171458 DTS:SRX061115601437 VS 2005 C++ app debug watch wont show class static
113974 Debugger does not load symbols for all appdomains when one module is used
114015 Attach to Process dialog should automatically refresh process list.
64926 Attach to Process dialog should automatically refresh process list.
148715 Allow "module loaded/unloaded" message in debugger to be disabled
125068 Just-in-time debugger after uninstallation
158642 Debugger Help, Support, Troubleshooting
158645 Concord
113973 cpde needs to drain debug events from all threads when it receives an event
74929 User should see prompt when user-unhandled exception kills stepper
71708 DTS SRZ060223001628 - Debugger doesn't step through if runing a VB client
75317 cpde needs to drain debug events from all threads when it receives an event
114052 "Changes are not allowed when debugger has been attached" dialog disrupts flow
69261 DTS SRX060215601001 Debugger: Unable to edit class library in VB with ASP.net
127479 Breakpoints don't work in mixed debugger when inside InternalCall methods
Taking it a Step Further
Some additional ideas to take this to the next level:
- Put the display into a web page (or SharePoint part)
- Save the results as an XML file that can be viewed & grouped in Excel, or displayed with a nice XSL->HTML
- Make the app a command line app (or better yet, a PowerShell commandlet)
- Use Crystal Reports to code a custom report
Resources
- MSDN: Walkthru: Extending Work Items
- Brian Harry on The Makings of VSTS Work Item Types
- Download: Visual Studio 2005 SDK v3.0
This contains a number of great examples on coding with the TFS Object Model, including the Work Item Object Model Sample - GoEleven.com on VSTS - The workitem client API
Comments
Anonymous
February 01, 2007
Jeff Beehler on Try out our Virtual Labs. Noah Coad on TFS Work Item Hierarchy. The Team Foundation...Anonymous
December 06, 2007
There is another option. I wrote a custom work item control. http://www.codeplex.com/WorkItemHierarchy Add the 'ParentWorkItemId' field as stated above, and use my custom control in the layout section of the WIT definition.