TFS 2010 and getting list of associated changesets and work items

Hi,

I need to get a list of associated change sets and work items for the current TFS build in order to generate some "release notes".

To do this I wrote a small program in C#. It accepts some command line arguments, including the TFS build number, and based on these it extracts information about each changeset and work item and export these to some xml files.

The program works just fine when I call it from a command line after a build has completed.

Next I added a "Execute Program" action in my FB script and this also executes the program, but no changesets or work items are exported.

Digging into the TFS workflow templates leads me to belive that this is because the information is not yet "committed" for a running build, and the info is thus only available on the build agent.

Next I tried to add an "InvokeProcess" activity to the FinalBuilderBuild.xaml template right after the FinalBuilder activity. Again my program is called correctly but is unable to locate any changesets or work items. Probaly due to the same problem as above....

 

Question 1: Is there any way I can get this info by calling my program anytime during the build run?

Question 2: Would it be possible to add a feature to FB that lists the info in a variable/list available in FB script?

Any help would be much appreciated.

 

br Lars

 

If I understand your needs, we already have it built in :slight_smile:

In your TFS Build Definition, make sure that the ‘Create Trigger File List’ option is set to true (that’s the default). Then add a Trigger Files Iterator to your FB project. Let me know if you run into any problems or it that isn’t actually what you’re trying to achieve.

Getting the changesets for a non-commited build was a bit of a pain due to some poor TFS API documentation. If you find that you still need to query TFS directly let me know and I’ll dig through our code and find the bits that will hopefully help you out.

Cheers,

Ben

I think what you are seeing here is typical TFS.

It doesn’t actually associate the changesets with the build until it’s completed (not all that useful!). We had to jump through hoops to get this working in FB, from memory it was a case of lookup the last successful build, the get all the changesets since then, not at all trivial and completely different between TFS2008 and 2010.

Hi,

Yes, TFS really isn't always acting as one might assume it would, and the docs are not all that elaborate

br Lars

 

 

Hi Lars,
Thanks for finding that bug - I'll have a look and fix it. I'll also see if we can restrict the fileset info to the current workspace.

To get Changesets and WorkItems, you'll probably have to resort to your own app. Here's a cut-down version of the code we use to pull the changes out of TFS, including an explanation about why its done this way:

Edit: code removed, see below

This is part of the code that's run on the agent, before FinalBuilder is called. Hope that's somewhat useful.

Cheers,

Ben

The forum software manged the code. Hopefully this is readable:

[code]/* For "efficiency" reasons, Changeset.Changes is almost always empty.* The only way to get a Changeset with Changes populated to to query * VersionControlServer and set the includeChanges parameter to true.* * Unfortunately you can't just query VCS for a specific changeset - you * have to use a date range. So, we find the most recent successful build* from the current build's definition, and find all changes since it ran.* * As it is, the 'unpopulated' nature of Changeset.Changes isn't documented in the * API doco. There may well be a better way to get populated Changesets, but I can't* find it.* * For info, this is the only reference I found:* http://blogs.msdn.com/bharry/archive/2008/07/09/working-on-tfs-sdk-improvements.aspx*/ IBuildDefinition buildDef = _context.GetValue<IBuildDetail>(BuildDetail).BuildDefinition;DateTime? comparison = null;IBuildDetail[] details = buildDef.QueryBuilds();// get the most recent successful build - we want changesets after this dateforeach (IBuildDetail detail in details) { if (detail.Status == BuildStatus.Succeeded || detail.Status == BuildStatus.PartiallySucceeded) { if (!comparison.HasValue || detail.StartTime > comparison) comparison = detail.StartTime; }} if (!comparison.HasValue){ return null;}IEnumerable history = vcs.QueryHistory("$/" + _context.GetValue(TeamProject), VersionSpec.Latest, 0, RecursionType.Full, null, new DateVersionSpec(comparison.Value), VersionSpec.Latest, Int32.MaxValue, true, false);foreach (Changeset changeset in history){ //… whatever} [/code]

As a follow-up on the workspace issue: I’ve been digging around and from what I’m reading it doesn’t seem like its (easily) do-able, see for example:

http://stackoverflow.com/questions/4788119/how-to-get-a-list-of-files-from-tfs-modified-on-a-certain-date-in-the-specified-w

TFS doesn’t seem to provide any linkage between a workspace and a changeset at the API level, unfortunately.

PS - the other bug is fixed and they’ll be a new build out later today.

Ben

Hi again Lars,
Here’s a link to the build with the CreateTriggerFile fix: https://www.finalbuilder.com/downloads/finalbuilder/aex6/FB700_1068.exe

Cheers,

Ben

Hi Ben,

 

Thanks for posting the fix.

Regarding getting the correct changesets and thus the trigger file list could it not be done in the following way using you code as the basis?:

- Obtain the "current" WorkSpace. As I understand it then TFS will create a new workspace for each build and map the folders specified on the build definition into this workspace.

- Iterate over the WorkSpace.Folders property calling vcs.QueryHistory(WorkSpace.Folders) instead of just passing the full project folder.

- Combining the returned Changesets into the full list of changesets for the workspace/build.

 

Second question. In the default workflow template there is an activity called AssociateChangesetsAndWorkItems. It takes two labels as input and returns a list of changesets. Is there no way to call the functionality of this activity from code? I looks like its in a namespace called something like "Microsoft.TeamFoundation.Build.Workflow ....." but I don't have that dll on my machine.

 

P.S. When I get a mail about new posts in the forum, the link to the post inside the mail doesn't work.

 

br Lars

 

Hi Lars,
Sorry for the late response - I was off yesterday.

Re TeamFoundation.Build.Workflow, you should find it in C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Build.Workflow.dll (or eqiv). Nothing like needing to reference ‘PrivateAssemblies’ to integrate with a product. Have I mentioned my dislike for TFS? :slight_smile:

Re the forum email link - we know about it and have been going back and forth with the support guys for the forum software, but unfortunately haven’t been able to get it working. Hopefully we’ll have it resolved soon.

Thanks for the suggestion re queryhistory and workspace folders - I"ll look into it and see if I can get something working.

Cheers,

Ben

Hi again Lars,
From my rudimentary testing, using Workspace.Folders seems to be producing the correct changeset info. Can you please grab that latest test build from https://www.finalbuilder.com/downloads/finalbuilder/aex6/FB700_1075.exe and let me know if its doing what you expect?

Cheers,

Ben

Hi Ben,

 

Looks like its working correctly with the applied changes.

 

Thanks, Lars

Good stuff, thanks for getting back to me.

Ben

We are doing a similar thing with TFS. We need to be able to do a delta get based on changesets related to work items. We have already created a action that will take in a work item and return the related change sets. We found that the normal TFS get from a changeset does not just get the files that are were changed in that changeset relative to the folder path that you can specify on the get operation. It actual tries to do a workspace/folder refresh. So we are creating our own action that will take in a changeset id, a tfs folder (root) and a path to get to. It will go through the changeset and only get the files that have the root path. The root path is necessary because TFS allows you to check in in one changeset changes across branches.
Our overall get process is to query TFS for PBIs related to the sprint. I am having issues with the FinalBuilder TFS Work Item Query action (see other thread). Then iterate through the PBI, calling our custom action to get the changesets. Put the returned changeset into a list, remove dups and sort ascending. Then iterate that list and call our Get custom action to get the files.
thanks,
Garth