Beads 与 Azure DevOps(ADO)双向同步配置完全指南
2026/9/12 4:49:22 网站建设 项目流程

Beads 与 Azure DevOps(ADO)双向同步配置完全指南

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

本篇指南围绕 Beads 提供的bd ado sync命令展开,讲解如何将 Beads 中基于 Dolt 数据库的 issue 体系与 Azure DevOps 工作项(Work Item)进行双向同步。你将掌握连接配置、过滤条件、优先级/状态/类型映射、Agile/Scrum/CMMI 过程模板适配、冲突解决、协调扫描与故障排查等完整实战方案,并深入了解底层实现(对应仓库源码 cmd/bd/ado.go 与 internal/ado/ 包)。

一、功能概览与适用场景

Beads 通过bd ado sync实现与 Azure DevOps 的双向同步:

  • Pull(导入):将 ADO 中新建/更新的工作项拉取为 Beads issue;
  • Push(导出):将本地 Beads issue 推送为 ADO 工作项,包括创建与更新;
  • 链接同步:将 Beads 的依赖关系(dependency)同步为 ADO 工作项关联(relations);
  • 协调扫描(Reconciliation):周期性检测 ADO 中已被删除或不可读的工作项,避免本地残留"幽灵 issue"。

重要限制(Proxied-server 模式)bd ado syncbd ado statusbd ado projects在 Beads 连接代理服务器(proxied server)时不受支持,会直接报错ado sync is not supported in proxied-server mode(见 cmd/bd/ado.go 中runADOSync的守卫逻辑)。这三个命令必须在拥有直接数据库访问权限的工作区中运行。

二、快速开始

2.1 使用配置项(推荐)

# 设置必需配置 bd config set ado.pat "your-personal-access-token" bd config set ado.org "your-organization" bd config set ado.project "your-project"

2.2 使用环境变量

export AZURE_DEVOPS_PAT="your-personal-access-token" export AZURE_DEVOPS_ORG="your-organization" export AZURE_DEVOPS_PROJECT="your-project"

2.3 执行同步

# 双向同步(先拉后推,默认) bd ado sync # 仅拉取(从 ADO 导入) bd ado sync --pull-only # 仅推送(导出到 ADO) bd ado sync --push-only # 预览模式,不做任何变更 bd ado sync --dry-run

配置优先级:通过bd config set设置的配置键(config key)优先于环境变量。源码中getADOConfigValue(cmd/bd/ado.go)的读取顺序正是"先查存储配置,再回退到环境变量"。

安全存储ado.pat是敏感密钥,存储在config.yaml(仓库级或用户全局级)中,永远不会写入共享数据库,因此 PAT 不会通过dolt push泄露。此外 internal/ado/types.go 中定义了SecretString类型,其String()MarshalJSON()均返回[REDACTED],确保密钥不会出现在日志、JSON 输出或fmt格式化中。

三、连接配置详解

3.1 配置键与环境变量对照表

配置键环境变量是否必需说明
ado.patAZURE_DEVOPS_PAT个人访问令牌(Personal Access Token)
ado.orgAZURE_DEVOPS_ORG条件¹组织名(如myorg
ado.urlAZURE_DEVOPS_URL条件¹自定义基础 URL(本地部署的 ADO Server)
ado.projectAZURE_DEVOPS_PROJECT条件²单个项目名
ado.projectsAZURE_DEVOPS_PROJECTS条件²逗号分隔的多项目名

¹ado.orgado.url必须设置其一:云版使用ado.org,本地部署(on-premises Azure DevOps Server)使用ado.url

²ado.projectado.projects至少配置其一。

源码中validateADOConfig(cmd/bd/ado.go)会依次校验 PAT、org/url、project 三个条件,缺失时会给出明确的错误提示。

3.2 连接参数的解析细节

getADOConfig在解析项目时有一个细节:它会同时读取ado.projects(复数)与ado.project(单数)两个来源,并通过tracker.ResolveProjectIDs合并解析;当存在多个项目时,第一个项目被用作 URL 构造的主项目cfg.Project = cfg.Projects[0])。

环境变量映射由adoConfigToEnvVar完成,支持的映射如下:

配置键环境变量
ado.patAZURE_DEVOPS_PAT
ado.orgAZURE_DEVOPS_ORG
ado.projectAZURE_DEVOPS_PROJECT
ado.projectsAZURE_DEVOPS_PROJECTS
ado.urlAZURE_DEVOPS_URL

3.3 本地部署 ADO Server(On-Premises)

对于本地部署的 Azure DevOps Server,改用ado.url而非ado.org

bd config set ado.url "https://tfs.company.com/DefaultCollection" bd config set ado.project "MyProject"

底层 API 客户端通过WithBaseURL设置自定义基础 URL(internal/ado/client.go)。有一个值得注意的安全校验:validateURLScheme会拒绝非 HTTPS 的 URL,除非主机是localhost127.0.0.1::1(用于本地测试模拟服务器)。也就是说,指向公网或内网其他主机的明文 HTTP 地址会被直接拒绝。

3.4 多项目同步

单个命令跨多个项目同步:

bd config set ado.projects "ProjectA,ProjectB,ProjectC"

多项目模式下,拉取查询会使用[System.TeamProject] IN (...)形式的 WIQL 子句;单项目则使用[System.TeamProject] = '...'(见 internal/ado/client.go 中buildPullWIQLMulti)。另外,bd ado sync还提供可重复的--project标志,在单次运行中覆盖ado.project/ado.projects配置。

3.5 用statusprojects验证连接

# 查看当前 ADO 配置与同步状态(含脱敏后的 PAT,仅显示前 4 位) bd ado status # 以 JSON 输出(便于脚本解析) bd ado status --json # 列出令牌可访问的所有项目 bd ado projects

runADOStatus在输出中会用maskADOToken对 PAT 脱敏(仅显示前 4 个字符加****,见 cmd/bd/ado.go),并输出Status: ✓ Configured或具体的缺失项错误。

四、过滤配置(Filters)

过滤器控制哪些 ADO 工作项参与同步。

4.1 配置键与 CLI 标志对照

配置键CLI 标志说明示例
ado.filter.area_path--area-path区域路径(Area path,层级使用 UNDER 语义)Project\Team
ado.filter.iteration_path--iteration-path迭代/冲刺路径Project\Sprint 1
ado.filter.types--types工作项类型(逗号分隔)Bug,Task,User Story
ado.filter.states--statesADO 状态(逗号分隔)New,Active,Resolved

CLI 标志优先于配置值buildADOPullFilters(cmd/bd/ado.go)通过cmd.Flags().Changed(...)判断标志是否被显式设置,只有未设置时才回退读取ado.filter.*配置。

双向语义

  • Pull 方向:过滤器限制 WIQL 查询(--area-path/--iteration-path对应UNDER子句,--types/--states对应IN子句);
  • Push 方向--types--states会先把 ADO 过滤值反向映射为 Beads 的类型与状态,再在推送前过滤本地 issue(见buildADOPushHooks的实现逻辑)。

4.2 生成的 WIQL 查询示例

SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = 'MyProject' AND [System.IsDeleted] = false AND [System.AreaPath] UNDER 'Project\Team' AND [System.WorkItemType] IN ('Bug', 'Task') AND [System.State] IN ('New', 'Active') ORDER BY [System.ChangedDate] ASC

4.3 过滤值的合法性校验

PullFilters.Validate()(internal/ado/client.go)会对所有过滤值做白名单正则校验,防止 WIQL 注入:

  • 区域/迭代路径:^[a-zA-Z0-9 ._\\/-]+$
  • 状态名:^[a-zA-Z0-9 _]+$
  • 组织名:^[a-zA-Z0-9._-]+$
  • 项目名:^[a-zA-Z0-9 ._'-]+$

同时 WIQL 字面量统一经escapeWIQL转义(反斜杠翻倍、单引号翻倍),查询中的字符串全部转义后才拼接。增量拉取还会自动追加[System.ChangedDate] >= 'YYYY-MM-DD'子句(日期按 UTC 截断到天,见formatWIQLDate,因为 ADO 日期精度字段拒绝带时间部分的值)。

五、默认字段映射

5.1 优先级映射(双向但 P3/P4 有损)

Beads 优先级ADO 优先级方向备注
0(Critical)1
1(High)2
2(Medium)3未知值默认
3(Low)4
4(Backlog)4有损:拉回时变成 P3

注意:Beads 的 P3 和 P4 都映射到 ADO 优先级 4。在空数据库上全新拉取时,ADO 4 会被映射回 Beads P3。因此对 P4 issue 而言,完整往返一次后原始优先级无法保留。

源码级缓解机制adoFieldMapper(internal/ado/fieldmapper.go)的PriorityToTracker将 Beads 3、4 均映射为 ADO 4(有损方向);但 internal/ado/mapping.go 中IssueToTracker会在 Beads 优先级为 3 或 4 时把原始值写入元数据键beads_priority,而IssueToBeads在拉回时会优先从该元数据恢复原始优先级——只要该 issue 仍由 Beads 管理(即有本地元数据),往返可近似无损;只有"直接导入一个陌生 ADO 工作项"才会落到默认的 P3。

Bug 类型额外要求:ADO 的 Bug 工作项必须有 Severity 字段,映射如下:

Beads 优先级ADO Severity
01 - Critical
12 - High
23 - Medium
3, 44 - Low

该逻辑对应adoFieldMapper.SeverityForBug:0→1 - Critical、1→2 - High、2→3 - Medium、3/4→4 - Low,未知值默认3 - Medium

5.2 状态映射

Beads 状态默认 ADO 状态配置键
openNewado.state_map.open
in_progressActiveado.state_map.in_progress
blockedActive+beads:blocked标签ado.state_map.blocked
deferredRemovedado.state_map.deferred
closedClosedado.state_map.closed

Blocked 状态的处理:ADO 没有原生的 blocked 状态。Beads 将blocked映射为Active并附加beads:blocked标签;拉回时,如果工作项状态为Active且带beads:blocked标签,则恢复为StatusBlocked(见 internal/ado/mapping.go 中IssueToBeads的恢复逻辑)。

自定义状态映射(适配你的过程模板):

# 示例:Scrum 模板 bd config set ado.state_map.open "To Do" bd config set ado.state_map.in_progress "In Progress" bd config set ado.state_map.closed "Done"

adoFieldMapper在双向转换时都优先查找自定义stateMap(反向查表,大小写不敏感),未命中才回退 Agile 默认值;反向查表失败的 ADO 状态在拉取时默认映射为StatusOpen

5.3 类型映射

Beads 类型默认 ADO 类型配置键
bugBugado.type_map.bug
featureUser Storyado.type_map.feature
taskTaskado.type_map.task
epicEpicado.type_map.epic
choreTaskado.type_map.chore

反向映射(ADO → Beads)还会识别:

  • Product Backlog Itemfeature(Scrum 模板)
  • Issuetask

自定义示例:

# 示例:Scrum 模板 bd config set ado.type_map.feature "Product Backlog Item"

TypeToTracker/TypeToBeads均采用"自定义表优先 + 大小写不敏感"的策略,未匹配的 ADO 类型默认映射为task

六、过程模板配置(Process Template)

ADO 支持多种过程模板,各自的工作项类型与状态流转不同。默认映射基于 Agile 模板,使用其他模板时需覆盖相应映射。

6.1 Agile(默认)

无需任何配置,默认映射开箱即用。状态流转:

Bug: New → Active → Resolved → Closed Task: New → Active → Closed User Story: New → Active → Resolved → Closed Epic: New → Active → Resolved → Closed

6.2 Scrum

bd config set ado.type_map.feature "Product Backlog Item" bd config set ado.state_map.open "New" bd config set ado.state_map.in_progress "Committed" bd config set ado.state_map.closed "Done"

状态流转:

Product Backlog Item: New → Approved → Committed → Done Task: To Do → In Progress → Done Bug: New → Approved → Committed → Done

6.3 CMMI

bd config set ado.type_map.feature "Requirement" bd config set ado.state_map.open "Proposed" bd config set ado.state_map.in_progress "Active" bd config set ado.state_map.closed "Closed"

状态流转:

Requirement: Proposed → Active → Resolved → Closed Task: Proposed → Active → Closed Bug: Proposed → Active → Resolved → Closed

6.4 状态转换处理(State Transition Handling)

当需要把工作项创建在非初始状态(例如推送一个已关闭的 issue)时,Beads 的执行策略是:

  1. 以初始状态创建工作项(如New,ADO 可用的初始状态包括NewTo DoProposed,见 internal/ado/statetransition.go 的initialStates);
  2. 沿中间状态逐级转换直至目标状态;
  3. 示例:创建已关闭的 Bug →New → Active → Resolved → Closed

失败回退机制transitionWorkItem会先尝试直接更新状态;若 ADO 返回400 Bad Request(说明过程模板不支持直接跳转),则自动按已知转换路径(defaultTransitions,覆盖 Agile/Scrum/CMMI 常见类型与状态组合)逐级推进;若路径未知则返回带原始错误上下文的报错。

七、同步选项(Sync Options)

7.1 同步方向

标志说明
(无)双向:先拉后推
--pull-only仅从 ADO 导入
--push-only仅导出到 ADO

注意--pull-only--push-only不能同时使用(源码会报错cannot use both --pull-only and --push-only)。

7.2 冲突解决策略

当同一 issue 在本地与 ADO 都发生过修改时:

标志说明
--prefer-newer最近更新时间者胜出(默认)
--prefer-local始终保留本地 Beads 版本
--prefer-ado始终采用 ADO 版本

三个冲突标志互斥getADOConflictStrategy(cmd/bd/ado.go)会检测同时设置多个标志的情况并直接报错。底层对应tracker.ConflictTimestamp/ConflictLocal/ConflictExternal三种策略。

7.3 其他常用标志

标志说明
--dry-run预览同步结果,不落任何变更
--no-create只更新已有工作项/issue,绝不新建(双向生效)
--bootstrap-match首次同步时启用启发式标题匹配(见下文)
--reconcile强制执行协调扫描(见下文)
--issues按 Bead ID 或 ADO 工作项 ID 只同步指定 issue
--parent只推送某 bead 及其后代(仅推送模式,与--issues互斥)
--project本次运行的项目名,可重复,覆盖ado.project/ado.projects
--states按工作项状态过滤(逗号分隔)
--types按工作项类型过滤(逗号分隔)

--no-create的底层行为

  • Pull 方向:buildADOPullHooksShouldImport在无法通过 external_ref 或引导匹配关联到本地 issue 时,直接跳过(不新建);
  • Push 方向:buildADOPushHooksShouldPush只允许推送"已带 ADO external ref"的本地 issue,未关联的绝不创建新工作项。

--bootstrap-match的底层行为BootstrapMatcher(internal/ado/bootstrap.go)按优先级执行三种匹配策略:

  1. external_ref 精确匹配:本地 issue 的 ExternalRef 与 ADO 工作项 URL 一致;
  2. source_system 匹配:本地 issue 的 SourceSystem 中记录的 ADO ID 一致;
  3. 启发式匹配(需--bootstrap-match开启):标题 + 类型 + 创建时间(时间窗口 24 小时)同时吻合。

匹配成功后会把已有本地 issue 直接关联到 ADO 工作项(写入 external_ref 与 source_system),从而避免首次同步产生大量重复 issue;出现多个候选时会输出歧义警告。bd ado status的 JSON 输出会包含bootstrap_matched计数,方便验证匹配结果。

7.4 协调扫描(Reconciliation)

协调扫描会重新检查 Beads 已跟踪的工作项,从而发现**在 ADO 中被删除(404)或已不可读(403)**的工作项,避免本地残留陈旧 issue。它不会在每次同步都运行——那样会对每个被跟踪项都多消耗一次 API 调用——因此采用周期性执行策略:

配置键默认值说明
ado.reconcile_interval10每 N 次同步执行一次自动协调扫描
  • --reconcile立即强制执行一次扫描;
  • 扫描发现 ADO 中已删除的工作项时,会以ADO work item <id> deleted为原因自动关闭对应的本地 issue(见 cmd/bd/ado.go 中runADOSync的协调处理段);
  • 不可读(403)的工作项会输出访问被拒的警告,不关闭 issue。

两个容易混淆的配置键ado.syncs_since_reconcile也会出现在 config 中,但它是 Beads 用来记录"距上次协调已同步几次"的计数器,由 internal/ado/reconcile.go 的IncrementCounter/ResetCounter自动维护,不是需要用户编辑的设置项Reconciler.ReconcileMaxBatchSize(200)批量抓取工作项,批量失败时会对单项逐一验证,精确区分 404(deleted)、403(denied)与其它错误。

八、依赖关系同步与链接(Links)

同步完成后(非 dry-run 且非 pull-only 模式),runADOSync还会额外执行一轮依赖链接推送pushADOLinks):遍历所有带 ADO external ref 的本地 issue,把它们的依赖关系映射为 ADO 工作项关联(相关链接类型常量见 internal/ado/types.go,包括System.LinkTypes.RelatedSystem.LinkTypes.Dependency-Forward/ReverseSystem.LinkTypes.Hierarchy-Forward/Reverse等)。

这里有一个防止"误删人工链接"的细节:pushADOLinks会先构建managedTargets集合(Beads 正在跟踪的 ADO 工作项 ID),PushLinks只删除"目标在该集合内"的当前关联,从而保留人工创建的 Related / Predecessor-Successor 链接,避免被同步逻辑清空。拉取方向则通过ExtractLinkDeps把工作项关联恢复为 Beads 依赖。

九、PAT 权限要求

个人访问令牌(PAT)需要如下作用域:

作用域访问级别用途
Work ItemsRead & Write创建和更新工作项

生成地址:https://dev.azure.com/{org}/_usersettings/tokens。建议在受限范围的基础上按最小权限原则发放令牌。

十、往返保真:保留的元数据与描述转换

10.1 保留的 ADO 元数据

为保证"拉-改-推"往返的一致性,Beads 会把 ADO 特有字段存入 issue 元数据(buildMetadata/restoreMetadata,见 internal/ado/mapping.go):

元数据键说明
ado.revADO 修订号(rev)
ado.area_path区域路径
ado.iteration_path迭代/冲刺路径
ado.story_points故事点估算
ado.remaining_work剩余工时
ado.severityBug 严重级别

推送时restoreMetadata会把这些值回写进 ADO 字段——例如先前从 ADO 拉取的 severity 会优先于按优先级计算出的 severity,避免往返改写;拉取时buildMetadata同步保留这些字段。另有ado.external_ref机制:每个 ADO 工作项的 Web 编辑 URL(.../_workitems/edit/{id})会被记录为本地 issue 的外部引用,作为两边的关联锚点。

10.2 描述(Description)转换

  • Push(Beads → ADO):Markdown 转为 HTML。使用 goldmark 渲染器(XHTML 输出,不穿透原始 HTML,见 internal/ado/richtext.go 的MarkdownToHTML);
  • Pull(ADO → Beads):HTML 转为 Markdown。HTMLToMarkdown先用 bluemonday 的 UGC 策略清洗 HTML(剥离<script>、事件处理器等危险元素),再转换为 Markdown。

这意味着两边编辑器中都可以使用各自的原生富文本能力,而 Beads 侧始终以安全的 Markdown 落库。

十一、标签与标签映射(Tags and Labels)

  • ADO 标签是分号分隔的字符串;Beads 标签是数组;
  • 用户的标签通过 ADO 标签往返保留(buildTagString"; "连接,parseTags;切分并 trim);
  • 内部beads:*标签(如beads:blocked)在拉取时会被filterBeadsTags过滤掉,不会作为用户标签出现在本地 issue 中,但其存在与否决定了 blocked 状态能否恢复。

十二、API 限制与客户端行为

以下常量定义于 internal/ado/types.go,构成了 ADO 客户端的硬性边界:

限制项
单次 GET 请求最大批量200 个工作项
最大响应体50 MB
请求超时30 秒
最大重试次数3(仅 GET 与 WIQL)
重试退避指数退避 + 抖动,尊重Retry-After响应头

重试语义值得注意(internal/ado/client.go 的isIdempotent):只有 GET 请求和 WIQL 查询(POST 到/wit/wiql)允许重试;创建/更新等变更型 POST/PATCH 请求不会重试,因为服务端可能已应用该变更。退避策略为RetryDelay(1s)* 2^attempt再加随机抖动;若响应带Retry-After头,则直接采用服务端指定的延迟且不再叠加抖动。响应体通过io.LimitReader限制为 50 MB,防止异常响应撑爆内存。永久性错误(400/401/403/404)立即返回APIError(携带状态码,调用方可用errors.As精确判断),只有 429 与 5xx 才进入重试。

十三、故障排查

13.1 常见错误

ado.pat not configured: set via 'bd config set ado.pat <token>' or AZURE_DEVOPS_PAT env var

bd config set ado.pat "your-pat-here" # 或 export AZURE_DEVOPS_PAT="your-pat-here"

ado.org not configured: set via 'bd config set ado.org <org>' or AZURE_DEVOPS_ORG env var

bd config set ado.org "your-org" # 本地部署则用: bd config set ado.url "https://tfs.company.com/DefaultCollection"

状态转换错误(400 Bad Request):通常意味着过程模板不支持直接的状态跳转。请核对ado.state_map.*配置与实际过程模板是否一致;若仍失败,Beads 会自动沿已知转换路径(Agile/Scrum/CMMI 内置路径)推进,参见 internal/ado/statetransition.go。

类型不存在错误:核对ado.type_map.*配置与项目内实际可用的工作项类型是否一致;可以用--types过滤来限制参与同步的类型。也可用bd ado projects验证令牌对目标项目的访问权限。

HTTPS 校验失败ado.url使用非 localhost 的http://地址会被拒绝,请改用https://(本地联调可用http://localhosthttp://127.0.0.1)。

13.2 调试手段

# 预览将要发生的同步(不产生任何变更) bd ado sync --dry-run # 查看当前配置 bd config get ado.pat bd config get ado.org bd config get ado.project # 检查连接配置与令牌状态 bd ado status bd ado status --json

十四、推荐的上手路径

  1. 在 ADO 端按 第九节 生成具备 Work Items Read & Write 权限的 PAT;
  2. 使用bd config set配置ado.patado.orgado.project(本地部署用ado.url);
  3. bd ado projects确认令牌可访问的项目,用bd ado status确认配置完整;
  4. 首次同步前先跑bd ado sync --dry-run预览;若本地已有大量 issue,可配合--bootstrap-match减少重复创建;
  5. 正式执行bd ado sync,并根据实际过程模板调整ado.state_map.*ado.type_map.*
  6. 周期性同步可依赖内置协调扫描(ado.reconcile_interval,默认 10 次)自动清理 ADO 侧已删除的工作项。

提示:更完整的 Beads 集成生态可参考 docs/integrations/index.md;bd ado相关命令的实现细节集中在 cmd/bd/ado.go,同步引擎与数据模型分别在 internal/tracker/ 与 internal/ado/ 中。

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询