azure-devops

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Azure DevOps Pipelines

Azure DevOps Pipelines

Build, test, and deploy applications using Azure Pipelines with YAML or classic editor.
使用YAML或经典编辑器,通过Azure Pipelines构建、测试并部署应用程序。

When to Use This Skill

适用场景

Use this skill when:
  • Creating CI/CD pipelines in Azure DevOps
  • Configuring build and release stages
  • Managing Azure DevOps service connections
  • Deploying to Azure or other cloud platforms
  • Setting up multi-stage YAML pipelines
适用于以下场景:
  • 在Azure DevOps中创建CI/CD流水线
  • 配置构建与发布阶段
  • 管理Azure DevOps服务连接
  • 部署至Azure或其他云平台
  • 搭建多阶段YAML流水线

Prerequisites

前置条件

  • Azure DevOps organization and project
  • Service connections for target environments
  • Basic YAML understanding
  • Azure subscription (for Azure deployments)
  • Azure DevOps组织与项目
  • 目标环境的服务连接
  • 具备YAML基础知识
  • Azure订阅(用于Azure部署)

YAML Pipeline Structure

YAML流水线结构

Create
azure-pipelines.yml
in repository root:
yaml
trigger:
  branches:
    include:
      - main
      - develop
  paths:
    include:
      - src/*

pool:
  vmImage: 'ubuntu-latest'

variables:
  buildConfiguration: 'Release'
  nodeVersion: '20.x'

stages:
  - stage: Build
    jobs:
      - job: BuildJob
        steps:
          - task: NodeTool@0
            inputs:
              versionSpec: $(nodeVersion)
          - script: |
              npm ci
              npm run build
            displayName: 'Build application'
          - publish: $(Build.ArtifactStagingDirectory)
            artifact: drop

  - stage: Deploy
    dependsOn: Build
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: DeployWeb
        environment: 'production'
        strategy:
          runOnce:
            deploy:
              steps:
                - script: echo Deploying to production
在仓库根目录创建
azure-pipelines.yml
yaml
trigger:
  branches:
    include:
      - main
      - develop
  paths:
    include:
      - src/*

pool:
  vmImage: 'ubuntu-latest'

variables:
  buildConfiguration: 'Release'
  nodeVersion: '20.x'

stages:
  - stage: Build
    jobs:
      - job: BuildJob
        steps:
          - task: NodeTool@0
            inputs:
              versionSpec: $(nodeVersion)
          - script: |
              npm ci
              npm run build
            displayName: 'Build application'
          - publish: $(Build.ArtifactStagingDirectory)
            artifact: drop

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

Triggers

触发器

Branch Triggers

分支触发器

yaml
trigger:
  branches:
    include:
      - main
      - release/*
    exclude:
      - feature/*
  tags:
    include:
      - v*
yaml
trigger:
  branches:
    include:
      - main
      - release/*
    exclude:
      - feature/*
  tags:
    include:
      - v*

Pull Request Triggers

拉取请求触发器

yaml
pr:
  branches:
    include:
      - main
  paths:
    include:
      - src/*
    exclude:
      - docs/*
yaml
pr:
  branches:
    include:
      - main
  paths:
    include:
      - src/*
    exclude:
      - docs/*

Scheduled Triggers

定时触发器

yaml
schedules:
  - cron: '0 2 * * *'
    displayName: 'Nightly build'
    branches:
      include:
        - main
    always: true
yaml
schedules:
  - cron: '0 2 * * *'
    displayName: 'Nightly build'
    branches:
      include:
        - main
    always: true

Jobs and Stages

作业与阶段

Parallel Jobs

并行作业

yaml
stages:
  - stage: Test
    jobs:
      - job: UnitTests
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - script: npm run test:unit
      
      - job: IntegrationTests
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - script: npm run test:integration
yaml
stages:
  - stage: Test
    jobs:
      - job: UnitTests
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - script: npm run test:unit
      
      - job: IntegrationTests
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - script: npm run test:integration

Matrix Strategy

矩阵策略

yaml
jobs:
  - job: Build
    strategy:
      matrix:
        linux:
          vmImage: 'ubuntu-latest'
        windows:
          vmImage: 'windows-latest'
        mac:
          vmImage: 'macos-latest'
    pool:
      vmImage: $(vmImage)
    steps:
      - script: npm test
yaml
jobs:
  - job: Build
    strategy:
      matrix:
        linux:
          vmImage: 'ubuntu-latest'
        windows:
          vmImage: 'windows-latest'
        mac:
          vmImage: 'macos-latest'
    pool:
      vmImage: $(vmImage)
    steps:
      - script: npm test

Job Dependencies

作业依赖

yaml
stages:
  - stage: Build
    jobs:
      - job: A
        steps:
          - script: echo Job A
      - job: B
        dependsOn: A
        steps:
          - script: echo Job B
yaml
stages:
  - stage: Build
    jobs:
      - job: A
        steps:
          - script: echo Job A
      - job: B
        dependsOn: A
        steps:
          - script: echo Job B

Variables and Parameters

变量与参数

Variable Groups

变量组

yaml
variables:
  - group: 'production-secrets'
  - name: buildConfiguration
    value: 'Release'
yaml
variables:
  - group: 'production-secrets'
  - name: buildConfiguration
    value: 'Release'

Runtime Parameters

运行时参数

yaml
parameters:
  - name: environment
    displayName: 'Environment'
    type: string
    default: 'dev'
    values:
      - dev
      - staging
      - prod

stages:
  - stage: Deploy
    variables:
      env: ${{ parameters.environment }}
    jobs:
      - job: Deploy
        steps:
          - script: echo "Deploying to $(env)"
yaml
parameters:
  - name: environment
    displayName: 'Environment'
    type: string
    default: 'dev'
    values:
      - dev
      - staging
      - prod

stages:
  - stage: Deploy
    variables:
      env: ${{ parameters.environment }}
    jobs:
      - job: Deploy
        steps:
          - script: echo "Deploying to $(env)"

Secret Variables

机密变量

yaml
variables:
  - name: mySecret
    value: $(SECRET_FROM_PIPELINE)  # Set in pipeline settings

steps:
  - script: |
      echo "Using secret"
      ./deploy.sh
    env:
      API_KEY: $(mySecret)
yaml
variables:
  - name: mySecret
    value: $(SECRET_FROM_PIPELINE)  # Set in pipeline settings

steps:
  - script: |
      echo "Using secret"
      ./deploy.sh
    env:
      API_KEY: $(mySecret)

Templates

模板

Job Template

作业模板

yaml
undefined
yaml
undefined

templates/build-job.yml

templates/build-job.yml

parameters:
  • name: nodeVersion default: '20'
jobs:
  • job: Build steps:
    • task: NodeTool@0 inputs: versionSpec: ${{ parameters.nodeVersion }}
    • script: npm ci && npm run build
undefined
parameters:
  • name: nodeVersion default: '20'
jobs:
  • job: Build steps:
    • task: NodeTool@0 inputs: versionSpec: ${{ parameters.nodeVersion }}
    • script: npm ci && npm run build
undefined

Using Templates

使用模板

yaml
undefined
yaml
undefined

azure-pipelines.yml

azure-pipelines.yml

stages:
  • stage: Build jobs:
    • template: templates/build-job.yml parameters: nodeVersion: '20'
undefined
stages:
  • stage: Build jobs:
    • template: templates/build-job.yml parameters: nodeVersion: '20'
undefined

Stage Template

阶段模板

yaml
undefined
yaml
undefined

templates/deploy-stage.yml

templates/deploy-stage.yml

parameters:
  • name: environment type: string
  • name: serviceConnection type: string
stages:
  • stage: Deploy_${{ parameters.environment }} jobs:
    • deployment: Deploy environment: ${{ parameters.environment }} strategy: runOnce: deploy: steps: - task: AzureWebApp@1 inputs: azureSubscription: ${{ parameters.serviceConnection }} appName: 'myapp-${{ parameters.environment }}'
undefined
parameters:
  • name: environment type: string
  • name: serviceConnection type: string
stages:
  • stage: Deploy_${{ parameters.environment }} jobs:
    • deployment: Deploy environment: ${{ parameters.environment }} strategy: runOnce: deploy: steps: - task: AzureWebApp@1 inputs: azureSubscription: ${{ parameters.serviceConnection }} appName: 'myapp-${{ parameters.environment }}'
undefined

Deployments

部署

Environment Deployments

环境部署

yaml
stages:
  - stage: DeployStaging
    jobs:
      - deployment: DeployWeb
        environment: 'staging'
        strategy:
          runOnce:
            deploy:
              steps:
                - download: current
                  artifact: drop
                - script: ./deploy.sh staging
yaml
stages:
  - stage: DeployStaging
    jobs:
      - deployment: DeployWeb
        environment: 'staging'
        strategy:
          runOnce:
            deploy:
              steps:
                - download: current
                  artifact: drop
                - script: ./deploy.sh staging

Approval Gates

审批网关

Configure in Azure DevOps UI:
  1. Go to Environments
  2. Select environment
  3. Add approval check
  4. Configure approvers
在Azure DevOps UI中配置:
  1. 进入环境页面
  2. 选择目标环境
  3. 添加审批检查
  4. 配置审批人

Rolling Deployment

滚动部署

yaml
jobs:
  - deployment: Deploy
    environment: 'production'
    strategy:
      rolling:
        maxParallel: 2
        deploy:
          steps:
            - script: ./deploy.sh
yaml
jobs:
  - deployment: Deploy
    environment: 'production'
    strategy:
      rolling:
        maxParallel: 2
        deploy:
          steps:
            - script: ./deploy.sh

Azure Service Tasks

Azure服务任务

Azure Web App Deployment

Azure Web App部署

yaml
- task: AzureWebApp@1
  inputs:
    azureSubscription: 'my-azure-connection'
    appType: 'webAppLinux'
    appName: 'my-web-app'
    package: '$(Pipeline.Workspace)/drop/*.zip'
yaml
- task: AzureWebApp@1
  inputs:
    azureSubscription: 'my-azure-connection'
    appType: 'webAppLinux'
    appName: 'my-web-app'
    package: '$(Pipeline.Workspace)/drop/*.zip'

Azure Container Apps

Azure容器应用

yaml
- task: AzureContainerApps@1
  inputs:
    azureSubscription: 'my-azure-connection'
    containerAppName: 'my-container-app'
    resourceGroup: 'my-rg'
    imageToDeploy: 'myregistry.azurecr.io/myapp:$(Build.BuildId)'
yaml
- task: AzureContainerApps@1
  inputs:
    azureSubscription: 'my-azure-connection'
    containerAppName: 'my-container-app'
    resourceGroup: 'my-rg'
    imageToDeploy: 'myregistry.azurecr.io/myapp:$(Build.BuildId)'

Azure Kubernetes Service

Azure Kubernetes服务

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

Docker Builds

Docker构建

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

Self-Hosted Agents

自托管代理

Install Agent

安装代理

bash
undefined
bash
undefined

Download agent

Download agent

mkdir myagent && cd myagent curl -o vsts-agent.tar.gz https://vstsagentpackage.azureedge.net/agent/3.227.2/vsts-agent-linux-x64-3.227.2.tar.gz tar zxvf vsts-agent.tar.gz
mkdir myagent && cd myagent curl -o vsts-agent.tar.gz https://vstsagentpackage.azureedge.net/agent/3.227.2/vsts-agent-linux-x64-3.227.2.tar.gz tar zxvf vsts-agent.tar.gz

Configure

Configure

./config.sh --url https://dev.azure.com/myorg --auth pat --token PAT_TOKEN --pool default
./config.sh --url https://dev.azure.com/myorg --auth pat --token PAT_TOKEN --pool default

Run as service

Run as service

sudo ./svc.sh install sudo ./svc.sh start
undefined
sudo ./svc.sh install sudo ./svc.sh start
undefined

Use Self-Hosted Pool

使用自托管代理池

yaml
pool:
  name: 'my-self-hosted-pool'
  demands:
    - docker
    - Agent.OS -equals Linux
yaml
pool:
  name: 'my-self-hosted-pool'
  demands:
    - docker
    - Agent.OS -equals Linux

Common Issues

常见问题

Issue: Service Connection Fails

问题:服务连接失败

Problem: Cannot authenticate to Azure Solution: Verify service principal permissions, check connection in project settings
现象:无法认证到Azure 解决方案:验证服务主体权限,检查项目设置中的连接配置

Issue: Artifact Not Found

问题:工件未找到

Problem: Download artifact fails Solution: Ensure publish task ran successfully, check artifact name matches
现象:下载工件失败 解决方案:确保发布任务已成功执行,检查工件名称是否匹配

Issue: Environment Not Found

问题:环境未找到

Problem: Deployment to environment fails Solution: Create environment in Pipelines > Environments first
现象:部署至环境失败 解决方案:先在流水线>环境中创建目标环境

Best Practices

最佳实践

  • Use YAML pipelines over classic editor
  • Implement templates for reusable components
  • Use variable groups for shared configuration
  • Configure environment approvals for production
  • Use service connections with minimal permissions
  • Implement artifact versioning
  • Cache dependencies for faster builds
  • 优先使用YAML流水线而非经典编辑器
  • 实现模板以复用组件
  • 使用变量组管理共享配置
  • 为生产环境配置环境审批
  • 使用权限最小化的服务连接
  • 实现工件版本控制
  • 缓存依赖以加快构建速度

Related Skills

相关技能

  • github-actions - GitHub CI/CD alternative
  • terraform-azure - Azure IaC
  • azure-aks - AKS deployments
  • github-actions - GitHub CI/CD替代方案
  • terraform-azure - Azure基础设施即代码
  • azure-aks - AKS部署