练习 - 将结果发布到管道

已完成

此时,可以通过管道生成 Space Game Web 项目。

但是,生成的结果在何处? 现在,生成的输出仍保留在临时生成服务器上。 Mara 需要一种方法将此生成交给 Amita,使她可以开始测试。

可以在 Azure Pipelines 中存储生成工件,以便稍后在生成完成后可供团队中的其他人使用。 这是你将在此处执行的操作。 另一个好处是,你还能将生成配置重构为使用变量,从而使配置更易读取并保持最新。

备注

通过 Azure Pipelines,可以将生成应用自动部署到在云端或数据中心运行的测试或生产环境。 目前,Mara 的目标只是生成她可以使用现有流程交给 QA 的生成。

将生成发布到管道

在 .NET 中,可将应用打包为 .zip 文件。 然后,可以使用内置的 PublishBuildArtifacts@1 任务将 .zip 文件发布到 Azure Pipelines。

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

    trigger:
    - '*'
    
    pool:
      name: 'Default' #replace if needed with name of your agent pool
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET SDK 6.x'
      inputs:
        version: '6.x'
    
    - task: Npm@1
      displayName: 'Run npm install'
      inputs:
        verbose: false
    
    - script: './node_modules/.bin/node-sass Tailspin.SpaceGame.Web/wwwroot --output Tailspin.SpaceGame.Web/wwwroot'
      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: Tailspin.SpaceGame.Web/wwwroot
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore project dependencies'
      inputs:
        command: 'restore'
        projects: '**/*.csproj'
    
    - 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
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    
    trigger:
    - '*'
    
    pool:
      vmImage: ubuntu-latest
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET SDK 6.x'
      inputs:
        version: '6.x'
    
    - task: Npm@1
      displayName: 'Run npm install'
      inputs:
        verbose: false
    
    - script: './node_modules/.bin/node-sass Tailspin.SpaceGame.Web/wwwroot --output Tailspin.SpaceGame.Web/wwwroot'
      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: Tailspin.SpaceGame.Web/wwwroot
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore project dependencies'
      inputs:
        command: 'restore'
        projects: '**/*.csproj'
    
    - 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
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    

    此版本的 azure-pipelines.yml 与以前的版本类似,但添加了两个额外的任务。

    第一个任务使用 DotNetCoreCLI@2 任务将应用的生成结果(包括其依赖项)发布或打包到文件夹中。 zipAfterPublish 参数指定将生成结果添加到 .zip 文件。

    第二个任务使用 PublishBuildArtifacts@1 任务将 .zip 文件发布到 Azure Pipelines。 condition 参数指定仅在上一个任务成功时运行该任务。 succeeded() 是默认条件,因此无需指定它。 我们在此处显示它只是为了说明它的用途。

  2. 从集成终端,将 azure-pipelines.yml 添加到索引,提交更改,并将更改推送到 GitHub

    提示

    请记住在运行这些 Git 命令之前保存 azure-pipelines.yml。

    git add azure-pipelines.yml
    git commit -m "Add publish tasks"
    git push origin build-pipeline
    
  3. 像之前那样,从 Azure Pipelines 中,跟踪生成的每个步骤。

  4. 管道完成后,返回到生成摘要。

  5. “Related”下显示“1 published”。

    Screenshot of the build summary. Details include the repository and version, the time started and elapsed, and a link to the published build artifact.

  6. 选择该工件。

  7. 展开放置文件夹。

    你会看到一个 .zip 文件,其中包含生成应用及其依赖项:

    Screenshot of the packaged web application in the Artifacts explorer.

    如果你想尝试选做练习,可将此 .zip 文件下载到计算机并浏览其内容。

定义变量以提高可读性

Mara 退回到之前的步骤以检查她的工作。 生成配置可以满足她的需求,但她希望确保 Andy 和其他人可以轻松地帮助使其保持最新并对其进行扩展。

通过变量,可以一次定义多个值,并在整个管道中引用这些值。 管道运行时,Azure Pipelines 将每个变量替换为其当前值。

与其他编程语言一样,通过变量可以执行以下操作:

  • 定义可能在管道的运行之间发生变化的值。
  • 在一个位置存储整个管道中重复的信息,例如版本号或文件路径。 这样一来,不需要在需求变化时更新所有匹配项。

Azure Pipelines 提供了许多内置变量。 这些变量描述生成过程的各个方面,例如生成标识符以及生成和暂存软件的目录名称。

也可以自行定义变量。 下面的示例演示一个名为 buildConfiguration 的变量,该变量定义“发布”生成配置:

variables:
  buildConfiguration: 'Release'

多次重复相同值或某个值(如依赖项版本)可能发生更改时,请使用变量。

不需要为每项生成配置创建变量。 事实上,过多的变量可能会令他人更难以阅读和理解管道代码。

花一些时间检查 azure-pipelines.yml。 请注意,这些值都是重复的:

  • 生成配置:Release
  • wwwroot 目录的位置:Tailspin.SpaceGame.Web/wwwroot
  • .NET SDK 版本:6.x

现在使用变量来一次性定义这些值。 然后,在整个管道中引用这些变量。

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

    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'
    
    - 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
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    
    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'
    
    - 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
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    

    请注意 variables 部分,它定义这些变量:

    • buildConfiguration:指定生成配置。
    • wwwrootDir:指定 wwwroot 目录的路径。
    • dotnetSdkVersion:指定要使用的 .NET SDK 版本。

    要引用这些变量,可以像引用内置变量一样使用 $() 语法。 下面是运行 node-sass 将 Sass 文件转换为 CSS 的步骤。 为获取 wwwroot 目录的路径,它引用了 wwwrootDir 变量。

    - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
      displayName: 'Compile Sass assets'
    

    脚本命令使用此变量来定义 Sass 文件的源目录和写入 CSS 文件的目录。 它还使用此变量来定义用户界面中显示的任务名称。

  2. 从集成终端,将 azure-pipelines.yml 添加到索引,提交更改,并将更改推送到 GitHub

    git add azure-pipelines.yml
    git commit -m "Refactor common variables"
    git push origin build-pipeline
    
  3. 从 Azure Pipelines 中,跟踪生成的每个步骤。

    你会看到在生成运行时变量将替换为它们的值。 例如,下面是用于设置要使用的 .NET SDK 版本的 UseDotNet@2 任务。

    Screenshot of Azure Pipelines showing the .NET SDK task running in the pipeline.

    如前所述,若要查看生成完成时的工件,可导航到生成摘要。

恭喜! 你已成功使用 Azure Pipelines 并创建了第一个生成工件。