BuildHTTPClient not able to get Build Definition Steps?

microsoft teamfoundationserver core webapi
microsoft visualstudio services releasemanagement webapi
azure devops dll
tfs api c#
.net client library

We are using the BuildHTTPClient to programmatically create a copy of a build definition, update the variables in memory and then save the updated object as a new definition.

I'm using Microsoft.TeamFoundation.Build2.WebApi.BuildHTTPClient 16.141. The TFS version is 17 update 3 (rest api 3.x)

This is a similar question to https://serverfault.com/questions/799607/tfs-buildhttpclient-updatedefinition-c-example but I'm trying to stay within using the BuildHttpClient libraries and not go directly to the RestAPIs.

The problem is the Steps list is always null along with other properties even though we have them in the build definition.

UPDATE Posted as an answer below

After looking at @Daniel Frosts attempt below we started looking at using older versions of the NuGet package. Surprisingly the supported version 15.131.1 does not support this but we have found out that the version="15.112.0-preview" does. After rolling back all of our Dlls to match that version the steps were cloned when saving the new copy of the build.

All of the code examples we used work when you are using this package. We were unable to get Daniel's example working but the version of the Dll was the issue.

We need to create a GitHub issue and report it to MS

First Attempt - GetDefinitionAsync:

VssConnection connection = new VssConnection(DefinitionTypesDTO.serverUrl, new VssCredentials());
BuildHttpClient bdClient = connection.GetClient<BuildHttpClient>();

Task <BuildDefinition> resultDef = bdClient.GetDefinitionAsync(DefinitionTypesDTO.teamProjectName, buildID);
resultDef.Wait();
BuildDefinition updatedDefinition = UpdateBuildDefinitionValues(resultDef.Result, dr, defName);
updatedTask = bdClient.CreateDefinitionAsync(updatedDefinition, DefinitionTypesDTO.teamProjectName);

The update works on the variables and we can save the updated definition back to TFS but there are not any tasks in the newly created build definition. When we look at the object that is returned from GetDefinitionAsync we see that the Steps list is empty. It looks like GetDefinitionAsync just doesn't get the full object.

Second Attempt - Specific Revision:

int rev = 9;
Task <BuildDefinition> resultDef = bdClient.GetDefinitionAsync(DefinitionTypesDTO.teamProjectName, buildID, revision: rev);
resultDef.Wait();
BuildDefinition updatedDefinition = UpdateBuildDefinitionValues(resultDef.Result, dr, defName);

Based on SteveSims post we were thinking we are not getting the correct revision. So we added revision to the request. I see the same issue with the correct revision. Similarly to SteveSims post I can open the DefinitionURL in a browser and I see that the tasks are in the JSON in the browser but the BuildDefinition object is not populated with them.

Third Attempt - GetFullDefinition:

So then I thought to try getFullDefinition, maybe that's that "Full" means of course with out any documentation on these libraries I have no idea.

var task2 = bdClient.GetFullDefinitionsAsync(DefinitionTypesDTO.teamProjectName, "MyBuildDefName","$/","TfsVersionControl");
task2.Wait();

Still no luck, the Steps list is always null even though we have steps in the build definition.

Fourth Attempt - Save As Template

var task2 = bdClient.GetTemplateAsync DefinitionTypesDTO.teamProjectName, "1_Batch_Dev");
task2.Wait();

I tried saving the Build Definition off as a template. So in the Web UI I chose "Save as Template", still no steps.

Fifth Attempt: Using the URL as mentioned in SteveSims post:

Finally i said ok, i'll try the solution SteveSims used, using the webclient to get the object from the URL.

var client = new WebClient();
client.UseDefaultCredentials = true;
var json = client.DownloadString(LastDefinitionUrl);

//Convert the JSON to an actual builddefinition
BuildDefinition result = JsonConvert.DeserializeObject<BuildDefinition>(json);

This also didn't work. The build definition steps are null. Even when looking at the Json object (var json) i see the steps. But the object is not loaded with them.

I've seen this post which seems to add the Steps to the base definition, i've tried this but honestly I'm having an issue understanding how he has modified the BuildDefinition Object when referencing that via NuGet?

https://dennisdel.com/blog/getting-build-steps-with-visual-studio-team-services-.net-api/

After looking at @Daniel Frosts attempt below we started looking at using older versions of the NuGet package. Surprisingly the supported version 15.131.1 does not support this but we have found out that the version="15.112.0-preview" does. After rolling back all of our Dlls to match that version the steps were cloned when saving the new copy of the build.

All of the code examples above work when you are using this package. We were unable to get Daniel's example working but we didn't try hard as we had working code.

We need to create a GitHub issue for this.

BuiltHttpClient, https://stackoverflow.com/questions/52894176/buildhttpclient-not-able-to-get-​build-definition-steps. I wasn't sure if you had this on GitHub to  The reason for the need to programmatically update the build definition is that we are running the RTM version of Team Foundation Server 2015, and as of that release certain parts of the vNext Build Definitions are not exposed to the web GUI, and there is (as yet) no other way to change them. (Assuming that you want to keep your database in a supported state, and refuse to modify the database

Found this in my code, which works.

Use this package, not sure if it could have an impact (joke). ...packages\Microsoft.TeamFoundationServer.Client.15.112.1\lib\net45\Microsoft.TeamFoundation.Build2.WebApi.dll

private Microsoft.TeamFoundation.Build.WebApi.BuildDefinition GetBuildDefinition(string projectName, string buildDefinitionName)
{
    var buildDefinitionReferences = _buildHttpClient.GetFullDefinitionsAsync(projectName, "*", null, null, DefinitionQueryOrder.DefinitionNameAscending, top: 1000).Result;
    return buildDefinitionReferences.SingleOrDefault(x => x.Name == buildDefinitionName && x.DefinitionQuality != DefinitionQuality.Draft);
}

Getting Build Steps With Visual Studio Team Services .NET API , How to query build steps in Visual Studio Team Services through the . the most about Visual Studio Team Services is the ability to build my However, I recently tried to figure out how can I get the list of steps from a build definition, new BuildHttpClient(new Uri(Url), credentials); var definitions = await  Here are the examples of the java api class com.microsoft.teamfoundation.build.webapi.BuildHttpClient taken from open source projects.

With the newer clients Steps will always be empty. In newer api-versions (which are used by the newer clients) the steps have moved to Phases. If you use GetDefinitions or GetFullDefinitions and look in

definition.Process.Phases[0].Steps

you'll find them. (GetDefinitions gets shallow references so the process won't be included.)

The Steps collection still exists for compatibility reasons (we don't want apps to crash with stuff like MethodNotFoundExceptions) but it won't be populated.

BuildHttpClient Class (Microsoft.TeamFoundation.Build.WebApi , Represents a reference to a build definition. BuildDefinitionReference3_2. For back-compat with extensions that use the old Steps format instead of Process and  The build definition builds your project within your git repository, and the release definitions deploys it to your BizTalk Server environment. Before you begin. Complete Step 2 - Create VSTS token and install agent. Add the Build tasks. In your project, select Build and release. The Builds tab opens. Create a New definition:

I was having this problem, although I able to get Phases[0] information at runtime, but could not get it at design time. I solved this problem using dynamic type.

   dynamic process = buildDefTemplate.Process;                

   foreach (BuildDefinitionStep tempStep in process.Phases[0].Steps)
   {
        // do some work here            
   }

Not, it is working!

Microsoft.TeamFoundation.Build.WebApi Namespace, The main client to manage build definitions is the BuildHttpClient class. the scratch but it`s simpler to find steps in an existing build definition. I'd like to be able to get the buildDefinitionId for the build from within a Build Forge step, is there anyway to do that? Comments Spencer Murata commented Mar 06 '13, 2:53 p.m.

Azure DevOps Rest Api. 18. Create and Clone Build Definitions , By Mirek on 3/7/2016 (tags: build definition, clone, tfs, VSO, 2015 I found that it is not possible to reuse a build definition created in one team project into another team project. you have a possibility to save build definition as a template for future use, because for instance you use many build steps, many variables and​  TFS 2015 Api Get build information. Ask Question Asked 3 years, 6 months ago. Active 3 years, 6 months ago. Viewed 2k times 1. For our new TFS 2015 server I want to create a webpage where you can see a history of warning counts and code coverage for each

TFS 2015 clone/import/export build definition between team , We are working to automate this process programmatically. having a Template build, using the GetBuildDefinition method in the BuildHttpClient With some pretty extension research, I have not been able to find a different way to do it. According to your description, seems you want to update the build definition by the  BuildHttpClient Class // .NET Standard 1.6 + Platform Extensions // Microsoft.TeamFoundation.Build2.WebApi, Version=15.0.0.0, PublicKeyToken=b03f5f7f11d50a3a

Automation of Builds : azuredevops, GetClient<BuildHttpClient>(); var workitems = vssConnection. GetBuildWorkItemsRefsAsync(commits, build.Definition.Project.Name, build. From this blog, I was able to go through the steps and process how MSTest invokes and null); Invoke(null,null) = The first null parameter specifies whether it's a static class or not. In the next step we change the name of the build definition so it is clearly seen that this is a clone. We also need to remove the reference to the project. Since build definition contains a reference to the project it would not be possible to import it into a different project. Finally we create new build definition in target project providing

Comments
  • Any chance that you just get a new format of build definitions where steps are moved under phases? Check the Process.Phases[0].Steps value
  • I've emailed them and posted this. I don't see an official GitHub for this NuGet. developercommunity.visualstudio.com/content/problem/369146/…
  • did you try the version of the package I am refering to ?
  • yes.. did you succeed to get Steps that are not null?
  • yes! But I was also thinking that perhaps you should look at the REST API docs for V3.1. When looking at the request try using Fiddler to debug. I have seen that the JSON returned from VSTS/TFS has no Steps but it has a Task node.
  • Yes they are tasks in the Json but should get converted to Steps in when being cast into the object.
  • I would have to try this out, to be clear are you saying I need to upgrade the project back to 16.141? If so then exactly how would I use BuildHTTPClient to programmatically create a copy of a build definition, update the variables in memory and then save the updated object as a new definition?