12

我需要一个在构建之间进行的变更集(或工作项)列表(如果需要,我可以标记构建)。我需要我们的测试团队使用该列表(并发布“更改列表”)。

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

4

7 回答 7

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
      }
    }
  }
}

希望这可以帮助下一个尝试完成任务的人!

于 2012-01-27T01:03:53.400 回答
3

我知道这是旧帖子,但我一直在研究如何完成这个工作好几个小时,我认为其他人可能会从我整理的内容中受益。我正在使用 TFS 2013,这是从几个不同的来源一起编译的。我知道我现在不记得所有这些,但主要的:

从 Build 中获取关联的变更集

将另一个 Team Build 排队并传递参数

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

请注意,如果您从构建后的 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));
        }
    }
}
于 2014-06-07T18:37:37.780 回答
2

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

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

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

于 2010-01-16T16:49:17.987 回答
1

这篇博文可能是您正在寻找的。您基本上会浏览所有链接,找到包含“变更集”的 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.
        }
    }
}
于 2010-06-26T17:23:06.427 回答
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>
于 2015-03-15T04:01:27.233 回答
0

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

希望有帮助!

于 2014-08-25T16:21:59.767 回答
0

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

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

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

于 2010-01-15T00:01:23.260 回答