{"kind":"Skill","metadata":{"namespace":"community","name":"azure-devops-cli","version":"0.1.0"},"spec":{"description":"Manage Azure DevOps resources via CLI including projects, repos, pipelines, builds, pull requests, work items, artifacts, and service endpoints. Use when working with Azure DevOps, az commands, devops automation, CI/CD, or when user mentions Azure DevOps CLI.","files":{"SKILL.md":"---\nname: azure-devops-cli\ndescription: Manage Azure DevOps resources via CLI including projects, repos, pipelines, builds, pull requests, work items, artifacts, and service endpoints. Use when working with Azure DevOps, az commands, devops automation, CI/CD, or when user mentions Azure DevOps CLI.\n---\n\n# Azure DevOps CLI\n\nManage Azure DevOps resources using the Azure CLI with the Azure DevOps extension.\n\n**CLI Version:** 2.81.0 (current as of 2025)\n\n## Prerequisites\n\n```bash\n# Install Azure CLI\nbrew install azure-cli  # macOS\ncurl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash  # Linux\n\n# Install Azure DevOps extension\naz extension add --name azure-devops\n```\n\n## Authentication\n\n```bash\n# Login with PAT token\naz devops login --organization https://dev.azure.com/{org} --token YOUR_PAT_TOKEN\n\n# Set default organization and project (avoids repeating --org/--project)\n# Note: Legacy URL https://{org}.visualstudio.com should be replaced with https://dev.azure.com/{org}\naz devops configure --defaults organization=https://dev.azure.com/{org} project={project}\n\n# List current configuration\naz devops configure --list\n```\n\n## CLI Structure\n\n```\naz devops          # Main DevOps commands\n├── admin          # Administration (banner)\n├── extension      # Extension management\n├── project        # Team projects\n├── security       # Security operations\n│   ├── group      # Security groups\n│   └── permission # Security permissions\n├── service-endpoint # Service connections\n├── team           # Teams\n├── user           # Users\n├── wiki           # Wikis\n├── configure      # Set defaults\n├── invoke         # Invoke REST API\n├── login          # Authenticate\n└── logout         # Clear credentials\n\naz pipelines       # Azure Pipelines\n├── agent          # Agents\n├── build          # Builds\n├── folder         # Pipeline folders\n├── pool           # Agent pools\n├── queue          # Agent queues\n├── release        # Releases\n├── runs           # Pipeline runs\n├── variable       # Pipeline variables\n└── variable-group # Variable groups\n\naz boards          # Azure Boards\n├── area           # Area paths\n├── iteration      # Iterations\n└── work-item      # Work items\n\naz repos           # Azure Repos\n├── import         # Git imports\n├── policy         # Branch policies\n├── pr             # Pull requests\n└── ref            # Git references\n\naz artifacts       # Azure Artifacts\n└── universal      # Universal Packages\n```\n\n## Reference Files\n\nRead the relevant reference file based on the user's task. Each file contains complete command syntax and examples for its domain.\n\n| File | When to read | Covers |\n|---|---|---|\n| `references/repos-and-prs.md` | Repos, branches, pull requests, branch policies | Repositories, Import, PRs (create/list/vote/reviewers/policies), Git refs, Branch policies |\n| `references/pipelines-and-builds.md` | Pipelines, builds, releases, artifacts | Pipelines CRUD, runs, builds, releases, artifacts download/upload |\n| `references/boards-and-iterations.md` | Work items, sprints, area paths | Work items (WIQL/create/update/relations), Area paths, Iterations, Team iterations |\n| `references/variables-and-agents.md` | Pipeline variables, agent pools | Pipeline variables, Variable groups, Pipeline folders, Agent pools/queues |\n| `references/org-and-security.md` | Projects, teams, users, permissions, wikis | Projects, Extensions, Teams, Users, Security groups/permissions, Service endpoints, Wikis, Admin |\n| `references/advanced-usage.md` | Output formatting, JMESPath queries | Output formats, JMESPath queries (basic + advanced), Global args, Common params, Git aliases |\n| `references/workflows-and-patterns.md` | Automation scripts, best practices, error handling | Common workflows, Best practices, Error handling, Scripting patterns, Real-world examples |\n","references/advanced-usage.md":"# Advanced Usage: Output, Queries \u0026 Parameters\n\n## Table of Contents\n- [Output Formats](#output-formats)\n- [JMESPath Queries](#jmespath-queries)\n- [Advanced JMESPath Queries](#advanced-jmespath-queries)\n- [Global Arguments](#global-arguments)\n- [Common Parameters](#common-parameters)\n- [Git Aliases](#git-aliases)\n- [Getting Help](#getting-help)\n\n---\n\n## Output Formats\n\nAll commands support multiple output formats:\n\n```bash\n# Table format (human-readable)\naz pipelines list --output table\n\n# JSON format (default, machine-readable)\naz pipelines list --output json\n\n# JSONC (colored JSON)\naz pipelines list --output jsonc\n\n# YAML format\naz pipelines list --output yaml\n\n# YAMLC (colored YAML)\naz pipelines list --output yamlc\n\n# TSV format (tab-separated values)\naz pipelines list --output tsv\n\n# None (no output)\naz pipelines list --output none\n```\n\n## JMESPath Queries\n\nFilter and transform output:\n\n```bash\n# Filter by name\naz pipelines list --query \"[?name=='myPipeline']\"\n\n# Get specific fields\naz pipelines list --query \"[].{Name:name, ID:id}\"\n\n# Chain queries\naz pipelines list --query \"[?name.contains('CI')].{Name:name, ID:id}\" --output table\n\n# Get first result\naz pipelines list --query \"[0]\"\n\n# Get top N\naz pipelines list --query \"[0:5]\"\n```\n\n## Advanced JMESPath Queries\n\n### Filtering and Sorting\n\n```bash\n# Filter by multiple conditions\naz pipelines list --query \"[?name.contains('CI') \u0026\u0026 enabled==true]\"\n\n# Filter by status and result\naz pipelines runs list --query \"[?status=='completed' \u0026\u0026 result=='succeeded']\"\n\n# Sort by date (descending)\naz pipelines runs list --query \"sort_by([?status=='completed'], \u0026finishTime | reverse(@))\"\n\n# Get top N items after filtering\naz pipelines runs list --query \"[?result=='succeeded'] | [0:5]\"\n```\n\n### Nested Queries\n\n```bash\n# Extract nested properties\naz pipelines show --id $PIPELINE_ID --query \"{Name:name, Repo:repository.{Name:name, Type:type}, Folder:folder}\"\n\n# Query build details\naz pipelines build show --id $BUILD_ID --query \"{ID:id, Number:buildNumber, Status:status, Result:result, Requested:requestedFor.displayName}\"\n```\n\n### Complex Filtering\n\n```bash\n# Find pipelines with specific YAML path\naz pipelines list --query \"[?process.type.name=='yaml' \u0026\u0026 process.yamlFilename=='azure-pipelines.yml']\"\n\n# Find PRs from specific reviewer\naz repos pr list --query \"[?contains(reviewers[?displayName=='John Doe'].displayName, 'John Doe')]\"\n\n# Find work items with specific iteration and state\naz boards work-item show --id $WI_ID --query \"{Title:fields['System.Title'], State:fields['System.State'], Iteration:fields['System.IterationPath']}\"\n```\n\n### Aggregation\n\n```bash\n# Count items by status\naz pipelines runs list --query \"groupBy([?status=='completed'], \u0026[result]) | {Succeeded: [?key=='succeeded'][0].count, Failed: [?key=='failed'][0].count}\"\n\n# Get unique reviewers\naz repos pr list --query \"unique_by(reviewers[], \u0026displayName)\"\n\n# Sum values\naz pipelines runs list --query \"[?result=='succeeded'] | [].{Duration:duration} | [0].Duration\"\n```\n\n### Conditional Transformation\n\n```bash\n# Format dates\naz pipelines runs list --query \"[].{ID:id, Date:createdDate, Formatted:createdDate | format_datetime(@, 'yyyy-MM-dd HH:mm')}\"\n\n# Conditional output\naz pipelines list --query \"[].{Name:name, Status:(enabled ? 'Enabled' : 'Disabled')}\"\n\n# Extract with defaults\naz pipelines show --id $PIPELINE_ID --query \"{Name:name, Folder:folder || 'Root', Description:description || 'No description'}\"\n```\n\n### Complex Workflows\n\n```bash\n# Find longest running builds\naz pipelines build list --query \"sort_by([?result=='succeeded'], \u0026queueTime) | reverse(@) | [0:3].{ID:id, Number:buildNumber, Duration:duration}\"\n\n# Get PR statistics per reviewer\naz repos pr list --query \"groupBy([], \u0026reviewers[].displayName) | [].{Reviewer:@.key, Count:length(@)}\"\n\n# Find work items with multiple child items\naz boards work-item relation list --id $PARENT_ID --query \"[?rel=='System.LinkTypes.Hierarchy-Forward'] | [].{ChildID:url | split('/', @) | [-1]}\"\n```\n\n## Global Arguments\n\nAvailable on all commands:\n\n| Parameter | Description |\n|---|---|\n| `--help` / `-h` | Show command help |\n| `--output` / `-o` | Output format (json, jsonc, none, table, tsv, yaml, yamlc) |\n| `--query` | JMESPath query string for filtering output |\n| `--verbose` | Increase logging verbosity |\n| `--debug` | Show all debug logs |\n| `--only-show-errors` | Only show errors, suppress warnings |\n| `--subscription` | Name or ID of subscription |\n| `--yes` / `-y` | Skip confirmation prompts |\n\n## Common Parameters\n\n| Parameter | Description |\n|---|---|\n| `--org` / `--organization` | Azure DevOps organization URL (e.g., `https://dev.azure.com/{org}`) |\n| `--project` / `-p` | Project name or ID |\n| `--detect` | Auto-detect organization from git config |\n| `--yes` / `-y` | Skip confirmation prompts |\n| `--open` | Open resource in web browser |\n| `--subscription` | Azure subscription (for Azure resources) |\n\n## Git Aliases\n\nAfter enabling git aliases:\n\n```bash\n# Enable Git aliases\naz devops configure --use-git-aliases true\n\n# Use Git commands for DevOps operations\ngit pr create --target-branch main\ngit pr list\ngit pr checkout 123\n```\n\n## Getting Help\n\n```bash\n# General help\naz devops --help\n\n# Help for specific command group\naz pipelines --help\naz repos pr --help\n\n# Help for specific command\naz repos pr create --help\n\n# Search for examples\naz find \"az repos pr create\"\n```\n","references/boards-and-iterations.md":"# Work Items, Area Paths \u0026 Iterations\n\n## Table of Contents\n- [Work Items (Boards)](#work-items-boards)\n- [Area Paths](#area-paths)\n- [Iterations](#iterations)\n\n---\n\n## Work Items (Boards)\n\n### Query Work Items\n\n```bash\n# WIQL query\naz boards query \\\n  --wiql \"SELECT [System.Id], [System.Title], [System.State] FROM WorkItems WHERE [System.AssignedTo] = @Me AND [System.State] = 'Active'\"\n\n# Query with output format\naz boards query --wiql \"SELECT * FROM WorkItems\" --output table\n```\n\n### Show Work Item\n\n```bash\naz boards work-item show --id {work-item-id}\naz boards work-item show --id {work-item-id} --open\n```\n\n### Create Work Item\n\n```bash\n# Basic work item\naz boards work-item create \\\n  --title \"Fix login bug\" \\\n  --type Bug \\\n  --assigned-to user@example.com \\\n  --description \"Users cannot login with SSO\"\n\n# With area and iteration\naz boards work-item create \\\n  --title \"New feature\" \\\n  --type \"User Story\" \\\n  --area \"Project\\\\Area1\" \\\n  --iteration \"Project\\\\Sprint 1\"\n\n# With custom fields\naz boards work-item create \\\n  --title \"Task\" \\\n  --type Task \\\n  --fields \"Priority=1\" \"Severity=2\"\n\n# With discussion comment\naz boards work-item create \\\n  --title \"Issue\" \\\n  --type Bug \\\n  --discussion \"Initial investigation completed\"\n\n# Open in browser after creation\naz boards work-item create --title \"Bug\" --type Bug --open\n```\n\n### Update Work Item\n\n```bash\n# Update state, title, and assignee\naz boards work-item update \\\n  --id {work-item-id} \\\n  --state \"Active\" \\\n  --title \"Updated title\" \\\n  --assigned-to user@example.com\n\n# Move to different area\naz boards work-item update \\\n  --id {work-item-id} \\\n  --area \"{ProjectName}\\\\{Team}\\\\{Area}\"\n\n# Change iteration\naz boards work-item update \\\n  --id {work-item-id} \\\n  --iteration \"{ProjectName}\\\\Sprint 5\"\n\n# Add comment/discussion\naz boards work-item update \\\n  --id {work-item-id} \\\n  --discussion \"Work in progress\"\n\n# Update with custom fields\naz boards work-item update \\\n  --id {work-item-id} \\\n  --fields \"Priority=1\" \"StoryPoints=5\"\n```\n\n### Delete Work Item\n\n```bash\n# Soft delete (can be restored)\naz boards work-item delete --id {work-item-id} --yes\n\n# Permanent delete\naz boards work-item delete --id {work-item-id} --destroy --yes\n```\n\n### Work Item Relations\n\n```bash\n# List relations\naz boards work-item relation list --id {work-item-id}\n\n# List supported relation types\naz boards work-item relation list-type\n\n# Add relation\naz boards work-item relation add --id {work-item-id} --relation-type parent --target-id {parent-id}\n\n# Remove relation\naz boards work-item relation remove --id {work-item-id} --relation-id {relation-id}\n```\n\n## Area Paths\n\n### List Areas for Project\n\n```bash\naz boards area project list --project {project}\naz boards area project show --path \"Project\\\\Area1\" --project {project}\n```\n\n### Create Area\n\n```bash\naz boards area project create --path \"Project\\\\NewArea\" --project {project}\n```\n\n### Update Area\n\n```bash\naz boards area project update \\\n  --path \"Project\\\\OldArea\" \\\n  --new-path \"Project\\\\UpdatedArea\" \\\n  --project {project}\n```\n\n### Delete Area\n\n```bash\naz boards area project delete --path \"Project\\\\AreaToDelete\" --project {project} --yes\n```\n\n### Area Team Management\n\n```bash\n# List areas for team\naz boards area team list --team {team-name} --project {project}\n\n# Add area to team\naz boards area team add \\\n  --team {team-name} \\\n  --path \"Project\\\\NewArea\" \\\n  --project {project}\n\n# Remove area from team\naz boards area team remove \\\n  --team {team-name} \\\n  --path \"Project\\\\AreaToRemove\" \\\n  --project {project}\n\n# Update team area\naz boards area team update \\\n  --team {team-name} \\\n  --path \"Project\\\\Area\" \\\n  --project {project} \\\n  --include-sub-areas true\n```\n\n## Iterations\n\n### List Iterations for Project\n\n```bash\naz boards iteration project list --project {project}\naz boards iteration project show --path \"Project\\\\Sprint 1\" --project {project}\n```\n\n### Create Iteration\n\n```bash\naz boards iteration project create --path \"Project\\\\Sprint 1\" --project {project}\n```\n\n### Update Iteration\n\n```bash\naz boards iteration project update \\\n  --path \"Project\\\\OldSprint\" \\\n  --new-path \"Project\\\\NewSprint\" \\\n  --project {project}\n```\n\n### Delete Iteration\n\n```bash\naz boards iteration project delete --path \"Project\\\\OldSprint\" --project {project} --yes\n```\n\n### Team Iterations\n\n```bash\n# List iterations for team\naz boards iteration team list --team {team-name} --project {project}\n\n# Add iteration to team\naz boards iteration team add \\\n  --team {team-name} \\\n  --path \"Project\\\\Sprint 1\" \\\n  --project {project}\n\n# Remove iteration from team\naz boards iteration team remove \\\n  --team {team-name} \\\n  --path \"Project\\\\Sprint 1\" \\\n  --project {project}\n\n# List work items in iteration\naz boards iteration team list-work-items \\\n  --team {team-name} \\\n  --path \"Project\\\\Sprint 1\" \\\n  --project {project}\n```\n\n### Default \u0026 Backlog Iterations\n\n```bash\n# Set default iteration for team\naz boards iteration team set-default-iteration \\\n  --team {team-name} \\\n  --path \"Project\\\\Sprint 1\" \\\n  --project {project}\n\n# Show default iteration\naz boards iteration team show-default-iteration \\\n  --team {team-name} \\\n  --project {project}\n\n# Set backlog iteration for team\naz boards iteration team set-backlog-iteration \\\n  --team {team-name} \\\n  --path \"Project\\\\Sprint 1\" \\\n  --project {project}\n\n# Show backlog iteration\naz boards iteration team show-backlog-iteration \\\n  --team {team-name} \\\n  --project {project}\n\n# Show current iteration\naz boards iteration team show --team {team-name} --project {project} --timeframe current\n```\n","references/org-and-security.md":"# Organization, Security \u0026 Administration\n\n## Table of Contents\n- [Projects](#projects)\n- [Extension Management](#extension-management)\n- [Service Endpoints](#service-endpoints)\n- [Teams](#teams)\n- [Users](#users)\n- [Security Groups](#security-groups)\n- [Security Permissions](#security-permissions)\n- [Wikis](#wikis)\n- [Administration](#administration)\n- [DevOps Extensions](#devops-extensions)\n\n---\n\n## Projects\n\n### List Projects\n\n```bash\naz devops project list --organization https://dev.azure.com/{org}\naz devops project list --top 10 --output table\n```\n\n### Create Project\n\n```bash\naz devops project create \\\n  --name myNewProject \\\n  --organization https://dev.azure.com/{org} \\\n  --description \"My new DevOps project\" \\\n  --source-control git \\\n  --visibility private\n```\n\n### Show Project Details\n\n```bash\naz devops project show --project {project-name} --org https://dev.azure.com/{org}\n```\n\n### Delete Project\n\n```bash\naz devops project delete --id {project-id} --org https://dev.azure.com/{org} --yes\n```\n\n## Extension Management\n\n### List Extensions\n\n```bash\n# List available extensions\naz extension list-available --output table\n\n# List installed extensions\naz extension list --output table\n```\n\n### Manage Azure DevOps Extension\n\n```bash\n# Install Azure DevOps extension\naz extension add --name azure-devops\n\n# Update Azure DevOps extension\naz extension update --name azure-devops\n\n# Remove extension\naz extension remove --name azure-devops\n\n# Install from local path\naz extension add --source ~/extensions/azure-devops.whl\n```\n\n## Service Endpoints\n\n### List Service Endpoints\n\n```bash\naz devops service-endpoint list --project {project}\naz devops service-endpoint list --project {project} --output table\n```\n\n### Show Service Endpoint\n\n```bash\naz devops service-endpoint show --id {endpoint-id} --project {project}\n```\n\n### Create Service Endpoint\n\n```bash\n# Using configuration file\naz devops service-endpoint create --service-endpoint-configuration endpoint.json --project {project}\n```\n\n### Delete Service Endpoint\n\n```bash\naz devops service-endpoint delete --id {endpoint-id} --project {project} --yes\n```\n\n## Teams\n\n### List Teams\n\n```bash\naz devops team list --project {project}\n```\n\n### Show Team\n\n```bash\naz devops team show --team {team-name} --project {project}\n```\n\n### Create Team\n\n```bash\naz devops team create \\\n  --name {team-name} \\\n  --description \"Team description\" \\\n  --project {project}\n```\n\n### Update Team\n\n```bash\naz devops team update \\\n  --team {team-name} \\\n  --project {project} \\\n  --name \"{new-team-name}\" \\\n  --description \"Updated description\"\n```\n\n### Delete Team\n\n```bash\naz devops team delete --team {team-name} --project {project} --yes\n```\n\n### Show Team Members\n\n```bash\naz devops team list-member --team {team-name} --project {project}\n```\n\n## Users\n\n### List Users\n\n```bash\naz devops user list --org https://dev.azure.com/{org}\naz devops user list --top 10 --output table\n```\n\n### Show User\n\n```bash\naz devops user show --user {user-id-or-email} --org https://dev.azure.com/{org}\n```\n\n### Add User\n\n```bash\naz devops user add \\\n  --email user@example.com \\\n  --license-type express \\\n  --org https://dev.azure.com/{org}\n```\n\n### Update User\n\n```bash\naz devops user update \\\n  --user {user-id-or-email} \\\n  --license-type advanced \\\n  --org https://dev.azure.com/{org}\n```\n\n### Remove User\n\n```bash\naz devops user remove --user {user-id-or-email} --org https://dev.azure.com/{org} --yes\n```\n\n## Security Groups\n\n### List Groups\n\n```bash\n# List all groups in project\naz devops security group list --project {project}\n\n# List all groups in organization\naz devops security group list --scope organization\n\n# List with filtering\naz devops security group list --project {project} --subject-types vstsgroup\n```\n\n### Show Group Details\n\n```bash\naz devops security group show --group-id {group-id}\n```\n\n### Create Group\n\n```bash\naz devops security group create \\\n  --name {group-name} \\\n  --description \"Group description\" \\\n  --project {project}\n```\n\n### Update Group\n\n```bash\naz devops security group update \\\n  --group-id {group-id} \\\n  --name \"{new-group-name}\" \\\n  --description \"Updated description\"\n```\n\n### Delete Group\n\n```bash\naz devops security group delete --group-id {group-id} --yes\n```\n\n### Group Memberships\n\n```bash\n# List memberships\naz devops security group membership list --id {group-id}\n\n# Add member\naz devops security group membership add \\\n  --group-id {group-id} \\\n  --member-id {member-id}\n\n# Remove member\naz devops security group membership remove \\\n  --group-id {group-id} \\\n  --member-id {member-id} --yes\n```\n\n## Security Permissions\n\n### List Namespaces\n\n```bash\naz devops security permission namespace list\n```\n\n### Show Namespace Details\n\n```bash\n# Show permissions available in a namespace\naz devops security permission namespace show --namespace \"GitRepositories\"\n```\n\n### List Permissions\n\n```bash\n# List permissions for user/group and namespace\naz devops security permission list \\\n  --id {user-or-group-id} \\\n  --namespace \"GitRepositories\" \\\n  --project {project}\n\n# List for specific token (repository)\naz devops security permission list \\\n  --id {user-or-group-id} \\\n  --namespace \"GitRepositories\" \\\n  --project {project} \\\n  --token \"repoV2/{project}/{repository-id}\"\n```\n\n### Show Permissions\n\n```bash\naz devops security permission show \\\n  --id {user-or-group-id} \\\n  --namespace \"GitRepositories\" \\\n  --project {project} \\\n  --token \"repoV2/{project}/{repository-id}\"\n```\n\n### Update Permissions\n\n```bash\n# Grant permission\naz devops security permission update \\\n  --id {user-or-group-id} \\\n  --namespace \"GitRepositories\" \\\n  --project {project} \\\n  --token \"repoV2/{project}/{repository-id}\" \\\n  --permission-mask \"Pull,Contribute\"\n\n# Deny permission\naz devops security permission update \\\n  --id {user-or-group-id} \\\n  --namespace \"GitRepositories\" \\\n  --project {project} \\\n  --token \"repoV2/{project}/{repository-id}\" \\\n  --permission-mask 0\n```\n\n### Reset Permissions\n\n```bash\n# Reset specific permission bits\naz devops security permission reset \\\n  --id {user-or-group-id} \\\n  --namespace \"GitRepositories\" \\\n  --project {project} \\\n  --token \"repoV2/{project}/{repository-id}\" \\\n  --permission-mask \"Pull,Contribute\"\n\n# Reset all permissions\naz devops security permission reset-all \\\n  --id {user-or-group-id} \\\n  --namespace \"GitRepositories\" \\\n  --project {project} \\\n  --token \"repoV2/{project}/{repository-id}\" --yes\n```\n\n## Wikis\n\n### List Wikis\n\n```bash\n# List all wikis in project\naz devops wiki list --project {project}\n\n# List all wikis in organization\naz devops wiki list\n```\n\n### Show Wiki\n\n```bash\naz devops wiki show --wiki {wiki-name} --project {project}\naz devops wiki show --wiki {wiki-name} --project {project} --open\n```\n\n### Create Wiki\n\n```bash\n# Create project wiki\naz devops wiki create \\\n  --name {wiki-name} \\\n  --project {project} \\\n  --type projectWiki\n\n# Create code wiki from repository\naz devops wiki create \\\n  --name {wiki-name} \\\n  --project {project} \\\n  --type codeWiki \\\n  --repository {repo-name} \\\n  --mapped-path /wiki\n```\n\n### Delete Wiki\n\n```bash\naz devops wiki delete --wiki {wiki-id} --project {project} --yes\n```\n\n### Wiki Pages\n\n```bash\n# List pages\naz devops wiki page list --wiki {wiki-name} --project {project}\n\n# Show page\naz devops wiki page show \\\n  --wiki {wiki-name} \\\n  --path \"/page-name\" \\\n  --project {project}\n\n# Create page\naz devops wiki page create \\\n  --wiki {wiki-name} \\\n  --path \"/new-page\" \\\n  --content \"# New Page\\n\\nPage content here...\" \\\n  --project {project}\n\n# Update page\naz devops wiki page update \\\n  --wiki {wiki-name} \\\n  --path \"/existing-page\" \\\n  --content \"# Updated Page\\n\\nNew content...\" \\\n  --project {project}\n\n# Delete page\naz devops wiki page delete \\\n  --wiki {wiki-name} \\\n  --path \"/old-page\" \\\n  --project {project} --yes\n```\n\n## Administration\n\n### Banner Management\n\n```bash\n# List banners\naz devops admin banner list\n\n# Show banner details\naz devops admin banner show --id {banner-id}\n\n# Add new banner\naz devops admin banner add \\\n  --message \"System maintenance scheduled\" \\\n  --level info  # info, warning, error\n\n# Update banner\naz devops admin banner update \\\n  --id {banner-id} \\\n  --message \"Updated message\" \\\n  --level warning \\\n  --expiration-date \"2025-12-31T23:59:59Z\"\n\n# Remove banner\naz devops admin banner remove --id {banner-id}\n```\n\n## DevOps Extensions\n\nManage extensions installed in an Azure DevOps organization (different from CLI extensions).\n\n```bash\n# List installed extensions\naz devops extension list --org https://dev.azure.com/{org}\n\n# Search marketplace extensions\naz devops extension search --search-query \"docker\"\n\n# Show extension details\naz devops extension show --ext-id {extension-id} --org https://dev.azure.com/{org}\n\n# Install extension\naz devops extension install \\\n  --ext-id {extension-id} \\\n  --org https://dev.azure.com/{org} \\\n  --publisher {publisher-id}\n\n# Enable extension\naz devops extension enable \\\n  --ext-id {extension-id} \\\n  --org https://dev.azure.com/{org}\n\n# Disable extension\naz devops extension disable \\\n  --ext-id {extension-id} \\\n  --org https://dev.azure.com/{org}\n\n# Uninstall extension\naz devops extension uninstall \\\n  --ext-id {extension-id} \\\n  --org https://dev.azure.com/{org} --yes\n```\n","references/pipelines-and-builds.md":"# Pipelines, Builds \u0026 Releases\n\n## Table of Contents\n- [Pipelines](#pipelines)\n- [Pipeline Runs](#pipeline-runs)\n- [Builds](#builds)\n- [Build Definitions](#build-definitions)\n- [Releases](#releases)\n- [Release Definitions](#release-definitions)\n- [Universal Packages (Artifacts)](#universal-packages-artifacts)\n\n---\n\n## Pipelines\n\n### List Pipelines\n\n```bash\naz pipelines list --output table\naz pipelines list --query \"[?name=='myPipeline']\"\naz pipelines list --folder-path 'folder/subfolder'\n```\n\n### Create Pipeline\n\n```bash\n# From local repository context (auto-detects settings)\naz pipelines create --name 'ContosoBuild' --description 'Pipeline for contoso project'\n\n# With specific branch and YAML path\naz pipelines create \\\n  --name {pipeline-name} \\\n  --repository {repo} \\\n  --branch main \\\n  --yaml-path azure-pipelines.yml \\\n  --description \"My CI/CD pipeline\"\n\n# For GitHub repository\naz pipelines create \\\n  --name 'GitHubPipeline' \\\n  --repository https://github.com/Org/Repo \\\n  --branch main \\\n  --repository-type github\n\n# Skip first run\naz pipelines create --name 'MyPipeline' --skip-run true\n```\n\n### Show Pipeline\n\n```bash\naz pipelines show --id {pipeline-id}\naz pipelines show --name {pipeline-name}\n```\n\n### Update Pipeline\n\n```bash\naz pipelines update --id {pipeline-id} --name \"New name\" --description \"Updated description\"\n```\n\n### Delete Pipeline\n\n```bash\naz pipelines delete --id {pipeline-id} --yes\n```\n\n### Run Pipeline\n\n```bash\n# Run by name\naz pipelines run --name {pipeline-name} --branch main\n\n# Run by ID\naz pipelines run --id {pipeline-id} --branch refs/heads/main\n\n# With parameters\naz pipelines run --name {pipeline-name} --parameters version=1.0.0 environment=prod\n\n# With variables\naz pipelines run --name {pipeline-name} --variables buildId=123 configuration=release\n\n# Open results in browser\naz pipelines run --name {pipeline-name} --open\n```\n\n## Pipeline Runs\n\n### List Runs\n\n```bash\naz pipelines runs list --pipeline {pipeline-id}\naz pipelines runs list --name {pipeline-name} --top 10\naz pipelines runs list --branch main --status completed\n```\n\n### Show Run Details\n\n```bash\naz pipelines runs show --run-id {run-id}\naz pipelines runs show --run-id {run-id} --open\n```\n\n### Pipeline Artifacts\n\n```bash\n# List artifacts for a run\naz pipelines runs artifact list --run-id {run-id}\n\n# Download artifact\naz pipelines runs artifact download \\\n  --artifact-name '{artifact-name}' \\\n  --path {local-path} \\\n  --run-id {run-id}\n\n# Upload artifact\naz pipelines runs artifact upload \\\n  --artifact-name '{artifact-name}' \\\n  --path {local-path} \\\n  --run-id {run-id}\n```\n\n### Pipeline Run Tags\n\n```bash\n# Add tag to run\naz pipelines runs tag add --run-id {run-id} --tags production v1.0\n\n# List run tags\naz pipelines runs tag list --run-id {run-id} --output table\n```\n\n## Builds\n\n### List Builds\n\n```bash\naz pipelines build list\naz pipelines build list --definition {build-definition-id}\naz pipelines build list --status completed --result succeeded\n```\n\n### Queue Build\n\n```bash\naz pipelines build queue --definition {build-definition-id} --branch main\naz pipelines build queue --definition {build-definition-id} --parameters version=1.0.0\n```\n\n### Show Build Details\n\n```bash\naz pipelines build show --id {build-id}\n```\n\n### Cancel Build\n\n```bash\naz pipelines build cancel --id {build-id}\n```\n\n### Build Tags\n\n```bash\n# Add tag to build\naz pipelines build tag add --build-id {build-id} --tags prod release\n\n# Delete tag from build\naz pipelines build tag delete --build-id {build-id} --tag prod\n```\n\n## Build Definitions\n\n### List Build Definitions\n\n```bash\naz pipelines build definition list\naz pipelines build definition list --name {definition-name}\n```\n\n### Show Build Definition\n\n```bash\naz pipelines build definition show --id {definition-id}\n```\n\n## Releases\n\n### List Releases\n\n```bash\naz pipelines release list\naz pipelines release list --definition {release-definition-id}\n```\n\n### Create Release\n\n```bash\naz pipelines release create --definition {release-definition-id}\naz pipelines release create --definition {release-definition-id} --description \"Release v1.0\"\n```\n\n### Show Release\n\n```bash\naz pipelines release show --id {release-id}\n```\n\n## Release Definitions\n\n### List Release Definitions\n\n```bash\naz pipelines release definition list\n```\n\n### Show Release Definition\n\n```bash\naz pipelines release definition show --id {definition-id}\n```\n\n## Universal Packages (Artifacts)\n\n### Publish Package\n\n```bash\naz artifacts universal publish \\\n  --feed {feed-name} \\\n  --name {package-name} \\\n  --version {version} \\\n  --path {package-path} \\\n  --project {project}\n```\n\n### Download Package\n\n```bash\naz artifacts universal download \\\n  --feed {feed-name} \\\n  --name {package-name} \\\n  --version {version} \\\n  --path {download-path} \\\n  --project {project}\n```\n","references/repos-and-prs.md":"# Repositories \u0026 Pull Requests\n\n## Table of Contents\n- [Repositories](#repositories)\n- [Repository Import](#repository-import)\n- [Pull Requests](#pull-requests)\n- [Git References](#git-references)\n- [Repository Policies](#repository-policies)\n\n---\n\n## Repositories\n\n### List Repositories\n\n```bash\naz repos list --org https://dev.azure.com/{org} --project {project}\naz repos list --output table\n```\n\n### Show Repository Details\n\n```bash\naz repos show --repository {repo-name} --project {project}\n```\n\n### Create Repository\n\n```bash\naz repos create --name {repo-name} --project {project}\n```\n\n### Delete Repository\n\n```bash\naz repos delete --id {repo-id} --project {project} --yes\n```\n\n### Update Repository\n\n```bash\naz repos update --id {repo-id} --name {new-name} --project {project}\n```\n\n## Repository Import\n\n### Import Git Repository\n\n```bash\n# Import from public Git repository\naz repos import create \\\n  --git-source-url https://github.com/user/repo \\\n  --repository {repo-name}\n\n# Import with authentication\naz repos import create \\\n  --git-source-url https://github.com/user/private-repo \\\n  --repository {repo-name} \\\n  --user {username} \\\n  --password {password-or-pat}\n```\n\n## Pull Requests\n\n### Create Pull Request\n\n```bash\n# Basic PR creation\naz repos pr create \\\n  --repository {repo} \\\n  --source-branch {source-branch} \\\n  --target-branch {target-branch} \\\n  --title \"PR Title\" \\\n  --description \"PR description\" \\\n  --open\n\n# PR with work items\naz repos pr create \\\n  --repository {repo} \\\n  --source-branch {source-branch} \\\n  --work-items 63 64\n\n# Draft PR with reviewers\naz repos pr create \\\n  --repository {repo} \\\n  --source-branch feature/new-feature \\\n  --target-branch main \\\n  --title \"Feature: New functionality\" \\\n  --draft true \\\n  --reviewers user1@example.com user2@example.com \\\n  --required-reviewers lead@example.com \\\n  --labels \"enhancement\" \"backlog\"\n```\n\n### List Pull Requests\n\n```bash\n# All PRs\naz repos pr list --repository {repo}\n\n# Filter by status\naz repos pr list --repository {repo} --status active\n\n# Filter by creator\naz repos pr list --repository {repo} --creator {email}\n\n# Output as table\naz repos pr list --repository {repo} --output table\n```\n\n### Show PR Details\n\n```bash\naz repos pr show --id {pr-id}\naz repos pr show --id {pr-id} --open  # Open in browser\n```\n\n### Update PR (Complete/Abandon/Draft)\n\n```bash\n# Complete PR\naz repos pr update --id {pr-id} --status completed\n\n# Abandon PR\naz repos pr update --id {pr-id} --status abandoned\n\n# Set to draft\naz repos pr update --id {pr-id} --draft true\n\n# Publish draft PR\naz repos pr update --id {pr-id} --draft false\n\n# Auto-complete when policies pass\naz repos pr update --id {pr-id} --auto-complete true\n\n# Set title and description\naz repos pr update --id {pr-id} --title \"New title\" --description \"New description\"\n```\n\n### Checkout PR Locally\n\n```bash\n# Checkout PR branch\naz repos pr checkout --id {pr-id}\n\n# Checkout with specific remote\naz repos pr checkout --id {pr-id} --remote-name upstream\n```\n\n### Vote on PR\n\n```bash\naz repos pr set-vote --id {pr-id} --vote approve\naz repos pr set-vote --id {pr-id} --vote approve-with-suggestions\naz repos pr set-vote --id {pr-id} --vote reject\naz repos pr set-vote --id {pr-id} --vote wait-for-author\naz repos pr set-vote --id {pr-id} --vote reset\n```\n\n### PR Reviewers\n\n```bash\n# Add reviewers\naz repos pr reviewer add --id {pr-id} --reviewers user1@example.com user2@example.com\n\n# List reviewers\naz repos pr reviewer list --id {pr-id}\n\n# Remove reviewers\naz repos pr reviewer remove --id {pr-id} --reviewers user1@example.com\n```\n\n### PR Work Items\n\n```bash\n# Add work items to PR\naz repos pr work-item add --id {pr-id} --work-items {id1} {id2}\n\n# List PR work items\naz repos pr work-item list --id {pr-id}\n\n# Remove work items from PR\naz repos pr work-item remove --id {pr-id} --work-items {id1}\n```\n\n### PR Policies\n\n```bash\n# List policies for a PR\naz repos pr policy list --id {pr-id}\n\n# Queue policy evaluation for a PR\naz repos pr policy queue --id {pr-id} --evaluation-id {evaluation-id}\n```\n\n## Git References\n\n### List References (Branches)\n\n```bash\naz repos ref list --repository {repo}\naz repos ref list --repository {repo} --query \"[?name=='refs/heads/main']\"\n```\n\n### Create Reference (Branch)\n\n```bash\naz repos ref create --name refs/heads/new-branch --object-type commit --object {commit-sha}\n```\n\n### Delete Reference (Branch)\n\n```bash\naz repos ref delete --name refs/heads/old-branch --repository {repo} --project {project}\n```\n\n### Lock/Unlock Branch\n\n```bash\naz repos ref lock --name refs/heads/main --repository {repo} --project {project}\naz repos ref unlock --name refs/heads/main --repository {repo} --project {project}\n```\n\n## Repository Policies\n\n### List All Policies\n\n```bash\naz repos policy list --repository {repo-id} --branch main\n```\n\n### Create/Update/Delete Policy\n\n```bash\n# Create from config file\naz repos policy create --config policy.json\n\n# Update\naz repos policy update --id {policy-id} --config updated-policy.json\n\n# Delete\naz repos policy delete --id {policy-id} --yes\n```\n\n### Approver Count Policy\n\n```bash\naz repos policy approver-count create \\\n  --blocking true \\\n  --enabled true \\\n  --branch main \\\n  --repository-id {repo-id} \\\n  --minimum-approver-count 2 \\\n  --creator-vote-counts true\n```\n\n### Build Policy\n\n```bash\naz repos policy build create \\\n  --blocking true \\\n  --enabled true \\\n  --branch main \\\n  --repository-id {repo-id} \\\n  --build-definition-id {definition-id} \\\n  --queue-on-source-update-only true \\\n  --valid-duration 720\n```\n\n### Work Item Linking Policy\n\n```bash\naz repos policy work-item-linking create \\\n  --blocking true \\\n  --branch main \\\n  --enabled true \\\n  --repository-id {repo-id}\n```\n\n### Required Reviewer Policy\n\n```bash\naz repos policy required-reviewer create \\\n  --blocking true \\\n  --enabled true \\\n  --branch main \\\n  --repository-id {repo-id} \\\n  --required-reviewers user@example.com\n```\n\n### Merge Strategy Policy\n\n```bash\naz repos policy merge-strategy create \\\n  --blocking true \\\n  --enabled true \\\n  --branch main \\\n  --repository-id {repo-id} \\\n  --allow-squash true \\\n  --allow-rebase true \\\n  --allow-no-fast-forward true\n```\n\n### Case Enforcement Policy\n\n```bash\naz repos policy case-enforcement create \\\n  --blocking true \\\n  --enabled true \\\n  --branch main \\\n  --repository-id {repo-id}\n```\n\n### Comment Required Policy\n\n```bash\naz repos policy comment-required create \\\n  --blocking true \\\n  --enabled true \\\n  --branch main \\\n  --repository-id {repo-id}\n```\n\n### File Size Policy\n\n```bash\naz repos policy file-size create \\\n  --blocking true \\\n  --enabled true \\\n  --branch main \\\n  --repository-id {repo-id} \\\n  --maximum-file-size 10485760  # 10MB in bytes\n```\n","references/variables-and-agents.md":"# Pipeline Variables, Variable Groups \u0026 Agents\n\n## Table of Contents\n- [Pipeline Variables](#pipeline-variables)\n- [Variable Groups](#variable-groups)\n- [Pipeline Folders](#pipeline-folders)\n- [Agent Pools](#agent-pools)\n- [Agent Queues](#agent-queues)\n- [Agents](#agents)\n\n---\n\n## Pipeline Variables\n\n### List Variables\n\n```bash\naz pipelines variable list --pipeline-id {pipeline-id}\n```\n\n### Create Variable\n\n```bash\n# Non-secret variable\naz pipelines variable create \\\n  --name {var-name} \\\n  --value {var-value} \\\n  --pipeline-id {pipeline-id}\n\n# Secret variable\naz pipelines variable create \\\n  --name {var-name} \\\n  --secret true \\\n  --pipeline-id {pipeline-id}\n\n# Secret with prompt\naz pipelines variable create \\\n  --name {var-name} \\\n  --secret true \\\n  --prompt true \\\n  --pipeline-id {pipeline-id}\n```\n\n### Update Variable\n\n```bash\naz pipelines variable update \\\n  --name {var-name} \\\n  --value {new-value} \\\n  --pipeline-id {pipeline-id}\n\n# Update secret variable\naz pipelines variable update \\\n  --name {var-name} \\\n  --secret true \\\n  --value \"{new-secret-value}\" \\\n  --pipeline-id {pipeline-id}\n```\n\n### Delete Variable\n\n```bash\naz pipelines variable delete --name {var-name} --pipeline-id {pipeline-id} --yes\n```\n\n## Variable Groups\n\n### List Variable Groups\n\n```bash\naz pipelines variable-group list\naz pipelines variable-group list --output table\n```\n\n### Show Variable Group\n\n```bash\naz pipelines variable-group show --id {group-id}\n```\n\n### Create Variable Group\n\n```bash\naz pipelines variable-group create \\\n  --name {group-name} \\\n  --variables key1=value1 key2=value2 \\\n  --authorize true\n```\n\n### Update Variable Group\n\n```bash\naz pipelines variable-group update \\\n  --id {group-id} \\\n  --name {new-name} \\\n  --description \"Updated description\"\n```\n\n### Delete Variable Group\n\n```bash\naz pipelines variable-group delete --id {group-id} --yes\n```\n\n### Variable Group Variables\n\n```bash\n# List variables\naz pipelines variable-group variable list --group-id {group-id}\n\n# Create non-secret variable\naz pipelines variable-group variable create \\\n  --group-id {group-id} \\\n  --name {var-name} \\\n  --value {var-value}\n\n# Create secret variable (will prompt for value if not provided)\naz pipelines variable-group variable create \\\n  --group-id {group-id} \\\n  --name {var-name} \\\n  --secret true\n\n# Create secret with environment variable\nexport AZURE_DEVOPS_EXT_PIPELINE_VAR_MySecret=secretvalue\naz pipelines variable-group variable create \\\n  --group-id {group-id} \\\n  --name MySecret \\\n  --secret true\n\n# Update variable\naz pipelines variable-group variable update \\\n  --group-id {group-id} \\\n  --name {var-name} \\\n  --value {new-value} \\\n  --secret false\n\n# Delete variable\naz pipelines variable-group variable delete \\\n  --group-id {group-id} \\\n  --name {var-name}\n```\n\n## Pipeline Folders\n\n### List Folders\n\n```bash\naz pipelines folder list\n```\n\n### Create Folder\n\n```bash\naz pipelines folder create --path 'folder/subfolder' --description \"My folder\"\n```\n\n### Delete Folder\n\n```bash\naz pipelines folder delete --path 'folder/subfolder'\n```\n\n### Update Folder\n\n```bash\naz pipelines folder update --path 'old-folder' --new-path 'new-folder'\n```\n\n## Agent Pools\n\n### List Agent Pools\n\n```bash\naz pipelines pool list\naz pipelines pool list --pool-type automation\naz pipelines pool list --pool-type deployment\n```\n\n### Show Agent Pool\n\n```bash\naz pipelines pool show --pool-id {pool-id}\n```\n\n## Agent Queues\n\n### List Agent Queues\n\n```bash\naz pipelines queue list\naz pipelines queue list --pool-name {pool-name}\n```\n\n### Show Agent Queue\n\n```bash\naz pipelines queue show --id {queue-id}\n```\n\n## Agents\n\n### List Agents in Pool\n\n```bash\naz pipelines agent list --pool-id {pool-id}\n```\n\n### Show Agent Details\n\n```bash\naz pipelines agent show --agent-id {agent-id} --pool-id {pool-id}\n```\n","references/workflows-and-patterns.md":"# Workflows, Best Practices \u0026 Scripting Patterns\n\n## Table of Contents\n- [Common Workflows](#common-workflows)\n- [Best Practices](#best-practices)\n- [Error Handling \u0026 Retry Patterns](#error-handling--retry-patterns)\n- [Scripting Patterns for Idempotent Operations](#scripting-patterns-for-idempotent-operations)\n- [Real-World Workflows](#real-world-workflows)\n\n---\n\n## Common Workflows\n\n### Create PR from current branch\n\n```bash\nCURRENT_BRANCH=$(git branch --show-current)\naz repos pr create \\\n  --source-branch $CURRENT_BRANCH \\\n  --target-branch main \\\n  --title \"Feature: $(git log -1 --pretty=%B)\" \\\n  --open\n```\n\n### Create work item on pipeline failure\n\n```bash\naz boards work-item create \\\n  --title \"Build $BUILD_BUILDNUMBER failed\" \\\n  --type bug \\\n  --org $SYSTEM_TEAMFOUNDATIONCOLLECTIONURI \\\n  --project $SYSTEM_TEAMPROJECT\n```\n\n### Download latest pipeline artifact\n\n```bash\nRUN_ID=$(az pipelines runs list --pipeline {pipeline-id} --top 1 --query \"[0].id\" -o tsv)\naz pipelines runs artifact download \\\n  --artifact-name 'webapp' \\\n  --path ./output \\\n  --run-id $RUN_ID\n```\n\n### Approve and complete PR\n\n```bash\n# Vote approve\naz repos pr set-vote --id {pr-id} --vote approve\n\n# Complete PR\naz repos pr update --id {pr-id} --status completed\n```\n\n### Create pipeline from local repo\n\n```bash\n# From local git repository (auto-detects repo, branch, etc.)\naz pipelines create --name 'CI-Pipeline' --description 'Continuous Integration'\n```\n\n### Bulk update work items\n\n```bash\n# Query items and update in loop\nfor id in $(az boards query --wiql \"SELECT ID FROM WorkItems WHERE State='New'\" -o tsv); do\n  az boards work-item update --id $id --state \"Active\"\ndone\n```\n\n## Best Practices\n\n### Authentication and Security\n\n```bash\n# Use PAT from environment variable (most secure)\nexport AZURE_DEVOPS_EXT_PAT=$MY_PAT\naz devops login --organization $ORG_URL\n\n# Pipe PAT securely (avoids shell history)\necho $MY_PAT | az devops login --organization $ORG_URL\n\n# Set defaults to avoid repetition\naz devops configure --defaults organization=$ORG_URL project=$PROJECT\n\n# Clear credentials after use\naz devops logout --organization $ORG_URL\n```\n\n### Idempotent Operations\n\n```bash\n# Always use --detect for auto-detection\naz devops configure --defaults organization=$ORG_URL project=$PROJECT\n\n# Check existence before creation\nif ! az pipelines show --id $PIPELINE_ID 2\u003e/dev/null; then\n  az pipelines create --name \"$PIPELINE_NAME\" --yaml-path azure-pipelines.yml\nfi\n\n# Use --output tsv for shell parsing\nPIPELINE_ID=$(az pipelines list --query \"[?name=='MyPipeline'].id\" --output tsv)\n\n# Use --output json for programmatic access\nBUILD_STATUS=$(az pipelines build show --id $BUILD_ID --query \"status\" --output json)\n```\n\n### Script-Safe Output\n\n```bash\n# Suppress warnings and errors\naz pipelines list --only-show-errors\n\n# No output (useful for commands that only need to execute)\naz pipelines run --name \"$PIPELINE_NAME\" --output none\n\n# TSV format for shell scripts (clean, no formatting)\naz repos pr list --output tsv --query \"[].{ID:pullRequestId,Title:title}\"\n\n# JSON with specific fields\naz pipelines list --output json --query \"[].{Name:name, ID:id, URL:url}\"\n```\n\n### Pipeline Orchestration\n\n```bash\n# Run pipeline and wait for completion\nRUN_ID=$(az pipelines run --name \"$PIPELINE_NAME\" --query \"id\" -o tsv)\n\nwhile true; do\n  STATUS=$(az pipelines runs show --run-id $RUN_ID --query \"status\" -o tsv)\n  if [[ \"$STATUS\" != \"inProgress\" \u0026\u0026 \"$STATUS\" != \"notStarted\" ]]; then\n    break\n  fi\n  sleep 10\ndone\n\n# Check result\nRESULT=$(az pipelines runs show --run-id $RUN_ID --query \"result\" -o tsv)\nif [[ \"$RESULT\" == \"succeeded\" ]]; then\n  echo \"Pipeline succeeded\"\nelse\n  echo \"Pipeline failed with result: $RESULT\"\n  exit 1\nfi\n```\n\n### Variable Group Management\n\n```bash\n# Create variable group idempotently\nVG_NAME=\"production-variables\"\nVG_ID=$(az pipelines variable-group list --query \"[?name=='$VG_NAME'].id\" -o tsv)\n\nif [[ -z \"$VG_ID\" ]]; then\n  VG_ID=$(az pipelines variable-group create \\\n    --name \"$VG_NAME\" \\\n    --variables API_URL=$API_URL API_KEY=$API_KEY \\\n    --authorize true \\\n    --query \"id\" -o tsv)\n  echo \"Created variable group with ID: $VG_ID\"\nelse\n  echo \"Variable group already exists with ID: $VG_ID\"\nfi\n```\n\n### Service Connection Automation\n\n```bash\n# Create service connection using configuration file\ncat \u003e service-connection.json \u003c\u003c'EOF'\n{\n  \"data\": {\n    \"subscriptionId\": \"$SUBSCRIPTION_ID\",\n    \"subscriptionName\": \"My Subscription\",\n    \"creationMode\": \"Manual\",\n    \"serviceEndpointId\": \"$SERVICE_ENDPOINT_ID\"\n  },\n  \"url\": \"https://management.azure.com/\",\n  \"authorization\": {\n    \"parameters\": {\n      \"tenantid\": \"$TENANT_ID\",\n      \"serviceprincipalid\": \"$SP_ID\",\n      \"authenticationType\": \"spnKey\",\n      \"serviceprincipalkey\": \"$SP_KEY\"\n    },\n    \"scheme\": \"ServicePrincipal\"\n  },\n  \"type\": \"azurerm\",\n  \"isShared\": false,\n  \"isReady\": true\n}\nEOF\n\naz devops service-endpoint create \\\n  --service-endpoint-configuration service-connection.json \\\n  --project \"$PROJECT\"\n```\n\n### Pull Request Automation\n\n```bash\n# Create PR with work items and reviewers\nPR_ID=$(az repos pr create \\\n  --repository \"$REPO_NAME\" \\\n  --source-branch \"$FEATURE_BRANCH\" \\\n  --target-branch main \\\n  --title \"Feature: $(git log -1 --pretty=%B)\" \\\n  --description \"$(git log -1 --pretty=%B)\" \\\n  --work-items $WORK_ITEM_1 $WORK_ITEM_2 \\\n  --reviewers \"$REVIEWER_1\" \"$REVIEWER_2\" \\\n  --required-reviewers \"$LEAD_EMAIL\" \\\n  --labels \"enhancement\" \"backlog\" \\\n  --open \\\n  --query \"pullRequestId\" -o tsv)\n\n# Set auto-complete when policies pass\naz repos pr update --id $PR_ID --auto-complete true\n```\n\n## Error Handling \u0026 Retry Patterns\n\n### Retry Logic for Transient Failures\n\n```bash\n# Retry function for network operations\nretry_command() {\n  local max_attempts=3\n  local attempt=1\n  local delay=5\n\n  while [[ $attempt -le $max_attempts ]]; do\n    if \"$@\"; then\n      return 0\n    fi\n    echo \"Attempt $attempt failed. Retrying in ${delay}s...\"\n    sleep $delay\n    ((attempt++))\n    delay=$((delay * 2))\n  done\n\n  echo \"All $max_attempts attempts failed\"\n  return 1\n}\n\n# Usage\nretry_command az pipelines run --name \"$PIPELINE_NAME\"\n```\n\n### Check and Handle Errors\n\n```bash\n# Check if pipeline exists before operations\nPIPELINE_ID=$(az pipelines list --query \"[?name=='$PIPELINE_NAME'].id\" -o tsv)\n\nif [[ -z \"$PIPELINE_ID\" ]]; then\n  echo \"Pipeline not found. Creating...\"\n  az pipelines create --name \"$PIPELINE_NAME\" --yaml-path azure-pipelines.yml\nelse\n  echo \"Pipeline exists with ID: $PIPELINE_ID\"\nfi\n```\n\n### Validate Inputs\n\n```bash\n# Validate required parameters\nif [[ -z \"$PROJECT\" || -z \"$REPO\" ]]; then\n  echo \"Error: PROJECT and REPO must be set\"\n  exit 1\nfi\n\n# Check if branch exists\nif ! az repos ref list --repository \"$REPO\" --query \"[?name=='refs/heads/$BRANCH']\" -o tsv | grep -q .; then\n  echo \"Error: Branch $BRANCH does not exist\"\n  exit 1\nfi\n```\n\n### Handle Permission Errors\n\n```bash\n# Try operation, handle permission errors\nif az devops security permission update \\\n  --id \"$USER_ID\" \\\n  --namespace \"GitRepositories\" \\\n  --project \"$PROJECT\" \\\n  --token \"repoV2/$PROJECT/$REPO_ID\" \\\n  --allow-bit 2 \\\n  --deny-bit 0 2\u003e\u00261 | grep -q \"unauthorized\"; then\n  echo \"Error: Insufficient permissions to update repository permissions\"\n  exit 1\nfi\n```\n\n### Pipeline Failure Notification\n\n```bash\n# Run pipeline and check result\nRUN_ID=$(az pipelines run --name \"$PIPELINE_NAME\" --query \"id\" -o tsv)\n\n# Wait for completion\nwhile true; do\n  STATUS=$(az pipelines runs show --run-id $RUN_ID --query \"status\" -o tsv)\n  if [[ \"$STATUS\" != \"inProgress\" \u0026\u0026 \"$STATUS\" != \"notStarted\" ]]; then\n    break\n  fi\n  sleep 10\ndone\n\n# Check result and create work item on failure\nRESULT=$(az pipelines runs show --run-id $RUN_ID --query \"result\" -o tsv)\nif [[ \"$RESULT\" != \"succeeded\" ]]; then\n  BUILD_NUMBER=$(az pipelines runs show --run-id $RUN_ID --query \"buildNumber\" -o tsv)\n\n  az boards work-item create \\\n    --title \"Build $BUILD_NUMBER failed\" \\\n    --type Bug \\\n    --description \"Pipeline run $RUN_ID failed with result: $RESULT\\n\\nURL: $ORG_URL/$PROJECT/_build/results?buildId=$RUN_ID\"\nfi\n```\n\n### Graceful Degradation\n\n```bash\n# Try to download artifact, fallback to alternative source\nif ! az pipelines runs artifact download \\\n  --artifact-name 'webapp' \\\n  --path ./output \\\n  --run-id $RUN_ID 2\u003e/dev/null; then\n  echo \"Warning: Failed to download from pipeline run. Falling back to backup source...\"\n\n  # Alternative download method\n  curl -L \"$BACKUP_URL\" -o ./output/backup.zip\nfi\n```\n\n## Scripting Patterns for Idempotent Operations\n\n### Create or Update Pattern\n\n```bash\n# Ensure pipeline exists, update if different\nensure_pipeline() {\n  local name=$1\n  local yaml_path=$2\n\n  PIPELINE=$(az pipelines list --query \"[?name=='$name']\" -o json)\n\n  if [[ -z \"$PIPELINE\" ]]; then\n    echo \"Creating pipeline: $name\"\n    az pipelines create --name \"$name\" --yaml-path \"$yaml_path\"\n  else\n    echo \"Pipeline exists: $name\"\n  fi\n}\n```\n\n### Ensure Variable Group\n\n```bash\n# Create variable group with idempotent updates\nensure_variable_group() {\n  local vg_name=$1\n  shift\n  local variables=(\"$@\")\n\n  VG_ID=$(az pipelines variable-group list --query \"[?name=='$vg_name'].id\" -o tsv)\n\n  if [[ -z \"$VG_ID\" ]]; then\n    echo \"Creating variable group: $vg_name\"\n    VG_ID=$(az pipelines variable-group create \\\n      --name \"$vg_name\" \\\n      --variables \"${variables[@]}\" \\\n      --authorize true \\\n      --query \"id\" -o tsv)\n  else\n    echo \"Variable group exists: $vg_name (ID: $VG_ID)\"\n  fi\n\n  echo \"$VG_ID\"\n}\n```\n\n### Ensure Service Connection\n\n```bash\n# Check if service connection exists, create if not\nensure_service_connection() {\n  local name=$1\n  local project=$2\n\n  SC_ID=$(az devops service-endpoint list \\\n    --project \"$project\" \\\n    --query \"[?name=='$name'].id\" \\\n    -o tsv)\n\n  if [[ -z \"$SC_ID\" ]]; then\n    echo \"Service connection not found. Creating...\"\n    # Create logic here\n  else\n    echo \"Service connection exists: $name\"\n    echo \"$SC_ID\"\n  fi\n}\n```\n\n### Idempotent Work Item Creation\n\n```bash\n# Create work item only if doesn't exist with same title\ncreate_work_item_if_new() {\n  local title=$1\n  local type=$2\n\n  WI_ID=$(az boards query \\\n    --wiql \"SELECT ID FROM WorkItems WHERE [System.WorkItemType]='$type' AND [System.Title]='$title'\" \\\n    --query \"[0].id\" -o tsv)\n\n  if [[ -z \"$WI_ID\" ]]; then\n    echo \"Creating work item: $title\"\n    WI_ID=$(az boards work-item create --title \"$title\" --type \"$type\" --query \"id\" -o tsv)\n  else\n    echo \"Work item exists: $title (ID: $WI_ID)\"\n  fi\n\n  echo \"$WI_ID\"\n}\n```\n\n### Bulk Idempotent Operations\n\n```bash\n# Ensure multiple pipelines exist\ndeclare -a PIPELINES=(\n  \"ci-pipeline:azure-pipelines.yml\"\n  \"deploy-pipeline:deploy.yml\"\n  \"test-pipeline:test.yml\"\n)\n\nfor pipeline in \"${PIPELINES[@]}\"; do\n  IFS=':' read -r name yaml \u003c\u003c\u003c \"$pipeline\"\n  ensure_pipeline \"$name\" \"$yaml\"\ndone\n```\n\n### Configuration Synchronization\n\n```bash\n# Sync variable groups from config file\nsync_variable_groups() {\n  local config_file=$1\n\n  while IFS=',' read -r vg_name variables; do\n    ensure_variable_group \"$vg_name\" \"$variables\"\n  done \u003c \"$config_file\"\n}\n\n# config.csv format:\n# prod-vars,API_URL=prod.com,API_KEY=secret123\n# dev-vars,API_URL=dev.com,API_KEY=secret456\n```\n\n## Real-World Workflows\n\n### CI/CD Pipeline Setup\n\n```bash\n# Setup complete CI/CD pipeline\nsetup_cicd_pipeline() {\n  local project=$1\n  local repo=$2\n  local branch=$3\n\n  # Create variable groups\n  VG_DEV=$(ensure_variable_group \"dev-vars\" \"ENV=dev API_URL=api-dev.com\")\n  VG_PROD=$(ensure_variable_group \"prod-vars\" \"ENV=prod API_URL=api-prod.com\")\n\n  # Create CI pipeline\n  az pipelines create \\\n    --name \"$repo-CI\" \\\n    --repository \"$repo\" \\\n    --branch \"$branch\" \\\n    --yaml-path .azure/pipelines/ci.yml \\\n    --skip-run true\n\n  # Create CD pipeline\n  az pipelines create \\\n    --name \"$repo-CD\" \\\n    --repository \"$repo\" \\\n    --branch \"$branch\" \\\n    --yaml-path .azure/pipelines/cd.yml \\\n    --skip-run true\n\n  echo \"CI/CD pipeline setup complete\"\n}\n```\n\n### Automated PR Creation\n\n```bash\n# Create PR from feature branch with automation\ncreate_automated_pr() {\n  local branch=$1\n  local title=$2\n\n  # Get branch info\n  LAST_COMMIT=$(git log -1 --pretty=%B \"$branch\")\n  COMMIT_SHA=$(git rev-parse \"$branch\")\n\n  # Find related work items\n  WORK_ITEMS=$(az boards query \\\n    --wiql \"SELECT ID FROM WorkItems WHERE [System.ChangedBy] = @Me AND [System.State] = 'Active'\" \\\n    --query \"[].id\" -o tsv)\n\n  # Create PR\n  PR_ID=$(az repos pr create \\\n    --source-branch \"$branch\" \\\n    --target-branch main \\\n    --title \"$title\" \\\n    --description \"$LAST_COMMIT\" \\\n    --work-items $WORK_ITEMS \\\n    --auto-complete true \\\n    --query \"pullRequestId\" -o tsv)\n\n  # Set required reviewers\n  az repos pr reviewer add \\\n    --id $PR_ID \\\n    --reviewers $(git log -1 --pretty=format:'%ae' \"$branch\") \\\n    --required true\n\n  echo \"Created PR #$PR_ID\"\n}\n```\n\n### Pipeline Monitoring and Alerting\n\n```bash\n# Monitor pipeline and alert on failure\nmonitor_pipeline() {\n  local pipeline_name=$1\n  local slack_webhook=$2\n\n  while true; do\n    # Get latest run\n    RUN_ID=$(az pipelines list --query \"[?name=='$pipeline_name'] | [0].id\" -o tsv)\n    RUNS=$(az pipelines runs list --pipeline $RUN_ID --top 1)\n\n    LATEST_RUN_ID=$(echo \"$RUNS\" | jq -r '.[0].id')\n    RESULT=$(echo \"$RUNS\" | jq -r '.[0].result')\n\n    # Check if failed and not already processed\n    if [[ \"$RESULT\" == \"failed\" ]]; then\n      # Send Slack alert\n      curl -X POST \"$slack_webhook\" \\\n        -H 'Content-Type: application/json' \\\n        -d \"{\\\"text\\\": \\\"Pipeline $pipeline_name failed! Run ID: $LATEST_RUN_ID\\\"}\"\n    fi\n\n    sleep 300 # Check every 5 minutes\n  done\n}\n```\n\n### Bulk Work Item Management\n\n```bash\n# Bulk update work items based on query\nbulk_update_work_items() {\n  local wiql=$1\n  local updates=(\"$@\")\n\n  # Query work items\n  WI_IDS=$(az boards query --wiql \"$wiql\" --query \"[].id\" -o tsv)\n\n  # Update each work item\n  for wi_id in $WI_IDS; do\n    az boards work-item update --id $wi_id \"${updates[@]}\"\n    echo \"Updated work item: $wi_id\"\n  done\n}\n\n# Usage: bulk_update_work_items \"SELECT ID FROM WorkItems WHERE State='New'\" --state \"Active\" --assigned-to \"user@example.com\"\n```\n\n### Branch Policy Automation\n\n```bash\n# Apply branch policies to all repositories\napply_branch_policies() {\n  local branch=$1\n  local project=$2\n\n  # Get all repositories\n  REPOS=$(az repos list --project \"$project\" --query \"[].id\" -o tsv)\n\n  for repo_id in $REPOS; do\n    echo \"Applying policies to repo: $repo_id\"\n\n    # Require minimum approvers\n    az repos policy approver-count create \\\n      --blocking true \\\n      --enabled true \\\n      --branch \"$branch\" \\\n      --repository-id \"$repo_id\" \\\n      --minimum-approver-count 2 \\\n      --creator-vote-counts true\n\n    # Require work item linking\n    az repos policy work-item-linking create \\\n      --blocking true \\\n      --branch \"$branch\" \\\n      --enabled true \\\n      --repository-id \"$repo_id\"\n\n    # Require build validation\n    BUILD_ID=$(az pipelines list --query \"[?name=='CI'].id\" -o tsv | head -1)\n    az repos policy build create \\\n      --blocking true \\\n      --enabled true \\\n      --branch \"$branch\" \\\n      --repository-id \"$repo_id\" \\\n      --build-definition-id \"$BUILD_ID\" \\\n      --queue-on-source-update-only true\n  done\n}\n```\n\n### Multi-Environment Deployment\n\n```bash\n# Deploy across multiple environments\ndeploy_to_environments() {\n  local run_id=$1\n  shift\n  local environments=(\"$@\")\n\n  # Download artifacts\n  ARTIFACT_NAME=$(az pipelines runs artifact list --run-id $run_id --query \"[0].name\" -o tsv)\n  az pipelines runs artifact download \\\n    --artifact-name \"$ARTIFACT_NAME\" \\\n    --path ./artifacts \\\n    --run-id $run_id\n\n  # Deploy to each environment\n  for env in \"${environments[@]}\"; do\n    echo \"Deploying to: $env\"\n\n    # Get environment-specific variables\n    VG_ID=$(az pipelines variable-group list --query \"[?name=='$env-vars'].id\" -o tsv)\n\n    # Run deployment pipeline\n    DEPLOY_RUN_ID=$(az pipelines run \\\n      --name \"Deploy-$env\" \\\n      --variables ARTIFACT_PATH=./artifacts ENV=\"$env\" \\\n      --query \"id\" -o tsv)\n\n    # Wait for deployment\n    while true; do\n      STATUS=$(az pipelines runs show --run-id $DEPLOY_RUN_ID --query \"status\" -o tsv)\n      if [[ \"$STATUS\" != \"inProgress\" ]]; then\n        break\n      fi\n      sleep 10\n    done\n  done\n}\n```\n"},"import":{"commit_sha":"541b7819d8c3545c6df122491af4fa1eae415779","imported_at":"2026-05-18T20:07:09Z","license_text":"MIT License\n\nCopyright GitHub, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","owner":"github","repo":"github/awesome-copilot","source_url":"https://github.com/github/awesome-copilot/tree/541b7819d8c3545c6df122491af4fa1eae415779/skills/azure-devops-cli"}},"content_hash":[78,141,255,221,122,101,216,148,70,157,168,8,235,2,98,235,30,249,52,191,199,108,193,255,184,129,229,126,97,75,54,141],"trust_level":"unsigned","yanked":false}
