Back to Beads

Azure DevOps (ADO) Integration Configuration

docs/ADO_CONFIG.md

1.0.39.8 KB
Original Source

Azure DevOps (ADO) Integration Configuration

This guide covers all configuration options for the bd ado sync command, which synchronizes beads issues with Azure DevOps work items.

Quick Start

bash
# Set required config
bd config set ado.pat "your-personal-access-token"
bd config set ado.org "your-organization"
bd config set ado.project "your-project"

# Or use environment variables
export AZURE_DEVOPS_PAT="your-personal-access-token"
export AZURE_DEVOPS_ORG="your-organization"
export AZURE_DEVOPS_PROJECT="your-project"

# Sync (bidirectional)
bd ado sync

# Pull only (import from ADO)
bd ado sync --pull-only

# Push only (export to ADO)
bd ado sync --push-only

# Preview without making changes
bd ado sync --dry-run

Connection Configuration

Config KeyEnv VariableRequiredDescription
ado.patAZURE_DEVOPS_PATYesPersonal Access Token
ado.orgAZURE_DEVOPS_ORGConditional¹Organization name (e.g., myorg)
ado.urlAZURE_DEVOPS_URLConditional¹Custom base URL (on-prem ADO Server)
ado.projectAZURE_DEVOPS_PROJECTConditional²Single project name
ado.projectsAZURE_DEVOPS_PROJECTSConditional²Comma-separated project names

¹ Either ado.org or ado.url must be set. Use ado.url for on-premises Azure DevOps Server.

² At least one project must be configured via ado.project or ado.projects.

Config vs env var precedence: Config keys (set via bd config set) take priority over environment variables.

On-Premises ADO Server

For Azure DevOps Server (on-prem), use ado.url instead of ado.org:

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

Multi-Project Sync

Sync across multiple projects in a single command:

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

The first project is used as the primary for URL construction. WIQL queries use TeamProject IN (...) for multi-project support.

Filter Configuration

Filters control which ADO work items are included in sync operations.

Config KeyCLI FlagDescriptionExample
ado.filter.area_path--area-pathArea path (uses UNDER)Project\Team
ado.filter.iteration_path--iteration-pathSprint/iteration pathProject\Sprint 1
ado.filter.types--typesWork item types (comma-separated)Bug,Task,User Story
ado.filter.states--statesADO states (comma-separated)New,Active,Resolved

CLI flags override config values for that sync run.

WIQL query example (generated from filters):

sql
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

Default Mappings

Priority Mapping

Priority mapping is bidirectional but lossy for P3/P4:

Beads PriorityADO PriorityDirectionNotes
0 (Critical)1
1 (High)2
2 (Medium)3Default for unknown values
3 (Low)4
4 (Backlog)4Lossy: becomes P3 on pull

Note: Beads P3 and P4 both map to ADO priority 4. On a fresh pull into an empty database, ADO 4 maps back to beads P3. The original priority is not preserved across a full round-trip for P4 issues.

For Bug-type work items, ADO also requires a Severity field:

Beads PriorityADO Severity
01 - Critical
12 - High
23 - Medium
3, 44 - Low

Status Mapping

Beads StatusDefault ADO StateConfig Key
openNewado.state_map.open
in_progressActiveado.state_map.in_progress
blockedActive + beads:blocked tagado.state_map.blocked
deferredRemovedado.state_map.deferred
closedClosedado.state_map.closed

Blocked status: ADO has no native blocked state. beads maps blocked to Active and adds a beads:blocked tag. On pull, Active + beads:blocked tag restores StatusBlocked.

Override defaults for your process template:

bash
# Example: Scrum template
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"

Type Mapping

Beads TypeDefault ADO TypeConfig Key
bugBugado.type_map.bug
featureUser Storyado.type_map.feature
taskTaskado.type_map.task
epicEpicado.type_map.epic
choreTaskado.type_map.chore

Reverse mapping (ADO → beads) also recognizes:

  • Product Backlog Itemfeature (Scrum template)
  • Issuetask

Override for your process template:

bash
# Example: Scrum template
bd config set ado.type_map.feature "Product Backlog Item"

Process Template Configuration

ADO supports multiple process templates with different work item types and state transitions. The defaults assume the Agile template. Override mappings for other templates.

Agile (Default)

No configuration needed. Default mappings work out of the box.

State transitions:

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

Scrum

bash
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"

State transitions:

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

CMMI

bash
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"

State transitions:

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

State Transition Handling

When creating a work item in a non-initial state (e.g., pushing a closed issue), beads:

  1. Creates the item in the initial state (e.g., New)
  2. Transitions through intermediate states to reach the target
  3. Example: Creating a closed Bug → New → Active → Resolved → Closed

If a direct transition fails (ADO returns 400), beads automatically walks the known transition path for the work item type and process template.

Sync Options

Direction

FlagDescription
(none)Bidirectional: pull then push
--pull-onlyImport from ADO only
--push-onlyExport to ADO only

Conflict Resolution

When the same issue has been modified both locally and in ADO:

FlagDescription
--prefer-newerMost recently updated version wins (default)
--prefer-localLocal beads version always wins
--prefer-adoADO version always wins

Additional Flags

FlagDescription
--dry-runPreview sync without making changes
--no-createOnly update existing items, never create new ones
--bootstrap-matchEnable heuristic title matching for first sync
--reconcileForce reconciliation scan for deleted items
--issuesSync specific issues by bead ID or ADO work item ID
--labelFilter by label
--statusFilter by beads status
--typeFilter by beads issue type

PAT Permissions

The Personal Access Token needs these scopes:

ScopeAccessRequired For
Work ItemsRead & WriteCreating and updating work items

Generate a PAT at: https://dev.azure.com/{org}/_usersettings/tokens

Metadata Preserved

beads stores ADO-specific metadata for round-trip fidelity:

Metadata KeyDescription
ado.revADO revision number
ado.area_pathArea path
ado.iteration_pathIteration/sprint path
ado.story_pointsStory points estimate
ado.remaining_workRemaining work hours
ado.severityBug severity value

Description Conversion

  • Push (beads → ADO): Markdown converted to HTML
  • Pull (ADO → beads): HTML converted to Markdown

Tags and Labels

  • ADO tags are semicolon-separated; beads labels use arrays
  • User labels round-trip through ADO tags
  • Internal beads:* tags (e.g., beads:blocked) are filtered on pull — they don't appear as user labels

API Limits

LimitValue
Max batch size200 work items per GET request
Max response size50 MB
Request timeout30 seconds
Max retries3 (GET and WIQL only)
Retry backoffExponential with jitter, respects Retry-After header

Troubleshooting

Common Errors

"Azure DevOps PAT not configured"

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

"Azure DevOps organization not configured"

bash
bd config set ado.org "your-org"
# or for on-prem:
bd config set ado.url "https://tfs.company.com/DefaultCollection"

State transition errors (400 Bad Request) This usually means the process template doesn't support a direct state change. Check your ado.state_map.* config matches your actual process template.

Type not found errors Verify your ado.type_map.* config matches the work item types available in your project. Use --types filter to restrict which types are synced.

Debugging

bash
# Preview what would happen
bd ado sync --dry-run

# Check current config
bd config get ado.pat
bd config get ado.org
bd config get ado.project