Programmatically adding new Work Items to a Team System Project
If you're migrating from another work item tracking system to Team System, you may want to import your existing tasks or bugs from that product into Team System. While you can do this, to a degree, with the built in two-way Excel integration, it will probably be easier to import the work items programmatically.
Fortunately, Team System has an excellent extensibility model which makes it relatively easy to write your own import routines. Here's a skeleton Visual Studio 2005 solution which programmatically creates a new bug and a new task in the Team System project of your choice.
The code is relatively straightforward; it's cribbed directly from the Visual Studio 2005 SDK Team System samples. It's short, so I'll reprint it here:
static string serverName = "http://tsweb01:8080";
static string projectName = "demo";
static void Main(string[] args)
{
Console.WriteLine("Connecting to {0}...", serverName);
TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(serverName);
WorkItemStore store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
Project project = store.Projects[projectName];
AddNewWorkItem(project, "bug", "This bug was created programmatically", "Description goes here.");
AddNewWorkItem(project, "task", "This task was created programmatically", "Description goes here.");
}
/// <summary>
/// Adds a new work item to the specified Team System project
/// </summary>
private static void AddNewWorkItem(Project p, string type, string title, string desc)
{
WorkItemType wit = p.WorkItemTypes[type];
WorkItem wi = new WorkItem(wit);
wi.Title = title;
wi.Description = desc;
//wi.State = "badstate"; // this makes the work item invalid
if (!FieldValidityCheck(wi))
{
Console.WriteLine("new work item has invalid fields and cannot be saved.");
}
else
{
wi.Save();
Console.WriteLine(String.Format("work item {0} added: {1}", wi.Id, wi.Uri));
}
}
/// <summary>
/// Make sure all fields are valid before saving
/// </summary>
private static bool FieldValidityCheck(WorkItem wi)
{
ArrayList invalidFields = wi.Validate();
if (invalidFields.Count == 0)
{
return true;
}
else
{
foreach (Field f in invalidFields)
{
Console.WriteLine("Invalid Field '{0}': {1}", f.Name, f.Status.ToString());
Console.WriteLine("Current Value: '{0}'", f.Value);
Console.WriteLine();
}
return false;
}
}
Obviously, this is an extremely simple Hello World example. But it works! Here's what those two new Work Items look like in the All Work Items Team Query:
The Visual Studio 2005 SDK includes a rather large word doc, "Work Item Tracking Object Model.doc", which documents all of this in much more detail. I highly recommend you dig that up and read through it if you start get into the real nitty-gritty of importing. Here's an essential overview of the WorkItem class from the document, which is definitely enough to get you started:
The major components of a work item are as follows.
- Store – Every work item belongs to a WorkItemStore.
- Project – Every work item belongs to a team project on the Team Foundation Server.
- Type – Every work item is an instance of a specific work item type. The work item type defines the fields, rules, and workflow for the work item. Work item types are scoped to team projects.
- Revision – The revision count for the work item.
- Revisions – The collection of all revisions of the work item. Do not get this confused with the System.History field which is a text field used to track the conversation thread for a work item.
- Fields – The collection of fields defined by the work item type. The value for each Field in the collection can be viewed and edited.
- Links – A collection of outbound links. Work items can link to each other, other artifacts, or URL/UNC paths.
- Attachments – A collection of file attachments that are stored with a work item on the server.
The Fields, Links, and Attachments collections of a WorkItem can be viewed and edited. Once any edits are made to these parts of a WorkItem, the work item is marked as dirty via the IsDirty property.
Changes to a work item are committed to the server via Save() method. Unless a work item is saved, all changes to it will be lost. When saving a work item, rules defined for the work item type will be evaluated. Violations will throw exceptions upon saving. If there are no violations, the work item is successfully saved, its revision is incremented, and its history updated with the latest changes. Note that an IsValid() method can be used to evaluate whether a work item's fields pass all rules before attempting to save the work item.
Each time a work item is committed, a new revision is created for that work item. The latest revision of a work item reflects its current state, while previous revisions reflect the state of the work item at different points in its history. Different revisions of a work item are akin to different versions of source code on a server.
Good luck and happy importing! I also put together a visual class diagram of the WorkItem, if you're interested.