Eseguire script multipiattaforma

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Con Azure Pipelines è possibile eseguire le build su computer macOS, Linux e Windows. Se si sviluppano tecnologie multipiattaforma come .NET Core, Node.js e Python, queste funzionalità comportano vantaggi e sfide.

Ad esempio, la maggior parte delle pipeline include uno o più script da eseguire durante il processo di compilazione. Ma gli script spesso non vengono eseguiti nello stesso modo su piattaforme diverse. È possibile usare il collegamento con parole chiave per semplificare la script scrittura di script e usare le condizioni per definire piattaforme specifiche con gli script.

Eseguire strumenti multipiattaforma con un passaggio script

La parola chiave script è un collegamento per l'attività della riga di comando. La script parola chiave esegue Bash in Linux e macOS e cmd.exe in Windows.

L'uso script di può essere utile quando l'attività passa solo argomenti a uno strumento multipiattaforma. Ad esempio, la chiamata npm con un set di argomenti può essere eseguita facilmente con un script passaggio. script viene eseguito in ogni interprete di script nativo della piattaforma: Bash in macOS e Linux, cmd.exe in Windows.

steps:
- script: |
    npm install
    npm test

Gestire le variabili di ambiente

Le variabili di ambiente generano la prima ruga nella scrittura di script multipiattaforma. La riga di comando, PowerShell e Bash hanno modi diversi per leggere le variabili di ambiente. Se è necessario accedere a un valore fornito dal sistema operativo come PATH, sono necessarie tecniche diverse per ogni piattaforma.

Azure Pipelines offre tuttavia un modo multipiattaforma per fare riferimento alle variabili note sulla sintassi delle macro. Circondando un nome di variabile in $( ), viene espanso prima che la shell della piattaforma lo veda mai. Ad esempio, se si vuole eseguire l'eco dell'ID della pipeline, lo script seguente è multipiattaforma:

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

Questo funziona anche per le variabili specificate nella pipeline.

variables:
  Example: 'myValue'

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

Prendere in considerazione Bash o pwsh

Se sono necessari scripting più complessi rispetto agli esempi illustrati in precedenza, è consigliabile scriverli in Bash. La maggior parte degli agenti macOS e Linux ha Bash come shell disponibile e gli agenti Windows includono Git Bash o sottosistema Windows per Linux Bash.

Per Azure Pipelines, gli agenti ospitati da Microsoft hanno sempre Bash disponibile.

Ad esempio, se è necessario prendere una decisione su se la compilazione viene attivata da una richiesta pull:

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) è anche un'opzione. Richiede che ogni agente abbia installato PowerShell Core.

Cambia in base alla piattaforma

In generale, è consigliabile evitare script specifici della piattaforma per evitare problemi come la duplicazione della logica della pipeline. La duplicazione causa un lavoro aggiuntivo e un rischio aggiuntivo di bug. Tuttavia, se non è possibile evitare script specifici della piattaforma, è possibile usare un condition per rilevare la piattaforma in uso.

Si supponga, ad esempio, che per qualche motivo sia necessario l'indirizzo IP dell'agente di compilazione. In Windows ottiene ipconfig tali informazioni. In macOS è ifconfig. E in Ubuntu Linux, è ip addr.

Configurare la pipeline seguente, quindi provare a eseguirla su agenti in piattaforme diverse.

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)