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

Exporting Work Items for a Project Template

TFS

There comes a time in every TFS implementation where you need to create your own set of default project work items in your template. You can do this straight in the XML by editing workitems.xml in your process template’s Work Item Tracking folder. I said you could, not that you’d actually want to! You can also use the Process Editor to add them one at a time like you do with the Team Foundation client. Uggh. Wouldn’t it be better just to use Excel to put them into a scratch, temporary TF Project? I certainly think so; I can enter work items in Excel a lot faster than I can in the TF Client (or in the Process Editor).

I did some looking about thinking that someone must have solved this already and posted some code, open source, whatever. There was one result that looked promising but … the URL didn’t work (so I’m not posting it here). <Heavy Sigh>

Oh well, time to pop open Visual Studio and start coding …

It turned out that it was pretty easy, in fact. In the sample below, you take a raw work item query (in WIQL) and get the list of work items that you want to export with the columns that you also want to export. The order doesn’t matter. From there, you execute the query against the Work Item Store to get the list of work items. Loop over them and write to XML in the format that the project template uses.

It is, for the most part, really that simple. There are only 2 things that you really have to watch out for. First, the project name should be replaced with a marker for the target project name  ($$PROJECTNAME$$). Second, you need to make sure that the field is applicable to the work item type. This is something that you need to be especially aware of if you have multiple work item types in your default work item set. With all of that … I am proud to present to you … the actual code (exception handling removed for clarity … put yours in!)

public void Export(
string serverName, string projectName, string filePath, string WIQL)
{
TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(
serverName, new UICredentialsProvider() );
tfs.Authenticate();WorkItemStore store = 
(WorkItemStore)tfs.GetService(typeof(WorkItemStore));WorkItemCollection workItems = store.Query(WIQL);using (System.IO.Stream output = 
System.IO.File.Open(filePath, 
System.IO.FileMode.Create, 
System.IO.FileAccess.ReadWrite))
{
using (XmlWriter writer = XmlWriter.Create(output))
{
writer.WriteStartDocument(true);
writer.WriteStartElement("WORKITEMS");
WriteWorkItems(projectName, workItems, writer);
writer.Flush();
writer.Close();
}
}
}
private static void WriteWorkItems(string projectName, WorkItemCollection workItems, XmlWriter writer)
{
for (int i = 0; i < workItems.Count; i++)
{
var workItem = workItems[i];
writer.WriteStartElement("WI");
writer.WriteAttributeString("type", workItem.Type.Name);foreach (FieldDefinition field in workItems.DisplayFields)
{
if (workItem.Fields.Contains(field.Name))
{
writer.WriteStartElement("FIELD");
writer.WriteAttributeString("refname", field.ReferenceName);
writer.WriteAttributeString("value", 
workItem.Fields[field.Name].Value.ToString().Replace(
projectName, "$$PROJECTNAME$$"));
writer.WriteEndElement();
}
}
writer.WriteEndElement();
}
}

In the immortal words of Porky Pig … That’s all folks!