Skip to main content

Lesson 16: Azure DevOps Integration Guide

Time: 45 minutes Goal: Set up and master bidirectional Azure DevOps sync


Why Azure DevOps Integration?

Azure DevOps is the enterprise choice for Microsoft-centric organizations. SpecWeave integration provides:

  • Work Item hierarchy (Features → User Stories → Tasks)
  • Board synchronization (progress reflects on Kanban boards)
  • Sprint/Iteration planning (increments map to iterations)
  • Area Path support (team-based organization)

Azure DevOps ↔ SpecWeave Mapping

┌─────────────────────────────────────────────────────────────┐
│ HIERARCHY MAPPING │
├─────────────────────────────────────────────────────────────┤
│ │
│ SpecWeave Azure DevOps │
│ ───────── ───────────── │
│ Feature (FS-XXX) ──────▶ Feature │
│ └─ User Story (US-XXX) ───▶ └─ User Story │
│ └─ Task (T-XXX) ────▶ └─ Task │
│ │
│ Increment 0042 ──────▶ Feature: AB#1000 │
│ └─ US-001 Login ──────▶ └─ User Story: AB#1001│
│ └─ T-001 Service ──────▶ └─ Task: AB#1002 │
│ │
│ Area Path: MyProject\Backend │
│ Iteration: Sprint 23 │
│ │
└─────────────────────────────────────────────────────────────┘

Step 1: Create Personal Access Token (PAT)

1. Go to: https://dev.azure.com/{your-organization}
2. Click: User Settings (top right) → Personal Access Tokens
3. Click: "+ New Token"

Token Configuration

Name: SpecWeave Integration
Organization: Your Organization
Expiration: 1 year (or custom)

Scopes:
☑ Work Items: Read & Write
☑ Code: Read (for commit linking)
☑ Build: Read (optional, for pipeline status)
☑ Project and Team: Read

Store the PAT

# .env file (gitignored)
ADO_PAT=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ADO_ORGANIZATION=your-org-name
ADO_PROJECT=your-project-name
ADO_TEAM=your-team-name # Optional, for team filtering
PAT Security
  • PATs are as sensitive as passwords
  • Never commit to version control
  • Set shortest practical expiration
  • Use separate PATs per integration

Step 2: Initialize with Azure DevOps

During specweave init

specweave init .

# Questions you'll see:
? Which Git provider are you using?
GitHub (github.com)
GitHub Enterprise
GitLab
❯ Azure DevOps (dev.azure.com)

? Do you want to sync increments with an external issue tracker?
Yes, GitHub Issues
Yes, JIRA
❯ Yes, Azure DevOps Work Items
No, keep everything local

? Azure DevOps organization name: your-org-name

? Project name: your-project-name

? Team name(s) (comma-separated, or press Enter for default):
Frontend,Backend,Mobile

? Default work item type for increments:
❯ Feature
Epic
User Story

? Map tasks to ADO Tasks? (Y/n)

Verify Configuration

cat .specweave/config.json
{
"sync": {
"ado": {
"enabled": true,
"organization": "your-org-name",
"project": "your-project-name",
"teams": ["Frontend", "Backend", "Mobile"],
"incrementType": "Feature",
"userStoryType": "User Story",
"taskType": "Task",
"syncTasks": true
}
}
}

Test Connection

/specweave-ado:status

# Output:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AZURE DEVOPS CONNECTION STATUS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✅ PAT: Valid (expires: Dec 31, 2025)
✅ Organization: your-org-name
✅ Project: your-project-name
✅ Teams: Frontend, Backend, Mobile
✅ Permissions: Work Items (RW)

Ready for sync!

Step 3: Team and Area Path Configuration

Understanding Azure DevOps Structure

Organization: Contoso
└── Project: ProductLine-A
├── Team: Frontend Team
│ └── Area Path: ProductLine-A\Frontend
├── Team: Backend Team
│ └── Area Path: ProductLine-A\Backend
└── Team: Mobile Team
└── Area Path: ProductLine-A\Mobile

Iterations:
├── Sprint 23 (Nov 18 - Dec 1)
├── Sprint 24 (Dec 2 - Dec 15)
└── Sprint 25 (Dec 16 - Dec 29)

Single Team Setup

? Team name: Backend

# Config:
{
"sync": {
"ado": {
"team": "Backend",
"areaPath": "ProductLine-A\\Backend"
}
}
}

Multi-Team Setup

? Team names (comma-separated): Frontend,Backend,Mobile

# Config:
{
"sync": {
"ado": {
"teams": ["Frontend", "Backend", "Mobile"],
"areaPathMapping": {
"Frontend": "ProductLine-A\\Frontend",
"Backend": "ProductLine-A\\Backend",
"Mobile": "ProductLine-A\\Mobile"
}
}
}
}

# Folder structure:
.specweave/docs/specs/
├── Frontend/ ← Area Path: ProductLine-A\Frontend
├── Backend/ ← Area Path: ProductLine-A\Backend
└── Mobile/ ← Area Path: ProductLine-A\Mobile

Creating Work Items

Automatic Creation

When an increment is created:

/specweave:increment "User authentication"

# Output:
Creating increment: 0042-user-authentication
✓ spec.md generated
✓ plan.md generated
✓ tasks.md generated
✓ Azure DevOps Feature AB#1000 created

Created work item hierarchy:
Feature: AB#1000 "User Authentication Feature"
└─ User Story: AB#1001 "US-001: User Login"
├─ Task: AB#1002 "T-001: Create AuthService"
├─ Task: AB#1003 "T-002: Implement JWT"
└─ Task: AB#1004 "T-003: Add login endpoint"
└─ User Story: AB#1005 "US-002: Password Reset"
├─ Task: AB#1006 "T-004: Reset email"
└─ Task: AB#1007 "T-005: Reset confirmation"

Area Path: ProductLine-A\Backend
Iteration: Sprint 23

Manual Creation

/specweave-ado:create-workitem 0042

# Creates Feature → User Stories → Tasks

Work Item Format

The created Feature looks like:

Title: [FS-001] User Authentication Feature

Description:
<div>
<h2>Implementation of user authentication feature</h2>

<h3>User Stories</h3>
<ul>
<li>US-001: User Login</li>
<li>US-002: Password Reset</li>
</ul>

<h3>Acceptance Criteria</h3>
<ul>
<li>AC-US1-01: Login with email/password works</li>
<li>AC-US1-02: JWT token issued on success</li>
<li>AC-US1-03: Rate limit 5 attempts per minute</li>
</ul>

<hr/>
<p>📋 Managed by SpecWeave | Increment: 0042-user-authentication</p>
</div>

Tags: specweave, feature:auth, increment:0042
Area Path: ProductLine-A\Backend
Iteration Path: ProductLine-A\Sprint 23

Syncing Progress

Manual Sync

/specweave-ado:sync 0042

# Output:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AZURE DEVOPS SYNC: 0042-user-authentication
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Direction: SpecWeave → Azure DevOps

Changes:
AB#1002: New → Closed
AB#1003: New → Closed
AB#1000: Progress updated (Completed Work: 40%)

Sync complete!

State Mapping

SpecWeave task status maps to Azure DevOps states:

SpecWeave StatusADO State
pendingNew
in_progressActive
completedClosed
blockedBlocked (if configured)

Custom State Mapping

{
"sync": {
"ado": {
"stateMapping": {
"pending": "New",
"in_progress": "Active",
"completed": "Resolved",
"blocked": "On Hold"
},
"closedState": "Closed",
"resolvedState": "Resolved"
}
}
}

Bidirectional Sync

If someone updates status in Azure DevOps:

/specweave-ado:sync 0042 --from-external

# Output:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AZURE DEVOPS SYNC: 0042-user-authentication
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Direction: Azure DevOps → SpecWeave

Changes detected:
AB#1006: ADO shows "Closed", tasks.md shows "pending"

Update tasks.md? (Y/n)
✓ T-004 marked complete in tasks.md

Iteration (Sprint) Integration

Linking Increments to Iterations

{
"sync": {
"ado": {
"iterations": {
"enabled": true,
"autoAssign": true,
"useCurrentIteration": true
}
}
}
}

Automatic Iteration Assignment

/specweave:increment "User authentication"

# Output includes:
✓ Feature AB#1000 assigned to Sprint 23 (current iteration)
✓ All child work items inherit iteration

Sprint Planning View

/specweave-ado:sprint-status

# Output:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SPRINT 23 STATUS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Iteration: ProductLine-A\Sprint 23
Dates: Nov 18 - Dec 1
Days remaining: 8

SpecWeave Increments in Sprint:
0042-user-authentication ████████░░ 75%
0043-payment-processing ██░░░░░░░░ 20%

Capacity: 120 hours
Completed: 84 hours
Remaining: 36 hours

Burndown: On track ✓

Board Integration

Kanban Board Sync

When tasks change state, they move on the board automatically:

Board: Backend Team Board

New | Active | Resolved | Closed
─────────────┼──────────────┼──────────────┼─────────────
AB#1004 | AB#1005 | | AB#1002
AB#1006 | | | AB#1003
AB#1007 | | |

Board Columns Mapping

{
"sync": {
"ado": {
"boardColumns": {
"New": "pending",
"Active": "in_progress",
"Resolved": "completed",
"Closed": "completed"
}
}
}
}

Queries (WIQL)

Find SpecWeave-managed Items

-- All SpecWeave-managed work items
SELECT [System.Id], [System.Title], [System.State]
FROM WorkItems
WHERE [System.Tags] CONTAINS 'specweave'

-- Active increments
SELECT [System.Id], [System.Title]
FROM WorkItems
WHERE [System.Tags] CONTAINS 'specweave'
AND [System.State] <> 'Closed'

-- Specific increment
SELECT [System.Id], [System.Title], [System.State]
FROM WorkItems
WHERE [System.Tags] CONTAINS 'increment:0042'

Custom Queries in Config

{
"sync": {
"ado": {
"queries": {
"activeIncrements": "SELECT * FROM WorkItems WHERE [System.Tags] CONTAINS 'specweave' AND [System.State] <> 'Closed'",
"myWork": "SELECT * FROM WorkItems WHERE [System.Tags] CONTAINS 'specweave' AND [System.AssignedTo] = @Me"
}
}
}
}

Field Mapping

Default Fields

SpecWeaveADO Field
Increment titleTitle
spec.md descriptionDescription (HTML)
Feature ID (FS-XXX)Tags
User Story (US-XXX)Title
Acceptance CriteriaAcceptance Criteria field
Task (T-XXX)Title
Task statusState

Custom Fields

{
"sync": {
"ado": {
"customFields": {
"SpecWeave Increment": "Custom.SpecWeaveIncrement",
"Feature ID": "Custom.FeatureId",
"Test Coverage": "Custom.TestCoverage"
},
"fieldMapping": {
"increment": "Custom.SpecWeaveIncrement",
"featureId": "Custom.FeatureId",
"testCoverage": "Custom.TestCoverage"
}
}
}
}

Effort/Story Points

{
"sync": {
"ado": {
"effortMapping": {
"enabled": true,
"field": "Microsoft.VSTS.Scheduling.Effort",
"defaultEffort": {
"Task": 4,
"User Story": 8
}
}
}
}
}

Closing Work Items

Automatic Close on Done

/specweave:done 0042

# Output includes:
✓ Feature AB#1000 state: Closed
✓ All User Stories: Closed
✓ All Tasks: Closed
✓ Reason: "Completed"
✓ Comment added with completion summary

Manual Close

/specweave-ado:close-workitem 0042

# Or close with specific reason:
/specweave-ado:close-workitem 0042 --reason "Deferred"

Troubleshooting

"Authentication failed"

# Check PAT validity
/specweave-ado:status

# Common issues:
# 1. PAT expired (regenerate)
# 2. Wrong organization name
# 3. Insufficient scopes

# Test manually:
curl -u "":"$ADO_PAT" \
"https://dev.azure.com/$ADO_ORGANIZATION/_apis/projects?api-version=7.0"

"Project not found"

# Verify project name (exact match required)
# Check project exists in organization

# List all projects:
curl -u "":"$ADO_PAT" \
"https://dev.azure.com/$ADO_ORGANIZATION/_apis/projects?api-version=7.0"

"Area path not found"

# Area paths are hierarchical:
# ProductLine-A\Backend ✓
# Backend ✗ (missing project prefix)

# List area paths:
/specweave-ado:area-paths

# Output:
Area Paths for ProductLine-A:
ProductLine-A
ProductLine-A\Frontend
ProductLine-A\Backend
ProductLine-A\Mobile

"State transition not allowed"

# ADO workflows may restrict transitions
# Check allowed transitions:
/specweave-ado:transitions AB#1002

# Output:
Current state: Active
Allowed transitions:
→ New (Revert)
→ Resolved (Resolve)
→ Closed (Close)

# Update config to use allowed transitions

"Work item type not found"

# Process template determines available types
# Agile: Epic, Feature, User Story, Task, Bug
# Scrum: Epic, Feature, PBI, Task, Bug
# CMMI: Epic, Feature, Requirement, Task, Bug

# Check available types:
/specweave-ado:work-item-types

# Update config to match your process template

Azure Pipelines Integration

# azure-pipelines.yml
trigger:
branches:
include:
- main
- develop

jobs:
- job: Build
steps:
- script: |
# Commits with AB#1234 auto-link to work items
git log -1 --pretty=%B
displayName: 'Show commit message'

Sync on Pipeline Completion

# azure-pipelines.yml
stages:
- stage: Deploy
jobs:
- job: SyncSpecWeave
steps:
- script: |
npm install -g specweave
specweave sync-progress --auto-yes
displayName: 'Sync SpecWeave progress'
env:
ADO_PAT: $(ADO_PAT)

Enterprise Features

Azure DevOps Server (On-premises)

{
"sync": {
"ado": {
"type": "server",
"serverUrl": "https://tfs.your-company.com/tfs",
"collection": "DefaultCollection"
}
}
}

Service Account

For team-wide sync:

# Create service account in Azure AD
# Generate PAT for service account
# Use in .env:
ADO_PAT=service_account_pat

Webhooks (Advanced)

# 1. In ADO: Project Settings → Service Hooks → Create
# Service: Web Hooks
# Trigger: Work item updated
# URL: https://your-server.com/specweave/ado-webhook

# 2. In SpecWeave config:
{
"sync": {
"ado": {
"webhooks": {
"enabled": true,
"secret": "your-webhook-secret"
}
}
}
}

Real-World Example

Full Workflow

# 1. Create increment
/specweave:increment "User profile feature"

# Output:
✓ Increment 0050-user-profile created
✓ Azure DevOps Feature AB#2000 created
└─ User Story AB#2001 "US-001: View Profile"
├─ Task AB#2002 "T-001: ProfileService"
└─ Task AB#2003 "T-002: Profile UI"
└─ User Story AB#2004 "US-002: Edit Profile"
└─ Task AB#2005 "T-003: Edit form"

Area Path: ProductLine-A\Backend
Iteration: Sprint 23

# 2. Work on tasks
/specweave:do

# Each task completion syncs to ADO
# Tasks transition: New → Closed
# Board updates automatically

# 3. PM checks in Azure DevOps
# - Board shows tasks moving across columns
# - Feature shows 60% complete
# - Sprint burndown updates

# 4. Complete increment
/specweave:done 0050

# All work items closed automatically
# Feature state: Closed
# Reason: Completed

Quick Exercise

Set up Azure DevOps integration:

# 1. Create PAT at dev.azure.com

# 2. Configure credentials
cat >> .env << EOF
ADO_PAT=your-pat-here
ADO_ORGANIZATION=your-org
ADO_PROJECT=your-project
EOF

# 3. Reconfigure SpecWeave
specweave init . --reconfigure

# 4. Test connection
/specweave-ado:status

# 5. Create test increment
/specweave:increment "Test ADO sync"

# 6. Verify in Azure DevOps
# Check your project board for new Feature

Key Takeaways

  1. Hierarchy mapping preserves structure (Feature → User Story → Task)
  2. Area Paths enable team-based organization
  3. Iterations integrate with sprint planning
  4. Board sync provides real-time visibility
  5. Bidirectional updates keep both systems current

Glossary Terms Used


What's Next?

You've completed the external tools integration lessons! Now let's return to advanced patterns and see how everything comes together.

:nextBack to Advanced Patterns or Academy Overview