Welcome to MSDN Blogs Sign in | Join | Help

Exporting Areas and Iterations

A couple of days ago someone asked me how to export the areas and iterations from one project and be able to use them as a template to create other projects.  Creating a set of pre-defined Areas & Iterations is a feature of the TFS process templates.  In this post I've included a sample to show how to export the Areas and Iterations of an existing project into the format required for the Project Creation Wizard to use.

It is a command line tool with usage of the following form:

ExportClassifications /server:<yourserver> <yourproject>

This will create a file called Classification.xml that contains properly formatted XML for the Project Creation Wizard to use.

The only things that remain are

  • Export your Process Template using Team -> Team Foundation Server Settings -> Process Template Manager
  • Replace your the Classifications\Classifications.xml with the one generated by ExportClassifications
  • Use Process Template Manager to upload the updated Process Template
  • Start creating projects

I've attached the full sample project and a compiled version of the exe to this post for those who want it.  I've also included here the "heart" of the code that does the real work if you're just intersted in the API mechanics.

    // Connect to the server.
    TeamFoundationServer tfs = new TeamFoundationServer(server);

    // Get the common structure interface.
    ICommonStructureService css = (ICommonStructureService)tfs.GetService(typeof(ICommonStructureService));

    // Get the project we want to operate on.
    ProjectInfo projectInfo = css.GetProjectFromName(project);

    // Create the XML document that we are going to write the areas and iterations to.
    XmlDocument doc = new XmlDocument();
    doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));

    // Create the tasks top level node.
    XmlNode parent = doc.CreateNode(XmlNodeType.Element, "tasks", String.Empty);
    doc.AppendChild(parent);

    // Create the node for the CommonStructureService task.
    XmlNode child = doc.CreateNode(XmlNodeType.Element, "task", String.Empty);
    AddAttribute(doc, child, "id", "UploadStructure");
    AddAttribute(doc, child, "name", "Creating project structure");
    AddAttribute(doc, child, "plugin", "Microsoft.ProjectCreationWizard.Classification");
    AddAttribute(doc, child, "completionMessage", "Team project structure created.");
    parent.AppendChild(child);
    parent = child;

    // Create the node to contain the data for the CommonStructureService task.
    child = doc.CreateNode(XmlNodeType.Element, "taskXml", String.Empty);
    parent.AppendChild(child);
    parent = child;
    XmlNode taskXmlNode = child;

    // Create the container for the root level CSS heirarchy nodes.
    child = doc.CreateNode(XmlNodeType.Element, "Nodes", String.Empty);
    parent.AppendChild(child);
    parent = child;

    // Get the list of heirarchies from the server.
    NodeInfo[] nodes = css.ListStructures(projectInfo.Uri);
    foreach (NodeInfo node in nodes)
    {
        // Handle the root nodes in the hierarchy specially because they have slightly different
        // naming and attribute handling.
        String name;
        if (node.StructureType == "ProjectModelHierarchy")
        {
            name = "Area";
        }
        else
        {
            name = "Iteration";
        }
        child = doc.CreateNode(XmlNodeType.Element, "Node", String.Empty);
        AddAttribute(doc, child, "StructureType", node.StructureType);
        AddAttribute(doc, child, "Name", name);
        AddAttribute(doc, child, "xmlns", String.Empty);
        parent.AppendChild(child);

        // Get the XML for this CSS Hierarchy.
        XmlElement parentXmlNode = css.GetNodesXml(new String[] { node.Uri }, true);

        // Skip down the hierarchy past the root node (which contains the same data as in the
        // NodeInfo that we got with ListStructures).
        XmlNode inNode = parentXmlNode.ChildNodes[0];
        if (inNode.ChildNodes.Count > 0)
        {
            inNode = inNode.ChildNodes[0];
            WriteNodes(doc, child, inNode.ChildNodes);
        }
    }

    // Write the reference to the project mapping file.
    child = doc.CreateNode(XmlNodeType.Element, "properties", String.Empty);
    taskXmlNode.AppendChild(child);
    parent = child;
    child = doc.CreateNode(XmlNodeType.Element, "property", String.Empty);
    AddAttribute(doc, child, "name", "MSPROJ");
    AddAttribute(doc, child, "value", @"Classification\FileMapping.xml");
    AddAttribute(doc, child, "isFile", "true");
    parent.AppendChild(child);

Brian

Published Monday, August 28, 2006 9:46 AM by bharry
Attachment(s): ExportClassifications.zip

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# VSTS Links - 08/28/2006

Monday, August 28, 2006 11:05 AM by Team System News
The Visual Studio Team System User Education blog on New Team Build Customization Content on MSDN.
...

# re: Exporting Areas and Iterations

Monday, August 28, 2006 12:28 PM by davidacoder
I just had to smile when I saw your code example and thought of the new capabilities of C# 3.0 and XLINQ. This is a prime example, where you do something really, really simple, but the code to do this is awfully hard to read due to the current limitations of the XML APIs.

So, just a very random comment from me :)

# while(availableTime>0) { : VSTS Links

Monday, August 28, 2006 1:34 PM by while(availableTime>0) { : VSTS Links

# re: Exporting Areas and Iterations

Tuesday, August 29, 2006 4:21 AM by Farshid Sedghi
the exe in the attached zip file does not execute this part of the code properly (probably the bug was fixed after compiling the exe?)

# re: Exporting Areas and Iterations

Tuesday, August 29, 2006 4:21 AM by farshid
this is the part I meant:

  if (node.Name == "ProjectModelHierarchy")
       {
           name = "Area";
       }
       else
       {
           name = "Iteration";
       }

# re: Exporting Areas and Iterations

Tuesday, August 29, 2006 6:16 AM by bharry
Someone pointed out to me that the top of my post got chopped off in the publishing.  I have fixed that.

You are correct about the mistake.  It should have read

if (node.StructureType == "ProjectModelHierarchy")

I have fixed the sample and the attachment.

Brian

# Bug with nested children

Friday, November 02, 2007 4:09 AM by Arjan

When I tried to import the generated areas in my team project template, verification of the generated XML file failed.

Nested children where generated as:

<node/>

<children/>

Instead as:

<node>

 <children/>

</node>

This was fixed by changing the line:

WriteNodes(doc, outParent, child.ChildNodes[0].ChildNodes);

into:

WriteNodes(doc, outChild, child.ChildNodes[0].ChildNodes);

Arjan

# Bulk update of TFS Areas with ICommonStructureService

Saturday, June 06, 2009 5:48 PM by jampick's WebLog

I recently had to create an area tree, in a TFS project, with&#160; large number (500+) of nodes.&#160;

# Tune Up Your PC &raquo; Post Topic &raquo; Bulk update of TFS Areas with ICommonStructureService

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker