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

已完成

你在上一个练习中实现了生成 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 中,跟踪生成的每个步骤。

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

    显示展开的模板任务的 Azure Pipelines 屏幕截图。包括“调试”和“发布”配置的生成和发布任务。

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

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

    显示“调试”和“发布”配置的打包应用程序的 Azure Pipelines 屏幕截图。

将分支合并到主分支

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

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

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