教程:使用 Azure DevOps 创建多阶段管道

Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022

使用 Azure DevOps 多阶段管道将 CI/CD 进程划分为表示开发周期的不同部分的阶段。 多阶段管道可以更深入地了解部署过程,并更轻松地集成 审批和检查

在本文中,你将创建两个应用服务实例,并生成包含三个阶段的 YAML 管道:

在实际场景中,根据您的 DevOps 流程,可能还会有另一个用于部署到生产环境的阶段。

本练习中的示例代码是一项模拟太空游戏的 .NET Web 应用程序,其中包含用于显示高分的排行榜。 你将部署到适用于 Linux 的 Azure Web 应用的开发和过渡实例。

先决条件

产品 要求
Azure DevOps - Azure DevOps 组织和项目。 免费创建一个
- 权限:
    - 若要授予对项目中所有管道的访问权限:必须是 项目管理员组的成员。
    - 若要创建服务连接:必须具有服务连接的管理员创建者角色。
- 能够在Microsoft托管代理上运行管道。 启用免费层,或购买 并行作业
GitHub - GitHub 帐户。

为项目创建分支

在 GitHub 上创建以下示例存储库分支。

https://github.com/MicrosoftDocs/mslearn-tailspin-spacegame-web-deploy

创建 App Service 实例

在部署管道之前,需要先创建要部署到的应用服务实例。 你将使用 Azure CLI 创建实例。

  1. 登录到 Azure 门户

  2. 从菜单中选择 Cloud ShellBash 体验。

  3. 生成一个使 Web 应用域名唯一的随机数。 具有唯一值的优点是应用服务实例不会与要完成本教程的其他学习者发生名称冲突。

    webappsuffix=$RANDOM    
    
  4. 打开命令提示符,并使用az group create命令创建名为tailspin-space-game-rg的资源组,其中包含你的所有应用服务实例。 将 location 的值更新为离您最近的区域。

    az group create --location eastus --name tailspin-space-game-rg
    
  5. 使用命令提示符创建应用服务计划。

    az appservice plan create \
      --name tailspin-space-game-asp \
      --resource-group tailspin-space-game-rg \
      --sku B1 \
      --is-linux
    
  6. 在命令提示符下,使用az webapp create命令创建两个应用服务实例,每个实例(开发和过渡)各一个。

    az webapp create \
      --name tailspin-space-game-web-dev-$webappsuffix \
      --resource-group tailspin-space-game-rg \
      --plan tailspin-space-game-asp \
      --runtime "DOTNET|8.0"
    
    az webapp create \
      --name tailspin-space-game-web-staging-$webappsuffix \
      --resource-group tailspin-space-game-rg \
      --plan tailspin-space-game-asp \
      --runtime "DOTNET|8.0"
    
  7. 使用命令提示符,通过az webapp list命令列出两个应用服务实例,验证它们是否正在运行。

    az webapp list \
      --resource-group tailspin-space-game-rg \
      --query "[].{hostName: defaultHostName, state: state}" \
      --output table
    
  8. 复制应用服务实例的名称,用作下一部分中的变量。

创建 Azure DevOps 项目和变量

设置 Azure DevOps 项目和生成管道。 你还将为开发和过渡实例添加变量。

你的构建流水线:

  • 包含一个触发器,该触发器在分支代码发生更改时运行
  • 定义两个变量,buildConfigurationreleaseBranchName
  • 包含一个名为 Build 的阶段,该阶段生成 Web 应用程序
  • 发布稍后阶段要使用的项目

添加构建阶段

  1. 在 Azure DevOps 项目中,从左侧导航菜单中选择 “管道 ”。

  2. 如果此管道是项目中的第一个管道,请选择“ 新建管道 ”或 “创建管道 ”。

  3. “您的代码在哪里” 屏幕中,选择 GitHub

  4. 可能会重定向到 GitHub 进行登录。 如果是这样,请输入 GitHub 凭据。

  5. “选择存储库 ”屏幕上,选择 .NET 应用位于的存储库。

  6. 你可能会被重定向到 GitHub 来安装 Azure Pipelines 应用。 如果是,请选择批准并安装

  1. 出现配置选项卡时,选择初学者管道

  2. 用以下代码替换 azure-pipelines.yml 的内容。

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
      releaseBranchName: 'release'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-22.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '8.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
  3. 准备就绪后,选择保存并运行

添加实例变量

  1. 在 Azure DevOps 中,转到管道>

  2. 选择 + Variable group

  3. 属性下,为变量组名称添加 Release

  4. 创建两个变量,用于表示开发环境和预发布环境的主机名。 将1234变量替换为实例的正确值。

    变量名称 示例值
    WebAppNameDev tailspin-space-game-web-dev-1234
    WebAppName预发布 tailspin-space-game-web-test-1234
  5. 选择保存以保存变量。

添加“开发”阶段

接下来,你将更新流水线,将构建提升至 Dev 阶段。

  1. 在 Azure Pipelines 中,转到管道>管道

  2. 在上下文菜单中选择编辑以编辑管道。

    选择“编辑”菜单项的屏幕截图。

  3. 更新 azure-pipelines.yml 以包含 Dev 阶段。 在 Dev 阶段,管道将执行以下操作:

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
      releaseBranchName: 'release'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-22.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '8.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
    - stage: 'Dev'
      displayName: 'Deploy to the dev environment'
      dependsOn: Build
      condition:  succeeded()
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-22.04'
        environment: dev
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: dev website'
                inputs:
                  azureSubscription: 'your-subscription'
                  appType: 'webAppLinux'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
  4. AzureWebApp@1 任务更改为使用订阅。

    1. 为任务选择设置

      YAML 编辑器任务中的“设置”选项的屏幕截图。

    2. your-subscription更新 Azure 订阅的值以使用你自己的订阅。 在此过程中,可能需要授予访问权限。 如果在 YAML 编辑器中授权资源时遇到问题,另一种方法是创建服务连接

      “Azure 订阅”菜单项的屏幕截图。

    3. 在 Linux 上,将应用类型设置为“Web 应用”。

    4. 选择添加以更新任务。

  5. 保存并运行您的流水线。

添加“过渡”阶段

最后,你将把 Dev 阶段提升到 Staging 阶段。 与 Dev 环境不同,在预发布环境中,你需要进行更多控制,因此需要添加手动审批。

创建过渡环境

  1. 在 Azure Pipelines 中,选择 Environments

  2. 选择“新建环境”。

  3. 创建名为 staging资源设置为的新环境。

  4. 在暂存环境页面上,选择审批和检查

    “审批和检查”菜单选项的屏幕截图。

  5. 选择审批

  6. 审批者下,选择添加用户和组,然后选择你的帐户。

  7. 审批者说明下,写下在准备好进行过渡时批准此更改

  8. 选择保存

向流水线添加新阶段

你将向管道中添加一个包含手动审批的新阶段 Staging

  1. 编辑管道文件并添加 Staging 部分。

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
      releaseBranchName: 'release'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-22.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '8.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
    - stage: 'Dev'
      displayName: 'Deploy to the dev environment'
      dependsOn: Build
      condition:  succeeded()
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-22.04'
        environment: dev
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: dev website'
                inputs:
                  azureSubscription: 'your-subscription'
                  appType: 'webAppLinux'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Staging'
      displayName: 'Deploy to the staging environment'
      dependsOn: Dev
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-22.04'
        environment: staging
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: staging website'
                inputs:
                  azureSubscription: 'your-subscription'
                  appType: 'webAppLinux'
                  appName: '$(WebAppNameStaging)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
  2. 将 Staging 阶段中的 AzureWebApp@1 任务更改为使用订阅。

    1. 为任务选择设置

      YAML 编辑器任务中的“设置”选项的屏幕截图。

    2. your-subscription更新 Azure 订阅的值以使用你自己的订阅。 在此过程中,可能需要授予访问权限。

      “Azure 订阅”菜单项的屏幕截图。

    3. 在 Linux 上,将应用类型设置为“Web 应用”。

    4. 选择添加以更新任务。

  3. 转到管道运行。 管道运行时观察 Build 阶段的变化情况。 当它到达 Staging 时,管道将等待手动发布审批。 你还会收到一封电子邮件,指出你有一个等待审批的管道。

    等待管道审批的屏幕截图。

  4. 查看审批内容,并允许管道运行。

    手动验证检查的屏幕截图。

清理资源

如果不打算继续使用此应用程序,请通过以下步骤删除 Azure 门户中的资源组和 Azure DevOps 中的项目:

若要清理资源组:

  1. 转到 Azure 门户并登录。

  2. 从菜单栏中选择 Cloud Shell。 出现提示时,选择 Bash 体验。

    显示选择 Cloud Shell 菜单项的 Azure 门户屏幕截图。

  3. 运行以下 az group delete 命令,以删除所使用的资源组 tailspin-space-game-rg

    az group delete --name tailspin-space-game-rg
    

若要删除 Azure DevOps 项目(包括生成管道),请参阅删除项目