mcpField
A
ado-windows-git-bash-compatibility

ado-windows-git-bash-compatibility

github.com/josiahsiegelクラウド・DevOps59155 回インストール19 週間前に更新
リポジトリ

ado-windows-git-bash-compatibility について

Azure DevOps チーム向けの互換性ガイドです。Windows エージェントで Git Bash を使う際のパス変換やシェルの違いを扱い、クロスプラットフォームのパイプライン例、設定方法、トラブルシューティングを紹介します。

主な機能

  1. 01MINGW のパス変換問題の解説
  2. 02MSYS のパス変換制御
  3. 03クロスプラットフォームのパイプライン例
  4. 04OS とシェルの検出方法
  5. 05一般的なエラーと診断方法

活用シーン

  1. 01Windows パイプラインのパスエラー修正
  2. 02複数 OS 向けビルド手順の作成
  3. 03Git Bash のコマンド引数設定
  4. 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"

ベストプラクティスのまとめ

必ず行うこと
  1. すべてのパス変数を引用符で囲む:"$(Build.SourcesDirectory)"
  2. Windows 固有のコマンドでは MSYS_NO_PATHCONV を使用する
  3. $(Agent.OS) または uname でプラットフォームを検出する
  4. Windows へのデプロイを対象とする場合は、Windows エージェントでテストする
  5. 可能な場合は、パスにスラッシュを使用する(Git Bash と互換性があります)
絶対に行わないこと
  1. ❌ 引用符で囲んでいないパスを使用する:cd $(Build.SourcesDirectory)
  2. ❌ Bash を Linux と同じだと想定する(Windows には Git Bash があります)
  3. ❌ プラットフォーム固有のパスをハードコードする
  4. ❌ 1 つのスクリプト内で PowerShell と Bash の構文を混在させる
  5. ❌ 引数における 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 を使用してください。

コメント