執行跨平臺腳本
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
使用 Azure Pipelines 時,您可以在 macOS、Linux 和 Windows 機器上執行組建。 如果您在 .NET Core、Node.js 和 Python 等跨平臺技術上進行開發,這些功能會帶來優點和挑戰。
例如,大部分管線都包含您想要在建置程式期間執行的一或多個腳本。
但在不同的平臺上,腳本通常不會以相同方式執行。 您可以使用 script
關鍵詞快捷方式,讓撰寫腳本更容易,也可以使用條件來搭配腳本以特定平台為目標。
使用腳本步驟執行跨平臺工具
script 關鍵詞是命令行工作的快捷方式。 關鍵詞會在 script
Linux和macOS上執行Bash,並在Windows上執行cmd.exe。
當您的工作剛將自變數傳遞至跨平臺工具時,使用 script
會很有用。 例如,使用一組自變數呼叫 npm
,即可透過步驟輕鬆完成 script
。
script
在每個平臺的原生腳本解釋器中執行:macOS 和 Linux 上的 Bash,cmd.exe Windows。
處理環境變數
環境變數會擲回第一個摺痕,以撰寫跨平臺腳本。 命令行、PowerShell 和Bash各有不同的讀取環境變數方式。 如果您需要存取PATH之類的操作系統提供值,則每個平臺都需要不同的技術。
不過,Azure Pipelines 提供跨平臺方式來參考其知道的稱為 宏語法的變數。 藉由圍繞 中的 $( )
變數名稱,它會在平臺殼層看到它之前展開。 例如,如果您想要回應管線的標識碼,下列腳本是跨平臺易記的:
steps:
- script: echo This is pipeline $(System.DefinitionId)
這也適用於您在管線中指定的變數。
variables:
Example: 'myValue'
steps:
- script: echo The value passed in is $(Example)
考慮Bash或 pwsh
如果您有比上述範例更複雜的腳本需求,請考慮在Bash中撰寫這些腳本。 大部分的macOS和Linux代理程式都有Bash作為可用的殼層,而 Windows 代理程式包含 Git Bash 或 Windows 子系統 Linux 版 Bash。
針對 Azure Pipelines,Microsoft 裝載的代理程式一律有 Bash 可用。
例如,如果您需要決定您的組建是否由提取要求觸發:
trigger:
batch: true
branches:
include:
- main
steps:
- bash: |
echo "Hello world from $AGENT_NAME running on $AGENT_OS"
case $BUILD_REASON in
"Manual") echo "$BUILD_REQUESTEDFOR manually queued the build." ;;
"IndividualCI") echo "This is a CI build for $BUILD_REQUESTEDFOR." ;;
"BatchedCI") echo "This is a batched CI build for $BUILD_REQUESTEDFOR." ;;
*) $BUILD_REASON ;;
esac
displayName: Hello world
PowerShell Core (pwsh
) 也是一個選項。
它要求每個代理程式都已安裝PowerShell Core。
根據平臺切換
一般而言,建議您避免平臺特定的腳本,以避免管線邏輯重複等問題。 重複會導致額外的工作和錯誤的額外風險。
不過,如果沒有辦法避免平臺特定的腳本,您可以使用 condition
來偵測您正在使用的平臺。
例如,假設基於某些原因,您需要組建代理程式的IP位址。
在 Windows 上, ipconfig
取得該資訊。
在macOS上,它是 ifconfig
。
在 Ubuntu Linux 上,它是 ip addr
。
設定下列管線,然後嘗試對不同平臺上的代理程序執行它。
steps:
# Linux
- bash: |
export IPADDR=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')
echo "##vso[task.setvariable variable=IP_ADDR]$IPADDR"
condition: eq( variables['Agent.OS'], 'Linux' )
displayName: Get IP on Linux
# macOS
- bash: |
export IPADDR=$(ifconfig | grep 'en0' -A3 | grep inet | tail -n1 | awk '{print $2}')
echo "##vso[task.setvariable variable=IP_ADDR]$IPADDR"
condition: eq( variables['Agent.OS'], 'Darwin' )
displayName: Get IP on macOS
# Windows
- powershell: |
Set-Variable -Name IPADDR -Value ((Get-NetIPAddress | ?{ $_.AddressFamily -eq "IPv4" -and !($_.IPAddress -match "169") -and !($_.IPaddress -match "127") } | Select-Object -First 1).IPAddress)
Write-Host "##vso[task.setvariable variable=IP_ADDR]$IPADDR"
condition: eq( variables['Agent.OS'], 'Windows_NT' )
displayName: Get IP on Windows
# now we use the value, no matter where we got it
- script: |
echo The IP address is $(IP_ADDR)