# バッチ設計書 67-symbols-validation.ps1

## 概要

本ドキュメントは、NuGetパッケージに含まれるシンボルファイル（PDB）の検証を行うPowerShellスクリプト `eng/common/post-build/symbols-validation.ps1` の設計仕様を定義する。

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

このバッチは、NuGetパッケージに含まれるDLL/EXE/SO/DYLIBファイルに対応するシンボルファイル（PDB/DBG/DWARF）がMicrosoft Symbol Server（MSDL）およびSymWebに正しくアップロードされているかを検証する。dotnet-symbolツールを使用して、各バイナリのシンボルの有無をチェックする。

**業務上の目的・背景**：デバッグやクラッシュダンプ解析のためには、リリースされたバイナリに対応するシンボルファイルがシンボルサーバーに公開されている必要がある。本バッチは、パッケージ公開前にシンボルが適切にアップロードされているかを自動検証し、デバッグ体験の品質を保証する。

**バッチの実行タイミング**：CIパイプラインのポストビルドステージで、シンボルアップロード完了後に実行される。

**主要な処理内容**：
1. dotnet-symbolツールのグローバルインストール
2. NuGetパッケージの展開と対象バイナリの抽出
3. 各バイナリに対するシンボル検索（MSDLとSymWeb両方）
4. 並列処理による高速検証
5. 検証結果のサマリー報告

**前後の処理との関連**：シンボルアップロード処理の後、パッケージ公開前に実行される。sourcelink-validation.ps1やnuget-validation.ps1と並行して実行可能。

**影響範囲**：パイプラインのビルドステータスに影響。シンボル不足が検出された場合、ビルドが失敗する。

## バッチ種別

検証処理 / シンボルファイル整合性検証

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（CIビルド時） |
| 実行時刻 | - |
| 実行曜日 | - |
| 実行日 | - |
| トリガー | CIパイプラインのポストビルドステージ |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| NuGetパッケージの存在 | 検証対象の.nupkgファイルが指定パスに存在すること |
| インターネット接続 | シンボルサーバーへのアクセスとdotnet-symbolのインストールのため |
| .NET SDK | dotnet toolコマンドが実行可能であること |
| 書き込み権限 | 展開ディレクトリへの書き込みが可能であること |

### 実行可否判定

InputPathが指定され、対象ディレクトリにパッケージが存在する場合に実行される。パッケージが存在しない場合は正常終了（ExitWithExitCode 0）。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| InputPath | string | Yes | - | NuGetパッケージが格納されているディレクトリパス |
| ExtractPath | string | Yes | - | パッケージ展開先ディレクトリパス |
| DotnetSymbolVersion | string | Yes | - | 使用するdotnet-symbolのバージョン |
| CheckForWindowsPdbs | switch | No | - | Windows PDBの存在もチェック |
| ContinueOnError | switch | No | - | エラー発生時も検証を継続 |
| Clean | switch | No | - | 検証後に展開ディレクトリを削除 |
| SymbolExclusionFile | string | No | - | 検証から除外するシンボルのリストファイル |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| *.nupkg | NuGetパッケージ | 検証対象のパッケージファイル群 |
| SymbolExclusionFile | テキスト | 除外対象ファイルパスのリスト |
| tools.ps1 | PowerShellスクリプト | 共通ユーティリティ関数 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| コンソール | テキスト | 検証結果メッセージ |
| Azure Pipelines | テレメトリエラー | CheckSymbolsカテゴリのエラー |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 展開されたパッケージコンテンツ |
| 出力先 | ExtractPathで指定されたディレクトリ |
| 文字コード | - |
| 区切り文字 | - |

## 処理フロー

### 処理シーケンス

```
1. パラメータ受け取りと初期化
   └─ エラーコード定数定義（ERROR_BADEXTRACT=-1、ERROR_FILEDOESNOTEXIST=-2）
2. 入力検証
   └─ InputPathの存在確認（存在しなければ正常終了）
3. 除外リストの読み込み
   └─ SymbolExclusionFileが存在する場合、HashSetに読み込み
4. dotnet-symbolのインストール
   └─ InstallDotnetSymbol関数で指定バージョンをグローバルインストール
5. 展開ディレクトリの初期化
   └─ 既存ディレクトリがあれば削除
6. パッケージごとの検証（並列処理）
   └─ 6.1 Microsoft.DotNet.Darc.*とMicrosoft.DotNet.Maestro.Tasks.*は除外
   └─ 6.2 パッケージをZIP展開
   └─ 6.3 対象拡張子（.dll, .exe, .so, .dylib）のファイルを抽出
   └─ 6.4 \ref\パス内のファイルは除外（参照アセンブリ）
   └─ 6.5 各ファイルでdotnet-symbolを実行
   └─ 6.6 MSDLとSymWebの両方でシンボル検索
   └─ 6.7 最大5回のリトライ
7. ジョブ結果の集約
   └─ 7.1 各ジョブの結果を確認
   └─ 7.2 失敗・重複エラーをカウント
8. 最終結果報告
   └─ 8.1 全成功："All symbols validated!"
   └─ 8.2 失敗あり：エラー報告してExitWithExitCode 1
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{InputPath存在?}
    B -->|No| C[正常終了 ExitCode 0]
    B -->|Yes| D[除外リスト読み込み]
    D --> E[dotnet-symbolインストール]
    E --> F[展開ディレクトリ初期化]
    F --> G[パッケージループ開始]
    G --> H{Arcade-servicesパッケージ?}
    H -->|Yes| I[スキップ]
    H -->|No| J[Start-Job 並列検証]
    J --> K{16ジョブ以上?}
    K -->|Yes| L[待機]
    L --> K
    K -->|No| M[次のパッケージ]
    M --> G
    I --> M
    G -->|終了| N[全ジョブ待機]
    N --> O[結果集約]
    O --> P{失敗あり?}
    P -->|Yes| Q[エラー報告]
    Q --> R[ExitWithExitCode 1]
    P -->|No| S["All symbols validated!"]
    S --> T[正常終了]
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| -1 | 展開エラー | パッケージにシンボルファイルが重複 | パッケージ構成を確認 |
| -2 | ファイル不在 | 指定されたパッケージが存在しない | パッケージパスを確認 |
| 正の数 | シンボル不足 | MSDLまたはSymWebにシンボルが見つからない | シンボルアップロードを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 5回（MaxRetry） |
| リトライ間隔 | 即時 |
| リトライ対象エラー | シンボルサーバーからの取得失敗 |

### 障害時対応

1. シンボルアップロードパイプラインのログを確認
2. dotnet-symbolを手動実行して問題を切り分け
3. シンボルサーバーの状態を確認

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（読み取り専用操作） |
| コミットタイミング | - |
| ロールバック条件 | - |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数十〜数百パッケージ |
| 目標処理時間 | パッケージ数に依存 |
| メモリ使用量上限 | 並列ジョブ16個分 |
| 並列度 | 最大16ジョブ（MaxParallelJobs） |

## 排他制御

Start-Jobによる並列処理を使用。各ジョブは独自のGUIDディレクトリに展開するため、ファイル競合は発生しない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | パッケージ検証時 | "Validating {PackagePath}" |
| 進捗ログ | ファイル検証時 | "Checking file {FileName}..." |
| 成功ログ | シンボル発見時 | "Symbols found on MSDL ({type}) and SymWeb ({type})" |
| 警告ログ | シンボル不在時 | "No symbols found on MSDL!" / "No symbols found on SymWeb!" |
| 成功ログ | 完了時 | "All symbols validated!" |
| エラーログ | 失敗時 | "Symbols missing for {count}/{total} packages" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| シンボル不足 | 1件以上 | Azure Pipelines（ビルド失敗） |
| 重複シンボル | 1件以上 | Azure Pipelines（ビルド失敗） |

## 備考

- 並列処理により検証を高速化（最大16並列）
- dotnet-symbolツールを使用してシンボルサーバーにクエリ
- Arcade-servicesパッケージ（Microsoft.DotNet.Darc.*、Microsoft.DotNet.Maestro.Tasks.*）は既知の問題によりスキップ（Issue #2457）
- \ref\パス内の参照アセンブリはシンボル検証から除外
- PortableおよびEmbedded PDB、Windows PDB、Linux/macOS用シンボル（.so.dbg、.dylib.dwarf）に対応
- dotnet/arcadeフレームワークの共通スクリプト群の一部
