Запуск кроссплатформенных скриптов

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

С помощью Azure Pipelines можно запускать сборки на компьютерах MacOS, Linux и Windows. Если вы разрабатываете кроссплатформенные технологии, такие как .NET Core, Node.js и Python, эти возможности приносят как преимущества, так и проблемы.

Например, большинство конвейеров включают один или несколько скриптов, которые необходимо запустить во время процесса сборки. Но сценарии часто не выполняются одинаково на разных платформах. Вы можете использовать script ярлык ключевое слово, чтобы упростить написание скриптов, а также использовать условия для целевых платформ с помощью скриптов.

Запуск кроссплатформенных средств с помощью шага скрипта

Скрипт ключевое слово — это ярлык для задачи командной строки. Ключевое слово script запускает Bash в Linux и macOS и cmd.exe в Windows.

Использование script может быть полезно, если задача просто передает аргументы кроссплатформенной инструменту. Например, вызов npm с набором аргументов можно легко выполнить с script помощью шага. script выполняется в собственном интерпретаторе скриптов каждой платформы: Bash в macOS и Linux, 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 агенты, размещенные корпорацией Майкрософт, всегда имеют доступ к 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)