关于 deployment-pipelines-authoring-cli
通过 Fabric 控制平面 REST API 管理部署管道的 CLI 技能,用于在阶段间推广受支持的 Fabric 内容。它涵盖管道和阶段生命周期、工作区分配及异步部署操作。
主要功能
- 01创建、更新和管理部署管道与阶段
- 02将工作区分配到阶段
- 03部署相邻阶段间的受支持内容
- 04选择性部署指定项目
- 05轮询异步部署操作状态
适用场景
- 01将开发阶段内容推广到测试或生产阶段
- 02为阶段配置工作区
- 03检查阶段项目并部署选定内容
MCP 相关
输入未说明此技能与 MCP 的关系。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ skills-for-fabric --skill deployment-pipelines-authoring-cli安装后在 Claude Code 中输入/deployment-pipelines-authoring-cli确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
apm.ymlreferences/supported-item-types.mdreferences/scripts/diff_item_definitions.py详细介绍
遥测 — 强制要求。 每次
api.fabric.microsoft.com调用都必须携带x-ms-fabric-skill: deployment-pipelines-authoring-cli(az rest:--headers "x-ms-fabric-skill=deployment-pipelines-authoring-cli"), 包括每次 LRO 轮询、fabric_lro和重试。代码片段中省略了此项 — 仍须添加。
重要说明
- 根据工作区名称查找工作区详细信息(包括其 ID):列出所有工作区,然后使用 JMESPath 筛选
- 根据工作区 ID、项类型和项名称查找项的详细信息(包括其 ID):列出该工作区中该类型的所有项,然后使用 JMESPath 筛选
- 查找部署管道或阶段 ID:列出部署管道(然后列出阶段),并使用 JMESPath 按
displayName筛选 — 切勿猜测 ID。
Fabric 部署管道创作 — CLI 技能
使用部署管道自动化 Fabric 应用程序生命周期管理(ALM):通过 Fabric 核心控制平面 REST API,在不同阶段(通常为开发 → 测试 → 生产)之间提升 Fabric 内容。此技能涵盖管道/阶段生命周期、工作区分配,以及阶段间部署(长时间运行操作)。
前置知识
请先阅读以下配套文档 — 此技能假设你已了解其中的操作模式,因此不会重复介绍:
| 任务 | 参考资料 | 说明 |
|---|---|---|
| 在 Fabric 中查找工作区和项 | COMMON-CLI.md § 在 Fabric 中查找工作区和项 | 强制要求 — 通过列出并使用 JMESPath 按名称解析工作区/项 ID |
| 身份验证和令牌获取 | COMMON-CORE.md § 身份验证和令牌获取 | 令牌受众必须为 https://api.fabric.microsoft.com;受众错误会导致 401 |
| 身份验证方案 | COMMON-CLI.md § 身份验证方案 | az login 流程和令牌获取 |
通过 az rest 使用 Fabric 控制平面 API | COMMON-CLI.md § 通过 az rest 使用 Fabric 控制平面 API | 始终传入 --resource https://api.fabric.microsoft.com |
| 核心控制平面 REST API | COMMON-CORE.md § 核心控制平面 REST API | 分页、LRO 轮询和速率限制操作模式 |
| 长时间运行操作(LRO) | COMMON-CLI.md § 长时间运行操作(LRO)模式 | 部署是 LRO — 轮询 /v1/operations/{id},直至操作进入终止状态 |
| 环境 URL | COMMON-CORE.md § 环境 URL | 主权云/政府云使用不同的主机 |
| 支持的项类型 | references/supported-item-types.md | 部署可复制的项类型清单(按类别列出,并标注预览标志)— 请依据Microsoft 官方文档(权威来源)进行核对;不要猜测 |
| 比较两项定义(节省令牌) | references/scripts/diff_item_definitions.py | 本地工具,可解码两个 getDefinition 负载、规范化自动重新绑定的字段,并仅输出差异 — 将差异(而非完整定义)提供给模型。python references/scripts/diff_item_definitions.py source.json target.json(退出代码 0=相同,1=已更改) |
此技能补充说明:如何通过 Agent 式终端操作部署管道 REST 接口。
概念
- 一个部署管道包含 2–10 个有序阶段(
order从 0 开始)。每个阶段最多只能分配一个工作区,每个工作区也最多只能分配给一个阶段。 - 部署会将支持的项内容从源阶段复制到相邻目标阶段。向前部署(dev→test→prod)可在任意相邻阶段之间进行。向后部署(例如 prod→test)目前仅在目标阶段为空(未分配工作区)时支持——不能向后部署到已分配工作区的阶段。
- 项配对(自动绑定)。部署期间,Fabric 会记录源项与其在目标阶段中的克隆项之间的连接;后续部署会通过此配对确定要覆盖哪个目标项,并确保相关项(例如报表和语义模型)保持绑定。没有用于 设置 配对的 REST API——配对会自动维护,但你可以通过
List stage items返回的sourceItemId/targetItemId字段查看当前配对。唯一受支持的修复方式见下文的 修复损坏的项配对 工作流。 - 部署是异步长时间运行操作(LRO):API 会返回
202 Accepted和操作 ID;你需要轮询操作是否完成。 - 部署规则和参数规则(例如,为每个阶段重新指定数据源)需在 Fabric 门户 UI 中配置——没有用于创建规则的 REST API。请勿声称有此类 API。
- 部署只会复制受支持的项类型;不受支持的项会被跳过(不会报错)。受支持的项类型会随时间变化——请参阅 references/supported-item-types.md。
- 没有“变更内容”/比较 REST API。
List stage items会返回项的标识信息和配对信息(itemId、itemDisplayName、itemType、sourceItemId、targetItemId、lastDeploymentTime)——但不包含变更状态;而且lastDeploymentTime是上次部署时间,不是上次编辑时间,因此不能作为可靠的变更信号。若要只部署已变更的项,你必须自行比较两个阶段并构建items列表(见下文的 仅部署已变更的项 工作流)。门户中的“比较”视图在服务器端运行,API 不提供此功能。
必须做 / 建议做 / 避免做
必须做
- 执行任何变更操作之前,先通过列表查询和 JMESPath 按名称解析管道、阶段和工作区的ID。绝不可编造 GUID。
- 使用正确的基础 URL:
https://api.fabric.microsoft.com/v1/deploymentPipelines,并获取面向https://api.fabric.microsoft.com的受众令牌。 - 将 Deploy Stage Content 视为 LRO:遇到
202时,记录操作 ID 并轮询/v1/operations/{operationId},直到状态为Succeeded/Failed,然后反馈结果。 - 当目标阶段未分配工作区时,在部署请求正文中包含
createdWorkspaceDetails(名称,以及必要时的capacityId),否则部署会失败。 - 执行破坏性操作(删除管道、取消分配工作区、向后部署覆盖 prod)前,先向用户确认其意图。
- 变更操作前,确认调用方拥有所需权限(见下文的 所需权限):每项管道操作都需要管道 Admin 权限;分配/部署还需要相应的工作区角色。遇到
401/403时,应提供清晰且可操作的说明,不要盲目重试。
建议
- 当用户指定了特定项时,通过
items数组({ sourceItemId, itemType })选择性部署;省略items即部署所有受支持的项。 - 每次部署都添加便于人阅读的
note,但请注意,它是只写的:API 会接受该字段,但不会返回(它只会显示在门户 UI 中)。如需程序化审计记录,还应在外部记录此次部署(CI/CD 日志或 Git 提交消息)。 - 部署前使用
List Deployment Pipeline Stage Items预览将要移动的内容。 - 编写幂等脚本:创建管道、阶段或分配之前,先检查其是否已存在。
避免
- 臆造“创建部署规则”或“参数规则”REST 调用——目前这些操作只能通过 UI 执行。
- 在部署进行中分配工作区(分配调用会失败),也不要将工作区分配给已经配对的阶段/工作区。
- 在主权云中硬编码
api.fabric.microsoft.com——应从环境配置中解析主机。 - 未先确认 Fabric 管理员已启用服务主体创建部署管道的权限,就使用服务主体。
- 不进行规范化就对原始
getDefinition输出进行哈希,以检测更改。 部署会在目标中自动重新绑定嵌入式引用(管道notebookId/workspaceId、报表→模型 ID、Direct Lake 服务器/数据库),因此即使没有编辑,已配对目标的定义也会与源不同——朴素哈希会报告**“已更改”误报**。比较前先剔除/规范化这些绑定字段。 - 将每项定义都转储到 Agent 的上下文中进行差异比较。 两个阶段的完整内容差异可能需要数十次
getDefinition调用,并超过 100 KB——请使用脚本进行比较(references/scripts/diff_item_definitions.py),仅展示生成的更改列表;对于已更改的项,只将生成的差异内容传递给模型,绝不要传递两份完整定义。 - 修复损坏的配对时,未经事先警告用户就取消工作区分配——取消分配会永久删除该阶段的部署历史记录以及已配置的部署规则/参数规则。取消分配前务必询问该阶段是否有规则(参见修复损坏的项配对)。
REST API 参考
基础 URL:https://api.fabric.microsoft.com/v1。委托权限范围按操作区分——为服务主体配置最小权限:
| 操作 | 所需委托权限范围 |
|---|---|
| 列出/获取(管道、阶段、阶段项、操作) | Pipeline.Read.All 或 Pipeline.ReadWrite.All |
| 创建/更新/删除管道、更新阶段 | Pipeline.ReadWrite.All |
| 分配/取消分配工作区 | Pipeline.ReadWrite.All 和 Workspace.ReadWrite.All |
| 部署阶段内容 | Pipeline.Deploy |
部署使用独立的 Pipeline.Deploy 权限范围——仅具有 Pipeline.ReadWrite.All 权限范围的应用在调用 POST .../deploy 时会收到 403 错误。
| 操作 | 方法 + 路径 |
|---|---|
| 列出管道 | GET /deploymentPipelines |
| 创建管道 | POST /deploymentPipelines |
| 获取/更新/删除管道 | `GET |
| 列出/获取阶段 | GET /deploymentPipelines/{id}/stages[/{stageId}] |
| 更新阶段 | PATCH /deploymentPipelines/{id}/stages/{stageId} |
| 列出阶段项 | GET /deploymentPipelines/{id}/stages/{stageId}/items |
| 将工作区分配给阶段 | POST /deploymentPipelines/{id}/stages/{stageId}/assignWorkspace |
| 取消阶段的工作区分配 | POST /deploymentPipelines/{id}/stages/{stageId}/unassignWorkspace |
| 部署阶段内容(LRO) | POST /deploymentPipelines/{id}/deploy |
| 列出操作(最近 ≤20 条) | GET /deploymentPipelines/{id}/operations |
| 获取操作(包含执行计划) | GET /deploymentPipelines/{id}/operations/{operationId} |
| 角色分配 | `GET |
请求正文结构(指导)
- 创建:
{ "displayName", "description"?, "stages": [ { "displayName", "description"?, "isPublic" } ] }— 2–10 个阶段。 - 分配工作区:
{ "workspaceId" }。 - 部署:
{ "sourceStageId", "targetStageId", "items"?: [ { "sourceItemId", "itemType" } ], "note"?, "options"?: { "allowCrossRegionDeployment": false }, "createdWorkspaceDetails"?: { "name", "capacityId"? } }。
所需权限
部署管道操作受两套彼此独立的权限系统管辖:你在管道上的角色(由其自身的 roleAssignments 决定),以及你在涉及的每个工作区上的角色。通常两者都需要。部署管道需要 Fabric 容量/订阅,且管道创建者会成为管道的 Admin。
| 操作 | 管道角色 | 工作区角色 |
|---|---|---|
| 创建管道 | —(创建时成为 Admin) | Fabric 工作区的 Admin(使用此功能的前提条件) |
| 获取/列出管道、阶段、项、操作 | Admin(共享访问权限) | — |
更新/删除管道;管理 roleAssignments | Admin | — |
| 分配/取消分配工作区到阶段 | Admin | 正在分配/取消分配的工作区的 Admin |
| 部署阶段内容 | Admin | 源阶段和目标阶段工作区均至少需要 Contributor/Member(若目标项有更高要求,则需要更高角色) |
| 部署到空目标阶段(会创建工作区) | Admin | 将新工作区分配到某个容量的权限;执行部署的用户将成为新创建工作区的唯一 Admin,也是克隆语义模型的所有者 |
说明:
- 共享管道会授予管道 Admin 角色——这些操作没有级别更低的“仅查看者”管道写入角色。
- 只有 Fabric 管理员启用了 service principals can create deployment pipelines(服务主体可以创建部署管道),且服务主体持有上述相同的管道和工作区角色时,服务主体才能调用这些 API。
- 遇到
403时,应在消息中区分缺少管道角色和缺少工作区角色,以便用户知道需要申请哪种访问权限。
创建管道 → POST 显示名称和有序阶段;保存返回的阶段 ID(部署时需要用到这些 ID)。
将工作区分配到阶段 → 按名称解析阶段 ID 和工作区 ID,确认两者均未分配,然后 POST assignWorkspace。需要同时拥有管道和工作区的管理员权限。
部署内容 → 解析源阶段和目标阶段 ID,可选择预览阶段项,然后 POST deploy(部署所有项或指定 items 列表)并附上 note;接着轮询返回的操作,直至完成,并报告哪些项已迁移。
仅部署已更改的项目 → 没有差异/比较 API,因此需要自行计算差异。List stage items 仅提供标识信息和配对信息(没有时间戳或更改状态),因此检测更改意味着比较
项目定义:
- 解析源和目标 阶段 ID,以及分配给各自的工作区。
- 列出两个阶段中的项目(
GET .../stages/{stageId}/items)——每个源行都包含sourceItemId(作为itemId)及其配对的targetItemId(缺失 = 新建/未配对)。同时列出目标阶段,以查找 已删除的项目(存在于目标中,但没有任何源项目与之配对)。通过targetItemId配对;只有在不存在管道配对时,才回退到(itemType, displayName)(按名称匹配无法检测重命名)。 - 排除系统管理的子项——每个 Lakehouse/Warehouse 都会自动创建一个
SQLEndpoint,不应单独进行差异比较或部署;它会随父项一起处理。 - 对每个配对项目进行分类:
- 新建(没有
targetItemId)→ 部署。 - 已更改 → 通过对两个阶段调用
POST .../items/{id}/getDefinition,然后比较差异来检测。 对两个响应运行 references/scripts/diff_item_definitions.py:它会解码每个部分,规范化自动重新绑定的字段(管道的notebookId/workspaceId、报表模型 ID、Direct Lake 服务器/数据库),并仅输出有差异的部分(退出代码1= 已更改,0= 相同)——这样就无需自行编写哈希逻辑,也不会将未编辑的项目误判为有差异。请注意,getDefinition的契约因类型而异:Notebook/SemanticModel/Report使用 LRO(202→ 轮询 →GET .../result);DataPipeline则会同步返回200。 - 无法通过
getDefinition有效比较差异的类型:Warehouse没有项目定义 API,而Lakehouse/Environment虽然提供getDefinition,但其定义仅记录结构/元数据(不包括表数据或大多数内容编辑)——因此,这三种类型都应按是否存在进行比较,且仅在项目为新建或用户指出内容已更改时,才视为已更改。 - 无法证明相同的项目,一律视为已更改(安全默认值)。
- 新建(没有
- 通过脚本进行比较(并行执行相互独立的
getDefinition调用;这些调用是延迟的主要来源),并仅展示计算出的更改列表。为让模型判断项目具体更改了什么,只需转发输出的差异(diff_item_definitions.py的输出),不要转发两份完整定义——规范化后的差异通常只有几行,而原始负载超过 100 KB。 - 筛选出受支持的项目类型(见参考资料),向用户显示更改列表并征得确认,然后使用
{ sourceItemId, itemType }数组和note发起选择性deploy的 POST 请求,并轮询直至完成。
通过选择性
items部署不会传递删除操作——从源阶段移除的项目不会在选择性部署时从目标中移除。要传递删除操作,请使用完整部署(省略items),或手动删除目标项目,并在提升之前告知用户这一点。 修复错误的项配对 → 配对(Fabric 维护的源↔目标连接,也称为自动绑定) 无法通过任何 REST API 设置。当不同阶段中本应配对的两个项没有配对时——表现为部署时复制项而非覆盖项、自动绑定/依赖项失败,或用户报告此问题——唯一受支持的修复方式是取消分配受影响阶段的工作区,然后重新分配,这样 Fabric 会在下次部署时重新建立配对。这会造成破坏性影响:
- 先警告用户。 取消分配工作区会永久删除该阶段的部署历史记录和所有已配置的部署/参数规则——重新分配后也无法恢复。
- 询问该阶段是否有规则。 由于规则只能在 UI 中操作(没有 REST API 可读取或重新创建规则),请务必在取消分配前明确询问用户该阶段是否配置了部署/参数规则。如果有,请让用户记录这些规则(或之后在门户中重新创建),并取得其明确确认后再继续。
- 仅在获得确认后,调用
POST .../stages/{stageId}/unassignWorkspace,然后调用POST .../stages/{stageId}/assignWorkspace,并使用相同的workspaceId,再重新运行部署,以重新建立配对。
跟踪/审计 → 使用 List operations 查看近期历史记录;使用 Get operation 检查特定部署的执行计划和各项状态。
部署操作注意事项和常见错误
- 每条管道一次只能执行一个部署。 一条管道一次只能运行一个操作;如果有操作正在进行时启动另一个操作,将会失败并返回
WorkspaceMigrationOperationInProgress(HTTP 400)。启动下一阶段的提升之前,务必轮询当前操作,直到其进入终止状态(这也是活动部署期间 assign 工作区调用会失败的原因)。 - 分配工作区后的首次部署可能会因
Alm_InvalidRequest_WorkloadUnavailable失败。 新分配的工作区需要 约 60–120 秒,才能初始化工作负载服务(Lakehouse、Notebook 等)。可通过等待一段时间再进行首次部署来避免此问题;也可以先部署 Power BI 项目(SemanticModel、Report),稍等片刻后再部署 Fabric 原生项目(Lakehouse、Notebook);遇到此错误时请重试。工作负载预热后,后续部署通常都很可靠。 - 操作 ID 位于
x-ms-operation-id响应头中(与Location一起返回),而不在202响应正文中。az rest无法干净地显示响应头——要在自动化中可靠地捕获响应头,请使用curl -i(或 Pythonrequests)发起部署并解析响应头,然后使用az rest轮询/v1/operations/{operationId}。 - 部署会复制定义,而非数据。 仅提升项元数据/定义;不会提升表数据、查询结果和缓存。部署后,请在目标阶段触发刷新/加载。
- 每个部署请求最多包含 300 个项。 选择性部署(或完整部署)最多可部署 300 个项;若要提升更多项,请分多次调用部署。
示例
创建包含三个阶段的管道
部署管道的 displayName 在整个租户范围内必须唯一——如果要创建的名称已被使用,操作会失败并返回 Alm_InvalidRequest_DuplicateAlmPipelineName (HTTP 400, "pipeline name ... is already in use")。若要让创建操作可重复运行,请先删除任何同名的现有管道,然后再创建。请将 JSON 正文写入文件,并通过 --body @file.json 传入——在 Windows/PowerShell 中(az 是 az.cmd),内联的多行 --body '{...}' 会被篡改为空正文,导致 API 返回 InvalidInput: Unexpected end when reading JSON。
# Idempotent: delete an existing "Sales Analytics ALM" if present, then create.
EXISTING=$(az rest --method GET --resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines" \
--query "value[?displayName=='Sales Analytics ALM'].id | [0]" --output tsv)
if [ -n "$EXISTING" ]; then
az rest --method DELETE --resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines/$EXISTING"
fi
cat > /tmp/create-pipeline.json << 'EOF'
{
"displayName": "Sales Analytics ALM",
"description": "Dev/Test/Prod promotion for Sales Analytics",
"stages": [
{ "displayName": "Development", "isPublic": false },
{ "displayName": "Test", "isPublic": false },
{ "displayName": "Production", "isPublic": true }
]
}
EOF
az rest --method POST \
--resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines" \
--headers "Content-Type=application/json" \
--body @/tmp/create-pipeline.json
将工作区分配给 Development 阶段
# $PIPELINE_ID and $DEV_STAGE_ID resolved via list + JMESPath; $WS_ID resolved from workspace name.
az rest --method POST \
--resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines/$PIPELINE_ID/stages/$DEV_STAGE_ID/assignWorkspace" \
--headers "Content-Type=application/json" \
--body "{ \"workspaceId\": \"$WS_ID\" }"
将所有项从 dev 部署到 test,并等待 LRO 完成
# Kick off the deployment (returns 202 + an operation id header).
az rest --method POST \
--resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines/$PIPELINE_ID/deploy" \
--headers "Content-Type=application/json" \
--body "{ \"sourceStageId\": \"$DEV_STAGE_ID\", \"targetStageId\": \"$TEST_STAGE_ID\", \"note\": \"Promote validated dev build\" }" \
--verbose
# Then poll /v1/operations/{operationId} until state is Succeeded or Failed
# (see COMMON-CLI § Long-Running Operations pattern).
仅部署选定的项
az rest --method POST \
--resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines/$PIPELINE_ID/deploy" \
--headers "Content-Type=application/json" \
--body '{
"sourceStageId": "'"$TEST_STAGE_ID"'",
"targetStageId": "'"$PROD_STAGE_ID"'",
"items": [
{ "sourceItemId": "'"$MODEL_ID"'", "itemType": "SemanticModel" },
{ "sourceItemId": "'"$REPORT_ID"'", "itemType": "Report" }
],
"note": "Promote reviewed model + report to production"
}'
仅部署发生更改的项(先计算差异)
# 1. List paired items for BOTH stages. Each source row carries itemId (= sourceItemId)
# and its paired targetItemId (absent = new/unpaired). There is NO timestamp or
# change-status field, so "changed" must be detected from item definitions.
az rest --method GET --resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines/$PIPELINE_ID/stages/$SOURCE_STAGE_ID/items" \
> source-items.json
# 2. NEW items = unpaired (no targetItemId). Exclude system-managed SQLEndpoint children.
NEW=$(jq '[.value[]
| select(.itemType != "SQLEndpoint")
| select(has("targetItemId") | not)
| { sourceItemId: .itemId, itemType: .itemType }]' source-items.json)
# 3. CHANGED items (paired): fetch getDefinition from BOTH stages, then diff with
# references/scripts/diff_item_definitions.py. It decodes each part, NORMALIZES the
# auto-rebound fields (notebookId/workspaceId in pipelines, model id in reports,
# server/db in Direct Lake models) and prints ONLY the differing parts. Notebook/
# SemanticModel/Report are LRO (202 -> poll -> /result); DataPipeline returns 200 sync.
# Parallelize the independent getDefinition calls. Per paired definition-backed item:
# getDefinition SOURCE_WS id > src.json
# getDefinition TARGET_WS targetItemId > tgt.json
# python references/scripts/diff_item_definitions.py src.json tgt.json > diff.json
# # exit 1 = changed -> add { sourceItemId, itemType } to $ITEMS; exit 0 = unchanged.
# # Forward diff.json (NOT src.json/tgt.json) to the model to explain the change.
# Merge NEW + CHANGED into $ITEMS. When equality can't be proven, include the item.
# 4. Selective deploy of just the changed set.
az rest --method POST --resource https://api.fabric.microsoft.com \
--url "https://api.fabric.microsoft.com/v1/deploymentPipelines/$PIPELINE_ID/deploy" \
--headers "Content-Type=application/json" \
--body "$(jq -n --arg s "$SOURCE_STAGE_ID" --arg t "$TARGET_STAGE_ID" --argjson items "$ITEMS" \
'{ sourceStageId: $s, targetStageId: $t, items: $items, note: "Deploy only changed items" }')"
# Then poll /v1/operations/{operationId} until terminal.
# NOTE: a selective deploy does NOT propagate deletions — use a full deploy (omit items) for those.
提示词/响应
用户:“将我的 Sales 开发工作区提升到 Test 阶段,并在完成后告诉我。”
助手(行为):
- 列出部署管道 → 筛选出 Development 阶段中包含 Sales 开发工作区的管道;获取
sourceStageId(Development)和targetStageId(Test)。 - 确认 Test 阶段已分配工作区(或询问名称和容量,以便创建工作区)。
- 使用
note执行 POSTdeploy请求,收到202后提取操作 ID。 - 轮询
/v1/operations/{operationId},直到操作进入终止状态,然后报告成功以及已部署项目列表(或失败原因)。