30 December 2008

Get Files Associated with a Build

One of the greatest features of Team Foundation Server is it's extensibility via the TFS Object Model.  A short while back I received a question asking how to retrieve a list of all files included in all the changesets associated with a build.  The intent (of the person asking the question) was to deploy only those files that had been modified in one of the changesets.

The following code example is what I came up with.  I can't say it's the only way, or even the most efficient way, to achieve the desired result, but it's at least one way :-)  I've also posted this example on TFSExamples.com, here.

/// <summary>
/// Gets a list of files included in all changesets associated with the specified build URI.
/// </summary>
/// <param name="tfServerName">The name of the Team Foundation Server server.</param>
/// <param name="buildUri">The URI of the build to retrieve items for.</param>
/// <param name="workspaceName">The name of the workspace that's used to map server items
/// to local items (e.g. to a file on the client machine).</param>
/// <param name="workspaceOwner">The workspace owner.</param>
/// <returns>A list of files included in all changesets associated with the specified
/// build URI.</returns>
/// <remarks>You can specifiy an empty/null <paramref name="workspaceName"/> and/or
/// <paramref name="workspaceOwner"/> if you want a list of server items returned.</remarks>
private List<string> GetFilesAssociatedWithBuild(string tfServerName, Uri buildUri, string workspaceName, string workspaceOwner)
var buildFiles = new List<string>();
Workspace workspace = null;

// Obtain cached instance of TeamFoundationServer (if a match is found). If the current credentials are not
// valid, then a connection dialog will be displayed when EnsureAuthenticated is called below
var tfServer = TeamFoundationServerFactory.GetServer(tfServerName, new UICredentialsProvider());

// Ensure the current user can authenticate with TFS

// Get a reference to the build service
var buildServer = (IBuildServer)tfServer.GetService(typeof(IBuildServer));

// Get a reference to the version control service
var versionControl = (VersionControlServer)tfServer.GetService(typeof(VersionControlServer));

// Get the workspace used to map server items to local items
if (!string.IsNullOrEmpty(workspaceName) && !string.IsNullOrEmpty(workspaceOwner))
workspace = versionControl.GetWorkspace(workspaceName, workspaceOwner);

// Get the build specified by the selected build URI
var build = buildServer.GetBuild(buildUri);
if (build != null)
// Get a list of all changesets associated with the selected build
var changesets = InformationNodeConverters.GetAssociatedChangesets(build);
if (changesets != null)
// Iterate through all changesets associated with the selected build
foreach (var changesetSummary in changesets)
// Get the changeset for the specified ID
var changeset = versionControl.GetChangeset(changesetSummary.ChangesetId);

if (changeset.Changes != null)
// Add each file associated with the current changeset
foreach (var changesetItem in changeset.Changes)
if (workspace != null)
// Since a workspace is available, map the server item to a local item
item = workspace.GetLocalItemForServerItem(changesetItem.Item.ServerItem);
// A workspace was not provided, so return the server item
item = changesetItem.Item.ServerItem;

// Do not add duplicate filenames
if (!buildFiles.Contains(item))
return buildFiles;