# バッチ設計書 61-Set-LatestVCToolsVersion.ps1

## 概要

本ドキュメントは、CI/CDパイプラインで使用されるPowerShellスクリプト `Set-LatestVCToolsVersion.ps1` のバッチ設計書である。Visual Studioにインストールされている最新のVC++ Toolsバージョンを検出し、Azure DevOpsのパイプライン変数として設定する。

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

本スクリプトは、ビルド環境にインストールされているVisual StudioのVC++ Toolsの最新バージョンを自動検出し、そのバージョン番号をAzure DevOpsのパイプライン変数 `VCToolsVersion` に設定する処理を行う。

**業務上の目的・背景**：OpenConsoleプロジェクトのCI/CDビルドパイプラインにおいて、ビルドに使用するVC++ Toolsのバージョンを動的に決定する必要がある。ビルドエージェントにインストールされているVisual Studioのバージョンは環境によって異なる可能性があり、パッケージマネージャが報告するバージョンとディスク上の実際のバージョンが一致しないケースも観測されている（コード内コメントに記載）。このスクリプトにより、常に正しいVC++ Toolsバージョンを使用してビルドを実行できるようにする。

**バッチの実行タイミング**：CI/CDパイプラインのビルドステップの前段階として、ビルドジョブ開始時に実行される。Azure DevOpsのビルドパイプラインから自動的に呼び出される。

**主要な処理内容**：
1. vswhereを使用して最新のVisual Studioインスタンス情報をXML形式で取得する
2. パッケージ一覧からMicrosoft.VisualCpp.Tools.Coreのバージョンを抽出する
3. Visual Studioのインストールパスからvc toolsのルートディレクトリを特定する
4. パッケージバージョンに対応するディレクトリが実在するか検証する
5. ディレクトリが存在しない場合、実際のディレクトリ一覧から最新バージョンを再取得する
6. Azure DevOpsのパイプライン変数 `VCToolsVersion` に検出したバージョンを設定する

**前後の処理との関連**：本スクリプトはビルドパイプラインの初期化フェーズで実行され、後続のMSBuildビルドステップで `VCToolsVersion` 環境変数が参照される。

**影響範囲**：Azure DevOpsパイプラインのジョブスコープの環境変数 `VCToolsVersion` に影響する。後続のすべてのビルドステップがこの変数を参照する可能性がある。

## バッチ種別

環境設定 / CI/CD支援

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（CI/CDパイプライン実行時） |
| 実行時刻 | パイプライントリガーに依存 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | Azure DevOpsパイプラインのビルドジョブ開始時 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Visual Studioインストール済み | Microsoft.VisualStudio.Component.VC.Tools.x86.x64コンポーネントを含むVisual Studioがインストールされていること |
| vswhereの存在 | `C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe` が利用可能であること |
| Azure DevOps環境 | `##vso` ログコマンドが処理されるAzure DevOpsエージェント環境で実行されること |

### 実行可否判定

vswhereコマンドが正常に実行でき、VC++ Toolsパッケージ情報が取得できること。Visual Studioがインストールされていない場合はエラーとなる。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 本スクリプトはパラメータを受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| vswhere.exe出力 | XML | Visual Studioインスタンスのパッケージ情報 |
| VC Tools ディレクトリ | ファイルシステム | `{VSRoot}\VC\Tools\MSVC` 配下のバージョンディレクトリ一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | 検出されたVC Toolsバージョン情報 |
| Azure DevOpsパイプライン変数 | ##vsoコマンド | `VCToolsVersion` 変数にバージョン文字列を設定 |

### 出力ファイル仕様

ファイル出力はなし。標準出力にログメッセージおよびAzure DevOpsのログコマンドを出力する。

| 項目 | 内容 |
|-----|------|
| ファイル名 | 該当なし（標準出力のみ） |
| 出力先 | 標準出力 |
| 文字コード | UTF-8 |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. vswhereでVisual Studioインスタンス情報取得
   └─ vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -include packages -format xml を実行
2. パッケージ情報からVC Toolsバージョン抽出
   └─ Microsoft.VisualCpp.Tools.Coreパッケージのversionプロパティを取得
3. Visual Studioインストールパス取得
   └─ vswhere.exe -latest -requires ... -property resolvedInstallationPath を実行
4. VC Toolsルートパス構築
   └─ {VSRoot}\VC\Tools\MSVC をVC Toolsルートとする
5. パッケージバージョンのディレクトリ存在確認
   └─ {VCToolsRoot}\{バージョン} のパスをGet-Itemで確認（ErrorAction:Ignore）
6. バージョン不一致時の補正処理
   └─ ディレクトリ一覧をGet-ChildItemで取得し、[Version]でソートして最新を取得
   └─ 不一致の場合、ToString(3)で3セグメントのバージョン文字列に変換
7. 環境変数設定コマンド出力
   └─ ##vso[task.setvariable variable=VCToolsVersion]コマンドで変数を設定
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[vswhereでVSインスタンス情報取得]
    B --> C[VC Toolsパッケージバージョン抽出]
    C --> D[VSインストールパス取得]
    D --> E[VC Toolsルートパス構築]
    E --> F{パッケージバージョンのディレクトリが存在するか}
    F -->|存在する| H[バージョン確定]
    F -->|存在しない| G[ディレクトリ一覧から最新バージョン再取得]
    G --> G2{パッケージ版と実ディレクトリ版が一致するか}
    G2 -->|不一致| G3[不一致メッセージ出力・バージョン上書き]
    G2 -->|一致| H
    G3 --> H
    H --> I[バージョン情報を標準出力]
    I --> J[##vsoコマンドでパイプライン変数VCToolsVersion設定]
    J --> K[バッチ終了]
```

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

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

データベース操作は行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | - |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | vswhere実行エラー | vswhereが存在しないまたは実行に失敗した場合 | Visual Studioインストーラーの存在を確認する |
| - | パッケージ未検出 | VC Toolsパッケージが見つからない場合 | VC++ Toolsコンポーネントがインストールされているか確認する |
| - | ディレクトリ不在 | パッケージバージョンのディレクトリが存在しない場合 | スクリプト内でフォールバック処理（ディレクトリスキャン）が自動実行される |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ処理は未実装） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

スクリプトが失敗した場合、パイプライン変数 `VCToolsVersion` が設定されないため、後続のビルドステップが失敗する可能性がある。Visual Studioのインストール状態を確認し、必要に応じてビルドエージェントの再構成を行う。

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回のバージョン検出処理 |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

排他制御は不要。読み取り専用の操作のみを行い、環境変数の設定はパイプラインジョブスコープに限定される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | バージョン検出時 | `Latest VCToolsVersion: {version}` |
| 情報ログ | 変数設定時 | `Updating VCToolsVersion environment variable for job` |
| 警告ログ | バージョン不一致時 | `VC Tools Mismatch: Directory = {actual}, Package = {package}` |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| パイプラインステップ失敗 | 1回 | Azure DevOpsパイプライン通知 |

## 備考

- vswhereが報告するパッケージバージョンとディスク上のディレクトリバージョンが一致しないケースが観測されており、そのための補正ロジックが組み込まれている（コード内コメント参照）
- `##vso[task.setvariable]` はAzure DevOps固有のログコマンドであり、他のCI/CD環境では動作しない
- ソースファイル: `build/scripts/Set-LatestVCToolsVersion.ps1`
