Saltar al contenido
jesusprodriguez.com

azure-pipelines

Azure Pipelines: CI/CD en YAML

Pipelines YAML que no bloquean al equipo: un artefacto para todos los entornos, plantillas versionadas, secretos fuera del repo.

stack:
Azure DevOps
versión:
v1.0.0
actualizada:
tamaño:
4.1 KB
lectura:
2 min
licencia:
CC-BY-4.0

Cuándo se activa

Al crear o modificar azure-pipelines.yml, o cuando una build falla solo en el agente.

description: Escribe y depura pipelines YAML de Azure DevOps - etapas, plantillas reutilizables, caché, variable groups y despliegues con aprobación. Úsala al crear o modificar azure-pipelines.yml, al montar CI para un repo nuevo o cuando una build falle solo en el agente.

  • Stages y environments
  • Plantillas y caché
  • Secretos y aprobaciones
  • Depurar el agente

Cómo se le pide

> Revisa azure-pipelines.yml: la build pasa en local y falla solo en el agente.

Escríbeselo tal cual al agente: la skill se carga sola por la descripción, no hay que nombrarla.

Cómo se instala

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

La vía nativa, y la única que se actualiza sola: el marketplace se añade una vez y `/plugin marketplace update` trae las versiones nuevas. Las skills quedan con espacio de nombres propio (`azure-devops:azure-pr-review`).

El fichero, entero

Esto es exactamente lo que descargas: sin resúmenes ni recortes.

Azure Pipelines: CI/CD en YAML

Un pipeline es código de producción: se lee más veces de las que se escribe y cuando falla bloquea a todo el equipo.

Esqueleto

trigger:
  branches: { include: [main, release/*] }
  paths:    { exclude: [docs/*, README.md] }

pr:
  branches: { include: [main] }

variables:
  - group: comun-produccion          # variable group de Library
  - name: buildConfiguration
    value: Release

stages:
  - stage: Build
    jobs:
      - job: Compilar
        pool: { vmImage: ubuntu-latest }
        steps:
          - task: UseDotNet@2
            inputs: { version: '8.0.x' }
          - script: dotnet restore
          - script: dotnet build -c $(buildConfiguration) --no-restore
          - script: dotnet test -c $(buildConfiguration) --no-build --collect:"XPlat Code Coverage"
          - task: PublishTestResults@2
            condition: succeededOrFailed()      # los tests rojos también se publican

condition: succeededOrFailed() en la publicación de resultados: si solo publicas cuando todo va bien, el día que falla no tienes el informe que explica por qué.

Reglas que evitan la mayoría de los sustos

Fija las versiones. vmImage: ubuntu-latest cambia bajo tus pies; los SDK también. Fija la versión del SDK explícitamente y anota por qué si te quedas atrás.

Un artefacto, varios entornos. Se compila una vez y ese mismo artefacto se despliega a dev, pre y producción. Recompilar por entorno significa que lo que validaste no es lo que desplegaste.

Secretos, nunca en el YAML. Variable groups enlazados a Key Vault, o variables marcadas como secretas. Un secreto no se expone como variable de entorno a un script que no lo necesita, y no se imprime nunca (Azure enmascara ***, pero solo si lo reconoce literalmente: en base64 o troceado no lo enmascara).

Entornos con aprobación. Producción es un environment con approvals and checks, no un stage más:

  - stage: Produccion
    dependsOn: Preproduccion
    condition: succeeded()
    jobs:
      - deployment: Desplegar
        environment: produccion       # aquí cuelgan las aprobaciones
        strategy:
          runOnce:
            deploy:
              steps: [ ... ]

Plantillas contra el copiar-pegar. Cinco repos con el mismo YAML duplicado son cinco sitios donde arreglar el mismo fallo:

resources:
  repositories:
    - repository: plantillas
      type: git
      name: Plataforma/pipelines-comunes
      ref: refs/tags/v3            # etiqueta, no rama: una rama cambia sola

extends:
  template: dotnet-api.yml@plantillas
  parameters:
    proyecto: src/Api/Api.csproj

Caché de dependencias con clave que incluya el lockfile, o el caché servirá paquetes obsoletos:

  - task: Cache@2
    inputs:
      key: 'nuget | "$(Agent.OS)" | **/packages.lock.json'
      path: $(NUGET_PACKAGES)

Depurar una build que falla solo en el agente

Por probabilidad, de mayor a menor:

  1. Diferencia de entorno: versión de SDK, de Node, de imagen del agente.
  2. Rutas y mayúsculas: el agente Linux distingue mayúsculas; tu Windows no. Models/User.cs vs models/user.cs compila en local y falla ahí.
  3. Ficheros no versionados: funciona en local porque tienes un appsettings.Development.json que está en .gitignore.
  4. Orden y paralelismo: los tests pasan en tu máquina por el orden de ejecución y fallan al paralelizar. El bug es del test, no del agente.
  5. Restore parcial: fuentes de NuGet privadas sin autenticar en el agente.

Activa system.debug: true en las variables de la ejecución antes de empezar a adivinar. Y reproduce en un agente, no en tu portátil: cada iteración a ciegas cuesta una cola de build al equipo entero.