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

发布于 2024-08-18 02:50:22 字数 183 浏览 5 评论 0原文

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

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

I need a list of changesets (or Work Items) that were made betweend builds (I can label builds if its necessary).
I need that list for our test team (and to publish 'changelist').

Is MSBuild task able to retrieve that list and save as file (then I can process that list further.
Or maybe I need to connect to TFS from C# code and retrieve that list myself (I'm familiar with retrieving WorkItems in C#).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

演出会有结束 2024-08-25 02:50:22

我知道这个线程已经有几年了,但我在尝试完成同样的事情时发现了它。
我已经为此工作了几天,并提出了完成此特定任务的解决方案。 (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
      }
    }
  }
}

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

I know this thread is a couple of years old, but I found it when trying to accomplish the same thing.
I've been working on this for a couple of days now, and came up with a solution that accomplishes this specific task. (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
      }
    }
  }
}

Hope this helps the next person trying to accomplish the task!

苏大泽ㄣ 2024-08-25 02:50:22

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

从构建中获取关联的变更集

将另一个团队构建排队并传递参数

我在我找到的大多数文章中缺少的内容这个主题是如何获取构建细节并加载关联的变更集或工作项。 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));
        }
    }
}

I know this is old post but I have been digging around for how to accomplish this for many hours and I thought someone else might benefit from what I have put together. I am working with TFS 2013 and this was compiled together from several different sources. I know I don't remember them all at this point but the main ones where:

Get Associated Changesets from Build

Queue a Team Build from another and pass parameters

What I was missing from most articles I found on this subject was how to take the build detail and load the associated changesets or work items. The InformationNodeConverters class was the missing key for this and allows you to get other items as well. Once I had this I was able to come up with the following code that is pretty simple.

Note that if you are running this from a post build powershell script you can use the TF_BUILD_BUILDURI variable. I have also included the code that I came up with to take the summary data retrieved and load the actual item.

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));
        }
    }
}
放手` 2024-08-25 02:50:22

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

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

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

TFS will automatically produce a list of all change sets and associated work items checked-in between two successful builds. You will find the lists at the end of the build report.

You could set up a build that is used to communicate with the testers. When that build is build successfully the testers could just look at the build report to see what work items and change sets has been committed since the last build.

If you set up an event listener for the build quality property of a build you could send an email alert to the testers when that builds quality filed changes to a specific version.

有深☉意 2024-08-25 02:50:22

我们为每个构建都有构建标签,它们与构建号相同,与我们的 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>

We have build labels for each build, they are the same as build number, which is the same as the product version number that our QA and Support operate on.

So, this works for us:

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

results look like this:

Changeset User              Date       Comment
--------- ----------------- ---------- -------------------------------------    ----------------
3722      Sergei Vorobiev   2013-11-16 Merge changeset 3721 from Main
3720      <redacted>
3719      <redacted>
乱了心跳 2024-08-25 02:50:22

这篇博文可能就是您正在寻找的内容。您基本上会浏览所有链接,查找 Uri 包含“变更集”的链接。似乎没有专门的属性来实现这一点。

链接

(从博客复制以防腐烂)

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

This blog post may be what you are looking for. You basically go through all the links finding ones with a Uri containing 'changeset'. There doesn't seem to be a specific property for this.

Link

(copied from blog in case of rot)

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.
        }
    }
}
很酷又爱笑 2024-08-25 02:50:22

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

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

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

We do something similar in our TFS Build process. To do this we created a MSBuild custom task in C# that makes the call to TFS for the items. It is pretty straight forward to create the custom tasks.

Here is an article to get you started with writing MSBuild tasks. http://msdn.microsoft.com/en-us/library/t9883dzc.aspx

I assume you already know how to do the calls to TFS based on your question.

冷情 2024-08-25 02:50:22

我在这里发布了一篇关于如何执行此操作的博客文章:获取 TFS 2013 中指定构建/标签后的更改列表。它提供了一个快速而简洁的功能,用于检索自给定构建/标签以来已更改的文件列表。

希望有帮助!

I posted a blog article on how to do this here: Getting a List of Changes After a Specified Build/Label from TFS 2013. It provides a quick and concise function for retrieving the list of files that have been changed since a given Build/Label.

Hope that helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文