Azure DevOps中批量自动更新需求链接类型的可行性咨询
在Azure DevOps中批量替换需求的Successor/Predecessor链接为Affected by/Affects的方案
可以通过Azure DevOps CLI或REST API结合脚本实现批量替换,以下是具体可行方案:
方法一:Azure DevOps CLI + PowerShell脚本
前置准备
- 安装Azure DevOps CLI扩展:
az extension add --name azure-devops - 登录并配置默认组织和项目:
az login az devops configure --defaults organization=https://dev.azure.com/你的组织名 project=你的项目名
批量处理脚本
以下PowerShell脚本会遍历指定类型的需求工作项,自动替换链接类型:
# 替换为你的项目中需求对应的工作项类型(如Product Backlog Item、User Story) $workItemType = "Product Backlog Item" # 查询所有需求工作项ID $wiqlQuery = "SELECT [System.Id] FROM WorkItems WHERE [System.WorkItemType] = '$workItemType'" $workItems = az boards work-item query --wiql "$wiqlQuery" | ConvertFrom-Json foreach ($item in $workItems) { # 获取当前工作项的所有链接 $workItemDetails = az boards work-item show --id $item.id --expand relations | ConvertFrom-Json $relations = $workItemDetails.relations # 遍历链接,判断并替换类型 for ($i = $relations.Count - 1; $i -ge 0; $i--) { $link = $relations[$i] $targetId = $link.url.Split('/')[-1] switch ($link.rel) { "System.LinkTypes.Dependency-Successor" { # 删除Successor链接,添加Affects链接 az boards work-item relation remove --id $item.id --relation-type $link.rel --target-id $targetId az boards work-item relation add --id $item.id --relation-type "System.LinkTypes.Dependency-Affects" --target-id $targetId } "System.LinkTypes.Dependency-Predecessor" { # 删除Predecessor链接,添加Affected by链接 az boards work-item relation remove --id $item.id --relation-type $link.rel --target-id $targetId az boards work-item relation add --id $item.id --relation-type "System.LinkTypes.Dependency-AffectedBy" --target-id $targetId } } } }
注意点
- 提前在测试环境验证脚本,避免误操作生产数据
- 若项目自定义了链接类型,需替换脚本中对应的
rel值(可通过查看工作项详情的API返回获取准确rel)
方法二:Azure DevOps REST API 实现
如果更倾向于直接调用API,可按以下步骤操作:
- 生成具有Work Items读写权限的个人访问令牌(PAT)
- 编写脚本(以Python为例核心逻辑):
import requests org_url = "https://dev.azure.com/你的组织名" proj_name = "你的项目名" pat = "你的PAT令牌" headers = {"Content-Type": "application/json-patch+json", "Authorization": f"Basic {pat}"} # 查询所有需求工作项ID wiql_url = f"{org_url}/{proj_name}/_apis/wit/wiql?api-version=7.1-preview.2" wiql_body = {"query": "SELECT [System.Id] FROM WorkItems WHERE [System.WorkItemType] = 'Product Backlog Item'"} response = requests.post(wiql_url, json=wiql_body, headers=headers) work_item_ids = [item["id"] for item in response.json()["workItems"]] for item_id in work_item_ids: # 获取工作项及链接详情 item_url = f"{org_url}/{proj_name}/_apis/wit/workitems/{item_id}?$expand=relations&api-version=7.1-preview.3" item_response = requests.get(item_url, headers=headers) item_data = item_response.json() relations = item_data.get("relations", []) # 构建PATCH请求体,批量替换链接 patch_ops = [] for idx, link in enumerate(relations): target_id = link["url"].split('/')[-1] if link["rel"] == "System.LinkTypes.Dependency-Successor": # 删除旧链接 patch_ops.append({"op": "remove", "path": f"/relations/{idx}"}) # 添加新的Affects链接 patch_ops.append({ "op": "add", "path": "/relations/-", "value": {"rel": "System.LinkTypes.Dependency-Affects", "url": link["url"]} }) elif link["rel"] == "System.LinkTypes.Dependency-Predecessor": patch_ops.append({"op": "remove", "path": f"/relations/{idx}"}) patch_ops.append({ "op": "add", "path": "/relations/-", "value": {"rel": "System.LinkTypes.Dependency-AffectedBy", "url": link["url"]} }) # 执行PATCH更新 if patch_ops: requests.patch(item_url, json=patch_ops, headers=headers)
关键提醒
- 批量操作前务必备份工作项数据,或先选择少量工作项测试
- 若项目中有工作项状态机或自动化规则,需确认替换链接不会触发异常流程
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

