返回 Skill 列表
extension
分类: 开发与工程无需 API Key

azure-devops-pipelines

构建Azure DevOps YAML流水线以支持CI/CD,管理发布、制品和部署环境。创建构建和发布流水线,配置触发器、模板,并与Azure服务集成。在Azure DevOps中自动化构建、测试和部署时使用。(项目)

person作者: jakexiaohubgithub

Azure DevOps Pipelines

Expert guidance for Azure DevOps CI/CD pipeline configuration.

When to Use This Skill

  • Creating YAML-based build pipelines
  • Setting up multi-stage deployments
  • Configuring pipeline triggers and schedules
  • Creating reusable pipeline templates
  • Managing artifacts and releases
  • Integrating with Azure services
  • Setting up deployment environments

Basic Pipeline Structure

# azure-pipelines.yml
trigger:
  branches:
    include:
      - main
      - develop
  paths:
    exclude:
      - docs/*
      - README.md

pr:
  branches:
    include:
      - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  - name: buildConfiguration
    value: 'Release'
  - group: my-variable-group

stages:
  - stage: Build
    displayName: 'Build Stage'
    jobs:
      - job: BuildJob
        steps:
          - task: DotNetCoreCLI@2
            inputs:
              command: 'build'
              projects: '**/*.csproj'
              arguments: '--configuration $(buildConfiguration)'

  - stage: Test
    displayName: 'Test Stage'
    dependsOn: Build
    jobs:
      - job: TestJob
        steps:
          - task: DotNetCoreCLI@2
            inputs:
              command: 'test'
              projects: '**/*Tests.csproj'

  - stage: Deploy
    displayName: 'Deploy Stage'
    dependsOn: Test
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: DeployJob
        environment: 'production'
        strategy:
          runOnce:
            deploy:
              steps:
                - script: echo 'Deploying...'

Triggers

# Branch triggers
trigger:
  branches:
    include:
      - main
      - release/*
    exclude:
      - feature/*

# Path filters
trigger:
  paths:
    include:
      - src/*
    exclude:
      - src/tests/*

# Tag triggers
trigger:
  tags:
    include:
      - v*

# Scheduled triggers
schedules:
  - cron: '0 0 * * *'
    displayName: 'Nightly build'
    branches:
      include:
        - main
    always: true

# PR triggers
pr:
  branches:
    include:
      - main
  paths:
    include:
      - src/*
  drafts: false

Variables

# Inline variables
variables:
  buildConfiguration: 'Release'
  dotnet
# Variable groups (from Library)
variables:
  - group: my-secrets
  - group: my-config

# Template variables
variables:
  - template: variables/common.yml
  - name: environment
    value: 'production'

# Conditional variables
variables:
  ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
    environment: 'production'
  ${{ else }}:
    environment: 'staging'

# Runtime expressions
variables:
  - name: fullPath
    value: $(Build.SourcesDirectory)/$(projectName)

Jobs and Steps

jobs:
  - job: Build
    displayName: 'Build Application'
    timeoutInMinutes: 60
    pool:
      vmImage: 'ubuntu-latest'

    steps:
      # Checkout
      - checkout: self
        clean: true
        fetchDepth: 0

      # Script tasks
      - script: |
          echo "Building..."
          npm install
          npm run build
        displayName: 'Build with npm'

      # PowerShell
      - powershell: |
          Write-Host "Running PowerShell"
        displayName: 'PowerShell script'

      # Bash
      - bash: |
          echo "Running Bash"
        displayName: 'Bash script'

      # Task shorthand
      - task: UseDotNet@2
        inputs:
          
      # Download artifact
      - download: current
        artifact: drop

      # Publish artifact
      - publish: $(Build.ArtifactStagingDirectory)
        artifact: drop

Multi-Stage Pipeline

stages:
  - stage: Build
    jobs:
      - job: BuildJob
        steps:
          - task: DotNetCoreCLI@2
            inputs:
              command: 'publish'
              publishWebProjects: true
              arguments: '--configuration Release --output $(Build.ArtifactStagingDirectory)'

          - publish: $(Build.ArtifactStagingDirectory)
            artifact: webapp

  - stage: DeployDev
    displayName: 'Deploy to Dev'
    dependsOn: Build
    jobs:
      - deployment: DeployDev
        environment: 'dev'
        strategy:
          runOnce:
            deploy:
              steps:
                - download: current
                  artifact: webapp
                - task: AzureWebApp@1
                  inputs:
                    azureSubscription: 'Azure-Connection'
                    appName: 'myapp-dev'
                    package: '$(Pipeline.Workspace)/webapp/**/*.zip'

  - stage: DeployProd
    displayName: 'Deploy to Production'
    dependsOn: DeployDev
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: DeployProd
        environment: 'production'
        strategy:
          runOnce:
            deploy:
              steps:
                - download: current
                  artifact: webapp
                - task: AzureWebApp@1
                  inputs:
                    azureSubscription: 'Azure-Connection'
                    appName: 'myapp-prod'
                    package: '$(Pipeline.Workspace)/webapp/**/*.zip'

Templates

Step Template

# templates/build-steps.yml
parameters:
  - name: buildConfiguration
    type: string
    default: 'Release'
  - name: projects
    type: string

steps:
  - task: DotNetCoreCLI@2
    displayName: 'Restore packages'
    inputs:
      command: 'restore'
      projects: ${{ parameters.projects }}

  - task: DotNetCoreCLI@2
    displayName: 'Build'
    inputs:
      command: 'build'
      projects: ${{ parameters.projects }}
      arguments: '--configuration ${{ parameters.buildConfiguration }}'

Job Template

# templates/build-job.yml
parameters:
  - name: name
    type: string
  - name: pool
    type: object
    default:
      vmImage: 'ubuntu-latest'

jobs:
  - job: ${{ parameters.name }}
    pool: ${{ parameters.pool }}
    steps:
      - template: build-steps.yml
        parameters:
          buildConfiguration: 'Release'
          projects: '**/*.csproj'

Stage Template

# templates/deploy-stage.yml
parameters:
  - name: environment
    type: string
  - name: azureSubscription
    type: string
  - name: appName
    type: string

stages:
  - stage: Deploy_${{ parameters.environment }}
    displayName: 'Deploy to ${{ parameters.environment }}'
    jobs:
      - deployment: Deploy
        environment: ${{ parameters.environment }}
        strategy:
          runOnce:
            deploy:
              steps:
                - task: AzureWebApp@1
                  inputs:
                    azureSubscription: ${{ parameters.azureSubscription }}
                    appName: ${{ parameters.appName }}
                    package: '$(Pipeline.Workspace)/**/*.zip'

Using Templates

# azure-pipelines.yml
trigger:
  - main

stages:
  - stage: Build
    jobs:
      - template: templates/build-job.yml
        parameters:
          name: BuildApp

  - template: templates/deploy-stage.yml
    parameters:
      environment: 'dev'
      azureSubscription: 'Azure-Dev'
      appName: 'myapp-dev'

  - template: templates/deploy-stage.yml
    parameters:
      environment: 'prod'
      azureSubscription: 'Azure-Prod'
      appName: 'myapp-prod'

Common Tasks

Docker

- task: Docker@2
  inputs:
    containerRegistry: 'myacr'
    repository: 'myapp'
    command: 'buildAndPush'
    Dockerfile: '**/Dockerfile'
    tags: |
      $(Build.BuildId)
      latest

Kubernetes

- task: KubernetesManifest@0
  inputs:
    action: 'deploy'
    kubernetesServiceConnection: 'aks-connection'
    namespace: 'default'
    manifests: |
      manifests/deployment.yml
      manifests/service.yml
    containers: |
      myacr.azurecr.io/myapp:$(Build.BuildId)

Terraform

- task: TerraformInstaller@0
  inputs:
    terraform
- task: TerraformTaskV4@4
  inputs:
    provider: 'azurerm'
    command: 'init'
    workingDirectory: '$(System.DefaultWorkingDirectory)/terraform'
    backendServiceArm: 'Azure-Connection'
    backendAzureRmResourceGroupName: 'tfstate-rg'
    backendAzureRmStorageAccountName: 'tfstatestorage'
    backendAzureRmContainerName: 'tfstate'
    backendAzureRmKey: 'terraform.tfstate'

- task: TerraformTaskV4@4
  inputs:
    provider: 'azurerm'
    command: 'apply'
    workingDirectory: '$(System.DefaultWorkingDirectory)/terraform'
    environmentServiceNameAzureRM: 'Azure-Connection'

Testing

- task: DotNetCoreCLI@2
  inputs:
    command: 'test'
    projects: '**/*Tests.csproj'
    arguments: '--configuration $(buildConfiguration) --collect:"XPlat Code Coverage"'

- task: PublishCodeCoverageResults@1
  inputs:
    codeCoverageTool: 'Cobertura'
    summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'

Environments and Approvals

# Environment with approvals (configure in Azure DevOps UI)
jobs:
  - deployment: DeployProd
    environment: 'production'  # Requires approval
    strategy:
      runOnce:
        deploy:
          steps:
            - script: echo 'Deploying to production'

# Deployment strategies
strategy:
  canary:
    increments: [10, 20, 50, 100]
    deploy:
      steps:
        - script: echo 'Canary deployment'

strategy:
  rolling:
    maxParallel: 2
    deploy:
      steps:
        - script: echo 'Rolling deployment'

Best Practices

  1. Use Templates for reusable pipeline components
  2. Separate Stages for build, test, and deploy
  3. Use Variable Groups for secrets and shared config
  4. Enable Branch Policies for PR validation
  5. Use Environments with approval gates
  6. Cache Dependencies to speed up builds
  7. Use Service Connections for Azure resources
  8. Pin Task Versions to avoid breaking changes