Associating changesets and Work Items Since the Last Successful Build
We got a forum post the other day on whether changesets and work items could be associated since the last Successful build. Some of you may be thinking "Isn't that how it already works?" Actually, it's not quite how it works. Changesets and Work Items are, by default, associated since the last "good" build, where "good" means compilation and tests succeeded, but something else may have gone wrong. That is, the last "good" build may well be marked Partially Succeeded and not Succeeded.
I started responding to the forum post, and then figured it would make a good blog post instead. (Of course, I've posted a link to this post in the forums...)
So - to modify the default behavior and associate changesets and work items only since the last successful build, you'll need to do three things:
- Skip the default logic to associate changesets and work items. This is pretty simple - just set the SkipGetChangesetsAndUpdateWorkItems property to true.
- Write a custom task to find the last successful build and return its label.
- Call this custom task and then call the GenCheckinNotesUpdateWorkItems task with its output.
Lucky for you, I've already written the custom task (or at least a simple version of it). Here is the source for it:
using System;
using Microsoft.Build.Framework;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.Client;
namespace BlogProjects
{
public class GetLastSuccessfulBuildLabel : ITask
{
#region Properties
[Required]
public String BuildDefinitionName
{
get
{
return m_buildDefinitionName;
}
set
{
m_buildDefinitionName = value;
}
}
[Output]
public String LastSuccessfulBuildLabel
{
get
{
return m_lastSuccessfulBuildLabel;
}
}
[Required]
public String TeamFoundationServerUrl
{
get
{
return m_teamFoundationServerUrl;
}
set
{
m_teamFoundationServerUrl = value;
}
}
[Required]
public String TeamProject
{
get
{
return m_teamProject;
}
set
{
m_teamProject = value;
}
}
#endregion
#region ITask Members
public bool Execute()
{
TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(TeamFoundationServerUrl);
IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));
IBuildDetailSpec spec = buildServer.CreateBuildDetailSpec(TeamProject, BuildDefinitionName);
spec.MaxBuildsPerDefinition = 1;
spec.Status = BuildStatus.Succeeded;
spec.QueryOrder = BuildQueryOrder.FinishTimeDescending;
IBuildQueryResult queryResult = buildServer.QueryBuilds(spec);
if (queryResult.Builds.Length > 0)
{
m_lastSuccessfulBuildLabel = queryResult.Builds[0].LabelName;
}
return true;
}
public IBuildEngine BuildEngine
{
get
{
return m_buildEngine;
}
set
{
m_buildEngine = value;
}
}
public ITaskHost HostObject
{
get
{
return m_taskHost;
}
set
{
m_taskHost = value;
}
}
#endregion
#region Private Members
private IBuildEngine m_buildEngine;
private ITaskHost m_taskHost;
private String m_teamFoundationServerUrl;
private String m_buildDefinitionName;
private String m_teamProject;
private String m_lastSuccessfulBuildLabel;
#endregion
}
}
Note the fancy querying that is possible with an IBuildDetailSpec - pretty cool...
Calling the custom task should be similarly simple. Something like the following should do the trick:
<Target Name="BeforeGetChangesetsAndUpdateWorkItems">
<GetLastSuccessfulBuildLabel TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
TeamProject="$(TeamProject)"
BuildDefinitionName="$(BuildDefinitionName)">
<Output TaskParameter="LastSuccessfulBuildLabel" PropertyName="LastSuccessfulBuildLabel" />
</GetLastSuccessfulBuildLabel>
<GenCheckinNotesUpdateWorkItems TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
BuildNumber="$(BuildNumber)"
CurrentLabel="$(LabelName)@$(LabelScope)"
LastLabel="$(LastSuccessfulBuildLabel)"
UpdateWorkItems="$(UpdateAssociatedWorkItems)"
ContinueOnError="true" />
</Target>
Hope this helps!
UPDATE: My original post had a typo - the property SkipGetChangesetsAndUpdateWorkItems was missing its And. My apologies to anyone who banged their head against the wall trying to figure out why it wasn't working!
Comments
- Anonymous
July 16, 2008
PingBack from http://blog.a-foton.ru/2008/07/associating-changesets-and-work-items-since-the-last-successful-build/ - Anonymous
July 21, 2008
Ed Glas on New tool for SQL Load testing Lakhminder on TFS 2005: How to do data tier move only The... - Anonymous
June 21, 2011
Good Post.How to do the same in TFS 2010 with workflows? Can yo share the approch?