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

## 概要

本ドキュメントは、リリース前にNuGetパッケージ内のPDBファイルの整合性と完全性を検証するためのPowerShellスクリプト `eng/common/post-build/symbols-validation.ps1` の設計仕様を記載する。

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

このバッチは、NuGetパッケージに含まれるバイナリファイル（DLL、EXE、SO、DYLIB）に対して、シンボルサーバー（MSDL、SymWeb）にシンボル情報が公開されているかを検証する。並列処理を使用して大量のパッケージを効率的に検証する。

**業務上の目的・背景**：.NETランタイムをリリースする際、デバッグシンボル（PDB）がシンボルサーバーに正しく公開されていることは、開発者がクラッシュダンプを解析したり、ステップ実行デバッグを行うために不可欠である。本スクリプトはリリース前の品質ゲートとして機能し、シンボル公開の漏れを検出する。

**バッチの実行タイミング**：CI/CDパイプラインのポストビルドフェーズで実行される。パッケージ公開前の検証ステップとして構成される。

**主要な処理内容**：
1. dotnet-symbolツールのインストール
2. NuGetパッケージの展開
3. DLL/EXE/SO/DYLIBファイルの検出
4. MSDLとSymWebの両シンボルサーバーへのシンボル問い合わせ
5. シンボル存在確認と結果レポート

**前後の処理との関連**：本スクリプトはtools.ps1を読み込む。パッケージビルド完了後、公開前に実行される。

**影響範囲**：検証のみであり、パッケージやシンボルサーバーには影響しない。検証結果に基づいてリリース可否が判断される。

## バッチ種別

検証 / シンボル検証 / ポストビルド

## 実行スケジュール

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

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| PowerShell | PowerShell 5.1以降が利用可能であること |
| ネットワーク接続 | MSDL、SymWebシンボルサーバーへのアクセスが可能であること |
| dotnet CLI | dotnet toolインストールが可能であること |
| NuGetパッケージ | 検証対象の.nupkgファイルが存在すること |

### 実行可否判定

- InputPathが存在しない場合は正常終了（検証対象なし）
- 検証対象パッケージがない場合も正常終了

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | 検証進捗と結果 |
| 終了コード | int | 0:全シンボルあり、1:欠落あり |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| 展開ディレクトリ | $ExtractPath\{GUID}\ |
| シンボルディレクトリ | $ExtractPath\{GUID}\Symbols\ |
| クリーンアップ | -Clean指定時に削除 |

## 処理フロー

### 処理シーケンス

```
1. dotnet-symbolツールインストール
   └─ dotnet tool install --global
2. 除外リスト読み込み
   └─ SymbolExclusionFileからHashSetに格納
3. パッケージループ開始
   └─ *.nupkgファイルを順次処理
4. パッケージ展開
   └─ ZipFile.ExtractToDirectoryで展開
5. バイナリファイル検出
   └─ .dll、.exe、.so、.dylibを再帰検索
6. シンボル検証（並列）
   └─ dotnet-symbolで各ファイルのシンボルを問い合わせ
7. 結果判定
   └─ MSDL/SymWeb両方にシンボルがあるか確認
8. 結果集計
   └─ 欠落シンボル数をカウント
9. クリーンアップ（-Clean時）
   └─ 展開ディレクトリを削除
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{InputPath存在?}
    B -->|No| C[正常終了]
    B -->|Yes| D[dotnet-symbolインストール]
    D --> E[除外リスト読み込み]
    E --> F[パッケージループ]
    F --> G{パッケージあり?}
    G -->|No| H[結果集計]
    G -->|Yes| I{Arcade-services?}
    I -->|Yes| J[スキップ]
    I -->|No| K[Start-Job並列実行]
    J --> F
    K --> L[パッケージ展開]
    L --> M[バイナリ検出]
    M --> N[除外判定]
    N --> O[dotnet-symbol MSDL]
    O --> P[dotnet-symbol SymWeb]
    P --> Q{シンボル存在?}
    Q -->|両方あり| R[成功]
    Q -->|片方/なし| S[失敗カウント]
    R --> T[Job完了]
    S --> T
    T --> F
    H --> U{失敗あり?}
    U -->|Yes| V[エラー終了]
    U -->|No| W[正常終了]
```

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

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

本スクリプトはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| -1 | 展開失敗 | ZIPファイル展開エラー | パッケージファイルの整合性確認 |
| -2 | ファイル未存在 | 入力パッケージが見つからない | パスを確認 |
| 1 | シンボル欠落 | シンボルサーバーにシンボルがない | シンボル公開ジョブを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 5回（MaxRetry） |
| リトライ間隔 | dotnet-symbolのデフォルト |
| リトライ対象エラー | シンボルサーバー問い合わせ失敗 |

### 障害時対応

1. エラーメッセージを確認し、該当パッケージを特定
2. シンボル公開ジョブのログを確認
3. 必要に応じてシンボルを手動で公開

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

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

本スクリプトはトランザクション管理を行わない。

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数十〜数百パッケージ |
| 目標処理時間 | パッケージ数とネットワーク速度依存 |
| メモリ使用量上限 | パッケージ展開サイズ依存 |
| 並列ジョブ数 | 16（MaxParallelJobs） |

## 排他制御

並列ジョブごとに異なるGUIDディレクトリを使用するため、排他制御は不要。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | 検証開始時 | "Validating $PackagePath" |
| 情報ログ | ファイル検証時 | "Checking file $FileName..." |
| 情報ログ | シンボル発見時 | "Symbols found on MSDL ($type) and SymWeb ($type)" |
| 情報ログ | 検証完了時 | "All symbols verified for package $packagePath" |
| 警告ログ | シンボルなし時 | "No symbols found on MSDL!" / "No symbols found on SymWeb!" |
| 警告ログ | 参照アセンブリ時 | "Ignoring reference assembly file $FileName" |
| エラーログ | 欠落検出時 | "Missing symbols for $result modules in the package $packagePath" |
| エラーログ | 重複シンボル時 | "$packagePath has duplicated symbol files" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | CI/CDパイプライン（Write-PipelineTelemetryError） |
| 欠落シンボル数 | 1以上 | CI/CDパイプラインログ（カテゴリ：CheckSymbols） |

## 備考

- Microsoft.DotNet.Darc.*とMicrosoft.DotNet.Maestro.Tasks.*パッケージはスキップされる（Issue #2457）
- 参照アセンブリ（\ref\配下）はシンボル検証対象外
- dotnet-symbolの--microsoft-symbol-serverオプションでMSDLを、--internal-serverオプションでSymWebを問い合わせ
- シンボル種別：Module、PDB、NGen PDB、SO DBG、Dylib DWARF
- 検証対象拡張子：.dll、.exe、.so、.dylib
- SecondsBetweenLoadChecks（10秒）間隔でジョブ数を監視
- HashSetで除外パスを管理し、高速な除外判定を実現
