Azure DevOps / TFS PowerShell Custom Task 建置

Mars Wang
11 min readDec 13, 2022

--

Photo by Jon Tang on Unsplash

前言

當你在使用Azure DevOps, Azure DevOps Server,舊稱Team Foundation Server(TFS)當中的時候,你一定會特別使用到CI/CD的功能。

在下方的圖片當中可以看到,不論是上述哪種DevOps產品,都會有介面化GUI的方式(class editor),可以在每一台Agent當中點選要執行的工作事項(Task),進而去完成CI (Continuous Integration)或是CD (Continuous Deployment)上的自動化流程。

選擇Task的方式可以有三種:

  1. Default Task:由Microsoft來去做管理版本以及更新的工作事項。
  2. Third-Party Task:也可以在Marketplace當中查詢是否有相關的Task可以使用。
  3. Custom Task:在以上情況下自己design所需要的Task。本篇會以Custom Task on TFS/Azure DevOps上的情境來做說明。

本篇會以Custom Jmeter Task來做Loading Test。

Azure DevOps產品當中,可以在CI/CD當中加入工作事項(Task)來流程化

Prerequisites

前置作業,我們依照Microsoft官方提供的文件去做下載相對應的元件做開發:

  • 需要有Azure DevOps (Cloud) 或是建置Azure DevOps Server/TFS於地端當中
  • 你習慣使用的 IDE or 文字編輯器,我們範例當中會使用Visual Studio Code來做範例。
  • Node.js:Microsoft官方建議於production環境使用Node10 or Node6版本。(本篇使用Node10)
  • OS: MacOS Ventura 13.0.1 (Apple M1 Chip)
  • Apache Jmeter

最後長出的資料夾結構,會變成以下的樣子:

|--- README.md
|--- vss-extension.json // extension's manifest -> 會利用這個檔案打包程式
|--- Jmeter
|--- icon.png
|--- sript.ps1
|--- task.json

在下載完Node.js之後,應該會自動一起下載npm套件管理工具。打開terminal輸入npm 就可以查看是否有安裝成功。
若有的話,繼續安裝相關Custom Task工具進入:

TFX
利用以下指令,可以打包建立好的custom task,也可以快速建立一個新的template出來。
npm install -g tfx-cli

建立專案模板以及資料夾

像上述所說的資料夾結構,我們可以利用剛剛下載的tfx-cli來建立起csutom task的template。

tfx build tasks create \
--task-name Jmeter \
--friendly-name "Jmeter" \
--description 'This is example task for Jmeter' \
--author 'MarsWang'

touch README.md vss-extension.json
建立custom task template(左); 建立出的original資料夾內容會長如圖所示(右)

以下做檔案的簡單說明:

icon.png

可以選擇自己的圖片檔案,並且大小32x32的.png檔案做custom task的Logo

sample.ps1/.js

可以看到/Jmeter 當中有sample.js以及sample.ps1 可以用Javascript或是Powershell來做開發,但我們本篇採用Powershell建立Custom Task,因此可以Delete sample.js

Task.json

這裡面會利用.json格式,來定義你在Azure DevOps/TFS上所使用的介面,如果需要更詳細的所有格式使用,可以參考官方文件schema.

vss-extension.json

用來說明整體資料夾結構的說明文件,主要會用這份.json檔案來build Custom Task出來。如果需要更詳細的所有格式說明,可以參考官方文件schema.

寫腳本!

Import-Module

先安裝後續會用到的Module,並安裝於 /Jmeter/ps_modules 底下,統一管理會使用到的modules。以下我們下載VstsTaskSdk此Module。

PS> Save-Module –Name VstsTaskSdk –Path .\[taskname]\ps_modules –Force
# 替換掉[taskname]的部分,因此以我的範例會變成以下這樣:
PS> Save-Module –Name VstsTaskSdk –Path .\Jmeter\ps_modules –Force

安裝後把版本號內的所有functions拉出來,並且把版本號刪掉
→ 這裡我猜是為了避免recursive到不同的版本下去,導致load module的時候出現conflict

Create PowerShell Script for Jmeter

為了方便起見,我把source code放在Github Repo當中,有興趣的可以直接 git clone 下來。

Sample.ps1:主要從Azure DevOps/TFS server當中發動指令,執行 jmeter.sh -n -t xxx.jmx -l script.jtl -j script.log -e -o ./HTML 這樣自動產生報表以及.log, .jtl的指令。

Task.json:裡面放置我們UI的主要介面,截取其中一段為例。在執行方面,vss-extension.json當中,會看見execution的屬性,可以去選擇要以PowerShell或是Javascript的檔案去執行。

# 利用inputs這個attribute來去設定介面該傳入哪種type, 哪種default value, 等等
"inputs": [
{
"name": "jmeterExeLocation",
"type": "filePath",
"label": "Jmeter.bat/.sh Location",
"defaultValue": "",
"required": true,
"helpMarkDown": "Path of Jmeter execution file"
},
{
"name": "jmeterScriptLocation",
"type": "filePath",
"label": "Script(.jmx) Location",
"defaultValue": "**/*.jmx",
"required": true,
"helpMarkDown": "Path of Jmeter script *.jmx"
}
]
...
"execution": {
"PowerShell3": {
"target": "sample.ps1"
}
}

vss-extension.json:在Repo當中可以見到有兩個,分別後綴 azuredevops 以及 tfs,主要兩者差別在TFS版本以及Azure DevOps版本當中,會在Categories當中有所區別,在建置時需要特別注意。

再次提醒!vss-extension.json以及task.json當中的版本號需一致!已避免上傳時出現錯誤。

後面舉例我們以Azure DevOps版本為例。

... # in Azure DevOps version
"categories": [
"Azure Pipelines"
]
...

... # in TFS version
"categories": [
"Build and release"
]
...

建立Publisher on Marketplace

在打包以及上傳package前,必須在Azure DevOps/TFS上建立publisher,詳細的建立方式可以參考此篇官方文件Doc

此步驟需要記得你所建立的publisher名稱,e.g. marswang,這個名稱必須對應到vss-extension.json當中的publisher屬性才可以成功上傳並且建立。

{
"manifestVersion": 1,
"id": "Jmeter",
"name": "Jmeter",
"version": "1.1.3",
"publisher": "marswang", # 必須對應到marketplace上建立的publisher名稱,並且以此帳號登入上傳
...
}

建立Custom Task Package

把CLI位置移動至與vss-extension.json相同的路徑下,並且輸入以下指令:

tfx extension create --manifest-globs vss-extension-azuredevops.json
# or
tfx extension create --manifest-globs vss-extension-tfs.json
在原先的目錄底下會產生一個.vsix檔案,也就是要上傳到marketplace的package

上傳Package to Marketplace

登入Marketplace,並且選擇右上方Publish extensions → + New Extnesion → Azure DevOps → Upload .vsix

上傳成功

若要使用到你的organization/projects當中的話:

Step1: 懸浮在Custom task上 → 點選 ··· 圖示 → Share/Unshare → 選擇你的org/enterprise做分享

Step2: 進入到分享的organization(組織)當中,並且點選左下角 organization setting → Extensions → Shared,當中點選Jmeter,並且Install即可使用。

Finally!

進入到Azure Pipeline當中選擇Release (CD)功能。就可以看到我們的Custom Task出現在畫面當中,就可以開始做測試了!

心得

整個建立的過程第一次使用會遇到很多bug,以及如果要做更多的指令的時候,會更加的複雜。在設計整個UI介面以及,對應輸入進入到PowerShell的時候,雖都會有一定的規則可以follow,但還是會因為變數比較多,或是邏輯比較複雜,在PowerShell的時候會小複雜。如果你是熟悉Javascript的人,可以直接考慮用.js做開發,或許會有更多的功能可以套入。

Reference:

--

--

Mars Wang
Mars Wang

Written by Mars Wang

99' | Software Development | Cloud | Adventurer

No responses yet