クロスプラットフォーム スクリプトを実行する
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
Azure Pipelines を使うと、macOS、Linux、Windows マシン上でビルドを実行できます。 .NET Core、Node.js、Python などのクロスプラットフォーム テクノロジで開発する場合、これらの機能には利点と課題の両方があります。
たとえば、ほとんどのパイプラインには、ビルド プロセス中に実行したいスクリプトが 1 つまたは複数含まれています。
ただし、多くの場合、スクリプトは、プラットフォームが異なるとその実行方法も異なります。 script
キーワード (keyword) ショートカットを使用すると、スクリプトの記述を容易にしたり、条件を使用してスクリプトを使用して特定のプラットフォームをターゲットにしたりできます。
スクリプトのステップを使用してクロスプラットフォーム ツールを実行する
スクリプト キーワードは、コマンド ライン タスクに対するショートカットです。 script
キーワードを使用すると、Linux および macOS 上では Bash が実行され、Windows 上では cmd.exe が実行されます。
自身のタスクでクロスプラットフォーム ツールに引数を渡すだけの場合は、script
を使用すると便利です。 たとえば、一連の引数を使用して npm
を呼び出す場合は、script
ステップを使用すると簡単に実行できます。
script
は、次に示す各プラットフォームのネイティブ スクリプト インタープリターで実行されます: macOS と Linux では Bash、Windows では cmd.exe。
環境変数を処理する
クロスプラットフォーム スクリプトの作成では、環境変数が最初の問題となります。 コマンド ライン、PowerShell、Bash では、環境変数を読み取る方法がそれぞれ異なります。 PATH などのオペレーティング システムで提供される値にアクセスする必要がある場合は、プラットフォームごとに異なる手法が必要になります。
ただし、Azure Pipelines には、マクロ構文と呼ばれる、既知の変数を参照するクロスプラットフォームの方法が用意されています。 変数名を $( )
で囲むと、それは展開されてから、プラットフォームのシェルによって認識されます。 たとえば、パイプラインの ID をエコーアウトする場合は、次のスクリプトがクロスプラットフォームに適しています。
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 または Linux 用 Windows サブシステム Bash が含まれます。
Azure Pipelines の場合、Microsoft によってホストされるエージェントでは常に Bash を使用できます。
たとえば、ビルドが pull request によってトリガーされるようにするかどうかを決定する場合は、次のようにします。
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)