You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#通过Azure DevOps API批量更新生成与发布定义的代理池?

完全可以通过Azure DevOps REST API或者官方.NET客户端库实现你描述的逻辑,以下是具体实现方案:

前置准备
  • 申请Azure DevOps个人访问令牌(PAT),授权范围勾选 生成(Build)的读取、写入和管理、发布(Release)的读取、写入和管理
  • 安装对应NuGet依赖包:
Install-Package Microsoft.TeamFoundationServer.Client
Install-Package Microsoft.VisualStudio.Services.Release.Client
核心代码实现

1. 初始化服务连接

using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using Microsoft.TeamFoundation.Build.WebApi;
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients;
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi;

// 配置参数
string orgUrl = "https://dev.azure.com/你的组织名称";
string pat = "你的PAT令牌";
int oldPoolId = 旧代理池ID;
int newPoolId = 新代理池ID;
string updateComment = "迁移到Azure环境,统一更新代理池";

// 初始化连接
var credentials = new VssBasicCredential(string.Empty, pat);
var connection = new VssConnection(new Uri(orgUrl), credentials);

// 初始化生成、发布服务客户端
var buildClient = connection.GetClient<BuildHttpClient>();
var releaseClient = connection.GetClient<ReleaseHttpClient>();

2. 筛选并更新生成定义

// 可根据需求添加筛选条件,比如名称前缀、创建时间、路径等,避免全量拉取
List<BuildDefinition> buildDefinitions = await buildClient.GetDefinitionsAsync(
    project: "你的项目名称",
    // 可选筛选参数示例:name: "前缀*", minCreatedTime: DateTime.Now.AddDays(-30)
);

foreach (var def in buildDefinitions)
{
    // 获取完整定义详情
    var fullDef = await buildClient.GetDefinitionAsync(def.Project.Id, def.Id);
    
    // 遍历生成定义下的所有代理作业
    if (fullDef.Process is DesignerProcess designerProcess)
    {
        bool hasUpdate = false;
        foreach (var phase in designerProcess.Phases.OfType<AgentJobPhase>())
        {
            if (phase.Target?.Id == oldPoolId)
            {
                phase.Target.Id = newPoolId;
                hasUpdate = true;
            }
        }
        // 有变更才提交更新
        if (hasUpdate)
        {
            fullDef.Comment = updateComment;
            await buildClient.UpdateDefinitionAsync(fullDef, fullDef.Project.Id, fullDef.Id);
        }
    }
}

3. 筛选并更新经典发布定义

// 同样可添加筛选条件减少拉取量
List<ReleaseDefinition> releaseDefinitions = await releaseClient.GetReleaseDefinitionsAsync(
    project: "你的项目名称",
    // 可选筛选参数示例:searchText: "前缀*", isDeleted: false
    expand: ReleaseDefinitionExpands.Phases
);

foreach (var def in releaseDefinitions)
{
    // 获取完整定义详情
    var fullDef = await releaseClient.GetReleaseDefinitionAsync(def.Project.Id, def.Id);
    bool hasUpdate = false;
    
    // 遍历发布定义的所有阶段
    foreach (var environment in fullDef.Environments)
    {
        // 遍历阶段下的所有代理作业
        foreach (var phase in environment.DeployPhases.OfType<AgentDeploymentPhase>())
        {
            if (phase.DeploymentInput?.QueueId == oldPoolId)
            {
                phase.DeploymentInput.QueueId = newPoolId;
                hasUpdate = true;
            }
        }
    }
    // 有变更才提交更新
    if (hasUpdate)
    {
        fullDef.Comment = updateComment;
        await releaseClient.UpdateReleaseDefinitionAsync(fullDef, fullDef.Project.Id, fullDef.Id);
    }
}
注意事项
  • 执行前建议先注释更新接口调用,打印待修改的定义列表验证匹配规则,确认无误后再执行写入操作
  • 旧代理池ID可以在代理池的页面URL中获取,格式一般为_settings/agentpools?poolId=xxx中的xxx数值
  • 该方案仅适用于经典生成/发布定义,YAML格式的定义需要修改yaml文件本身,不适用该接口逻辑

内容的提问来源于stack exchange,提问作者jvanderwoude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 20:45:03