執行跨平臺腳本

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 ,即可透過步驟輕鬆完成 scriptscript 在每個平臺的原生腳本解釋器中執行:macOS 和 Linux 上的 Bash,cmd.exe Windows。

steps:
- script: |
    npm install
    npm test

處理環境變數

環境變數會擲回第一個摺痕,以撰寫跨平臺腳本。 命令行、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)