前一篇的「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 …
- steps
- jobs
扣除掉前面幾個只會設定一個的項目,範例結構會像這樣:
- stages
- 階段A(stage)
- jobs
- 作業1(job)
- steps
- 步驟1(task)
- 步驟2(script)
- 步驟3(pwsh)
- steps
- 作業2(job)
- 作業1(job)
- jobs
- 階段B(stage)
- 階段C(stage)
- 階段A(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結構描述內容的定義資訊,可以直接看官方的文件(中文/英文)。