Azure DevOps - 通过代理池 ID 获取发布定义

5
我想查找所有配置为使用特定代理池的构建和发布,使用.NET客户端库。
假设 agentPoolId,可以按照以下方式获取所有构建定义:
// _connection is of type VssConnection
using (var buildClient = _connection.GetClient<BuildHttpClient>())
{
    List<BuildDefinitionReference> allBuilds = await buildClient.GetDefinitionsAsync(projectName, top: 1000, queryOrder: DefinitionQueryOrder.DefinitionNameAscending);
    List<BuildDefinitionReference> builds = allBuilds.Where(x => HasAgentPoolId(x, agentPoolId)).ToList();
}

private bool HasAgentPoolId(BuildDefinitionReference buildDefinition, int agentPoolId)
{
    TaskAgentPoolReference pool = buildDefinition?.Queue?.Pool;

    if (pool == null)
    {
        return false;
    }

    return pool.Id.Equals(agentPoolId);
}

但我找不到一种方法来查找配置了一个或多个特定代理的发布定义。有什么建议吗?
2个回答

2

我通过 Rest Api 而不是 NET 客户端库成功获取了所有代理池 ID 的发布版本。希望这能有所帮助。

C# 代码片段:

public class ReleaseResponse
{
     [JsonProperty("value")]
     public List<ReleaseItem> Value { get; set; }
}

public class ReleaseItem
{
     [JsonProperty("name")]
     public string Name { get; set; }

     [JsonProperty("Id")]
     public int Id { get; set; }
}

static void Main(string[] args)
{
     string tfsURL = "TFS URL";
     string releaseDefurl = $"{tfsURL}/_apis/release/definitions?$expand=artifacts&api-version=3.2-preview.3";
     const int agentPoolID = "AGENT Pool ID";
     List<string> relevantReleases = new List<string>(); 
     WebClient client = new WebClient();
     client.UseDefaultCredentials = true;
     client.Headers.Add("Content-Type", "application/json");
     var releaseList = client.DownloadString(releaseDefurl);
     var allReleases = JsonConvert.DeserializeObject<ReleaseResponse>(releaseList).Value;
     foreach (var release in allReleases)
     {
           string releaseInfoApi = $"{tfsURL}/_apis/Release/definitions/{release.Id}";
           var getReleseInfo = client.DownloadString(releaseInfoApi);
           var releaseInfo = JsonConvert.DeserializeObject<TFSLogic.RootObject>(getReleseInfo);
           var deploymentAgents = releaseInfo.environments.ToList().Where(e => e.deployPhases.FirstOrDefault().deploymentInput.queueId == agentPoolID).Count();
           if (deploymentAgents > 0)
           {
               relevantReleases.Add(release.Name);
           }

     }

}

在这里找到 TFSLogic:https://codebeautify.org/online-json-editor/cb7aa0d9

Powershell 代码片段:

$tfsUrl = "TFS URL"
$releaseDefurl = $tfsUrl + '/_apis/release/definitions?$expand=artifacts&api-version=3.2-preview.3'
$agentPoolID = "Agent Pool ID"
$relevantReleases = @();
$allReleasesID = (Invoke-RestMethod -Uri ($releaseDefurl) -Method Get -UseDefaultCredentials).value.id

function getReleaseByAgentPoolID($releaseID,$agentPoolID)
{
    $ReleaseInfo = Invoke-RestMethod -Uri "$tfsUrl/_apis/Release/definitions/$releaseID" -Method Get -UseDefaultCredentials

    $deploymentAgents = $ReleaseInfo.environments | % {$_.deployPhases.deploymentInput.queueId} | where {$_ -eq $agentPoolID}

    if($deploymentAgents.Count -gt 0)
    {
        return $ReleaseInfo.name
    }
}


foreach ($releaseID in $allReleasesID)
{
    $relevantReleases += getReleaseByAgentPoolID -releaseID $releaseID -agentPoolID $agentPoolID   
}

更新:

虽然花了些时间,但是我最后还是用azure-devops-dotnet-samples达成了目标。 希望这个例子能够满足你的需求。

using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Linq;
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients;
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts;
using Microsoft.VisualStudio.Services.Common;
using System.Collections.Generic;

namespace FindReleaseByAgentPoolID
{
    class Program
    {
        const int agentPoolID = 999;
        static void Main(string[] args)
        {
            var relevantReleases = new List<string>();
            VssCredentials c = new VssCredentials(new WindowsCredential(System.Net.CredentialCache.DefaultNetworkCredentials));
            var tfsURL = new Uri("TFS URL");
            var teamProjectName = "PROJECT";

            using (var connection = new VssConnection(tfsURL, c))
            using (var rmClient = connection.GetClient<ReleaseHttpClient2>())
            {
                var releases = rmClient
                    .GetReleaseDefinitionsAsync(teamProjectName, string.Empty, ReleaseDefinitionExpands.Environments)
                    .Result.ToArray();

                foreach (var release in releases)
                {
                    var r = rmClient.GetReleaseDefinitionAsync(teamProjectName, release.Id);
                    var deploymentAgents = r.Result.Environments.SelectMany(e =>
                     e.DeployPhases.Select(dp =>
                     dp.GetDeploymentInput()).Cast<DeploymentInput>()).Where(di =>
                     di.QueueId == agentPoolID).Count();

                    if (deploymentAgents > 0)
                    {
                        relevantReleases.Add(release.Name);
                    }
                }
            }
        }
    }
}

谢谢@amit-baranes,但我实际上想避免使用REST API,我宁愿使用.NET客户端库,这样我就不必处理序列化/反序列化。顺便说一下,我想获取发布定义,而不是发布。 - Rui Jarimba
非常感谢您的帮助@amit-baranes。我对您的代码示例进行了一些更改,如下所示。 - Rui Jarimba
1
我很高兴能帮助你解决问题。 每天学习新东西真是太好了! - Amit Baranes

2
找到了解决方案,非常感谢@amit-baranes指引我正确的方向。
我已经更改了他的代码示例,使用await关键字代替使用.Result,并使用.OfType<DeploymentInput>()代替.Cast<DeploymentInput>()(它会抛出一些异常)。
哦,还有最重要的一点我学到了:代理池ID和队列ID是不同的!!!如果您打算使用代理池ID获取发布定义,则需要获取相应的代理队列。
代码示例:
// set agent pool Id and project name
int agentPoolId = 123456; 
string teamProjectName = ".....";

// _connection is of type VssConnection
using (var taskAgentClient = _connection.GetClient<TaskAgentHttpClient>())
using (var releaseClient = _connection.GetClient<ReleaseHttpClient2>())
{
    // please note: agent pool Id != queue Id
    // agent pool id is used to get the build definitions
    // queue Id is used to get the release definitions
    TaskAgentPool agentPool = await taskAgentClient.GetAgentPoolAsync(agentPoolId);
    List<TaskAgentQueue> queues = await taskAgentClient.GetAgentQueuesByNamesAsync(teamProjectName, queueNames: new[] { agentPool.Name });
    TaskAgentQueue queue = queues.FirstOrDefault();

    List<ReleaseDefinition> definitions = await releaseClient.GetReleaseDefinitionsAsync(teamProjectName, string.Empty, ReleaseDefinitionExpands.Environments);

    foreach (ReleaseDefinition definition in definitions)
    {
        var fullDefinition = await releaseClient.GetReleaseDefinitionAsync(teamProjectName, definition.Id);

        bool hasReleasesWithPool = fullDefinition.Environments.SelectMany(GetDeploymentInputs)
                                                              .Any(di => di.QueueId == queue.Id);

        if (hasReleasesWithPool)
        {
            Debug.WriteLine($"{definition.Name}");
        }
    }
}

private IEnumerable<DeploymentInput> GetDeploymentInputs(ReleaseDefinitionEnvironment environment)
{
    return environment.DeployPhases.Select(dp => dp.GetDeploymentInput())
                                   .OfType<DeploymentInput>();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接