logo头像

Edward.K Thinking

用YAML建置Azure DevOps CI的Pipeline

自從VSTS改名成為Azure DevOps後,多出一個能透過YAML檔案,建立CI Pipeline的選項(之前其實就已經有透露),既然是YAML檔案也就勢必在Azure DevOps中會看不到用圖形化介面去定義在CI流程中,定義每個Task的設定與流程。如果使用YAML來建置CI Pipeline有甚麼好處呢?個人認為至少在目前這階段的好處有幾點

  • Pipeline可以做到版本管控,除非今天所有Pipeline都只能有一個人可以設置,不然,當中間被異動甚麼,久了大概也忘記,那樣版本管控就很重要
  • 具有更多的彈性,透過Code方式,可以讓設定屬性更為明確,也比較彈性,不會被制式Task的UI給綁死。當然,如果要大量異動多個Pipeline的屬性,用Code也比較快一點
  • 據說轉移Pipeline會比較快,透過File方式可以很快遷移,不過,個人覺得還是遷移在Azure DevOps間或是Azure DevOps和Azure DevOps Server間,會比較簡單,跨平台就很困難了
  • 建置CI時候,大多數情況下必須知道員開發者用甚麼Framework或是相關開發方式,才有辦法正確設置好CI,透過YAML方式也可以讓開發人員自訂屬於該專案或是系統自動化的CI

那樣是否該馬上把所有Pipeline都採用YAML,我認為倒也不必,如果一開始沒有用過YAML設定Pipeline的人,一開始要踏入的門檻還算高,不建議馬上使用的點,如下

  • 對於每個Task屬性要熟,設置起來比較順手
  • 如果CI是透過地端的Agent來建置,會常發生CI等不到Agent可以做建置動作,這時候大概就是你的地端Agent要更新版本了,我在猜因該是從Azure DevOps驅動Agent的Script有更新,但它無法認的版本不同的Agent,導致狀態被擱置了
  • 並非所有Task都可以用YAML設定,如果你有些特殊且非官方的Task,可能就不一定有支援YAML寫法

Azure DevOps 的 YAML


現在如果進入Azure DevOps可以發現並非直接採用圖形化介面產生CI了,而是下面這種畫面

如果依照畫面執行一步一步下去,基本上就是建置出一個YAML設定的Pipeline,如果你想要用視覺化方式建置,只要選擇Visual Designer,就可以回復到之前的視覺化建置CI的方式建置。不過,我個人反而不喜歡這樣一開始建置YAML檔案的流程方式,會有很多地方被受限,舉例來說,就是YAML檔案存放位置。

個人覺得比較好的方式,反而是先編輯好YAML檔案,在用指定YAML檔案方式,讓Azure DevOps的CI可以遵循YAML腳本去執行CI。

選定好自己設定好的YAML檔案

就可以開始執行YAML腳本了

YAML腳本的設計


YAML,一開始沒有寫過人可能會不習慣,不過如果有寫過像是Python的人,可能就還好,因為在YAML中的縮排是很重要的,如果,腳本的縮排不正確,就會引起腳本錯誤,導致無法執行,但這通常最難部分,你還必須去執行CI時候才知道是否有錯誤,並無法像其他語言一樣,可以先編譯看看是否有寫錯

不過當你的CI被執行時候,若腳本寫法有錯,還是會被顯示出來,只是這時候必須等這個YAML被執行時候,才會發現

在Azure DevOps中的YAML結構可以分為三塊

  • 區塊一: 設定要啟動的Pool Name,又或是你希望背後啟動的VM類型,如果今天是採用地端Agent,只需要設定Pool Name就可以,如果是使用Host Agent,還可以指定後面要起來VM類型是哪一種OS
  • 區塊二: 設定CI流程的Task屬性
  • 區塊三: CI其他細節或是屬性的相關設定

透過這三大塊方向,就可以簡易做出一個CI的YAML檔案,檔案類型大致會像下面這樣

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
name: $(SourceBranchName).$(Date:yyyyMMdd)$(Rev:.r) #Show Build Name, this is build number
trigger:
batch: true
branches:
include:
- DEV
paths:
include:
- Demo.asp.net
jobs:
- job:
displayName: Build Send Data Tool
pool: localagent
steps:
#restore
- task: DotNetCoreCLI@2
displayName: Restore package
inputs:
command: 'restore'
projects: XXXXX.sln
feedsToUse: config
nugetConfigPath: nuget.config
verbosityPack: 'detailed'
#置換參數
- task: qetza.replacetokens.replacetokens-task.replacetokens@2
displayName: 'Replace Config Parameter'
inputs:
rootDirectory: demo
targetFiles: appsettings.dev.json
actionOnMissing: fail
#NET Core Publish
- task: DotNetCoreCLI@2
displayName: Build & Publish Application
inputs:
Command: 'publish'
publishWebProjects: false
projects: XXXXX.sln
arguments: '--self-contained true -o $(Build.artifactstagingdirectory)\app -r win-x64'
zipAfterPublish: false
feedsToUse: config
nugetConfigPath: nuget.config
configuration: debug
- task: PublishBuildArtifacts@1
displayName: Upload file
inputs:
PathtoPublish: '$(Build.StagingDirectory)'
ArtifactName: 'drop'

假設一開始真的寫不出來,還有一種方式可以練習,就是先透過Visual Design設計出流程,透過CI介面上的View YAML就可以看出流程中所代表的YAML檔案是怎樣寫的

不過,雖然上面可以讓你COPY裡面程式碼,但是實際貼到YAML,並且讓CI去執行會有些小錯誤,所以建議還是必須手動修改或是看過才可以。

參考


上一篇