ado-windows-git-bash-compatibility について
Azure DevOps チーム向けの互換性ガイドです。Windows エージェントで Git Bash を使う際のパス変換やシェルの違いを扱い、クロスプラットフォームのパイプライン例、設定方法、トラブルシューティングを紹介します。
主な機能
- 01MINGW のパス変換問題の解説
- 02MSYS のパス変換制御
- 03クロスプラットフォームのパイプライン例
- 04OS とシェルの検出方法
- 05一般的なエラーと診断方法
活用シーン
- 01Windows パイプラインのパスエラー修正
- 02複数 OS 向けビルド手順の作成
- 03Git Bash のコマンド引数設定
- 04Azure DevOps エージェント障害の診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill ado-windows-git-bash-compatibilityインストール後、Claude Code で/ado-windows-git-bash-compatibilityを入力して読み込まれたか確認します。
詳細
Azure Pipelines:Windows と Git Bash の互換性
概要
Azure Pipelines は Windows エージェントで実行されることが多く、チームはスクリプトに Git Bash をよく使用します。このため、パス変換やシェルの互換性に関する課題が生じ、パイプラインの失敗につながることがあります。このガイドでは、Azure DevOps パイプラインで Windows と Git Bash を統合するための包括的な解決策を紹介します。
Windows エージェントに関する重要な事実
Git Bash との統合
Microsoft の公式見解:
- Microsoft は、エージェントの構成に mintty ベースのシェル(git-bash など)を使用しないことを推奨しています
- mintty は、Windows のネイティブな入出力 API と完全には互換性がありません
- ただし、パイプラインでの Git Bash タスクは広く使用されており、サポートされています
Git バージョンの管理:
- Windows エージェントでは、デフォルトでエージェントソフトウェアにバンドルされた Git が使用されます
- Microsoft は、バンドルされた Git バージョンの使用を推奨しています
System.PreferGitFromPath=trueで上書きできます
Windows エージェント上の Git Bash の場所:
C:\Program Files (x86)\Git\usr\bin\bash.exe
C:\Program Files\Git\usr\bin\bash.exe
パイプラインでのパス変換の問題
根本的な問題
Windows エージェントで Bash タスクを使用すると、Azure DevOps の変数は Windows 形式のパスを返しますが、Git Bash(MINGW)はパスを自動変換するため、問題が発生することがあります。
よくある失敗パターン
問題 1:Bash でのバックスラッシュのエスケープ
# ❌ FAILS - Backslashes treated as escape characters
- bash: |
cd $(System.DefaultWorkingDirectory) # d:\a\s\1 becomes d:as1
解決策:
# ✅ CORRECT - Use forward slashes or variable properly
- bash: |
cd "$BUILD_SOURCESDIRECTORY"
# Or use PWD variable which is already set correctly
echo "Working in: $PWD"
問題 2:引数でのパス変数
# ❌ FAILS - MINGW converts /d /s style arguments
- bash: |
my-tool /d $(Build.SourcesDirectory)
解決策:
# ✅ CORRECT - Use double slashes or environment variable
- bash: |
export MSYS_NO_PATHCONV=1
my-tool /d $(Build.SourcesDirectory)
unset MSYS_NO_PATHCONV
問題 3:コロン区切りのパスリスト
# ❌ FAILS - MINGW converts colon-separated Windows paths
- bash: |
export PATH="/usr/bin:$(Agent.ToolsDirectory)"
解決策:
# ✅ CORRECT - Use semicolon for Windows or convert properly
- bash: |
# For Windows-style paths
export PATH="/usr/bin;$(Agent.ToolsDirectory)"
パイプラインスクリプトでのシェル検出
方法 1:$OSTYPE を使用する(Bash 専用)
- bash: |
case "$OSTYPE" in
linux-gnu*)
echo "Running on Linux agent"
BUILD_PATH="$(Build.SourcesDirectory)"
;;
darwin*)
echo "Running on macOS agent"
BUILD_PATH="$(Build.SourcesDirectory)"
;;
msys*|mingw*|cygwin*)
echo "Running on Windows agent with Git Bash"
# Windows paths already work in MINGW, but may need conversion
BUILD_PATH="$(Build.SourcesDirectory)"
export MSYS_NO_PATHCONV=1
;;
*)
echo "Unknown OS: $OSTYPE"
BUILD_PATH="$(Build.SourcesDirectory)"
;;
esac
echo "Build path: $BUILD_PATH"
cd "$BUILD_PATH"
displayName: 'Cross-platform path handling'
方法 2:uname を使用する(最も移植性が高い方法)
- bash: |
OS_TYPE=$(uname -s)
case "$OS_TYPE" in
Darwin*)
echo "macOS agent detected"
;;
Linux*)
echo "Linux agent detected"
# Check if WSL
if grep -qi microsoft /proc/version 2>/dev/null; then
echo "Running in WSL"
fi
;;
MINGW64*|MINGW32*)
echo "Git Bash on Windows detected"
export MSYS_NO_PATHCONV=1
;;
CYGWIN*)
echo "Cygwin on Windows detected"
;;
MSYS_NT*)
echo "MSYS on Windows detected"
export MSYS_NO_PATHCONV=1
;;
*)
echo "Unknown OS: $OS_TYPE"
;;
esac
displayName: 'Detect shell environment'
方法 3:Agent.OS を使用する(Azure Pipelines の変数)
- bash: |
if [ "$(Agent.OS)" = "Windows_NT" ]; then
echo "Windows agent - applying MINGW path handling"
export MSYS_NO_PATHCONV=1
elif [ "$(Agent.OS)" = "Linux" ]; then
echo "Linux agent"
elif [ "$(Agent.OS)" = "Darwin" ]; then
echo "macOS agent"
fi
displayName: 'Agent-specific configuration'
パス変換の制御
MSYS_NO_PATHCONV(主な方法)
MINGW/Git Bash でのすべてのパス自動変換を無効にします。
- bash: |
# Disable path conversion for this script
export MSYS_NO_PATHCONV=1
# Now Windows paths work as-is
dotnet build /p:Configuration=Release
docker run -v "$(Build.SourcesDirectory):/workspace" myimage
# Optionally re-enable
unset MSYS_NO_PATHCONV
displayName: 'Build with path conversion disabled'
MSYS2_ARG_CONV_EXCL(選択的な除外)
特定の引数パターンを変換対象から除外します。
- bash: |
# Exclude specific prefixes from conversion
export MSYS2_ARG_CONV_EXCL="--config=;/p:"
dotnet build /p:Configuration=Release --config=$(Build.SourcesDirectory)/app.config
displayName: 'Selective path conversion'
cygpath による手動変換
Windows パスと Unix パスを明示的に相互変換します。
- bash: |
# Convert Windows path to Unix
UNIX_PATH=$(cygpath -u "$(Build.SourcesDirectory)")
echo "Unix path: $UNIX_PATH"
# Convert Unix path to Windows
WINDOWS_PATH=$(cygpath -w "$PWD")
echo "Windows path: $WINDOWS_PATH"
# Mixed format (forward slashes with drive letter)
MIXED_PATH=$(cygpath -m "$(Build.SourcesDirectory)")
echo "Mixed path: $MIXED_PATH"
displayName: 'Path conversion examples'
クロスプラットフォームのパイプラインパターン
パターン 1:条件を指定したプラットフォーム別のステップ
jobs:
- job: CrossPlatformBuild
strategy:
matrix:
Linux:
imageName: 'ubuntu-24.04'
osType: 'Linux'
Windows:
imageName: 'windows-2025'
osType: 'Windows_NT'
macOS:
imageName: 'macOS-15'
osType: 'Darwin'
pool:
vmImage: $(imageName)
steps:
# Windows-specific setup
- bash: |
export MSYS_NO_PATHCONV=1
echo "Windows Git Bash configuration applied"
condition: eq(variables['Agent.OS'], 'Windows_NT')
displayName: 'Windows Git Bash setup'
# Cross-platform build
- bash: |
echo "Building on: $(Agent.OS)"
cd "$(Build.SourcesDirectory)"
npm install
npm run build
displayName: 'Cross-platform build'
パターン 2:プラットフォーム検出を備えた再利用可能なテンプレート
# File: templates/cross-platform-script.yml
parameters:
- name: script
type: string
steps:
- bash: |
# Auto-detect Windows and apply MSYS configuration
if [ "$(Agent.OS)" = "Windows_NT" ]; then
export MSYS_NO_PATHCONV=1
fi
# Run provided script
${{ parameters.script }}
displayName: 'Cross-platform script execution'
# Usage in main pipeline:
steps:
- template: templates/cross-platform-script.yml
parameters:
script: |
dotnet build /p:Configuration=Release
dotnet test --no-build
パターン 3:Windows では PowerShell、Unix では Bash
- pwsh: |
Write-Host "Building on Windows with PowerShell"
dotnet build /p:Configuration=Release
condition: eq(variables['Agent.OS'], 'Windows_NT')
displayName: 'Windows build (PowerShell)'
- bash: |
echo "Building on Unix with Bash"
dotnet build -p:Configuration=Release
condition: ne(variables['Agent.OS'], 'Windows_NT')
displayName: 'Unix build (Bash)'
Windows エージェントでの Azure DevOps CLI
CLI でよくあるパスの問題
# ❌ FAILS - Windows paths in bash arguments
- bash: |
az pipelines run --id 123 --variables sourceDir=$(Build.SourcesDirectory)
解決策:
# ✅ CORRECT - Use MSYS_NO_PATHCONV or proper quoting
- bash: |
export MSYS_NO_PATHCONV=1
az pipelines run --id 123 --variables sourceDir="$(Build.SourcesDirectory)"
パスを指定したリポジトリ操作
- bash: |
# Configure Git to handle Windows paths correctly
git config --global core.autocrlf true
git config --global core.safecrlf false
# Clone with proper path handling
export MSYS_NO_PATHCONV=1
az repos pr create \
--repository myrepo \
--source-branch feature/new \
--target-branch main
displayName: 'Git operations on Windows agent'
condition: eq(variables['Agent.OS'], 'Windows_NT')
エージェント構成のベストプラクティス
Windows エージェント向けに Git を構成する
- bash: |
# Recommended Git configuration for Windows agents
git config --global core.autocrlf true
git config --global core.longpaths true
git config --global core.symlinks false
# Show configuration
git config --list | grep core
displayName: 'Configure Git for Windows'
condition: eq(variables['Agent.OS'], 'Windows_NT')
Use System.PreferGitFromPath を使用する
# Use system Git instead of agent-bundled Git
variables:
System.PreferGitFromPath: true
steps:
- bash: |
git --version
which git
displayName: 'Check Git version'
エージェントの .env 構成
セルフホストの Windows エージェントでは、エージェントのルートに .env ファイルを作成します。
# File: agent/.env
System.PreferGitFromPath=true
MSYS_NO_PATHCONV=1
Windows パイプラインの失敗のトラブルシューティング
診断スクリプト
- bash: |
echo "=== Environment Diagnostics ==="
echo "Agent.OS: $(Agent.OS)"
echo "Agent.OSArchitecture: $(Agent.OSArchitecture)"
echo "System.DefaultWorkingDirectory: $(System.DefaultWorkingDirectory)"
echo "Build.SourcesDirectory: $(Build.SourcesDirectory)"
echo ""
echo "=== Shell Detection ==="
echo "OSTYPE: $OSTYPE"
echo "MSYSTEM: $MSYSTEM"
uname -a
echo ""
echo "=== Path Information ==="
echo "PWD: $PWD"
echo "HOME: $HOME"
echo "PATH: $PATH"
echo ""
echo "=== Git Configuration ==="
git --version
which git
git config --list | grep core
echo ""
echo "=== Path Conversion Test ==="
echo "Windows-style: $(Build.SourcesDirectory)"
if command -v cygpath &> /dev/null; then
echo "Unix-style: $(cygpath -u "$(Build.SourcesDirectory)")"
echo "Mixed-style: $(cygpath -m "$(Build.SourcesDirectory)")"
fi
displayName: 'Windows agent diagnostics'
condition: eq(variables['Agent.OS'], 'Windows_NT')
よくあるエラーパターンと修正方法
エラー:「No such file or directory」
# Error: bash: line 1: d:as1: No such file or directory
# ❌ Problem: Backslashes removed
- bash: cd $(System.DefaultWorkingDirectory)
# ✅ Solution: Quote the variable
- bash: cd "$(System.DefaultWorkingDirectory)"
エラー:「Invalid switch」
# Error: Invalid switch - "/d"
# ❌ Problem: MINGW converts /d to Windows path
- bash: dotnet test /d:SonarQubeAnalysisPath=.
# ✅ Solution: Disable path conversion
- bash: |
export MSYS_NO_PATHCONV=1
dotnet test /d:SonarQubeAnalysisPath=.
パスにスペースが含まれる場合のエラー:「Access denied」
# Error: Access to path 'C:\Program' is denied
# ❌ Problem: Unquoted path with spaces
- bash: my-tool $(Agent.ToolsDirectory)/mytool
# ✅ Solution: Always quote paths
- bash: my-tool "$(Agent.ToolsDirectory)/mytool"
ベストプラクティスのまとめ
必ず行うこと
- すべてのパス変数を引用符で囲む:
"$(Build.SourcesDirectory)" - Windows 固有のコマンドでは MSYS_NO_PATHCONV を使用する
$(Agent.OS)またはunameでプラットフォームを検出する- Windows へのデプロイを対象とする場合は、Windows エージェントでテストする
- 可能な場合は、パスにスラッシュを使用する(Git Bash と互換性があります)
絶対に行わないこと
- ❌ 引用符で囲んでいないパスを使用する:
cd $(Build.SourcesDirectory) - ❌ Bash を Linux と同じだと想定する(Windows には Git Bash があります)
- ❌ プラットフォーム固有のパスをハードコードする
- ❌ 1 つのスクリプト内で PowerShell と Bash の構文を混在させる
- ❌ 引数における MINGW のパス変換を無視する
プラットフォーム検出テンプレート
複雑なクロスプラットフォームスクリプトの冒頭で使用します。
- bash: |
#!/bin/bash
set -euo pipefail
# Detect platform and configure
if [ "$(Agent.OS)" = "Windows_NT" ]; then
echo "Windows agent detected"
export MSYS_NO_PATHCONV=1
PATH_SEP=";"
else
echo "Unix-like agent detected"
PATH_SEP=":"
fi
# Your script logic here
echo "Build directory: $(Build.SourcesDirectory)"
cd "$(Build.SourcesDirectory)"
# Platform-agnostic operations
npm install
npm run build
displayName: 'Cross-platform build script'
その他のリソース
クイックリファレンスカード
| シナリオ | 解決策 |
|---|---|
| Windows 上の Bash スクリプト | export MSYS_NO_PATHCONV=1 を使用します |
| Windows エージェントの検出 | $(Agent.OS) が Windows_NT かどうかを確認します |
| Git Bash の検出 | uname -s が MINGW で始まるかどうかを確認します |
| Windows から Unix への変換 | cygpath -u "C:\path" |
| Unix から Windows への変換 | cygpath -w "/c/path" |
| スペースを含むパスの引用符での囲み方 | 常に "$(variable)" を使用します |
| 引数の変換を無効化 | export MSYS2_ARG_CONV_EXCL="pattern" |
| Git バージョンの確認 | git --version && which git |
| システムの Git の使用 | System.PreferGitFromPath: true を設定します |
| パス処理のテスト | 上記の診断スクリプトを実行します |
迷った場合は、Bash タスクを実行する Windows エージェントで MSYS_NO_PATHCONV=1 を使用してください。