练习 - 使用模板生成多个配置

已完成

你在上一个练习中实现了生成 Space Game 网站的管道。 你首先使用一个脚本执行各项生成操作,再将各项操作映射到相应的管道任务。 管道的输出是包含已编译的 Web 应用的一个 .zip 文件

在本练习中,你将使用模板定义可生成项目文件中定义的任何配置的生成任务。 使用模板,定义一次逻辑即可供多次重用。 模板将多个 YAML 文件的内容合并到一个管道中。

提示

模块中的此步骤是可选的。 如果目前不想了解模板,请继续执行下一步:清理 Azure DevOps 环境。 有关模板的详细信息,请参阅模板类型和用法

我们先来看看 Mara 和 Amita。

演示

Mara 非常高兴地共享她的结果,找到 Amita 向她展示生成管道。

Amita:你这么快就做好了,真是了不起! 其实我正打算去找你,因为我收到了一封电子邮件,告诉我生成已就绪。 谢谢! 但我发现管道只生成了“发布”配置。 我们还使用“调试”生成,以便在应用崩溃时捕获额外的信息。 可以添加这一个生成吗?

Mara:当然可以。 设置时,我忘了考虑“调试”生成。 我们一起来添加,可以吗?

Amita:你向我展示了定义生成步骤的 YAML 文件,但我不确定我是否知道如何对其进行修改。

Mara:没关系。 你可以在我键入的时候看着。 我们可以一起思考。

如何定义这两种生成配置?

请考虑以下任务,它们生成和发布 Space Game Web 项目的“发布”配置。 (不要将此代码添加到 azure-pipelines.yml 文件中。)

- task: DotNetCoreCLI@2
  displayName: 'Build the project - Release'
  inputs:
    command: 'build'
    arguments: '--no-restore --configuration Release'
    projects: '**/*.csproj'

- task: DotNetCoreCLI@2
  displayName: 'Publish the project - Release'
  inputs:
    command: 'publish'
    projects: '**/*.csproj'
    publishWebProjects: false
    arguments: '--no-build --configuration Release --output $(Build.ArtifactStagingDirectory)/Release'
    zipAfterPublish: true

要生成“调试”配置,可重复执行这两项任务,但需要将 Release 替换为 Debug

这样就能得到期望获得的结果,但是当生成变得更复杂或要求发生变化时会出现什么情况? 你需要手动定位和更改每个生成任务的两个变体。 添加额外的生成要求后,还需要创建两个任务,分别用于“调试”和“发布”这两个配置,以满足相应的要求。

更好的解决方案是使用模板。

什么是模板?

使用模板,定义一次常见的生成任务,即可多次重用这些任务。

从父管道调用模板,作为一个生成步骤。 可以将参数从父管道传递到模板中。

Mara 可定义将应用作为模板生成和发布的任务,再将该模板应用于她需要的每项配置。

定义模板

请记住,使用模板定义一次常见的生成任务,即可多次重用这些任务。 从父模板中调用模板作为一个生成步骤,并将参数从父管道传递到模板中。

你现在将创建一个模板,它可以生成项目文件中定义的任何配置。

  1. 从 Visual Studio Code 的集成控制台,在项目的根目录中创建“模板”目录。

    mkdir templates
    

    实际操作时,可以将模板文件放在任何位置。 无需将其放置在“模板”目录中。

  2. 在 Visual Studio Code 中,选择“文件”>“新建文件”。 接下来,选择“文件”>“保存”,在项目的“模板”目录中将空白文件保存为 build.yml。 例如 ~/mslearn-tailspin-spacegame-web/templates。

    重要

    如前所述,在 Windows 中,在“另存为类型”列表中选择“YAML”。

  3. 在 Visual Studio Code 中,将以下代码添加到 build.yml:

    parameters:
      buildConfiguration: 'Release'
    
    steps:
    - task: DotNetCoreCLI@2
      displayName: 'Build the project - ${{ parameters.buildConfiguration }}'
      inputs:
        command: 'build'
        arguments: '--no-restore --configuration ${{ parameters.buildConfiguration }}'
        projects: '**/*.csproj'
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish the project - ${{ parameters.buildConfiguration }}'
      inputs:
        command: 'publish'
        projects: '**/*.csproj'
        publishWebProjects: false
        arguments: '--no-build --configuration ${{ parameters.buildConfiguration }} --output $(Build.ArtifactStagingDirectory)/${{ parameters.buildConfiguration }}'
        zipAfterPublish: true
    

    这些任务看起来像你之前定义的构建和发布应用程序的任务;但在模板中,处理输入参数的方式与处理普通变量不同。 有两个区别:

    • 在模板文件中,使用 parameters 部分(而不是 variables)来定义输入。
    • 在模板文件中,使用 ${{ }} 语法(而不是 $())来读取参数值。 读取参数的值时,将在其名称中包含 parameters 部分。 例如 ${{ parameters.buildConfiguration }}

从管道调用模板

现在将调用刚才从管道生成的模板。 为“调试”配置执行一次此操作,然后为“发布”配置重复该过程。

  1. 在 Visual Studio Code 中,按如下所示修改 azure-pipelines.yml:

    trigger:
    - '*'
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      buildConfiguration: 'Release'
      wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
      dotnetSdkVersion: '6.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'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Debug'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Release'
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    
    trigger:
    - '*'
    
    pool:
      name: 'Default' #replace if needed with name of your agent pool
    
    variables:
      buildConfiguration: 'Release'
      wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
      dotnetSdkVersion: '6.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'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Debug'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Release'
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    

    此文件与原始文件类似,只不过它会将生成和发布任务替换为对执行相同任务的模板的调用。

    可以看到,为每个配置都调用了一次模板。 每个 template 任务都使用 parameters 参数将配置名称传递给模板。

运行管道

现在,你需要将更改推送到 GitHub,并查看管道运行情况。

  1. 从集成终端,将 azure-pipelines.yml 和 templates/build.yml 添加到索引,提交更改,然后将更改推送到 GitHub

    git add azure-pipelines.yml templates/build.yml
    git commit -m "Support build configurations"
    git push origin build-pipeline
    
  2. 像之前那样,从 Azure Pipelines 中,跟踪生成的每个步骤。

    管道运行时,你会看到该过程展开了模板中的任务。 生成和发布项目的任务会运行两次,也就是说,为每个生成配置执行一次。

    Screenshot of Azure Pipelines showing the expanded template tasks. Included are build and publish tasks for both the Debug and Release configurations.显示展开的模板任务的 Azure Pipelines 屏幕截图。包括“调试”和“发布”配置的生成和发布任务。

  3. 生成完成后,返回到“摘要”页,然后像之前一样选择已发布的工件。 展开放置文件夹。

    可以看到,管道为“调试”和“发布”配置分别生成了一个 .zip 文件。

    Screenshot of Azure Pipelines showing the packaged application for both Debug and Release configurations.显示“调试”和“发布”配置的打包应用程序的 Azure Pipelines 屏幕截图。

将分支合并到主分支

此时,你有一个可用的生成管道,它可以完成 Mara 现在所需的一切操作。

在实际操作中,你将提交一个拉取请求,将 build-pipeline 分支合并到 main 分支中。

我们将暂时跳过该步骤。 在下一个模块中,你将了解在 GitHub 上与团队协作的一些方法,包括如何提交、评审和合并拉取请求。