跨Azure DevOps项目克隆Workitems的实现方案咨询
Azure DevOps 模板项目工作项迁移方案
实现流程
- 前置准备:创建具备源项目工作项读取、目标项目工作项写入权限的个人访问令牌(PAT),提前在目标项目配置和源项目一致的工作项类型、自定义字段、区域路径、迭代路径配置,避免字段不匹配
- 源数据拉取:批量拉取源模板项目所有工作项的完整信息,包括字段内容、父子层级关联、附件、链接关系
- 数据适配:替换工作项中的源项目标识(如区域路径前缀、迭代路径前缀),过滤系统自动生成的不可编辑字段
- 目标端写入:按工作项层级从高到低创建(先创建User Story等父级工作项,再创建Task等子级工作项),完成后根据源数据恢复关联关系、上传附件
- 结果校验:对比源和目标的工作项数量、字段内容、关联关系,确认迁移完整
相关API说明
官方提供的可用REST API接口如下,可直接在Azure DevOps开发文档中搜索对应接口名获取使用说明:
- 工作项查询接口:
Wiql - Query By Wiql,用于按条件拉取源项目所有工作项ID - 批量详情获取接口:
Work Items - Get Work Items Batch,可一次查询最多200个工作项的完整字段、关联、附件信息 - 工作项创建接口:
Work Items - Create,用于在目标项目新建工作项 - 工作项更新接口:
Work Items - Update,用于补充创建工作项后的关联关系、附件上传
Python 实现核心示例
首先安装官方Python SDK:pip install azure-devops
核心代码示例(简化版,仅演示核心逻辑,实际使用可根据需求扩展父子关联、附件迁移的处理):
from azure.devops.connection import Connection from msrest.authentication import BasicAuthentication from azure.devops.v7_1.work_item_tracking.models import JsonPatchOperation # 基础配置 PAT = "你的个人访问令牌" ORG_URL = "https://dev.azure.com/你的组织名称" SOURCE_PROJECT = "源模板项目名称" TARGET_PROJECT = "目标新项目名称" # 初始化客户端 credentials = BasicAuthentication("", PAT) conn = Connection(base_url=ORG_URL, creds=credentials) wit_client = conn.clients.get_work_item_tracking_client() # 1. 查询源项目所有工作项ID query_sql = f""" SELECT [System.Id], [System.WorkItemType] FROM WorkItems WHERE [System.TeamProject] = '{SOURCE_PROJECT}' ORDER BY [System.WorkItemType] DESC """ query_res = wit_client.query_by_wiql(query_sql, top=10000) source_wi_ids = [item.id for item in query_res.work_items] # 2. 批量获取源工作项完整信息 source_wis = wit_client.get_work_items(ids=source_wi_ids, expand="All") # 3. 批量创建目标工作项 wi_id_mapping = {} # 存储源ID到目标ID的映射,用于后续关联关系恢复 for source_wi in source_wis: patch_ops = [] # 遍历字段过滤并替换 for field_key, field_val in source_wi.fields.items(): # 跳过系统自动生成的不可编辑字段 if field_key in ["System.Id", "System.Rev", "System.CreatedDate", "System.CreatedBy", "System.ChangedDate", "System.ChangedBy", "System.TeamProject"]: continue # 替换项目相关路径字段 if field_key == "System.AreaPath" or field_key == "System.IterationPath": field_val = field_val.replace(SOURCE_PROJECT, TARGET_PROJECT) patch_ops.append(JsonPatchOperation( op="add", path=f"/fields/{field_key}", value=field_val )) # 创建新工作项 new_wi = wit_client.create_work_item( document=patch_ops, project=TARGET_PROJECT, type=source_wi.fields["System.WorkItemType"] ) wi_id_mapping[source_wi.id] = new_wi.id # 后续可基于wi_id_mapping恢复父子关联、关联附件等操作
注意事项
- 迁移前建议先用测试项目做完整验证,确认字段、关联、附件都正确迁移后再执行正式操作
- 工作项数量较大时,注意控制API调用频率,避免触发限流,可适当增加请求间隔或使用批量操作接口
- 如果源项目有自定义工作项类型,必须提前在目标项目导入同样的工作项类型配置,否则会创建失败
内容的提问来源于stack exchange,提问作者LewisH
相关产品推荐
相关产品推荐

