如何检索在构建之间签入的变更集(或工作项)列表?

时间:2010-01-14 22:28:34

标签: tfs msbuild workitem

我需要一个在构建之间制作的变更集(或工作项)列表(如果必要,我可以标记构建)。 我需要为我们的测试团队提供该列表(并发布'changelist')。

MSBuild任务是否能够检索该列表并保存为文件(然后我可以进一步处理该列表 或者我可能需要从C#代码连接到TFS并自己检索该列表(我熟悉在C#中检索WorkItems)。

7 个答案:

答案 0 :(得分:11)

我知道这个帖子已经有几年了,但是在尝试完成同样的事情时我发现了它。 我一直在研究这个问题几天,并提出了一个完成这项特定任务的解决方案。 (TFS 2010)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Build.Client;


namespace BranchMergeHistoryTest
{
  class Program
  {
    private static Uri tfsUri = new Uri("http://sctf:8080/tfs");
    private static TfsTeamProjectCollection tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsUri);

    static void Main(string[] args)
    {

      IBuildServer buildServer = tfs.GetService<IBuildServer>();
      IBuildDefinition buildDef = buildServer.GetBuildDefinition("Project", "Specific Build");
      IOrderedEnumerable<IBuildDetail> builds = buildServer.QueryBuilds(buildDef).OrderByDescending(build => build.LastChangedOn);
      /* I had to use some logic to find the last two builds that had actual changesets attached - we have some builds that don't have attached changesets. You may want to do the same. */ 
      IBuildDetail newestBuild = builds.ElementAt(0); 
      IBuildDetail priorBuild = builds.ElementAt(1);

      string newestBuildChangesetId = newestBuild.Information.GetNodesByType("AssociatedChangeset")[0].Fields["ChangesetId"];
      string priorBuildChangesetId = priorBuild.Information.GetNodesByType("AssociatedChangeset")[0].Fields["ChangesetId"];

      VersionControlServer vcs = tfs.GetService<VersionControlServer>();
      const string sourceBranch = @"$SourceBranch-ProbablyHEAD";
      const string targetBranch = @"$TargetBranch-ProbablyRelease";
      VersionSpec versionFrom = VersionSpec.ParseSingleSpec(newestBuildChangesetId, null);
      VersionSpec versionTo = VersionSpec.ParseSingleSpec(priorBuildChangesetId, null);
      ChangesetMergeDetails results = vcs.QueryMergesWithDetails(sourceBranch, VersionSpec.Latest, 0, targetBranch,VersionSpec.Latest, 0, versionFrom, versionTo, RecursionType.Full);
      foreach(Changeset change in results.Changesets)
      {
        Changeset details = vcs.GetChangeset(change.ChangesetId);
        // extract info about the changeset
      }
    }
  }
}

希望这有助于下一个尝试完成任务的人!

答案 1 :(得分:3)

我知道这是老帖子,但我一直在四处寻找如何完成这个任务好几个小时,我认为其他人可能会从我放在一起的东西中受益。我正在使用TFS 2013,这是从几个不同的来源汇编而成的。我知道我现在还不记得所有这些,但主要的是:

Get Associated Changesets from Build

Queue a Team Build from another and pass parameters

我在这个主题上找到的大多数文章中缺少的是如何获取构建细节并加载相关的变更集或工作项。 InformationNodeConverters类是缺少的关键,允许您获取其他项目。一旦我有了这个,我就能够提出以下非常简单的代码。

请注意,如果从post build powershell脚本运行此脚本,则可以使用TF_BUILD_BUILDURI变量。我还提供了我想出的代码来获取检索的摘要数据并加载实际项目。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace Sample
{
    class BuildSample
    {
        public void LoadBuildAssociatedDetails(Uri tpcUri, Uri buildUri)
        {
            TfsTeamProjectCollection collection = new TfsTeamProjectCollection(tpcUri);
            IBuildServer buildServer = collection.GetService<IBuildServer>();
            IBuildDetail buildDetail = buildServer.GetAllBuildDetails(buildUri);

            List<IChangesetSummary> changeSets = InformationNodeConverters.GetAssociatedChangesets(buildDetail);
            VersionControlServer vcs = collection.GetService<VersionControlServer>();
            IEnumerable<Changeset> actualChangeSets = changeSets.Select(x => vcs.GetChangeset(x.ChangesetId));

            List<IWorkItemSummary> workItems = InformationNodeConverters.GetAssociatedWorkItems(buildDetail);
            WorkItemStore wis = collection.GetService<WorkItemStore>();
            IEnumerable<WorkItem> actualWorkItems = workItems.Select(x => wis.GetWorkItem(x.WorkItemId));
        }
    }
}

答案 2 :(得分:2)

TFS将自动生成两个成功构建之间签入的所有更改集和关联工作项的列表。您将在构建报告的末尾找到列表。

您可以设置用于与测试人员通信的构建。成功构建该构建后,测试人员可以查看构建报告,以查看自上次构建以来已提交的工作项和更改集。

如果为构建的构建质量属性设置事件侦听器,则可以在构建质量字段更改为特定版本时向测试人员发送电子邮件警报。

答案 3 :(得分:1)

此博文可能就是您要找的内容。你基本上通过所有链接查找包含'changeset'的Uri的链接。似乎没有特定属性。

http://blogs.msdn.com/b/buckh/archive/2006/08/12/artifact-uri-to-changeset.aspx

(在腐烂的情况下从博客复制)

using System;
using System.Collections.Generic;

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.VersionControl.Client;

class ChangesetsFromWorkItems
{
    static void Main(string[] args)
    {
        if (args.Length < 2)
        {
            Console.Error.Write("Usage: ChangesetsFromWorkItems <server> <workitemid> [workitemid...]");
            Environment.Exit(1);
        }

        TeamFoundationServer server = TeamFoundationServerFactory.GetServer(args[0]);
        WorkItemStore wiStore = (WorkItemStore)server.GetService(typeof(WorkItemStore));
        VersionControlServer vcs = (VersionControlServer) server.GetService(typeof(VersionControlServer));

        int workItemId;
        for (int i = 1; i < args.Length; i++)
        {
            if (!int.TryParse(args[i], out workItemId))
            {
                Console.Error.WriteLine("ignoring unparseable argument {0}", args[i]);
                continue;
            }

            WorkItem workItem = wiStore.GetWorkItem(workItemId);
            List<Changeset> associatedChangesets = new List<Changeset>();
            foreach (Link link in workItem.Links)
            {
                ExternalLink extLink = link as ExternalLink;
                if (extLink != null)
                {
                    ArtifactId artifact = LinkingUtilities.DecodeUri(extLink.LinkedArtifactUri);
                    if (String.Equals(artifact.ArtifactType, "Changeset", StringComparison.Ordinal))
                    {
                        // Convert the artifact URI to Changeset object.
                        associatedChangesets.Add(vcs.ArtifactProvider.GetChangeset(new Uri(extLink.LinkedArtifactUri);
                    }
                }
            }

            // Do something with the changesets.  Changes property is an array, each Change
            // has an Item object, each Item object has a path, download method, etc.
        }
    }
}

答案 4 :(得分:1)

我们为每个构建构建标签,它们与构建号相同,这与我们的QA和支持部门运行的产品版本号相同。

所以,这对我们有用:

tf.exe history <BRANCH> /version:L<BUILD_NUMBER_FROM>~L<BUILD_NUMBER_TO> /recursive /collection:http://<our TFS server>

结果如下:

Changeset User              Date       Comment
--------- ----------------- ---------- -------------------------------------    ----------------
3722      Sergei Vorobiev   2013-11-16 Merge changeset 3721 from Main
3720      <redacted>
3719      <redacted>

答案 5 :(得分:0)

我们在TFS构建过程中做了类似的事情。为此,我们在C#中创建了一个MSBuild自定义任务,用于调用项目的TFS。创建自定义任务非常简单。

这是一篇让您开始编写MSBuild任务的文章。 http://msdn.microsoft.com/en-us/library/t9883dzc.aspx

我假设您已经知道如何根据您的问题调用TFS。

答案 6 :(得分:0)

我在这里发布了一篇关于如何执行此操作的博客文章:Getting a List of Changes After a Specified Build/Label from TFS 2013。它提供了一个快速简洁的功能,用于检索自给定的构建/标签以来已更改的文件列表。

希望有所帮助!