---
name: azure-devops-cli
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.
version: 1.0.0
license: CC-BY-4.0
updated: 2026-08-16
---

# 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

```bash
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:

```bash
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 repos | `Code (Read)` |
| Comentar en PRs | `Code (Read & Write)` |
| Leer backlog y sprints | `Work Items (Read)` |
| Crear o mover PBIs | `Work Items (Read & Write)` |
| Leer builds | `Build (Read)` |

Nunca en un fichero versionado. Dos formas:

```bash
# 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:

```bash
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`):

```bash
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.

```sql
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
```

```bash
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):

```bash
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.
