# バッチ設計書 27-evaluate-changed-paths

## 概要

本ドキュメントは、Git差分から変更パスを評価し、Azure DevOps変数を設定するためのスクリプト `eng/evaluate-changed-paths.sh` の設計を記述する。

### 本バッチの処理概要

このバッチは、Gitの差分情報から変更されたファイルパスを評価し、指定されたフィルタ条件（含める/除外するパス）に基づいてAzure DevOpsパイプライン変数を設定する処理を実行する。

**業務上の目的・背景**：大規模なモノリポジトリでは、すべての変更に対してすべてのビルド・テストを実行すると時間とリソースが無駄になる。本バッチは、変更されたファイルのパスを分析し、特定のサブセット（ライブラリ、インストーラ等）に関連する変更があるかどうかを判定する。この判定結果をAzure DevOps変数として設定することで、後続のパイプラインステップを条件付きで実行・スキップでき、CIの効率化を実現する。

**バッチの実行タイミング**：本バッチはCIパイプラインの初期段階で実行される。PRの変更内容を分析し、後続のビルド・テストステップの実行要否を判定する。

**主要な処理内容**：
1. コマンドライン引数の解析（difftarget、excludepaths、includepaths、subset、azurevariable）
2. 除外パスによる差分フィルタリング
3. 含めるパスによる差分フィルタリング
4. マッチするファイルがある場合、Azure DevOps変数を設定

**前後の処理との関連**：本バッチはパイプラインの初期ステップとして実行され、設定された変数は後続のビルド・テストステップの条件として参照される。

**影響範囲**：本バッチはAzure DevOpsパイプライン変数を設定する。これにより後続のジョブの実行可否が制御される。ファイルシステムへの書き込みは行わない。

## バッチ種別

パス評価（CI最適化）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（CI実行時） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | CIパイプライン |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Unix環境 | Bash実行環境が利用可能であること |
| Git | gitコマンドが利用可能であること |
| Azure DevOps | Azure DevOpsパイプライン内で実行されること |

### 実行可否判定

difftargetパラメータが指定されている必要がある。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --difftarget | string | Yes | - | 差分比較対象（SHA/ブランチ名） |
| --excludepaths | string | No | - | 除外パス（'+'区切り） |
| --includepaths | string | No | - | 含めるパス（'+'区切り） |
| --subset | string | No | - | サブセット名（ログ用） |
| --azurevariable | string | No | - | 設定するAzure DevOps変数名 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Gitリポジトリ | Git | 差分情報の取得元 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| Azure DevOps変数 | 変数 | 指定された変数名にtrueを設定 |
| 標準出力 | テキスト | 処理進捗・マッチしたファイル一覧 |

### 出力ファイル仕様

本バッチはファイル出力を行わない。

## 処理フロー

### 処理シーケンス

```
1. 引数解析
   └─ difftarget、excludepaths、includepaths、subset、azurevariableの取得
2. パイプラインログ関数読み込み
   └─ eng/common/pipeline-logging-functions.sh の読み込み
3. 除外パスのプローブ（excludepaths指定時）
   └─ git diff --exit-code で差分確認
   └─ マッチした場合はfound_applying_changes=true
4. 含めるパスのプローブ（includepaths指定時、まだマッチしていない場合）
   └─ git diff --exit-code で差分確認
   └─ マッチした場合はfound_applying_changes=true
5. 結果設定
   └─ マッチした場合：Azure DevOps変数を設定
   └─ マッチしなかった場合：変更なしメッセージ出力
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[引数解析]
    B --> C[パイプラインログ関数読み込み]
    C --> D{excludepaths指定あり?}
    D -->|はい| E[除外パスプローブ]
    D -->|いいえ| F{includepaths指定あり?}
    E --> G{差分あり?}
    G -->|はい| H[found=true、マッチファイル表示]
    G -->|いいえ| F
    H --> I[Azure DevOps変数設定]
    F -->|はい| J[含めるパスプローブ]
    F -->|いいえ| K[変更なしメッセージ出力]
    J --> L{差分あり?}
    L -->|はい| M[found=true、マッチファイル表示]
    L -->|いいえ| K
    M --> I
    I --> N[バッチ終了]
    K --> N
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | Git操作エラー | git diffが失敗 | Gitリポジトリの状態を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

### 障害時対応

set -eにより、エラー発生時は即座にスクリプトが終了する。Gitの状態やdifftargetパラメータを確認して再実行する。

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし |
| コミットタイミング | - |
| ロールバック条件 | - |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | パス数に依存 |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

読み取り専用操作のため、排他制御は不要。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | パスプローブ開始時 | "******* Probing {subset} exclude/include paths *******" |
| パスログ | 各パス評価時 | パス文字列 |
| マッチログ | 差分検出時 | "----- Matching files for {subset} -----"、ファイル一覧 |
| 変数設定ログ | 変数設定時 | "Setting pipeline variable {name}=true" |
| 結果ログ | 変更なし時 | "No changed files for {subset}" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| なし | - | - |

## 備考

- set -fでグロビングを無効化している（パスパターンを正確に処理するため）
- set -uで未定義変数のアクセスをエラーにしている
- set -eでコマンドエラー時に即座に終了する
- git diffオプション：
  - -M：名前変更検出
  - -C：コピー検出
  - -b：空白変更無視
  - --ignore-cr-at-eol：行末CRを無視
  - --ignore-space-at-eol：行末空白を無視
  - --exit-code：差分がある場合に非ゼロで終了
- パスフィルタ構文：
  - :!path：除外パス
  - :path：含めるパス
- Write-PipelineSetVariable関数でAzure DevOps変数を設定
- is_multi_job_variable=trueで複数ジョブ間で変数を共有
