TFS 2012 has improved the way that it handles iterations to allow data for iteration start and end dates to be included as metadata in-line with an iteration path.

clip_image002

Recently I was working with a customer upgrading from TFS2010 to TFS2012 wanting to upgrade the features of their Microsoft Scrum v1.0 projects to include all the new TFS2012 features.

TFS2012 has a great upgrade story and once TFS is upgraded it is very simple to add the new TFS2012 functionality to existing projects (including Microsoft Scrum v1.0 based projects) detailed here on MSDN: http://msdn.microsoft.com/en-us/library/ff432837.aspx

The customer I was working with had a large number of Sprint work items in their project which contained fields with start an end dates that they wanted migrating into TFS2012 and automatically setup the new iteration start and end date metadata.

I wrote the below sample code as a way of querying their existing sprint work items and use this list to set the relevant iteration path start/end date metadata (because of the way Sprint work items in the scrum template work my upgraded project was guaranteed to have an iteration path entry for each sprint work item that existed):

using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
 
 
namespace IterationUtil
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length!=4)
            {   
                OutputUsageInfo();
                return;
            }
 
            string ProjectName = args[3];
            string rootNode = "\\" + ProjectName + "\\ITERATION";
 
            TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri(args[1]));
            tfs.EnsureAuthenticated();
 
            ICommonStructureService4 css = tfs.GetService<ICommonStructureService4>();
            WorkItemStore wit = tfs.GetService<WorkItemStore>();
 
            string WIQL = string.Format("SELECT [System.Id], [System.WorkItemType], [System.Title], " +
              "[System.AssignedTo], [System.State] FROM WorkItems WHERE [System.TeamProject] = '{0}'" +
              " AND [System.WorkItemType] = 'Sprint' ORDER BY [System.Id]", ProjectName);
 
            WorkItemCollection wic = wit.Query(WIQL);
            foreach (WorkItem wi in wic)
            {
                string iterationNode = wi.IterationPath.Substring(ProjectName.Length);
 
                DateTime start = Convert.ToDateTime(wi.Fields["Microsoft.VSTS.Scheduling.StartDate"].Value);
                DateTime finish = Convert.ToDateTime(wi.Fields["Microsoft.VSTS.Scheduling.FinishDate"].Value);
 
                NodeInfo ni = css.GetNodeFromPath(rootNode + iterationNode);
                css.SetIterationDates(ni.Uri,start,finish);
            }
        }
 
        static void OutputUsageInfo()
        {
            Console.WriteLine("Usage: IterationUtil.exe /collection <collection_url> /project <project_name>");
        }
    }
}

 

As it turns out the real work here is done on the new functionality in the new Common Structure Service (see ICommonStructureService4 documentation in MSDN: http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.server.icommonstructureservice4.aspx). Specifically SetIterationDates does the heavy lifting for us, however I thought the above utility code may help anyone else wanting to avoid re-keying lots of existing and future sprint start/end dates into the new metadata format as part of your migrations.

Colin.