Released a new Codeplex project: WITSynchronizer

Working with many clients on ALM and development processes I am often in a situation like this: I create a Process Template for the client and then create a Team Project based on it. The Team Project will become the “reference Team Project”, the main one for Process evolution. Then the client or I are making modifications on the existing Team Project (modify WIT, add new ones, create new WIQLs) when we want to upgrade the development process. Now it’s fine, but what happens when you have to start another Team Project (or you already had), and want it to be synchronized with the Work Item Types and WIQL of your “reference Team Project”? It is possible, but it’s not as easy as it should be…. You have to export the WIT and WIQL definition in local, download the Process Template, replace the WIT definition XML files, add new WIT and WIQL, references them in the WorkItems.xml and finally uploading the Process Template back to your Team Foundation Server. If you want to update a Team Project, the operation is less tedious, but still you have to perform the same set of tasks for each WIT and WIQL, one by […]

Modifying Work Item Type definition using the Object Model

I’m in the process of easing the installation of the Work Item Creator. To do that, I wanted to detect in runtime if a given Team Project doesn’t have its Work Item Types (WITs) supporting hierarchy and then asking the user to add them. It’s not very complicated to do, once you know how to do it (as always you might say). To get the definition of a given Work Item Type and add a field, it’s not complicated: 2412 // Get the Xml Document for the given WIT  2413 XmlDocument doc = wit.Export(false);  2414 XmlElement fields = doc.SelectSingleNode("*/WORKITEMTYPE/FIELDS") as XmlElement; 2415  2416 // Look for each field, and add the ones that are not present 2417 XmlElement field = fields.SelectSingleNode("FIELD[@refname="Cegedim.ParentWI"]") as XmlElement; 2418 if (field == null) 2419 { 2420     field = doc.CreateElement("FIELD"); 2421     field.SetAttribute("name", "ParentWI"); 2422     field.SetAttribute("refname", "Cegedim.ParentWI"); 2423     field.SetAttribute("type", "Integer"); 2424     field.InnerXml = "The ID of the Parent Work Item"; 2425     fields.AppendChild(field); 2426 } To validate the type before importing it: 2453 WITValidateSucceed = true; 2454 prj.WorkItemTypes.ImportEventHandler += new ImportEventHandler(WorkItemType_ValidationEventHandler); 2455 WorkItemType.Validate(prj, doc.OuterXml); 2456 if (WITValidateSucceed == false) 2457 { 2458     MessageBox.Show("Work Item Type couldn’t pass validation, something went wrong", "Work Item Creator", MessageBoxButtons.OK, MessageBoxIcon.Error); 2459     return false; 2460 } The registered event will be fired if […]

Get files from a Label

This post may be helpful for the people who are looking to get the content of a given label in a Workspace. I looked for the code snippet on the internet unsuccessfully, to finally ask for help on the TFS Forum.       VersionControlLabel[] labels = sourcecontrol.QueryLabels(labelname, "$/", tfs.AuthenticatedUserName, false, null, null, false);       if (labels.Length>0)   {     LabelVersionSpec lvs = new LabelVersionSpec(labels[0].Name);     workspace.Get(lvs, GetOptions.None);   } As you can see, it’s really simple once you know about the LabelVersionSpec class and that you can use it with the Workspace::Get(VersionSpec, GetOptions) method. There are several classes that derive from the VersionSpec one: ·         ChangeSetVersionSpec, to get the content of a given changeset into your workspace. ·         DateVersionSpec, to get the content that were checked in until the given date. ·         LabelVersionSpec, to get from a label. ·         LatestVersionSpec, to get the latest version. ·         WorkspaceVersionSpec, to get the content of another Workspace.

Simple way to create Work Item Hierarchy

Create a custom field in all your concerned Work Items named "ParentWI" for instance, of type integer.   Now, say you want to link two Work Items, the method will looks like: public void LinkWorkItems(WorkItem parent, WorkItem son) {     RelatedLink rl = new RelatedLink(son.Id);     rl.Comment = "";     parent.Links.Add(rl);     son.Fields["ParentWI"].Value = parent.Id;     son.Save();     parent.Save();     son.SyncToLatest(); }   I put a specific comment in the link to mark it as a hierarchy kind of link. Take care to the last line, you may wonder why I do a SyncToLatest(), the reason is quite simple: Work Item links are bi-directionals. Once you link a Work Item A to a Work Item B, the opposite link is created automatically when you save A. Then you better do a SyncToLatest() to get the other Work Item up to date. For our hierarchy evaluation, it might be a problem because you don’t know if the links you’ll evaluate are for children or the parent. But there’s a simple way to evaluate if a given link is to a child: just get the ParentWI of that child and compare it with the current Work Item ID. Here’s a snippet of […]

Getting Work Items from the Store

 There’re few things I want to share about the WorkItemStore::GetWorkItem() method.First, it may sound clear for everybody, but: WorkItem a = wis.GetWorkItem(10); WorkItem b = wis.GetWorkItem(10); The instance a and b won’t be the same, you’ll have two separate objects for the same Work Item! WorkItem instances could have been considered as singleton, with only one instance of a given WorkItem in the store. Would that made sense to you? Personally, yes, it would. GetWorkItem() is slooooow, I mean it, really, on my WebService which tracks states changes to synchronize related work item, I found out that 90% of the time execution was in that call (believe me, there’re much more than that in this WebService).As I was getting many time the same ID, I quickly made a class that implement a Work Item cache, based on a List<> (I know it’s maybe not the fastest way to find a occurrence from a given key, but well…)On my WebService, it turns out I was six times faster with this implementation…If Work Item were considered as singleton, I think I wouldn’t have had this performance issue. And one last thing: if you modify a, then b, then a.Save() and b.Save(), you’ll […]