Azure DevOps Enterprise Migration Guide
This guide explains how SpecWeave integrates with Azure DevOps (formerly VSTS) for enterprise teams managing work items, boards, repos, pipelines, and test plans in Microsoft-centric organizations.
🎯 Why Azure DevOps Integration Matters for Enterprises
The Microsoft Enterprise Reality
Azure DevOps (ADO) is the dominant ALM tool in Microsoft shops:
- Fortune 500 adoption: 70%+ of enterprise Windows shops use ADO
- End-to-End ALM: Work items + Repos + Pipelines + Test Plans + Artifacts
- Enterprise Features: Azure AD integration, compliance, audit logs, RBAC
- Hybrid Support: Cloud (azure.com) + On-Prem (Azure DevOps Server)
The Enterprise Challenge:
- ❌ ADO becomes the only source of truth (vendor lock-in)
- ❌ Developers hate rich-text editors for technical specs
- ❌ No version control for work item descriptions
- ❌ Hard to maintain technical depth in work items
- ❌ Difficult to migrate away from ADO
SpecWeave Solution:
- ✅
.specweave/= Technical source of truth (Markdown, Git, portable) - ✅ ADO = Business visibility + ALM workflows (work tracking, pipelines, testing)
- ✅ Bidirectional sync keeps both in sync automatically
- ✅ No vendor lock-in: Migrate to GitHub/GitLab without losing specs
🏗️ Architecture: Local-First, ADO as ALM Layer
Source of Truth Pattern
✅ CORRECT Architecture:
.specweave/docs/specs/ (LOCAL - Technical Truth)
↓ Bidirectional Sync
ADO Work Items (MIRROR - Business + ALM)
❌ WRONG (ADO as Source of Truth):
ADO Work Items (External)
↓ One-way sync
.specweave/ (Local - Backup copy)
Why This Matters:
| Aspect | .specweave/ (Local) | ADO (External) |
|---|---|---|
| Audience | Developers, Architects | PMs, Stakeholders, QA, Executives |
| Detail Level | Technical (code, APIs, tests) | Business (features, bugs, tasks) |
| Version Control | ✅ Git (full history) | ❌ Limited work item history |
| Offline Access | ✅ Always available | ❌ Requires VPN/internet |
| Search | ✅ Fast (grep, IDE search) | ❌ Slow (WIQL queries) |
| Format | Markdown (LLM-friendly) | HTML (LLM-hostile) |
| Portability | ✅ Portable (migrate to GitLab) | ❌ Locked to ADO |
Result: Developers work in .specweave/, stakeholders track in ADO, both stay in sync!
🚀 Quick Start: Azure DevOps Integration
Step 1: Generate Personal Access Token (PAT)
- Go to: https://dev.azure.com/`{organization}`/_usersSettings/tokens
- Click "New Token"
- Name: "SpecWeave -
{project-name}" - Organization:
{your-org} - Scopes:
- ☑ Work Items (Read, Write, Delete)
- ☑ Code (Read) - for repo info
- ☑ Build (Read) - for pipeline status
- Expiration: 90 days (recommended)
- Copy token (52-character base64 string)
Step 2: Initialize SpecWeave with Azure DevOps
# Initialize SpecWeave (interactive)
specweave init
# During setup, select:
? Select issue tracker: Azure DevOps
? ADO instance: Azure DevOps Services (cloud) or Azure DevOps Server (on-prem)
? Organization: myorg
? Project: MyProject
? Teams (comma-separated): Frontend,Backend,Mobile,QA
Result: Creates .env with ADO PAT and .specweave/config.json with sync profile.
Step 3: Verify Connection
# Test ADO connection
specweave validate-ado
# Expected output:
# ✓ Azure DevOps API connection successful
# ✓ Organization: myorg
# ✓ Project: MyProject
# ✓ Teams found: Frontend, Backend, Mobile, QA
# ✓ User permissions: Create, Edit, Delete work items
Step 4: Create First Increment (Auto-Syncs!)
# Plan increment
/sw:increment "User authentication with Azure AD B2C"
# Result: Auto-creates ADO Feature!
# 🔗 ADO Feature #1234 created
# 🔗 https://dev.azure.com/myorg/MyProject/_workitems/edit/1234
THAT'S IT! Every task completion now auto-updates ADO.
🏢 Azure DevOps Hierarchy & Mapping
ADO Work Item Types
Portfolio Level:
├── Epic (strategic initiative, 6-12 months)
└── Feature (deliverable capability, 1-3 months)
Requirement Level:
├── User Story (user-facing requirement)
├── Bug (defect to fix)
└── Issue (non-development work)
Implementation Level:
└── Task (development work unit)
SpecWeave → ADO Mapping
SpecWeave Azure DevOps
━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Increment (Feature) → Feature (#1234)
├── User Story 1 → ├── User Story (#1235)
│ ├── AC-US1-01 │ │ ├── Acceptance Criteria
│ ├── AC-US1-02 │ │ │ (in Description)
│ └── AC-US1-03 │ │ └── (in Acceptance Criteria field)
├── User Story 2 → ├── User Story (#1236)
│ ├── AC-US2-01 │ │ └── Acceptance Criteria
│ └── AC-US2-02 │ │
└── Tasks → └── Tasks
├── T-001 → ├── Task (#1237)
├── T-002 → ├── Task (#1238)
└── T-003 → └── Task (#1239)
Key Differences from GitHub/JIRA:
- ✅ ADO has native hierarchy (Feature → User Story → Task)
- ✅ ADO has Portfolio Backlog (Epic → Feature → User Story)
- ✅ ADO has built-in test plans (linked to user stories)
- ✅ ADO has custom work item types (you can create your own)
🏭 Enterprise ADO Patterns
Pattern 1: Team-Based Organization (Recommended)
Scenario: One project, multiple teams (ADO's native model):
Organization: Contoso
└── Project: ContosoApp
├── Team: Frontend Team
├── Team: Backend Team
├── Team: Mobile Team
├── Team: QA Team
└── Team: DevOps Team
SpecWeave Configuration:
// .specweave/config.json
{
"sync": {
"profiles": {
"ado-main": {
"provider": "ado",
"displayName": "Azure DevOps - ContosoApp",
"config": {
"organization": "contoso",
"project": "ContosoApp",
"teams": [
"Frontend Team",
"Backend Team",
"Mobile Team",
"QA Team",
"DevOps Team"
]
}
}
}
}
}
Folder Mapping:
.specweave/docs/specs/
├── Frontend-Team/
│ ├── spec-001-dashboard-redesign.md
│ └── spec-002-component-library.md
├── Backend-Team/
│ ├── spec-001-api-gateway.md
│ └── spec-002-auth-service.md
├── Mobile-Team/
│ ├── spec-001-ios-app.md
│ └── spec-002-android-app.md
├── QA-Team/
│ └── spec-001-automation-framework.md
└── DevOps-Team/
└── spec-001-ci-cd-pipeline.md
ADO Area Paths (Auto-Created):
ContosoApp
├── Frontend Team (Area Path)
├── Backend Team (Area Path)
├── Mobile Team (Area Path)
├── QA Team (Area Path)
└── DevOps Team (Area Path)
Benefits:
- ✅ Native ADO team model (no hacks)
- ✅ Team dashboards out-of-the-box
- ✅ Velocity tracking per team
- ✅ Sprint planning per team
Pattern 2: Area Path Hierarchy (Large Orgs)
Scenario: Complex org structure with sub-teams:
Organization: GlobalCorp
└── Project: ERPSystem
├── Area: Core Platform
│ ├── Subarea: API Gateway (Team: API Team)
│ └── Subarea: Database (Team: Data Team)
├── Area: Frontend
│ ├── Subarea: Web UI (Team: Web Team)
│ └── Subarea: Mobile UI (Team: Mobile Team)
└── Area: Integrations
├── Subarea: SAP (Team: SAP Team)
└── Subarea: Salesforce (Team: CRM Team)
SpecWeave Configuration:
{
"sync": {
"profiles": {
"ado-erp": {
"provider": "ado",
"displayName": "ERP System",
"config": {
"organization": "globalcorp",
"project": "ERPSystem",
"areaPathStrategy": "hierarchical",
"areaPaths": {
"Core Platform": {
"API Gateway": "API Team",
"Database": "Data Team"
},
"Frontend": {
"Web UI": "Web Team",
"Mobile UI": "Mobile Team"
},
"Integrations": {
"SAP": "SAP Team",
"Salesforce": "CRM Team"
}
}
}
}
}
}
}
Work Item Assignment:
Feature #1234: Implement OAuth
Area Path: ERPSystem\Core Platform\API Gateway
Assigned To: API Team
Iteration: Sprint 24
Pattern 3: Multi-Project Setup (Separate Projects)
Scenario: Multiple ADO projects (rare, but happens):
Organization: MegaCorp
├── Project: InternalPortal (for employees)
├── Project: CustomerApp (for customers)
└── Project: PartnerAPI (for partners)
SpecWeave Configuration:
{
"sync": {
"profiles": {
"ado-internal": {
"provider": "ado",
"config": {
"organization": "megacorp",
"project": "InternalPortal",
"teams": ["Web Team", "API Team"]
}
},
"ado-customer": {
"provider": "ado",
"config": {
"organization": "megacorp",
"project": "CustomerApp",
"teams": ["Mobile Team", "Backend Team"]
}
},
"ado-partner": {
"provider": "ado",
"config": {
"organization": "megacorp",
"project": "PartnerAPI",
"teams": ["Integration Team"]
}
}
}
}
}
Usage:
# Git-style sync (recommended)
/sw-ado:pull --project InternalPortal
/sw-ado:push 0018
# Or use legacy sync command with profiles
/sw-ado:sync 0018 --profile ado-internal
/sw-ado:sync 0019 --profile ado-customer
/sw-ado:sync 0020 --profile ado-partner
🔄 Git-Style Sync Commands (Recommended)
Quick Reference
SpecWeave provides intuitive git-style commands for ADO synchronization:
| Command | Purpose |
|---|---|
/sw-ado:pull | Pull changes from ADO (like git pull) |
/sw-ado:push | Push progress to ADO (like git push) |
/sw-ado:sync | Two-way sync (pull + push) |
/sw-ado:status | Check sync status |
Basic Usage
# Pull latest changes from ADO
/sw-ado:pull
# Push your progress to ADO
/sw-ado:push
# Two-way sync (both directions)
/sw-ado:sync 0005
Multi-Project Sync
# Pull ALL specs across ALL projects (living docs sync)
/sw-ado:pull --all
# Pull specific project only
/sw-ado:pull --project clinical-insights
# Pull specific feature hierarchy (Epic → Feature → User Stories)
/sw-ado:pull --feature FS-042
# Push all local changes to ADO
/sw-ado:push --all
Sync Brief Output
After every sync operation, you'll see a compact summary:
┌─────────────────────────────────────────────────────────┐
│ PULL COMPLETE ✓ ADO │
├─────────────────────────────────────────────────────────┤
│ Scanned: 47 specs across 3 projects │
│ Updated: 7 specs │
│ Conflicts: 2 (resolved: external wins) │
├─────────────────────────────────────────────────────────┤
│ CHANGES APPLIED │
│ ↓ Status changes: 4 │
│ ↓ Priority changes: 2 │
│ + Comments imported: 8 │
└─────────────────────────────────────────────────────────┘
Symbols: ↓ = pulled (incoming), ↑ = pushed (outgoing), ✓ = success
🔄 Sprint Planning with Azure DevOps
Sprint Creation Workflow
# 1. Create sprint in ADO (via ADO UI or CLI)
az boards iteration project create \
--org https://dev.azure.com/contoso \
--project ContosoApp \
--name "Sprint 24" \
--path "\\ContosoApp\\Iteration" \
--start-date "2025-11-13" \
--finish-date "2025-11-27"
# 2. Plan increments for sprint
/sw:increment "OAuth integration"
/sw:increment "User profile page"
# 3. Link to sprint (automatic)
# SpecWeave detects active sprint and assigns work items
# 4. Start sprint work
/sw:do
# 5. Daily standups: Check ADO board
# All task updates appear automatically!
# 6. Sprint burndown (ADO auto-generates)
# https://dev.azure.com/contoso/ContosoApp/_sprints/taskboard/Backend%20Team/Sprint%2024
# 7. Sprint review: Show ADO dashboard
# Velocity chart, burndown, work item status
# 8. Sprint retrospective: Export metrics
/sw:metrics --sprint 24 --ado
# Output:
📊 Sprint 24 Metrics (Azure DevOps)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Team: Backend Team
Sprint: Sprint 24 (Nov 13 - Nov 27, 2025)
Features Planned: 2
Features Completed: 2 (100%)
User Stories Planned: 8
User Stories Completed: 7 (88%)
Stories Rolled Over: 1 (to Sprint 25)
Tasks Planned: 34
Tasks Completed: 30 (88%)
Story Points Planned: 42
Story Points Completed: 38 (90%)
Velocity: 38 (target: 40)
Bugs Filed: 6
Bugs Fixed: 5 (83%)
Team Capacity: 80 hours
Actual Effort: 78 hours (98% utilization)
Pipeline Runs: 45
Pipeline Success Rate: 93% (42/45)
Test Plans Executed: 3
Test Suites Passed: 89% (278/312 tests)
ADO Links:
Sprint Backlog: https://dev.azure.com/contoso/ContosoApp/_sprints/backlog/Backend%20Team/Sprint%2024
Burndown Chart: https://dev.azure.com/contoso/ContosoApp/_sprints/taskboard/Backend%20Team/Sprint%2024
Velocity Chart: https://dev.azure.com/contoso/ContosoApp/_dashboards/dashboard/...
Recommendations:
✓ Velocity on target (38 vs 40)
✓ Team utilization healthy (98%)
⚠ 1 story rolled over (plan buffer next sprint)
✓ Pipeline success rate excellent (93%)
🏭 Multi-Environment ADO Setup
Scenario: Dev → QA → UAT → Prod Environments
Azure DevOps Organization: Contoso
├── Project: ContosoApp-Dev (development)
├── Project: ContosoApp-QA (testing)
├── Project: ContosoApp-UAT (user acceptance)
└── Project: ContosoApp-Prod (production)
SpecWeave Configuration:
{
"sync": {
"profiles": {
"ado-dev": {
"provider": "ado",
"displayName": "Development",
"config": {
"organization": "contoso",
"project": "ContosoApp-Dev"
}
},
"ado-qa": {
"provider": "ado",
"displayName": "QA Environment",
"config": {
"organization": "contoso",
"project": "ContosoApp-QA"
}
},
"ado-uat": {
"provider": "ado",
"displayName": "UAT Environment",
"config": {
"organization": "contoso",
"project": "ContosoApp-UAT"
}
},
"ado-prod": {
"provider": "ado",
"displayName": "Production",
"config": {
"organization": "contoso",
"project": "ContosoApp-Prod"
}
}
}
}
}
Promotion Workflow:
# 1. Pull latest from dev ADO (git-style)
/sw-ado:pull --profile ado-dev
# 2. Push progress to dev ADO
/sw-ado:push 0018 --profile ado-dev
# 3. Dev complete → Promote to QA
/sw-ado:promote 0018 --from ado-dev --to ado-qa
# 4. QA approved → Promote to UAT
/sw-ado:promote 0018 --from ado-qa --to ado-uat
# 5. UAT approved → Promote to prod
/sw-ado:promote 0018 --from ado-uat --to ado-prod
# Result: Same increment tracked across all 4 environments!
ADO Work Item States (per environment):
Dev Project:
Feature #1234: Implement OAuth
State: Done → Closed
Deployed to: Dev (https://dev.contoso.com)
QA Project:
Feature #5678: Implement OAuth
State: New → Active (testing)
Deployed to: QA (https://qa.contoso.com)
UAT Project:
Feature #9012: Implement OAuth
State: New (awaiting UAT approval)
Deployed to: UAT (https://uat.contoso.com)
Prod Project:
Feature #3456: Implement OAuth
State: New (awaiting prod deployment)
Deployed to: Prod (https://contoso.com)
🔗 Azure Pipeline Integration
Workflow: Auto-Sync on Deployment
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- task: NodeTool@0
inputs:
versionSpec: '18.x'
- script: npm install
displayName: 'Install dependencies'
- script: npm run build
displayName: 'Build application'
- stage: Test
jobs:
- job: TestJob
steps:
- script: npm test
displayName: 'Run tests'
- stage: Deploy
jobs:
- job: DeployJob
steps:
- task: Bash@3
displayName: 'Install SpecWeave'
inputs:
targetType: 'inline'
script: npm install -g specweave
- task: Bash@3
displayName: 'Sync SpecWeave to ADO'
env:
AZURE_DEVOPS_PAT: $(AZURE_DEVOPS_PAT)
inputs:
targetType: 'inline'
script: |
# Find active increment
ACTIVE_INCREMENT=$(specweave status --active --json | jq -r '.id')
# Sync to ADO
specweave sync ado $ACTIVE_INCREMENT
# Mark as deployed
specweave done $ACTIVE_INCREMENT --deployed
- task: AzureWebApp@1
displayName: 'Deploy to Azure App Service'
inputs:
azureSubscription: 'ContosoSubscription'
appName: 'contoso-app'
package: '$(System.DefaultWorkingDirectory)/**/*.zip'
Result: Every successful deployment auto-updates ADO work items!
📊 ADO Custom Fields for SpecWeave
Recommended Custom Fields
<!-- Create these in ADO Process Template -->
1. SpecWeave Increment (Text Field, String)
- Stores increment ID (e.g., "0018-user-authentication")
- Searchable via WIQL
- Required: No
- Default: Empty
2. SpecWeave Profile (Text Field, String)
- Stores sync profile (e.g., "ado-backend")
- Required: No
- Default: Empty
3. SpecWeave Completion (Integer Field)
- Stores completion percentage (0-100)
- Required: No
- Default: 0
- Auto-updated on task completion
4. SpecWeave Last Synced (Date Time Field)
- Stores last sync timestamp
- Required: No
- Auto-updated on every sync
5. SpecWeave Spec URL (Hyperlink Field)
- Links to spec.md in Azure Repos / GitHub
- Required: No
- Quick access to technical details
WIQL Queries:
-- Find all SpecWeave increments in current iteration
SELECT [System.Id], [System.Title], [Custom.SpecWeaveIncrement]
FROM WorkItems
WHERE [System.IterationPath] = @currentIteration
AND [Custom.SpecWeaveIncrement] <> ''
-- Find incomplete increments
SELECT [System.Id], [System.Title], [Custom.SpecWeaveCompletion]
FROM WorkItems
WHERE [Custom.SpecWeaveCompletion] < 100
AND [System.State] <> 'Done'
-- Find stale increments (not synced in 7 days)
SELECT [System.Id], [System.Title], [Custom.SpecWeaveLastSynced]
FROM WorkItems
WHERE [Custom.SpecWeaveLastSynced] < @today - 7
-- Find increments by profile
SELECT [System.Id], [System.Title], [Custom.SpecWeaveProfile]
FROM WorkItems
WHERE [Custom.SpecWeaveProfile] = 'ado-backend'
🔒 Security & Compliance
Personal Access Token (PAT) Best Practices
DO ✅:
- Create separate PATs per environment (dev/qa/prod)
- Use service accounts (
ado-service@company.com) - Store PATs in Azure Key Vault (not
.env) - Set expiration to 90 days (maximum)
- Use minimal scopes (Work Items only)
- Rotate PATs before expiration
- Revoke PATs when team members leave
DON'T ❌:
- Share PATs via email/Slack
- Commit PATs to git
- Use personal account PATs for CI/CD
- Reuse PATs across projects
- Use PATs with
Full accessscope - Store PATs in plain text
Azure Key Vault Integration
# Store PAT in Azure Key Vault
az keyvault secret set \
--vault-name contoso-keyvault \
--name specweave-ado-pat \
--value "YOUR_PAT_HERE"
# Use in Azure Pipeline
# azure-pipelines.yml
variables:
- group: specweave-secrets # Links to Key Vault
steps:
- task: Bash@3
env:
AZURE_DEVOPS_PAT: $(specweave-ado-pat) # From Key Vault
inputs:
script: specweave sync ado 0018
🚨 Troubleshooting
Issue: "Authentication failed (401)"
Cause: Invalid or expired PAT.
Fix:
# Test PAT
curl -u :YOUR_PAT \
https://dev.azure.com/contoso/_apis/projects?api-version=7.0
# Should return projects list
# If 401 → regenerate PAT
Issue: "Project not found (404)"
Cause: Project name mismatch or no permissions.
Fix:
# List accessible projects
az devops project list \
--org https://dev.azure.com/contoso
# Verify exact project name (case-sensitive!)
# ContosoApp ✓
# contosoapp ✗
Issue: "Area path not found"
Cause: Area path doesn't exist or not configured.
Fix:
# List area paths
az boards area project list \
--org https://dev.azure.com/contoso \
--project ContosoApp
# Create missing area path
az boards area project create \
--org https://dev.azure.com/contoso \
--project ContosoApp \
--name "Backend Team"
📚 Related Guides
- GitHub Migration Guide
- JIRA Migration Guide
- Multi-Environment Deployment Strategy
- Release Management Guide
- Azure Pipeline Integration
🆘 Getting Help
- Documentation: https://spec-weave.com
- GitHub Issues: https://github.com/anton-abyzov/specweave/issues
- Azure DevOps Docs: https://docs.microsoft.com/azure/devops
- Enterprise Support: enterprise@spec-weave.com