執行跨平臺腳本
Azure DevOps Services |Azure DevOps Server 2022 - Azure DevOps Server 2019 |TFS 2018
使用 Azure Pipelines,您可以在 macOS、Linux 和 Windows 機器上執行組建。 如果您在 .NET Core、Node.js和 Python 等跨平臺技術上進行開發,這些功能會帶來優點和挑戰。
例如,大部分的管線都包含一或多個您想要在建置程式期間執行的腳本。 但腳本通常不會在不同的平臺上以相同方式執行。 以下是如何處理這類挑戰的一些秘訣。
使用腳本步驟執行跨平臺工具
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:
- master
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。
根據平臺切換
一般而言,建議您避免平臺特定的腳本,以避免發生管線邏輯重複之類的問題。 重複會導致額外的工作和額外的 Bug 風險。
不過,如果沒有任何方法可以避免平臺特定的腳本,您可以使用 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)