【把玩Azure DevOps】Day27 Build Pipeline的YAML结构描述:多个Agent Job

前一篇的「YAML格式以外的Pipeline传统编辑器(Classic Editor)」文章内容中看到了一个Pipeline中可以有多个不同的Agent Job,在每一个Agent Job底下再各自加入不同的Task,在前面文章的范例中都只是很单纯的加入Task,只在一个Agent的情况下执行Pipeline,这一篇就来看看该如何像Classic editor一样加入多个不同的Agent Job吧!

底下先来部份回顾前面文章「CI/CD从这里:设定第一个Pipeline(范本与编辑介面介绍)」内的YAML内容,也就是.NET Desktop的YAML范本:

trigger:
- master

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

- task: VSTest@2
  inputs:
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

从上面的内容中可以看到在第一层有trigger、pool、variables、steps,而在steps的下一层有多个task,在Pipeline的YAML结构应该是下面的这个样子:

  • YAML
  • name
  • resources
  • trigger
  • pool
  • variables
  • stages
    • jobs
      • steps
        • script/bash/pwsh/task …

扣除掉前面几个只会设定一个的项目,范例结构会像这样:

  • stages
    • 阶段A(stage)
      • jobs
        • 作业1(job)
          • steps
            • 步骤1(task)
            • 步骤2(script)
            • 步骤3(pwsh)
        • 作业2(job)
    • 阶段B(stage)
    • 阶段C(stage)

所以在上面的YAML范例内容中,其实是省略了上层的许多结构描述,这部份在官方的文件页面上有提到,如果只有单一阶段(stage),可以省略关键字stages并且直接使用jobs开始。如果只有单一阶段(stage)和单一作业(job),可以省略stages和jobs关键字,直接使用steps开始。所以在范本的YAML中才会看到只有steps开始定义底下的task的情况。

所以前一篇的「YAML格式以外的Pipeline传统编辑器(Classic Editor)」文章内容中看到了一个Pipeline中可以有多个不同的Agent Job,实际上在YAML格式的内容中就只是在jobs底下定义多个不同的job,在job底下再放入steps底下的内容即可,下面我以前面文章「CI/CD从这里:编译专案与上传成品」内容中的YAML稍作修改,steps中使用相同的内容,多增加一个job,YAML如下:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- none

pool:
  vmImage: ubuntu-latest

jobs:
  - job:
    displayName: Job1
    steps:
    - task: DotNetCoreCLI@2
      inputs:
        command: 'build'
        projects: 'ConsoleApp/*.csproj'
        arguments: '-o $(Build.BinariesDirectory)'
    - task: ArchiveFiles@2
      inputs:
        rootFolderOrFile: '$(Build.BinariesDirectory)'
        includeRootFolder: true
        archiveType: 'zip'
        archiveFile: '$(Build.ArtifactStagingDirectory)/Job1-$(Build.BuildId).zip'
        replaceExistingArchive: true
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'BuildOutputFiles'
        publishLocation: 'Container'

  - job:
    displayName: Job2
    pool:
      vmImage: windows-latest
    steps:
    - task: DotNetCoreCLI@2
      inputs:
        command: 'build'
        projects: 'ConsoleApp/*.csproj'
        arguments: '-o $(Build.BinariesDirectory)'
    - task: ArchiveFiles@2
      inputs:
        rootFolderOrFile: '$(Build.BinariesDirectory)'
        includeRootFolder: true
        archiveType: 'zip'
        archiveFile: '$(Build.ArtifactStagingDirectory)/Job2-$(Build.BuildId).zip'
        replaceExistingArchive: true
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'BuildOutputFiles'
        publishLocation: 'Container'

从上面的YAML内容可以看到有两个不同的Job,显示的名称分别是Job1、Job2,Job底下的steps几乎都是相同的内容(复制的),只有在压缩档案的名称内多了Job1、Job2的前缀字来分别,但是在Job1的displayName底下并没有额外的设定,在Job2的displayName底下却另外设定了pool的内容,指定使用Windows的vmImage。也就是说,Job1使用最上层定义的Linux的vmImage(ubuntu),Job2则是自行另外设定,改用Windows的vmImage。

实际执行的资讯页如下,可以看到最下面有两个不同的Job:

https://ithelp.ithome.com.tw/upload/images/20211009/20033961BdBX5YcUK8.png

点击任何一个Job都可以进入执行的Log页面,可以看到下面两个不同Job的Agent是来自不同的OS(Linux/Windows):

https://ithelp.ithome.com.tw/upload/images/20211009/20033961KpRQfzRSo4.png

https://ithelp.ithome.com.tw/upload/images/20211009/20033961uTQSEhL1lM.png

执行之後上传的成品档案也如预期以不同的Job名称为开头命名:

https://ithelp.ithome.com.tw/upload/images/20211009/20033961QgZE7fXJBi.png

不同的Job除了可以定义不同的pool之外,也可以定义不同的variables等其它不同的设定,如果需要更多详细的YAML结构描述内容的定义资讯,可以直接看官方的文件(中文/英文)。


<<:  【Day 23】与 DOM 的互动:Ref

>>:  Day 25 - [Android APP] 03-Android 的 STT 与 TTS

[iT铁人赛Day23]练习题(2)

嗨,大家好,由於本人昨天去打了疫苗,然後晚上9点开始被副作用折腾 以至於过了12点不能马上发文 然後...

Day4 决策树(Decision tree)

决策树是什麽? 讲人话就是利用特徵与分类结果之间的关系,藉由历史资料建构出一棵「如果这样就那样」的树...

[Day 29] 会员登入及登出(一)

我们先做登入的画面, 在app/Http/Controllers/UserAuthControlle...

【Day 25】Go 与 Python gRPC 小练习

乾 我今天差点忘记要发文QQ 明天有力气来补程序码与更详细的心得 参考这篇文章Python 和 G...

深不可测的海 - Regular Expression

使用终端机搜寻特定字串时,大家一定用过 grep 这个指令吧~ 但你有想过 grep 为什麽叫 gr...