Ejecución de scripts multiplataforma

Azure Pipelines | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018

Con Azure Pipelines, puede ejecutar las compilaciones en macOS, Linux y Windows virtuales. Si desarrolla tecnologías multiplataforma como .NET Core, Node.js y Python, estas funcionalidades aportan ventajas y desafíos.

Por ejemplo, la mayoría de las canalizaciones incluyen uno o varios scripts que desea ejecutar durante el proceso de compilación. Pero los scripts a menudo no se ejecutan de la misma manera en distintas plataformas. A continuación se muestran algunas sugerencias sobre cómo controlar este tipo de desafío.

Ejecución de herramientas multiplataforma con un paso de script

La palabra clave script es un acceso directo para la tarea de línea de comandos. La script palabra clave ejecuta Bash en Linux y macOS y cmd.exe en Windows.

El script uso de puede ser útil cuando la tarea simplemente pasa argumentos a una herramienta multiplataforma. Por ejemplo, la npm llamada a con un conjunto de argumentos se puede realizar fácilmente con un script paso. scriptse ejecuta en el intérprete de script nativo de cada plataforma: Bash en macOS y Linux, cmd.exe en Windows.

steps:
- script: |
    npm install
    npm test

Control de variables de entorno

Las variables de entorno inician el primer proceso para escribir scripts multiplataforma. La línea de comandos, PowerShell y Bash tienen distintas formas de leer variables de entorno. Si necesita acceder a un valor proporcionado por el sistema operativo como PATH, necesitará técnicas diferentes por plataforma.

Sin embargo, Azure Pipelines ofrece una manera multiplataforma de hacer referencia a variables que conoce como sintaxis de macro. Al rodear un nombre de variable en , se expandirá antes de que el shell de la plataforma $( ) lo vea. Por ejemplo, si desea hacer eco del identificador de la canalización, el siguiente script es descriptivo para varias plataformas:

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

Esto también funciona para las variables que especifique en la canalización.

variables:
  Example: 'myValue'

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

Consideración de Bash o pwsh

Si tiene necesidades de scripting más complejas que los ejemplos mostrados anteriormente, considere la posibilidad de escribirlas en Bash. La mayoría de los agentes de macOS y Linux tienen Bash como shell disponible y Windows agentes incluyen Git Bash o Subsistema de Windows para Linux Bash.

Por Azure Pipelines, los agentes hospedados por Microsoft siempre tienen Bash disponible.

Por ejemplo, si necesita tomar una decisión en función de si se trata de una compilación de solicitud de extracción:

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 ) también es una opción. Requiere que cada agente tenga PowerShell Core instalado.

Cambio basado en la plataforma

En general, se recomienda evitar scripts específicos de la plataforma para evitar problemas como la duplicación de la lógica de canalización. La duplicación provoca un trabajo adicional y un riesgo adicional de errores. Sin embargo, si no hay ninguna manera de evitar el scripting específico de la plataforma, puede usar para detectar en qué plataforma condition se encuentra.

Por ejemplo, suponga que, por algún motivo, necesita la dirección IP del agente de compilación. En Windows, ipconfig obtiene esa información. En macOS, es ifconfig . Y en Ubuntu Linux, es ip addr .

Configure la canalización siguiente y, a continuación, intente ejecutarla en agentes en distintas plataformas.

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)