【2021鐵人賽】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:

點擊任何一個Job都可以進入執行的Log頁面,可以看到下面兩個不同Job的Agent是來自不同的OS(Linux/Windows):

執行之後上傳的成品檔案也如預期以不同的Job名稱為開頭命名:

不同的Job除了可以定義不同的pool之外,也可以定義不同的variables等其它不同的設定,如果需要更多詳細的YAML結構描述內容的定義資訊,可以直接看官方的文件(中文/英文)。

發佈留言