從前面的幾篇文章應該已經知道建立新的Pipeline可以從哪裡開始,所以廢話不多說,第二個Pipeline就直接從Starter範本再度開始。
首先,這個共用的Build Pipeline是純粹用來手動輸入C#的Project名稱來讓Pipeline執行Build csproj的動作,所以先把Yaml中的trigger設定改為none:
trigger:
- none
接下來在Save and run的按鈕旁邊有個Variables按鈕,按下去之後就會出現Variables對話框,如果沒設定過任何變數會像下圖左邊的樣子,點選New variable之後就會出現新增變數的對話框:
這裡我設定一個ProjectName變數,預設值設定為** ,並且將下面的Let users override this value when running this pipeline打勾,這麼做是為了讓執行Pipeline的使用者可以在執行Pipeline的時候設定這個變數的值,以達成這個共用的Pipeline設計目的。
設定完成之後按下OK,這時候會看到下圖的Variables對話框,按下Save之後如果重新再從Save and run旁邊的Variables點進來也是同樣的畫面:
這時候會發現,怎麼好像Yaml的內容並沒有變化?前面的文章看到.NET Desktop範本裡面不是有variables的設定區段嗎?
沒錯!Pipeline設定變數的方式有好幾種,在Yaml中的variables設定是其中的一種,透過上圖UI的設定是另外一種方式。透過UI設定的方式可以讓使用者在執行Pipeline的時候選擇是否填入他需要的值,並且有些機密的內容可以勾選Keep this value secret(如上圖),像是金鑰值或是密碼之類的,在Yaml中透過變數取得內容,又不會將機密的值曝露在Yaml檔案內容中。
更多設定變數的方式,可以點擊對話框左下的Learn about variables,官方的文件有更詳細的說明。
接著同樣將steps底下不需要的script部份刪除,然後從右邊的Task清單加入.NET Core task,在Path to project(s)屬性中填入$(ProjectName)/*.csproj。這裡我們假設C#專案檔會放在同名稱的資料夾內,所以在前面使用$(ProjectName),後面的 *.csproj也可以改成$(ProjectName).csproj。
Arguments的部份則是輸入-o $(Build.BinariesDirectory),代表要將Build產生的檔案放到$(Build.BinariesDirectory)所代表的位置。
Task的Yaml內容如下:
- task: DotNetCoreCLI@2
inputs:
command: 'build'
projects: '$(ProjectName)/*.csproj'
arguments: '-o $(Build.BinariesDirectory)'
接著為了節省篇幅,可以參考前一篇文章的內容,將壓縮為zip檔案的ArchiveFiles task和上傳Artifact的PublishPipelineArtifact task陸續加入Yaml中。其中壓縮zip的task內容在zip檔名的部份加入了$(ProjectName)這個變數,讓檔案更具有識別性,詳細內容可以參考下面的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
steps:
- task: DotNetCoreCLI@2
inputs:
command: 'build'
projects: '$(ProjectName)/*.csproj'
arguments: '-o $(Build.BinariesDirectory)'
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(Build.BinariesDirectory)'
includeRootFolder: false
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/$(ProjectName)-$(Build.BuildId).zip'
replaceExistingArchive: true
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifact: 'BuildOutputFiles'
publishLocation: 'pipeline'
最後別忘了修改一下Pipeline的Yaml檔名,此例我將檔名設為CommonBuildPipeline.yml,按下Save(不Run)之後,在Pipeline清單中將剛才建立的Pipeline改名為BuildSpecifiedProject。
上面按Save而不是Save and run的原因是Save and run會直接使用變數的預設值執行Pipeline,雖然在前面我們設定變數的預設值是**,搭配Task中設定的是$(ProjectName)/.csproj,使用預設值的情況下就會變成**/.csproj,其實也就是將Repo中的所有csproj檔案都拿來Build的意思。
這裡再複習一下Git Repo中先前放入的C#專案如下:
進入剛才建立的BuildSpecifiedProject Pipeline,按下右上角的Run pipeline,在Variables選項中選擇ProjectName變數將Value更新為ModuleA之後按下對話框下面的Update,回到上一層之後按下左上角的箭頭回到Run pipeline對話框之後就可以按下右下角的Run按鈕執行Pipeline了。
Pipeline執行成功之後,進入成品庫(Artifacts)中就可以看到ModuleA的zip檔案,檔案內容就是ModuleA相關的dll等檔案。同樣的方式可以再試試將變數值換成ConsoleApp或ModuleBase。
透過這樣的設計就可以讓使用者手動執行這個Pipeline並指定要編譯哪一個專案,在切分很多專案或是Module開發的情況,又需要在後續的Release中設計多個不同的成品來源時,可以不需要設計多個不同的Pipeline。