在 TFS 查询中查找所有工作项的变更集详细信息





5.00/5 (3投票s)
从 TFS 生成工作项报告,包括其关联的变更集详细信息
引言
这是一个控制台程序,用于生成Excel报告,显示TFS查询中列出的每个工作项的变更集详细信息。
背景
我遇到一个需求,需要生成一份报告,以确定一个bug是在哪个分支中修复的,例如开发分支或发布分支。仅仅通过创建TFS查询,我无法获得每个变更集的详细信息以及与相应变更集关联的源代码管理项的详细信息。
因此,我决定使用Microsoft.TeamFoundation
库创建一个程序来生成Excel报告。
Using the Code
使用Visual Studio创建一个控制台应用程序,并在引用管理器对话框的扩展选项卡中添加以下引用。
因此,在program.cs文件中,应使用以下命名空间。
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
在app.config文件中添加一些键,这些键说明了TFS服务器、查询名称以及我们正在查找的分支
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="TfsServer" value="http://tfs.yourServer.com:8080/tfs"/>
<add key="TfsProjectName" value="YourTFSProject"/>
<add key="TfsQueryGroup" value="My Queries"/>
<add key="TfsQueryName" value="YourQuery"/>
<add key="ExcelFile" value="C:\TfsReport.xls"/>
<add key="DevBranchName" value="YourDevelopmentBranch"/>
<add key="ReleaseBranchName" value="YourReleaseBranch"/>
</appSettings>
</configuration>
因此,初始需求已经完成,让我们开始编写代码,连接到TFS服务器并使用以下代码获取我们关心的TFS项目
//Initialize TFS Server object
TfsConfigurationServer configurationServer = TfsConfigurationServerFactory.GetConfigurationServer(new Uri(ConfigurationManager.AppSettings["TfsServer"]));
//Get the catalog of team project collections
CatalogNode catalogNode = configurationServer.CatalogNode;
//Get all CatalogNodes which are ProjectCollection
ReadOnlyCollection<catalognode> tpcNodes = catalogNode.QueryChildren(new Guid[]
{ CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None);
//Get InstanceId of a ProjectCollection
Guid tpcId = Guid.Empty;
foreach (CatalogNode tpcNode in tpcNodes)
{
tpcId = new Guid(tpcNode.Resource.Properties["InstanceId"]);
break;
}
//Fill list of projects in a local variable
TfsTeamProjectCollection projectCollection = configurationServer.GetTeamProjectCollection(tpcId);
projectCollection.Authenticate();</catalognode>
现在,我们需要从与所选TFS项目关联的TFS查询中获取工作项
//Get WorkItem Tracking client for workitem collection for selected ProjectCollection
WorkItemStore workItemStore = projectCollection.GetService<workitemstore>();
//Get Project from Tracking client
Project project = workItemStore.Projects[ConfigurationManager.AppSettings["TfsProjectName"]];
//
QueryFolder teamQueryFolder = project.QueryHierarchy
[ConfigurationManager.AppSettings["TfsQueryGroup"]] as QueryFolder;
QueryItem queryItem = teamQueryFolder[ConfigurationManager.AppSettings["TfsQueryName"]];
QueryDefinition queryDefinition = workItemStore.GetQueryDefinition(queryItem.Id);
Dictionary<string, string=""> variables = new Dictionary<string,
string=""> { { "project", queryItem.Project.Name } };
WorkItemCollection workItemCollection = workItemStore.Query
(queryDefinition.QueryText, variables);DataTable dt = CreateDataTable();
获取所选项目的所选工作项的版本控制工件的代码
//Get Source Control/Version Control repository for selected project collection
VersionControlServer versionControlServer = projectCollection.GetService<versioncontrolserver>();
//Get Details of Version Control using artifact provider
VersionControlArtifactProvider artifactProvider = versionControlServer.ArtifactProvider;
一旦我们获得workItemCollection
,我们需要编写LINQ查询来获取所有链接的变更集并找到所需的信息。在这里,我只查找与变更集关联的源文件路径。
//Iterate through each item to get its details
foreach (WorkItem workItem in workItemCollection)
{
DataRow dr = dt.NewRow();
dr["ID"] = workItem.Id;
dr["Title"] = workItem.Title;
//use linq to get the linked changesets to a workitem
IEnumerable<changeset> changesets = workItem.Links.OfType<externallink>().Select
(link => artifactProvider.GetChangeset(new Uri(link.LinkedArtifactUri)));
//iterate through changesets' to get each changeset details
foreach (Changeset changeset in changesets)
{
dr["ChangesetId"] = changeset.ChangesetId;
foreach (Change changes in changeset.Changes)
{
//ServerItem is the full path of a source control file associated to changeset
if (changes.Item.ServerItem.Contains(ConfigurationManager.AppSettings["DevBranchName"]))
{
dr["Fix in DevBranch"] = "Yes";
break;
}
else if (changes.Item.ServerItem.Contains
(ConfigurationManager.AppSettings["ReleaseBranchName"]))
{
dr["Fix in ReleaseBranch"] = "Yes";
break;
}
}
}
dt.Rows.Add(dr);
}
//Write datable to excel file using StreamWriter
WriteToExcel(dt);
为了填充WorkItem
和Changeset
的详细信息,创建一个数据表,也可以使用其他方法。
public static DataTable CreateDataTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Title");
dt.Columns.Add("ChangesetId");
dt.Columns.Add("Fix in DevBranch");
dt.Columns.Add("Fix in ReleaseBranch");
return dt;
}
以下是使用填充了datatable
的表格数据创建Excel文件的函数
public static void WriteToExcel(DataTable dataTable)
{
StreamWriter streamWriter =
new StreamWriter(ConfigurationManager.AppSettings["ExcelFile"], false);
for (int i = 0; i < dataTable.Columns.Count; i++)
{
streamWriter.Write(dataTable.Columns[i].ToString().ToUpper() + "\t");
}
streamWriter.WriteLine();
for (int i = 0; i < (dataTable.Rows.Count); i++)
{
for (int j = 0; j < dataTable.Columns.Count; j++)
{
if (dataTable.Rows[i][j] != null)
{
streamWriter.Write(Convert.ToString(dataTable.Rows[i][j]) + "\t");
}
else
{
streamWriter.Write("\t");
}
}
streamWriter.WriteLine();
}
streamWriter.Close();
}
关注点
这段代码对所有想要自动化TFS报告的人都有益。要了解TFS库扩展的基础知识,请阅读此文。
历史
- 2016年4月14日:初始版本