locked
QueryBuilds does not return process parameters RRS feed

  • Question

  •  

     

    IBuildDetailSpec spec = BuildServer.CreateBuildDetailSpec(teamProject, buildDefinitionName);
    spec.BuildNumber = buildDetail.BuildNumber;
    spec.QueryOptions = QueryOptions.All;


    IBuildQueryResult res = buildDetail.BuildServer.QueryBuilds(spec);
    string processParameters = res.Builds[0].ProcessParameters;

    I am querying for the process parameters for a particular build using build number.  I get the process parameters string as empty.  Any ideas????  Thanks!

    Friday, November 5, 2010 1:06 AM

Answers

  • The IBuildDetail.BuildDefinition property returns the information for the BuildDefinition at the BuildDefinitionUri at the time the property is called. The Build Definition's details are not maintained historically anywhere that I can find, so I don't think you're ever going to be able to see (for example) what a build definition's process parameters were, say, three months ago. You'll only ever get to see what they are currently. No matter how you approach it from the API, it's limited by the DB.

    I've looked, and unless it's packed away somewhere with a misleading name, the information you seek isn't even in the DB.

    I really believe that the only way you can accomplish what you want is to write a custom activity which persists the process parameters on every build. This, however, is a "forward only" solution.

    • Marked as answer by vijayagnel Tuesday, November 23, 2010 10:53 PM
    Wednesday, November 10, 2010 8:35 PM

All replies

  • Consider using something like:

     

     

    IDictionary<string, object> pp = WorkflowHelpers.DeserializeProcessParameters(res.Builds[0].ProcessParameters);

    If I'm recalling correctly looking at that string directly can provide apparently empty results.

    Friday, November 5, 2010 1:53 AM
  • Ok, so you'll still want to consider using that helper method, but the issue is likely that you need to do:

    string processParameters = res.Builds[0].BuildDefinition.ProcessParameters;
    IDictionary<string, object> pp = WorkflowHelpers.DeserializeProcessParameters(processParameters);
    
    

    Note the extra BuildDefinition property in line one.

    Friday, November 5, 2010 2:17 AM
  • I tried using ....

    string processParameters = res.Builds[0].BuildDefinition.ProcessParameters;

    This returns the current process parameters for this build definition.  I want the process parameters that was used for a particular build.  I thought the "ProcessParameter" field under IBuildDetail will give me that.  This string returns null for all historical builds.

    Friday, November 5, 2010 9:28 PM
  • See the last two paragraphs here:

    http://blogs.msdn.com/b/jpricket/archive/2010/03/25/tfs2010-queuing-a-build-from-code-with-custom-process-parameter-values.aspx

    They describe the behavior of process parameters a bit.

    My interpretation of this is that if the params are empty in the specific build request, then they haven't been changed. I'll need to do testing locally to confirm this, though... which I won't be able to get to until later tonight.

    Friday, November 5, 2010 9:41 PM
  • From Pricket's blog post, it means

    IBuildDetail.BuildDefinition.ProcessParameters -> this field is updated when the user changes the parameters from the Edit Build Definition UI.

    IBuildDetail.ProcessParameters -> this field is updated when the parameters are modified while queuing a build manually via Queue New Build UI or using the IBuildRequest interface in code.

    But when you query for build details using the build number and try to retrieve the process parameters used for that build. I always get the current process parameters and not the settings used for that build.

    You can simulate this by doing the following:-

    1. Perform a build using a build definition. Note down the build number.

    2. Modify the build definition by changing the "Projects To Build" parameter. Save it.

    3. Try to query the build detail using the build number from Step-1.

    IBuildDetailSpec spec = BuildServer.CreateBuildDetailSpec(teamProject, buildDefinitionName);
    spec.BuildNumber = "set the build numer here!!!";
    spec.QueryOptions = QueryOptions.All;

    IBuildQueryResult res = BuildServer.QueryBuilds(spec);
    string processParameters = res.Builds[0].BuildDefinition.ProcessParameters;

    4. Look at res.Builds[0].BuildDefinition.ProcessParameters, this will contain the modified process parameters and not the definition used in Step-1.

    Friday, November 5, 2010 10:42 PM
  • Ok, I wanted to pass on some info in case I don't reach a full solution for you (I have a newborn and my time is sometimes taken without notice). I'm looking into combing the Information property of the IBuildDetail interface. I'm spitting out a warning with all the build settings using this code:

    IBuildQueryResult res = bd.BuildServer.QueryBuilds(spec);
    IBuildDetail bdResult = res.Builds[0];
    IBuildInformation buildInfo = bdResult.Information;
    IEnumerable<IBuildInformationNode> rootNodes = buildInfo.Nodes.Where(n => n.Parent == null);
    IBuildInformationNode rootActivityNode = rootNodes.FirstOrDefault(n => n.Type == "ActivityTracking");
    if (rootActivityNode != null)
    {
    	IEnumerable<IBuildInformationNode> activityProperties = rootActivityNode.Children.Nodes.Where(n => n.Type == "ActivityProperties");
    	foreach (IBuildInformationNode n in activityProperties)
    	{
    		foreach (string s in n.Fields.Select(dic => dic.Key + ": " + dic.Value))
    		{
    			context.TrackBuildWarning(s);
    		}
    	}
    }
    
    
    This is navigating the build log that's displayed after a build is finished. I still need to confirm that this doesn't require the verbosity be diagnostic (cause that's the only time you'll see the input properties for a build, and that it survives the build def changing as you describe.
    Saturday, November 6, 2010 1:33 AM
  • My suggestion requires verbosity be diagnostic. I can't figure this out without resorting to workarounds. I'd appreciate if an expert could chime in. All I can think of is that you'd need to manage this yourself by logging the process parameters at build time via a custom activity and then refer to that later. But this seems like more effort than should be necessary.

    Saturday, November 6, 2010 1:00 PM
  • Hi vijayagnel,

     

    Has this issue been resolved?


    Best Regards

    John Qiao

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, November 8, 2010 3:44 AM
    Moderator
  • Its not resolved yet.  Do you have any solution to this issue??

    Vijay

    Monday, November 8, 2010 6:38 AM
  •  

    Hi Vijay,

     

    Try the following codes:

        var tfsBuildServer = tfs.GetService<IBuildServer>();
        var builds = tfsBuildServer.QueryBuilds(tfsBuildServer.CreateBuildDefinitionSpec("TeamProjectName""DefinitionName"));
        String parameters = builds[0].BuildDefinition.ProcessParameters;

     

     


    Best Regards

    John Qiao

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, November 9, 2010 9:01 AM
    Moderator
  • It still does not give me the process parameters used for a particular build.  It returns the current definition for all builds.

    You can simulate this by doing the following:-

    1. Perform a build using a build definition.

    2. Modify the build definition by changing the "Projects To Build" parameter. Save it.

    3. Try to query the build detail.

        var tfsBuildServer = tfs.GetService<IBuildServer>();
        var builds = tfsBuildServer.QueryBuilds(tfsBuildServer.CreateBuildDefinitionSpec("TeamProjectName""DefinitionName"));

    4. Look at "builds" variable, this will contain the modified process parameters and not the definition used for that particular build.

    Can you tell me the difference between BuildDetail.ProcessParameters and BuildDetail.BuildDefinition.ProcessParameters ????

    Tuesday, November 9, 2010 7:13 PM
  • Hi vijayagnel,

     

    Builds[?].ProcessParameters return data just when do some changes before perform a build using a build definition. Please review the following steps:

    1        Right click the Build Definition and select Queue New Build…, then in the Parameters tab, do some changes.

    2        Click Queue button and wait build successfully.

    3        Run the code:     

          var tfsBuildServer = tfs.GetService<IBuildServer>();
          var builds = tfsBuildServer.QueryBuilds(tfsBuildServer.CreateBuildDefinitionSpec("TeamProjectName""DefinitionName"));
           foreach (var build in builds.OrderByDescending(b => b.StartTime))
                {
                    var p1 = build.ProcessParameters;
                    var date = build.StartTime;
                    Console.WriteLine("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");  
                    Console.WriteLine(date);
                    Console.WriteLine(p1);
                   
         }

    In this situation, the process parameters string is not empty.

     

    Generally speaking, if we don’t do any changes in Parameters when we queue a new build using the Build Definition, the build’s process parameters are the Build Definition(BuildDetail.BuildDefinition.ProcessParameters)’s process parameters. If we do some changes before perform a build in Queue New Build…, so the build’s process parameters are BuildDetail.ProcessParameters add BuildDetail.BuildDefinition.ProcessParameters.


    Best Regards

    John Qiao

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, November 10, 2010 3:42 AM
    Moderator
  • Hi John,

    I now got the difference between BuildDetail.ProcessParameters and BuildDetail.BuildDefinition.ProcessParameters.

    Coming back to my original question, I need to query the process parameters used in different builds with the same build definition.

    In the following scenario:-

    1. Perform a build using a build definition.

    2. Modify the build definition by changing the "Projects To Build" parameter. Save it.

    3. Try to query the build detail used in Step-1

        var tfsBuildServer = tfs.GetService<IBuildServer>();
        var builds = tfsBuildServer.QueryBuilds(tfsBuildServer.CreateBuildDefinitionSpec("TeamProjectName""DefinitionName"));

    4. Look at builds[?].BuildDefinition.ProcessParameters variable, this will contain the modified process parameters and not the definition used in Step-1.

    Sid Forcier suggested to write a custom activity which persists these settings. Since TFS already maintains the build information in its database, I would expect the process parameters are also stored with it.

    Wednesday, November 10, 2010 3:56 AM
  • Hi vijayagnel,

     

    I want to know that after step 2 and before step3, you perform this build used the changed Build Definition or not?

     

    The Build[?].BuildDefinition.ProcessParameters variable just contain the Build Definition’s process parameters when used for the Build[?].


    Best Regards

    John Qiao

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, November 10, 2010 5:42 AM
    Moderator
  • I DID NOT perform the build with the changed Build Definition after step 2 and before step 3. I tried to query the Build Detail from the build performed in Step 1 after modifying the current build definition.  It looks to me after saving the modifications into the database, it modifies the definitions of the previous builds as well.

    Wednesday, November 10, 2010 5:51 PM
  • The IBuildDetail.BuildDefinition property returns the information for the BuildDefinition at the BuildDefinitionUri at the time the property is called. The Build Definition's details are not maintained historically anywhere that I can find, so I don't think you're ever going to be able to see (for example) what a build definition's process parameters were, say, three months ago. You'll only ever get to see what they are currently. No matter how you approach it from the API, it's limited by the DB.

    I've looked, and unless it's packed away somewhere with a misleading name, the information you seek isn't even in the DB.

    I really believe that the only way you can accomplish what you want is to write a custom activity which persists the process parameters on every build. This, however, is a "forward only" solution.

    • Marked as answer by vijayagnel Tuesday, November 23, 2010 10:53 PM
    Wednesday, November 10, 2010 8:35 PM
  • Hi vijayagnel,

     

    As your scenario:

    1. Perform a build using a build definition.  (We named the build as “Build1”, and the definition as “Definition1” )

    2. Modify the build definition by changing the "Projects To Build" parameter. Save it. (After Definition1 be modified, it’s different with Definition1, we named the changed Definition1 as “Definition2”, the changed "Projects To Build" parameter belong to Definition2.)

    3. Try to query the build detail used in Step-1

            In step1, Build1 used Definition1 to complete build, so the Build1’s detailed process parameters should get by:

                    var tfsBuildServer = tfs.GetService<IBuildServer>();
                var builds = tfsBuildServer.QueryBuilds(tfsBuildServer.CreateBuildDefinitionSpec("TeamProjectName""DefinitionName"));
                var parameters1 = builds[last].BuildDefinition.ProcessParameters;
                var parameters2 = builds[last].ProcessParameters;    //  If there have nothing change in Parameters tab when Queue Definiton1 to build Build1, the parameters2 is empty.
                var Build1_Detailed_Parameters = parameters1 + parameters2;  

     

                Any Build use Definition2 to perform build, so the Definition2’s process parameters we should get by:

                            var tfsBuildServer = tfs.GetService<IBuildServer>();
                var buildsdefinition = tfsBuildServer.GetBuildDefinition("TeamProjectName"" DefinitionName");
                var Definition2_Parameters = buildsdefinition.ProcessParameters;  // The changed "Projects To Build" parameter in this result.

    Best Regards

    John Qiao

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Thursday, November 11, 2010 2:58 AM
    Moderator
  • The changes to Build Definition should be done to the same "Definition1" and saved.  Then try to query the process parameter for the last build done in Step-1.  You will get the last modified process parameter and not the definition used to perform the build.

    Please refer to Sid Forcier's last comment.  He understood my requirement correctly.  I would like Microsoft to confirm that, this is the behaviour, so that I can proceed writing my own custom activity.

    Thursday, November 11, 2010 3:30 AM