2011-09-26 101 views
5

我需要在完成TFS 2010中的构建时发送电子邮件,详细说明与作为此构建一部分编译的签入相关的工作项目。这可以通过使用构建工作流中可用的associatedChangesets变量来实现。TFS 2010 API - 从合并中获取工作项目

但是,在生产环境中,我们会将开发分支的更改合并到发布分支中。在这一点上,构建认为只有一个变化 - 这是前面提到的将发展合并到发布中。显然,这是相当无用的,因为我们需要找出合并的分支中的哪些更改以及与之相关联的工作项目

有谁知道如何使用TFS 2010 API完成此操作?从API的角度来看,这似乎相当糟糕。我知道你可以在VS2010中扩展合并历史记录节点,但显然这是不好的,因为这些数据需要以编程方式收集,因此可以发送报告电子邮件。

+0

它可能是这个的重复/子集:http://stackoverflow.com/questions/7536323/how-to-determine-the-work-items-fixed-in-a-particular-tfs-build-when - 使用分支 – pantelif

回答

7

好的......我认为我找到了一个解决方案,虽然它很笨重,而且事实告诉我我不确定它是如何工作的。但是在这里 - 也许它会指出某个人朝着正确的方向前进。

var associatedWorkItems = new List<WorkItem>(); 

//Passed in from the build workflow (this variable is available under the 'Run On Agent' sequence as 'associatedChangesets' 
IList<Changeset> associatedChangesets = context.GetValue(BuildAssociatedChangesets); 

if (associatedChangesets.Count > 0) 
{ 
    var projectCollection = 
     new TfsTeamProjectCollection(new Uri("http://localhost:8080/tfs/DefaultCollection")); 
    VersionControlServer versionControlServer = projectCollection.GetService<VersionControlServer>(); 

    foreach (var changeset in associatedChangesets) 
    { 
     //In order to view the individual changes, load the changeset directly from the VCS. 
     Changeset localChangeset = versionControlServer.GetChangeset(changeset.ChangesetId); 

     foreach (Change change in localChangeset.Changes) 
     { 
      //Find out what was merged in. 
      ChangesetMerge[] mergedChangesets = versionControlServer.QueryMerges(
       null, 
       null, 
       change.Item.ServerItem, 
       new ChangesetVersionSpec(localChangeset.ChangesetId), 
       new ChangesetVersionSpec(localChangeset.ChangesetId), 
       null, 
       RecursionType.Full); 

      //Extract work item information from changesets being identified as merged. 
      foreach (var changesetMerge in mergedChangesets) 
      { 
       Changeset actualChange = versionControlServer.GetChangeset(changesetMerge.SourceVersion); 

       foreach (WorkItem item in actualChange.WorkItems) 
       { 
        if (!associatedWorkItems.Exists(w => w.Id == item.Id)) 
        { 
         associatedWorkItems.Add(item); 
        } 
       } 
      } 
     } 
    } 
} 

不要问我究竟是如何QueryMerges作品,但所有我在这里做它说能告诉我什么东西合并在查了变更的一部分,你会发现,参数ChangesetVersionSpec是相同的 - 这意味着我们只是从这一个变更集合中寻找合并。

您将从QueryMerges()中返回一个ChangesetMerge对象的数组。在ChangesetMerge类中有一个名为SourceVersion的属性 - 这是合并的原始变更集的ChangesetId。一旦我们得到了,我们可以使用VersionControlServer.GetChangeset()方法加载单个集并提取WorkItem。然后将它添加到可以用任何你想要的方式操作的WorkItem列表(在我的情况下是一封电子邮件)。我还使用.Exists()检查来确保相同的WorkItem不会被记录两次。

请注意,即使您从构建工作流中收集'associatedChangesets',出于某种原因(至少对我而言),'associatedChangesets'内的Changes []属性从未被填充过(因此使用VersionControlServer.GetChangeset()方法,因为这似乎实际上填充了我们需要的所有字段。

就像我说的,1.这是一个笨重的解决方案(很多循环 - 其中一些可能是不必要的),2.我不喜欢尽管它看起来能够产生所需的结果,但我完全理解它是如何工作的 - 我通过大量测试和调试得出了这个结论),最后 - 这是我根据微软提供的悲惨文档得出的最好结果。

希望它可以帮助别人!