Azure DevOps 服務 |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020
Azure Pipelines 可以在 Linux、macOS 和 Windows 計算機上執行管線。 如果您使用 .NET Core、Node.js或 Python 等跨平台開發技術,這些跨平台建置功能會帶來好處和挑戰。 例如,大多數的流水線都包含一或多個要在建置過程中執行的腳本,但腳本語法通常會因平臺而異。
本文說明如何使用跨平台指令碼來支援不同的組建平台。 您可以使用 Azure Pipelines script 步驟來輕鬆撰寫跨平臺腳本。 您也可以使用 條件 將指令碼鎖定特定平台。
指令碼步驟
script 關鍵字是命令列任務的捷徑,該任務在 Linux 和 macOS 上運行 Bash,在 Windows 上運行 cmd.exe。
您可以使用 script 來輕鬆地將引數傳遞至跨平台工具。 此 script 步驟會在每個平台的原生腳本解譯器中執行,macOS 和 Linux 上的 Bash 或 Windows 上的 cmd.exe。 下列範例會用 script 步驟,以呼叫 npm 一組參數。
環境變數
命令列、PowerShell 和 Bash 會以不同的方式解析 環境變數 。 若要存取系統提供的值 (例如 PATH),您必須在每個平台使用不同的語法。
Azure Pipelines 會使用 巨集語法 作為跨平臺的方式在執行時參考變數。 在任務執行之前,具有巨集語法的變數會在運行時被處理。 變數會在平台殼層遇到它之前展開。
若要在管線中使用巨集語法,請將變數名稱括住,如下所示: $(<variable name>)。 下列跨平台範例指令碼會回應管線的識別碼。
steps:
- script: echo This is pipeline $(System.DefinitionId)
此語法也適用於您在管線中定義的變數。
variables:
Example: 'myValue'
steps:
- script: echo The value passed in is $(Example)
Bash 工作
如果您需要更複雜的腳本,請考慮在 Bash 中撰寫它們,並在管道中使用 Bash 任務。 大多數 macOS 和 Linux 代理程式使用 Bash 作為 shell,Windows 代理程式可以使用 Git Bash 或 Linux Bash 的 Windows 子系統 。 Microsoft 裝載的代理程式 預設已預先安裝 Bash。
下列範例會執行 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 也是腳本的一個選項。 此捷徑會在 pwsh macOS、Linux 或 Windows 上執行 PowerShell 7.x。 代理程式必須安裝 PowerShell 7.x。
Microsoft 裝載的代理程式 預設會安裝 PowerShell 7.x。
基於平台的交換
複製管線邏輯的平台特定指令碼會導致額外的工作並增加錯誤風險。 但是,如果您無法避免特定於平台的腳本編寫,您可以使用 條件 來偵測您所在的平台。
例如,若要取得組建代理程式的 IP 位址,您必須在 macOS、 ifconfig Ubuntu Linux 上使用ip addr,以及 Get-NetIPAddress Windows PowerShell 上的 Cmdlet。 下列管線會透過條件從不同平台的代理獲取該資訊。
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
# use the value
- script: |
echo The IP address is $(IP_ADDR)