Question

I need some help with a SQL query which will return a list of build definitions that have a specific custom argument in them.

I ran across this query, but I'm having a bit of difficulty figuring out how to drill further down.

;WITH XMLNAMESPACES('clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow' AS mtbwa, 
DEFAULT 'clr-namespace:System.Collections.Generic;assembly=mscorlib'), 
q AS (
  SELECT CAST(bd.ProcessParameters AS XML) p
  FROM dbo.tbl_BuildDefinition bd     
  ) 
SELECT  
  X.Doc.query('mtbwa:BuildSettings') AS 'Node',
  X.Doc.value('(mtbwa:BuildSettings/@ProjectsToBuild)[1]', 'VARCHAR(100)') AS 'ProjectsToBuild'
FROM q 
CROSS APPLY p.nodes('/Dictionary') AS X(Doc)

Here's an example of the XML returned by this query:

<Dictionary x:TypeArguments="x:String, x:Object" xmlns="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <mtbwa:BuildSettings x:Key="BuildSettings" ProjectsToBuild="$/ACME/Dev/v1.0.0/Source/ACME/ACME.sln">
    <mtbwa:BuildSettings.PlatformConfigurations>
      <mtbwa:PlatformConfigurationList Capacity="1">
        <mtbwa:PlatformConfiguration Configuration="ACMS Website" Platform="Any CPU" />
      </mtbwa:PlatformConfigurationList>
     </mtbwa:BuildSettings.PlatformConfigurations>
   </mtbwa:BuildSettings>
   <mtbwa:TestSpecList x:Key="TestSpecs" Capacity="1">
     <mtbwa:TestAssemblySpec MSTestCommandLineArgs="{x:Null}" TestSettingsFileName="{x:Null}" AssemblyFileSpec="**\*test*.dll" CategoryFilter="!CodedUITest" />
   </mtbwa:TestSpecList>
   <mtbwa:SourceAndSymbolServerSettings x:Key="SourceAndSymbolServerSettings" SymbolStorePath="\\ACME.com\dfs\USA\AppDev\TeamBuild\Symbols" />
   <mtbwa:AgentSettings x:Key="AgentSettings" MaxWaitTime="04:00:00" Name="*" Tags="" />
   <x:Boolean x:Key="SCA">False</x:Boolean>
   <x:String x:Key="SSCProjectVersion">ACME v1.0.0</x:String>
</Dictionary>

I'm trying to get to the <x:Boolean x:Key="SCA">False</x:Boolean> part of the returned XML. Any ideas on how I can accomplish this are always appreciated.

SOLUTION
Credit goes to jessehouwing for the suggestion.

TfsTeamProjectCollection server = new TfsTeamProjectCollection(new Uri("http://acmetfs:8080/tfs"));
server.EnsureAuthenticated();
IBuildServer build = (IBuildServer)server.GetService(typeof(IBuildServer));
IBuildDefinition buildDefinition = build.GetBuildDefinition("ACME", "ACME_v1.0.0");

object argumentValue;
if (WorkflowHelpers.DeserializeProcessParameters(buildDefinition.ProcessParameters).TryGetValue("SCA", out argumentValue))
{
  Console.WriteLine(argumentValue);
}        
Was it helpful?

Solution

WARNING

Querying the TFS operational datastores directly is not recommended and the contents of these fields can change between releases and even hotfixes without notice. The official way to do this is to use the Client Object Model. Any changes you accidentally make to the data will leave your server in an unsupported state.

The TFS Client Object Model provides a relatively easy API to query build definitions. And from there you can use the standard .NET XML classes (either Linq-2-XML or a standard XPathNavigator) to quickly get the information you're after. The parameter you're looking for might even be stored in the build metadata.

This would result in the following code (as provided by OP):

TfsTeamProjectCollection server = new TfsTeamProjectCollection(new Uri("http://acmetfs:8080/tfs"));
server.EnsureAuthenticated();
IBuildServer build = (IBuildServer)server.GetService(typeof(IBuildServer));
IBuildDefinition buildDefinition = build.GetBuildDefinition("ACME", "ACME_v1.0.0");

object argumentValue;
if (WorkflowHelpers.DeserializeProcessParameters(buildDefinition.ProcessParameters).TryGetValue("SCA", out argumentValue))
{
  Console.WriteLine(argumentValue);
}    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top