【发布时间】:2012-02-28 23:56:03
【问题描述】:
我正在尝试构建一个报告来显示我的各种构建代理的相对效率,并且无法从工具中获取我需要的信息。
我想要的是一个包含以下列的简单网格:
- 内部版本号
- 构建定义
- 构建代理
- 构建状态
- 构建开始时间
- 构建持续时间
这可以让我做一些事情,比如绘制 agent1 上给定构建定义的成功构建持续时间与 agent2 上通过 agentN 的相同构建定义的持续时间。
我该怎么做?
【问题讨论】:
我正在尝试构建一个报告来显示我的各种构建代理的相对效率,并且无法从工具中获取我需要的信息。
我想要的是一个包含以下列的简单网格:
这可以让我做一些事情,比如绘制 agent1 上给定构建定义的成功构建持续时间与 agent2 上通过 agentN 的相同构建定义的持续时间。
我该怎么做?
【问题讨论】:
我最初的意图是向您指出TFS OLAP Cube 并描述如何检索您所追求的东西。然后我意识到立方体没有提供代理构建什么构建的信息。
然后我认为编写一个小型 TFS 控制台应用程序来打印您所追求的信息会很简单:
using System;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
namespace BuildDetails
{
class Program
{
static void Main()
{
TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://TFS:8080/tfs/CoLLeCtIoNNaMe"));
var buildService = (IBuildServer)teamProjectCollection.GetService(typeof(IBuildServer));
IBuildDefinition buildDefinition = buildService.GetBuildDefinition("TeamProjectName", "BuildDefinitionName");
IBuildDetail[] buildDetails = buildService.QueryBuilds(buildDefinition);
foreach (var buildDetail in buildDetails)
{
Console.Write(buildDetail.BuildNumber+"\t");
Console.Write(buildDefinition.Name+"\t");
Console.Write(buildDetail.BuildAgent.Name+"\t");
Console.Write(buildDetail.Status+"\t");
Console.Write(buildDetail.StartTime+"\t");
Console.WriteLine((buildDetail.FinishTime - buildDetail.StartTime).Minutes);
}
}
}
}
这不会编译,因为
最终我进入了IBuildInformationNode[] 并获得了如下构建代理:
IBuildInformation buildInformation = buildDetail.Information;
IBuildInformationNode[] buildInformationNodes = buildInformation.Nodes;
string agentName;
try
{
agentName = buildInformationNodes[0].Children.Nodes[3].Fields["ReservedAgentName"];
}
catch
{
agentName = "Couldn't determine BuildAgent";
}
Console.Write(agentName + "\t");
try-catch 是必要的,因此您可以处理在代理选择之前失败/停止的构建。
如果您使用后一部分来替代失败的 Console.Write(buildDetail.BuildAgent.Name+"\t");,您应该最终使用控制台应用程序,其输出可以通过管道传输到 *.CSV 文件,然后导入 Excel。
【讨论】:
以下代码应有助于获取给定构建详细信息的构建代理名称。
private string GetBuildAgentName(IBuildDetail build)
{
var buildInformationNodes = build.Information.GetNodesByType("AgentScopeActivityTracking", true);
if (buildInformationNodes != null)
{
var node = buildInformationNodes.Find(s => s.Fields.ContainsKey(InformationFields.ReservedAgentName));
return node != null ? node.Fields[InformationFields.ReservedAgentName] : string.Empty;
}
return string.Empty;
}
确保您已刷新构建详细信息对象中的构建信息。您可以通过在获取构建代理之前在构建详细信息对象上调用以下代码来做到这一点
string[] refreshAllDetails = {"*"};
build.Refresh(refreshAllDetails, QueryOptions.Agents);
希望对你有帮助:)
【讨论】:
构建代理信息并不总是在同一个地方。
我在 buildInformationNodes[1].Children.Nodes[2].Fields["ReservedAgentName"] 中找到了我正在查看的构建。以下似乎对我有用(到目前为止)。
private static string GetAgentName(IBuildDetail buildDetail)
{
string agentName = "Unknown";
bool fAgentFound = false;
try
{
foreach (IBuildInformationNode node in buildDetail.Information.Nodes)
{
foreach (IBuildInformationNode childNode in node.Children.Nodes)
{
if (childNode.Fields.ContainsKey("ReservedAgentName"))
{
agentName = childNode.Fields["ReservedAgentName"];
break;
}
}
if (fAgentFound) break;
}
}
catch (Exception ex)
{
// change to your own routine as needed
DumpException(ex);
}
return agentName;
}
【讨论】: