Azure Devops - 按代理池ID获取版本定义

问题描述 投票:3回答:2

我正在尝试使用.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);
}

但我找不到找到一个或多个环境配置为使用特定代理的版本定义的方法。有什么建议吗?

c# .net azure-devops tfs-sdk
2个回答
1
投票

我设法通过Rest Api获取代理池ID的所有版本,而不是通过NET客户端库。希望有所帮助。

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);
                    }
                }
            }
        }
    }
}

0
投票

找到了解决方案,非常感谢@ 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>();
}
© www.soinside.com 2019 - 2024. All rights reserved.