I want to build a Query App that, which will query a branch in TFS, and retrieve all work items and display it as Master Detail report as such:
User Story:30669 [Closed] Ongoing Support and Maintenance
Task:31566 [Closed] Upgrade latest version of client libraries
Bug:30905 [Closed] Executing Error "The given Key was not present in the dictionary"
User Story:30351 [Closed] Add new Function
Task:28188 [Closed] Implement new Function
This will give us a good idea, of what work we have done on a given branch, and what will be in a build if we choose to build.
So currently I can retrieve all the work items for a branch between dates, excluding merges. I want to include merges, but I am struggling to understand TFS client interface.
This is what I have so far: The BranchModel
, ChangesetModel
, UserStories
, and TaskBugs
are classes to help me arrange WorkItem
objects for the output report:
const String c_collectionUri = "http://tfsServer:81/tfs/ProjectCollection";
const String c_projectName = "Project";
using (TfsTeamProjectCollection tpc =
new TfsTeamProjectCollection(new Uri(c_collectionUri)))
{
VersionControlServer vcServer =
tpc.GetService<VersionControlServer>();
WorkItemStore workItemStore = tpc.GetService<WorkItemStore>();
// Fetch the branch history
var history = vcServer.QueryHistory(@"$/ProjectCollection/Project/Branch1/Source", RecursionType.Full)
.Where(h => h.CreationDate >= new DateTime(2018, 1, 1) && h.CreationDate <= new DateTime(2018, 1, 5));
BranchModel branch = new BranchModel("Branch1");
// Get the changesets, for from the fetched history
List<Changeset> changesets = new List<Changeset>();
foreach (Changeset changeset in history)
{
changesets.Add(changeset);
// TODO: Add code to get Changesets related to merge
}
// Get the WorkItems from Changesets Fetched
foreach (Changeset changeset in changesets)
{
ChangesetModel changesetModel = branch.AddChangeset(changeset);
foreach (WorkItem workItem in changeset.WorkItems)
{
// Fetch the UserStory for a Bug/Task
foreach (var linkedItem in workItem.Links)
{
RelatedLink relatedItem = linkedItem as RelatedLink;
WorkItem userStory = null;
if (relatedItem != null)
userStory = GetWorkItem(workItemStore, c_projectName, relatedItem.RelatedWorkItemId);
if (userStory != null)
{
var userStoryModel = branch.AddUserStory(userStory);
var taskBugModel = userStoryModel.Add(workItem);
}
}
}
}
// Finally print the report
Console.WriteLine();
Console.WriteLine("Related Work:");
Console.WriteLine("=".PadLeft(80, '='));
foreach (var userStory in branch.UserStories)
{
Console.WriteLine(userStory.Value.ToString());
foreach (var taskBug in userStory.Value.TaskBugs)
{
Console.WriteLine(taskBug.Value.ToString());
}
}
And the Method for GetWorkItem:
void WorkItem GetWorkItem(WorkItemStore workItemStore, string c_projectName, int workitemID)
{
return workItemStore.Projects[c_projectName].Store.GetWorkItem(workitemID);
}
I would like to know, for a Changeset
that happens to be a merge, how to get it's related work items related to that merge.
You cannot get the related work items directly from the merge changeset. You need to get the merge history (version from
, version to
), then retrieve the related work items from the version from
and version to
changesets.
You can use the VersionControlServer.GetChangesForChangeset
Method to get the merge history for the merge changeset. Then Get the WorkItems from the history Changesets Fetched.
Below sample for your reference to get the merge changeset history:
static void Main(string[] args)
{
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("http://server:8080/tfs/DefaultCollection"));
new System.Net.NetworkCredential("username", "password");
tpc.EnsureAuthenticated();
VersionControlServer vcs = tpc.GetService<VersionControlServer>();
int cid = 376;
//List<IChangesetSummary> changeSets = InformationNodeConverters.GetAssociatedChangesets(build);
IEnumerable<Change> changes = vcs.GetChangesForChangeset(cid, false, Int32.MaxValue, null, null, true);
foreach (Change change in changes)
{
if ((change.ChangeType & ChangeType.Merge) == 0) continue;
foreach (var m in change.MergeSources)
{
Console.WriteLine("{0} {1} {2} {3}", change.Item.ChangesetId, m.ServerItem, m.VersionFrom, m.VersionTo);
}
}
Console.ReadLine();
}