Köra plattformsoberoende skript

Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019

Med Azure Pipelines kan du köra dina versioner på macOS-, Linux- och Windows-datorer. Om du utvecklar plattformsoberoende tekniker som .NET Core, Node.js och Python medför dessa funktioner både fördelar och utmaningar.

De flesta pipelines innehåller till exempel ett eller flera skript som du vill köra under byggprocessen. Men skript körs ofta inte på samma sätt på olika plattformar. Du kan använda nyckelordsgenvägen script för att göra det enklare att skriva skript och även använda villkor för att rikta in sig på specifika plattformar med dina skript.

Köra plattformsoberoende verktyg med ett skriptsteg

Skriptnyckelordet är en genväg för kommandoradsaktiviteten. Nyckelordet script kör Bash på Linux och macOS och cmd.exe i Windows.

Att använda script kan vara användbart när din uppgift bara skickar argument till ett plattformsoberoende verktyg. Till exempel kan anrop npm med en uppsättning argument enkelt utföras med ett script steg. script körs i varje plattforms inbyggda skripttolkare: Bash på macOS och Linux, cmd.exe i Windows.

steps:
- script: |
    npm install
    npm test

Hantera miljövariabler

Miljövariabler kastar den första rynkan till att skriva plattformsoberoende skript. Kommandoraden, PowerShell och Bash har olika sätt att läsa miljövariabler. Om du behöver komma åt ett värde som tillhandahålls av operativsystemet, till exempel PATH, behöver du olika tekniker per plattform.

Azure Pipelines erbjuder dock ett plattformsoberoende sätt att referera till variabler som den känner till som kallas makrosyntax. Genom att omge ett variabelnamn i $( )expanderas det innan plattformens gränssnitt någonsin ser det. Om du till exempel vill upprepa ID:t för pipelinen är följande skript plattformsoberoende:

steps:
- script: echo This is pipeline $(System.DefinitionId)

Detta fungerar även för variabler som du anger i pipelinen.

variables:
  Example: 'myValue'

steps:
- script: echo The value passed in is $(Example)

Överväg Bash eller pwsh

Om du har mer komplexa skriptbehov än exemplen ovan kan du skriva dem i Bash. De flesta macOS- och Linux-agenter har Bash som ett tillgängligt gränssnitt, och Windows-agenter inkluderar Git Bash eller Windows-undersystem för Linux Bash.

För Azure Pipelines har de Microsoft-värdbaserade agenterna alltid Bash tillgängligt.

Om du till exempel behöver fatta ett beslut om bygget utlöses av en pull-begäran:

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) är också ett alternativ. Det kräver att varje agent har PowerShell Core installerat.

Växla baserat på plattform

I allmänhet rekommenderar vi att du undviker plattformsspecifika skript för att undvika problem som duplicering av pipelinelogik. Duplicering orsakar extra arbete och extra risk för buggar. Men om det inte finns något sätt att undvika plattformsspecifik skriptning kan du använda en condition för att identifiera vilken plattform du är på.

Anta till exempel att du av någon anledning behöver byggagentens IP-adress. I Windows ipconfig hämtar du den informationen. På macOS är ifconfigdet . Och på Ubuntu Linux är ip addrdet .

Konfigurera pipelinen nedan och försök sedan köra den mot agenter på olika plattformar.

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)