💻 Développement

dev-azure-devops-pipeline-advisor

Conception de pipelines CI/CD avec Azure DevOps (YAML pipelines, stages, templates, déploiement multi-environnement).

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-azure-devops-pipeline-advisor --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-azure-devops-pipeline-advisor -Launch"

🚀 Déjà installé ?

claude "/dev-azure-devops-pipeline-advisor"

Ou tapez /dev-azure-devops-pipeline-advisor dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

azure devopspipeline YAMLazure pipelineCI/CD azurerelease pipelineazure artifacts

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-azure-devops-pipeline-advisor ~/.claude/skills/

Payload du plugin : skills/dev-azure-devops-pipeline-advisor · source éditable : dev-skills/azure-devops-pipeline-advisor

📖 Manuel

Conseiller Azure DevOps Pipelines

Workflow en étapes

  1. Qualifier le besoin — CI seul, CD seul, CI/CD complet ? Mono-repo ou multi-repo ? Type d'artefact (binaire, image Docker, package NuGet/npm) ? Environnements cibles (dev / staging / prod) ?
  2. Choisir la stratégie de déclenchementtrigger pour push/merge, pr pour pull request, schedules pour planifié, resources.pipelines pour pipeline-en-aval.
  3. Concevoir le graphe stages → jobs → steps — Identifier les parallélisations possibles, les dépendances (dependsOn), les conditions de déploiement.
  4. Extraire les templates — Tout bloc dupliqué entre stages/pipelines devient un template YAML paramétré.
  5. Sécuriser — Variable Groups liés à Key Vault, Service Connections à droits minimaux, Approvals sur les environments prod.
  6. Valider et optimiser — Activer le cache, mesurer la durée de chaque job, ajouter un health check post-déploiement.

Critères de décision clés

SituationRecommandation
Déploiement prod nécessite une validation humaineenvironment avec Approvals dans Azure DevOps UI
Build identique sur plusieurs environnementsTemplate de job paramétré (templates/build.yml)
Secrets (connexion DB, API key)Variable Group lié à Azure Key Vault
Temps de build > 5 min à cause des dépendancesCache@2 sur dossier NuGet/npm
Multi-repo (code + infra séparés)resources.repositories + checkout multiple
Déploiement par rolling / blue-greenStrategy rolling ou canary dans le job deployment

Structure de référence CI/CD complète

# azure-pipelines.yml
trigger:
  branches:
    include: [main, release/*]
  paths:
    exclude: [docs/*, '*.md']

pr:
  branches:
    include: [main]

pool:
  vmImage: ubuntu-latest

variables:
  - group: common-vars          # Variable Group partagé
  - name: buildConfiguration
    value: Release
  - name: dotnetVersion
    value: '8.0.x'

stages:
  - stage: Build
    displayName: Build & Test
    jobs:
      - job: BuildJob
        steps:
          - task: Cache@2
            inputs:
              key: 'nuget | "$(Agent.OS)" | **/packages.lock.json'
              restoreKeys: 'nuget | "$(Agent.OS)"'
              path: $(NUGET_PACKAGES)
            displayName: Cache NuGet

          - task: UseDotNet@2
            inputs:
              version: $(dotnetVersion)

          - script: dotnet restore --locked-mode
            displayName: Restore (locked)

          - script: dotnet build -c $(buildConfiguration) --no-restore
            displayName: Build

          - script: |
              dotnet test -c $(buildConfiguration) --no-build \
                --collect:"XPlat Code Coverage" \
                --results-directory $(Agent.TempDirectory)/TestResults
            displayName: Tests

          - task: PublishCodeCoverageResults@2
            inputs:
              summaryFileLocation: '$(Agent.TempDirectory)/TestResults/**/coverage.cobertura.xml'

          - task: PublishBuildArtifacts@1
            inputs:
              PathtoPublish: '$(Build.ArtifactStagingDirectory)'
              ArtifactName: drop

  - stage: DeployDev
    displayName: Deploy → Dev
    dependsOn: Build
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: DeployDev
        environment: dev
        strategy:
          runOnce:
            deploy:
              steps:
                - template: templates/deploy-steps.yml
                  parameters:
                    environment: dev

  - stage: DeployStaging
    displayName: Deploy → Staging
    dependsOn: DeployDev
    jobs:
      - deployment: DeployStaging
        environment: staging          # Approval configuré dans l'UI
        strategy:
          runOnce:
            deploy:
              steps:
                - template: templates/deploy-steps.yml
                  parameters:
                    environment: staging

  - stage: DeployProd
    displayName: Deploy → Production
    dependsOn: DeployStaging
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))
    jobs:
      - deployment: DeployProd
        environment: production       # Approval obligatoire
        strategy:
          runOnce:
            deploy:
              steps:
                - template: templates/deploy-steps.yml
                  parameters:
                    environment: production

Templates réutilisables

templates/deploy-steps.yml

parameters:
  - name: environment
    type: string

steps:
  - download: current
    artifact: drop

  - task: AzureWebApp@1
    inputs:
      azureSubscription: 'sc-myapp-${{ parameters.environment }}'
      appName: 'myapp-${{ parameters.environment }}'
      package: '$(Pipeline.Workspace)/drop/**/*.zip'
      deploymentMethod: zipDeploy

  - script: |
      for i in 1 2 3; do
        curl -sf https://myapp-${{ parameters.environment }}.azurewebsites.net/health && break
        echo "Retry $i..." && sleep 10
      done
    displayName: Health check (${{ parameters.environment }})

templates/dotnet-build-job.yml

parameters:
  - name: projects
    type: string
    default: '**/*.csproj'
  - name: testProjects
    type: string
    default: '**/*Tests.csproj'
  - name: dotnetVersion
    type: string
    default: '8.0.x'

jobs:
  - job: Build
    steps:
      - task: UseDotNet@2
        inputs:
          version: ${{ parameters.dotnetVersion }}
      - script: dotnet restore ${{ parameters.projects }} --locked-mode
      - script: dotnet build ${{ parameters.projects }} -c Release --no-restore
      - script: dotnet test ${{ parameters.testProjects }} -c Release --no-build

Cache des dépendances (gains typiques : 40–70 %)

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

# npm
- task: Cache@2
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    restoreKeys: 'npm | "$(Agent.OS)"'
    path: $(npm_config_cache)

Sécurité


Garde-fous / Anti-patterns

Anti-patternProblèmeCorrection
Secrets en clair dans le YAMLExposé dans l'historique GitVariable Group lié à Key Vault
Un seul stage "Build+Deploy"Pas de séparation CI/CD, rollback impossibleStages distincts avec artifacts
condition: always() sur le deployDéploie même si le build échoueUtiliser succeeded() explicitement
pool: vmImage: windows-latest pour toutLent et coûteux pour du LinuxChoisir l'OS en fonction de la cible
Pas de --locked-mode sur dotnet restoreVersions de packages non reproductiblesCommitter packages.lock.json et ajouter le flag
Jobs séquentiels par défautDurée inutilement longueIdentifier les jobs parallélisables via dependsOn: []
Template avec logique métier hardcodéeNon réutilisableParamétrer systématiquement (parameters)
Déployer sur prod sans health checkRégression silencieuseHealth check avec retry dans le template de déploiement

Bonnes pratiques 2026

```yaml strategy: matrix: dotnet8: dotnetVersion: '8.0.x' dotnet9: dotnetVersion: '9.0.x' ```

```yaml variables:

```