Claude Code Plugins

Community-maintained marketplace

Feedback

Guide for Azure DevOps automation using az CLI with azure-devops extension. Covers Azure Pipelines, Azure Repos, Azure Boards, work items, pull requests, artifacts, service connections, variable groups, and DevOps automation. Use when working with ADO, az devops commands, YAML pipelines, or Azure DevOps REST API.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name azure-devops
description Guide for Azure DevOps automation using az CLI with azure-devops extension. Covers Azure Pipelines, Azure Repos, Azure Boards, work items, pull requests, artifacts, service connections, variable groups, and DevOps automation. Use when working with ADO, az devops commands, YAML pipelines, or Azure DevOps REST API.

Azure DevOps CLI Guide

Purpose

Comprehensive guide for automating Azure DevOps operations using the az CLI with the azure-devops extension. Covers common patterns, best practices, and examples for working with Azure Pipelines, Repos, Boards, and Artifacts.

When to Use This Skill

Activates when you mention:

  • Azure DevOps, ADO, or az devops
  • Azure Pipelines, Azure Repos, Azure Boards
  • Work items, pull requests, or code reviews in Azure DevOps
  • DevOps automation, CI/CD pipelines
  • az CLI commands for DevOps
  • YAML pipeline definitions
  • Service connections, variable groups, artifacts

Prerequisites

1. Install Azure CLI

# Ubuntu/WSL
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Verify installation
az --version

2. Install Azure DevOps Extension

az extension add --name azure-devops
az extension update --name azure-devops  # Update to latest

3. Login to Azure

az login

# Or use Personal Access Token (PAT)
export AZURE_DEVOPS_EXT_PAT=<your-pat-token>

4. Set Default Organization and Project

# Set defaults to avoid repeating on every command
az devops configure --defaults organization=https://dev.azure.com/YourOrg project=YourProject

# View current defaults
az devops configure --list

Authentication Methods

Method 1: Interactive Login (Recommended for Development)

az login
# Opens browser for authentication

Method 2: Personal Access Token (PAT)

# Set as environment variable
export AZURE_DEVOPS_EXT_PAT=<your-pat-token>

# Or use --org and --detect flags
az devops project list --org https://dev.azure.com/YourOrg

Method 3: Service Principal (CI/CD)

az login --service-principal \
  --username <app-id> \
  --password <password-or-cert> \
  --tenant <tenant-id>

Common Commands by Category

Organization & Projects

# List organizations (requires authentication)
az devops project list --org https://dev.azure.com/YourOrg

# Show project details
az devops project show --project MyProject

# Create new project
az devops project create --name MyNewProject --visibility private

# List teams in project
az devops team list --project MyProject

Azure Repos

# List repositories
az repos list --project MyProject

# Create repository
az repos create --name MyNewRepo --project MyProject

# Show repo details
az repos show --repository MyRepo --project MyProject

# Import repository
az repos import create \
  --git-source-url https://github.com/user/repo \
  --repository MyRepo

# List branches
az repos ref list --repository MyRepo

# Create branch
az repos ref create \
  --name refs/heads/feature/new-feature \
  --object-id <commit-sha> \
  --repository MyRepo

# Delete branch
az repos ref delete \
  --name refs/heads/old-branch \
  --object-id <commit-sha> \
  --repository MyRepo

Pull Requests

# List pull requests
az repos pr list --repository MyRepo --status active

# Create pull request
az repos pr create \
  --repository MyRepo \
  --source-branch feature/my-feature \
  --target-branch main \
  --title "My Feature" \
  --description "Description here"

# Show PR details
az repos pr show --id 123

# Update PR
az repos pr update --id 123 --title "Updated Title"

# Add reviewers
az repos pr reviewer add --id 123 --reviewers user@domain.com

# Complete/merge PR
az repos pr set-vote --id 123 --vote approve
az repos pr update --id 123 --status completed

# Abandon PR
az repos pr update --id 123 --status abandoned

# List PR work items
az repos pr work-item list --id 123

Azure Pipelines

# List pipelines
az pipelines list --project MyProject

# Show pipeline details
az pipelines show --name MyPipeline

# Create pipeline from YAML
az pipelines create \
  --name MyPipeline \
  --repository MyRepo \
  --branch main \
  --yml-path azure-pipelines.yml

# Run pipeline
az pipelines run --name MyPipeline

# Run with parameters
az pipelines run --name MyPipeline \
  --parameters param1=value1 param2=value2

# List pipeline runs
az pipelines runs list --pipeline-ids 123

# Show run details
az pipelines runs show --id 456

# List pipeline artifacts
az pipelines runs artifact list --run-id 456

# Download artifact
az pipelines runs artifact download \
  --run-id 456 \
  --artifact-name drop \
  --path ./artifacts

Work Items

# List work items
az boards work-item query --wiql "SELECT [System.Id], [System.Title] FROM WorkItems WHERE [System.State] = 'Active'"

# Show work item
az boards work-item show --id 1234

# Create work item
az boards work-item create \
  --type "User Story" \
  --title "My User Story" \
  --description "Story description" \
  --assigned-to user@domain.com

# Update work item
az boards work-item update --id 1234 --state "In Progress"

# Add comment to work item
az boards work-item relation add \
  --id 1234 \
  --relation-type Comment \
  --target-id <comment-text>

# Link work items
az boards work-item relation add \
  --id 1234 \
  --relation-type Related \
  --target-id 5678

Variable Groups

# List variable groups
az pipelines variable-group list

# Create variable group
az pipelines variable-group create \
  --name MyVariableGroup \
  --variables key1=value1 key2=value2

# Show variable group
az pipelines variable-group show --group-id 123

# Update variable
az pipelines variable-group variable create \
  --group-id 123 \
  --name newKey \
  --value newValue

# Delete variable
az pipelines variable-group variable delete \
  --group-id 123 \
  --name oldKey

Service Connections

# List service connections
az devops service-endpoint list --project MyProject

# Create Azure RM service connection
az devops service-endpoint azurerm create \
  --name MyAzureConnection \
  --azure-rm-service-principal-id <sp-id> \
  --azure-rm-subscription-id <subscription-id> \
  --azure-rm-subscription-name "My Subscription" \
  --azure-rm-tenant-id <tenant-id>

# Show service connection
az devops service-endpoint show --id <connection-id>

Common Patterns & Scripts

Pattern 1: Auto-approve and Complete PR if CI Passes

#!/bin/bash
PR_ID=$1

# Wait for PR build to complete
while true; do
  STATUS=$(az repos pr show --id $PR_ID --query "mergeStatus" -o tsv)
  if [ "$STATUS" == "succeeded" ]; then
    echo "Build passed, approving PR..."
    az repos pr set-vote --id $PR_ID --vote approve
    az repos pr update --id $PR_ID --status completed --delete-source-branch true
    break
  elif [ "$STATUS" == "failed" ]; then
    echo "Build failed, not approving PR"
    break
  fi
  sleep 30
done

Pattern 2: Bulk Create Work Items from File

#!/bin/bash
# work-items.txt format: Type|Title|Description

while IFS='|' read -r type title description; do
  az boards work-item create \
    --type "$type" \
    --title "$title" \
    --description "$description"
done < work-items.txt

Pattern 3: Clone All Repos in a Project

#!/bin/bash
ORG="https://dev.azure.com/YourOrg"
PROJECT="YourProject"

az repos list --project $PROJECT --query "[].name" -o tsv | while read repo; do
  echo "Cloning $repo..."
  git clone "$ORG/$PROJECT/_git/$repo"
done

Pattern 4: Run Pipeline and Wait for Completion

#!/bin/bash
PIPELINE_NAME="MyPipeline"

# Start pipeline run
RUN_ID=$(az pipelines run --name $PIPELINE_NAME --query "id" -o tsv)
echo "Started run $RUN_ID"

# Poll for completion
while true; do
  STATUS=$(az pipelines runs show --id $RUN_ID --query "status" -o tsv)
  RESULT=$(az pipelines runs show --id $RUN_ID --query "result" -o tsv)

  if [ "$STATUS" == "completed" ]; then
    echo "Run completed with result: $RESULT"
    [ "$RESULT" == "succeeded" ] && exit 0 || exit 1
  fi

  sleep 10
done

Best Practices

1. Use Configuration Defaults

Set defaults to avoid repeating org/project on every command:

az devops configure --defaults \
  organization=https://dev.azure.com/YourOrg \
  project=YourProject

2. Use Output Formats Effectively

# Table format (human-readable)
az repos list -o table

# JSON for scripting
az repos list -o json

# TSV for parsing
az repos list --query "[].name" -o tsv

3. Use JMESPath Queries

# Get specific fields
az repos list --query "[].{Name:name, Id:id}" -o table

# Filter results
az repos pr list --query "[?status=='active'].id" -o tsv

4. Store PAT Securely

# Never hardcode PAT in scripts
# Use environment variables or Azure Key Vault
export AZURE_DEVOPS_EXT_PAT=$(az keyvault secret show --name ado-pat --vault-name myvault --query value -o tsv)

5. Error Handling in Scripts

set -e  # Exit on error
set -o pipefail  # Exit on pipe failure

if ! az repos show --repository MyRepo 2>/dev/null; then
  echo "Repository does not exist"
  exit 1
fi

6. Use Service Principals for CI/CD

Never use personal accounts for automated pipelines - use service principals with minimal required permissions.


Integration with .NET Projects

Trigger Pipeline After dotnet build

# Build .NET project
dotnet build MyProject.csproj

# If build succeeds, trigger Azure Pipeline
if [ $? -eq 0 ]; then
  az pipelines run --name DeployPipeline
fi

Create Work Items for Build Failures

# In Azure Pipeline YAML
- script: |
    if [ $(Agent.JobStatus) == "Failed" ]; then
      az boards work-item create \
        --type Bug \
        --title "Build $(Build.BuildNumber) failed" \
        --description "Build failed: $(Build.BuildUri)"
    fi
  condition: failed()
  displayName: 'Create work item on failure'

Useful Query Examples

Find Active PRs Older Than 7 Days

DATE_7_DAYS_AGO=$(date -d '7 days ago' +%Y-%m-%d)

az repos pr list --status active --query \
  "[?creationDate<'$DATE_7_DAYS_AGO'].{ID:pullRequestId, Title:title, Created:creationDate}" \
  -o table

List Failed Pipeline Runs in Last 24 Hours

az pipelines runs list \
  --query "[?finishTime>='$(date -d '1 day ago' --iso-8601=seconds)' && result=='failed'].{ID:id, Pipeline:definition.name, Result:result}" \
  -o table

Get All Work Items Assigned to Me

MY_EMAIL="user@domain.com"

az boards work-item query --wiql \
  "SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [System.AssignedTo] = '$MY_EMAIL' AND [System.State] <> 'Closed'"

Troubleshooting

Issue: "TF400813: Resource not available for anonymous access"

Solution: Ensure you're authenticated:

az login
# Or set PAT
export AZURE_DEVOPS_EXT_PAT=<your-token>

Issue: "The term 'az' is not recognized"

Solution: Install Azure CLI and add to PATH

Issue: Extension not found

Solution: Install azure-devops extension:

az extension add --name azure-devops

Issue: Permission denied errors

Solution: Check PAT scopes - ensure it has required permissions:

  • Code (Read, Write, Manage)
  • Build (Read, Execute)
  • Work Items (Read, Write)

Quick Reference

# Setup
az extension add --name azure-devops
az login
az devops configure --defaults organization=<org> project=<project>

# Repos
az repos list
az repos pr list --status active

# Pipelines
az pipelines list
az pipelines run --name <pipeline>

# Work Items
az boards work-item show --id <id>

# Output formats
-o json    # JSON output
-o table   # Table format
-o tsv     # Tab-separated values
--query    # JMESPath query

Related Documentation:

Skill Type: Domain Enforcement: Suggest Line Count: ~450 lines ✅