BuildHTTPClient无法获得构建定义步骤?

时间:2018-10-19 14:14:25

标签: tfs azure-devops tfsbuild azure-pipelines tfs2017

我们正在使用BuildHTTPClient来以编程方式创建构建定义的副本,更新内存中的变量,然后将更新后的对象另存为新定义。

我正在使用Microsoft.TeamFoundation.Build2.WebApi.BuildHTTPClient 16.141。 TFS版本是17更新3(REST API 3.x)

这是与https://serverfault.com/questions/799607/tfs-buildhttpclient-updatedefinition-c-example类似的问题,但是我试图不使用BuildHttpClient库,而不直接进入RestAPI。

问题在于,即使我们在构建定义中包含“步骤”列表,其他属性也始终为空。

更新在下面作为答案发布

在查看下面的@Daniel Frosts尝试之后,我们开始查看使用NuGet程序包的旧版本。令人惊讶的是,受支持的版本15.131.1不支持此功能,但是我们发现版本=“ 15.112.0-preview”可以。 回滚所有Dll以匹配该版本后,保存新版本的副本时将克隆这些步骤。

在使用此程序包时,我们使用的所有代码示例均有效。我们无法使Daniel的示例正常工作,但Dll的版本才是问题所在。

我们需要创建一个GitHub问题并将其报告给MS

首次尝试-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);

更新对变量起作用,我们可以将更新后的定义保存回TFS,但是新创建的构建定义中没有任何任务。当我们查看从GetDefinitionAsync返回的对象时,我们看到“步骤”列表为空。看起来GetDefinitionAsync只是没有获得完整的对象。

第二次尝试-具体修订:

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

基于SteveSims的帖子,我们认为我们没有得到正确的修订。因此,我们在请求中添加了修订。我看到正确版本的相同问题。与SteveSims帖子类似,我可以在浏览器中打开DefinitionURL,我看到任务在浏览器的JSON中,但是BuildDefinition对象未填充这些任务。

第三次尝试-GetFullDefinition:

所以我当时想尝试getFullDefinition,也许那是“ Full”的意思,当然我不知道这些库上没有任何文档。

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

仍然没有运气,即使我们在构建定义中包含步骤,“步骤”列表也始终为空。

第四次尝试-另存为模板

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

我尝试将构建定义保存为模板。因此,在Web UI中,我选择了“另存为模板”,仍然没有任何步骤。

第五次尝试:使用SteveSims帖子中提到的URL:

最后,我说好,我将尝试使用SteveSims使用的解决方案,并使用webclient从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);

这也不起作用。构建定义步骤为空。即使在查看Json对象(var json)时,我也看到了步骤。但是对象未加载它们。

我看过这篇帖子,似乎在基本定义中添加了步骤,我已经尝试过了,但老实说,我在理解他如何通过NuGet引用BuildDefinition对象时修改了该问题。

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

4 个答案:

答案 0 :(得分:3)

在查看下面的@Daniel Frosts尝试之后,我们开始查看使用NuGet程序包的旧版本。令人惊讶的是,受支持的版本15.131.1不支持此功能,但是我们发现版本=“ 15.112.0-preview”可以。
回滚所有Dll以匹配该版本后,保存新版本的副本时将克隆这些步骤。

使用此程序包时,以上所有代码示例均适用。我们无法使Daniel的示例正常工作,但是我们没有努力,因为我们拥有有效的代码。

我们需要为此创建一个GitHub问题。

答案 1 :(得分:1)

在我的代码中发现了这一点,效果很好。

使用此程序包,不确定是否会产生影响(笑话)。 ... 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);
}

答案 2 :(得分:0)

对于较新的客户,步骤将始终为空。在较新的api版本(由较新的客户端使用)中,步骤已移至“阶段”。如果您使用GetDefinitions或GetFullDefinitions并查看

definition.Process.Phases[0].Steps

您会找到它们。 (GetDefinitions获取浅引用,因此将不包括该过程。)

出于兼容性方面的考虑,Steps集合仍然存在(我们不希望应用程序因MethodNotFoundExceptions等崩溃而崩溃),但不会填充它。

答案 3 :(得分:0)

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!