As part of a project tracking workflow we have various points in the lifecycle of a project where we want to poke data into TFS, and have that data exposed through eScrum.
In particular, we need to:
- Create a new eScrum Product (at the inception of the project)
- Create eScrum Product Backlog items (on a weekly cycle)
After a bit of digging and dissassembling it turns out that it is not that hard to do. The first of the two above tasks implementation is as follows:(note that the eScrumRootAreaPathURI is the URI of the eScrum Team Project - you can find this URI in the team explorer in VS - it will look something like vstfs:///Classification/TeamProject/a1bac9db-c321-4fe6-8a12-fa19b4c2abab):
public static void CreateEScrumProduct(string name, string eScrumRootAreaPathURI, string tfsurl, string username, string password, string host)
{
NetworkCredential account = new NetworkCredential(username, password, host);
TeamFoundationServer server = new TeamFoundationServer(tfsurl, account);
server.Authenticate(); /**
* first the area path for the product must be created in the eScrum team project.
*/
ICommonStructureService ics = (ICommonStructureService)server.GetService(typeof(ICommonStructureService));
NodeInfo[] ni = ics.ListStructures(eScrumRootAreaPathURI);
foreach (NodeInfo n in ni)
{
if (n.StructureType == "ProjectModelHierarchy")
{
ics.CreateNode(name, n.Uri);
break;
}
}
/**
* now a new eScrum product details work item must be created referencing the above
* area path. note that this can fail due to the tfs warehouse not refreshing
* so it is brute forced until a better way is apparent.
*/
Thread t = new Thread(delegate()
{
bool cont = true;
while (cont)
{
try
{
WorkItemStore store = new WorkItemStore(server);
WorkItem item = new WorkItem(store.Projects["Escrum"].WorkItemTypes["eScrum Product Details"]);
item.Title = name;
item.Fields["Area Path"].Value = @"Escrum\" + name;
item.Fields["Assigned To"].Value = "Escrum Team";
item.Save();
cont = false;
}
catch (Exception ex)
{
Trace.WriteLine("failed saving... attempting again in 1000ms");
Thread.Sleep(1000);
cont = true;
}
}
});
t.Start();
}