Skip to content
jesusprodriguez.com

azure-devops-cli

Azure DevOps: acceso desde la terminal

The access foundation for Azure DevOps: a PAT with the right scope, CLI defaults, WIQL, Analytics OData and honest pagination.

stack:
Azure DevOps
version:
v1.0.0
updated:
size:
4.5 KB
read:
3 min
license:
CC-BY-4.0

When it fires

When reading from or writing to Azure Repos, Boards or Pipelines from the terminal.

description: Base de acceso a Azure DevOps desde la terminal y la REST API - autenticación con PAT, az devops, consultas WIQL, OData de Analytics y paginación. Úsala como cimiento de cualquier tarea que lea o escriba en Azure Repos, Boards o Pipelines.

  • PATs and scopes
  • az devops / az boards
  • WIQL queries
  • REST and pagination

How you ask for it

> Set up Azure DevOps access in this repo and check the PAT has the scopes it needs.

Say this to the agent as it is: the skill loads itself from its description, you do not have to name it.

How to install one

/plugin marketplace add https://jesusprodriguez.com/skills/marketplace.json
/plugin install azure-devops@jprodriguez-toolkit

The native route, and the only one that updates itself: add the marketplace once and `/plugin marketplace update` brings in new versions. Skills get their own namespace (`azure-devops:azure-pr-review`).

The whole file

This is exactly what you download: no summaries, nothing trimmed.

Heads-up: the skill file itself is written in Spanish. Agents read it fine and answer in your language, but the prose below is not translated.

Azure DevOps: acceso desde la terminal

Todas las demás skills de Azure DevOps asumen lo que hay aquí. Si una consulta falla por permisos o por formato, el problema casi siempre está en esta capa.

Configuración inicial

az extension add --name azure-devops
az devops configure --defaults \
  organization=https://dev.azure.com/<ORG> \
  project=<PROYECTO>

Con los defaults puestos, ningún comando posterior necesita --org ni --project. Compruébalos antes de dudar de un resultado vacío:

az devops configure --list

Autenticación

Un PAT (Personal Access Token) con los ámbitos mínimos de la tarea:

TareaÁmbito del PAT
Leer PRs y reposCode (Read)
Comentar en PRsCode (Read & Write)
Leer backlog y sprintsWork Items (Read)
Crear o mover PBIsWork Items (Read & Write)
Leer buildsBuild (Read)

Nunca en un fichero versionado. Dos formas:

# Interactiva: pega el PAT cuando lo pida
az devops login --organization https://dev.azure.com/<ORG>

# No interactiva (scripts, CI): variable de entorno
export AZURE_DEVOPS_EXT_PAT="$PAT"

Para la REST API el PAT va como basic auth con usuario vacío:

AUTH=$(printf ':%s' "$PAT" | base64 -w0)
curl -sS -H "Authorization: Basic $AUTH" \
  "https://dev.azure.com/$ORG/$PROJECT/_apis/git/repositories?api-version=7.1"

Si el PAT caduca o le falta un ámbito, Azure DevOps responde 200 con una página HTML de login, no un 401. Si jq se queja de que la entrada no es JSON, sospecha del token antes que de la URL.

Cuándo CLI y cuándo REST

az devops cubre lo habitual, pero no todo. Regla práctica:

  • CLI para listar, mostrar, crear y actualizar PRs y work items.
  • REST para lo que la CLI no expone: hilos de comentarios en PRs, iteraciones de equipo, estadísticas de rama, Analytics.

Comodín para cualquier endpoint sin montar curl a mano (reutiliza la sesión de az):

az devops invoke \
  --area git --resource pullRequestThreads \
  --route-parameters project=$PROJECT repositoryId=$REPO pullRequestId=$PR \
  --api-version 7.1 --http-method GET

Consultar el backlog con WIQL

WIQL es el SQL de los work items. Guárdalo en fichero: escapar comillas dentro de --wiql en PowerShell es una fuente inagotable de ratos perdidos.

SELECT [System.Id], [System.Title], [System.State], [System.AssignedTo]
FROM WorkItems
WHERE [System.TeamProject] = @project
  AND [System.WorkItemType] = 'Product Backlog Item'
  AND [System.State] NOT IN ('Done', 'Removed')
  AND [System.IterationPath] = @currentIteration
ORDER BY [Microsoft.VSTS.Common.BacklogPriority] ASC
az boards query --path ./consulta.wiql --output json

Macros que ahorran mantenimiento: @me, @project, @currentIteration, @today - 14.

WIQL devuelve solo IDs y los campos pedidos. Para el detalle completo, hidrata en lote (máximo 200 por llamada):

az boards work-item show --id 1234 --output json

Métricas y tendencias: OData Analytics

Burndown, velocidad o work items a lo largo del tiempo no salen de WIQL —WIQL es una foto del estado actual—, salen de Analytics:

https://analytics.dev.azure.com/<ORG>/<PROYECTO>/_odata/v4.0-preview/WorkItems
  ?$filter=State ne 'Removed' and Iteration/IterationPath eq '<ruta>'
  &$select=WorkItemId,Title,State,StoryPoints

Reglas de higiene

  • --output json siempre que el resultado se vaya a procesar; la tabla por defecto trunca columnas sin avisar.
  • Paginación: la REST API devuelve como mucho 100 elementos salvo que pidas más. Usa $top y $skip, o continuationToken donde exista, y no asumas que la primera página es todo.
  • Cachea en un fichero temporal lo que vayas a recorrer varias veces: una auditoría de 20 repos puede tumbarte contra el rate limit de la organización.
  • Los identificadores de repositorio son GUIDs; el nombre funciona en la CLI pero no siempre en las rutas REST. Resuelve el GUID una vez y reutilízalo.
  • Cualquier escritura (comentar, mover un PBI, cerrar una PR) se confirma con la persona antes de ejecutarse. Leer es gratis; escribir se ve.