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 a开发者_如何学Gond retrieve that list myself (I'm familiar with retrieving WorkItems in C#).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!
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));
}
}
}
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.
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>
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.
}
}
}
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.
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!
精彩评论