# バッチ設計書 52-msbuild.sh

## 概要

本ドキュメントは、MSBuildコマンドのラッパースクリプト `eng/common/msbuild.sh` の設計書です。このスクリプトはArcadeフレームワークの共通コンポーネントとして、MSBuildの実行を標準化し、一貫したビルド体験を提供します。

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

このバッチは、.NETプロジェクトのビルドに使用されるMSBuildコマンドを実行するためのラッパースクリプトです。引数の解析、環境の初期化、およびMSBuildの実行を行い、Arcadeフレームワークの標準的なビルドオプションを適用します。

**業務上の目的・背景**：F#コンパイラプロジェクトを含む.NETエコシステムのプロジェクトでは、MSBuildを使用してコンパイル、テスト、パッケージングを行います。このスクリプトは、MSBuildの実行に必要な環境設定（.NET CLIの初期化、ツールセットの準備など）を自動化し、開発者やCI/CDパイプラインが一貫した方法でビルドを実行できるようにします。直接MSBuildを呼び出す代わりにこのラッパーを使用することで、Arcadeフレームワークの規約に準拠したビルドが保証されます。

**バッチの実行タイミング**：
- 開発者がローカルでプロジェクトをビルドする際
- CI/CDパイプラインでのビルドステップ
- 他のビルドスクリプトから間接的に呼び出される場合
- 特定のMSBuildターゲットを直接実行する必要がある場合

**主要な処理内容**：
1. コマンドライン引数の解析（verbosity、warnaserror、nodereuse、ci、preparemachine）
2. スクリプトルートディレクトリの解決（シンボリックリンク対応）
3. tools.shの読み込みによる共通関数の初期化
4. CI環境の場合、node_reuseをfalseに設定
5. MSBuild関数の呼び出しによるビルド実行
6. 終了コード0での正常終了

**前後の処理との関連**：このスクリプトは `tools.sh` に依存しており、`InitializeBuildTool`、`InitializeToolset`、`MSBuild` などの関数を使用します。上位のビルドスクリプト（build.sh、cibuild.shなど）から呼び出されることが多く、MSBuildの低レベルなラッパーとして機能します。

**影響範囲**：
- プロジェクトのビルド出力（artifacts/bin、artifacts/obj）
- ビルドログ（artifacts/log）
- NuGetパッケージキャッシュ
- 一時ファイル（artifacts/tmp）

## バッチ種別

ビルド実行 / コンパイル

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動 / CI/CDパイプライン / 他スクリプトからの呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| bashシェル | Linux/macOS環境またはWSL |
| tools.sh | 同ディレクトリにtools.shが存在すること |
| global.json | リポジトリルートにglobal.jsonが存在すること |
| ネットワーク接続 | .NET SDKやNuGetパッケージの取得時に必要 |

### 実行可否判定

- tools.shが読み込める状態であること
- .NET SDKが利用可能（または自動インストール可能）であること
- MSBuildの対象プロジェクト/ソリューションが存在すること

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --verbosity | string | No | minimal | MSBuildの出力詳細度（quiet, minimal, normal, detailed, diagnostic） |
| --warnaserror | boolean | No | true | 警告をエラーとして扱うかどうか |
| --nodereuse | boolean | No | true（CI時はfalse） | MSBuildノードの再利用を許可するかどうか |
| --ci | flag | No | false | CI環境での実行を示すフラグ |
| --preparemachine | flag | No | false | マシン準備モード（ビルドプロセスのクリーンアップを有効化） |
| (その他) | any | No | - | MSBuildに渡される追加の引数 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| tools.sh | シェルスクリプト | 共通関数の読み込み |
| global.json | JSON | .NET SDKバージョンおよびツールセット設定 |
| プロジェクト/ソリューションファイル | .csproj/.fsproj/.sln | ビルド対象 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| artifacts/bin | ディレクトリ | ビルド出力（バイナリ） |
| artifacts/obj | ディレクトリ | 中間ファイル |
| artifacts/log | ディレクトリ | ビルドログ |
| 標準出力 | テキスト | MSBuildの出力 |
| 標準エラー出力 | テキスト | エラーおよび警告メッセージ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | MSBuildターゲットおよび設定に依存 |
| 出力先 | artifacts/配下 |
| 文字コード | UTF-8 |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. スクリプトルートの解決
   └─ シンボリックリンクを辿って実際のパスを取得

2. デフォルト変数の初期化
   └─ verbosity=minimal, warn_as_error=true, node_reuse=true, prepare_machine=false

3. コマンドライン引数の解析
   └─ 認識されたオプションは変数に格納、それ以外はextra_argsに追加

4. tools.shの読み込み
   └─ 共通関数を利用可能にする

5. CI環境チェック
   └─ --ci指定時はnode_reuseをfalseに強制

6. MSBuild関数の呼び出し
   └─ extra_argsを渡してMSBuildを実行

7. 正常終了
   └─ ExitWithExitCode 0
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[スクリプトルート解決]
    B --> C[デフォルト変数初期化]
    C --> D[引数解析ループ]
    D --> E{引数あり?}
    E -->|あり| F{認識可能な引数?}
    F -->|--verbosity| G[verbosity設定]
    F -->|--warnaserror| H[warn_as_error設定]
    F -->|--nodereuse| I[node_reuse設定]
    F -->|--ci| J[ci=true設定]
    F -->|--preparemachine| K[prepare_machine=true設定]
    F -->|その他| L[extra_argsに追加]
    G --> D
    H --> D
    I --> D
    J --> D
    K --> D
    L --> D
    E -->|なし| M[tools.sh読み込み]
    M --> N{ci == true?}
    N -->|はい| O[node_reuse=false]
    N -->|いいえ| P[MSBuild実行]
    O --> P
    P --> Q[ExitWithExitCode 0]
    Q --> R[バッチ終了]
```

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

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

このバッチはデータベース操作を行いません。

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 0以外 | MSBuildエラー | コンパイルエラー、ターゲット失敗など | エラーメッセージを確認し、ソースコードまたは設定を修正 |
| 1 | 初期化エラー | .NET SDKが見つからない、インストール失敗 | ネットワーク接続を確認、手動でSDKをインストール |
| 2 | ツールセットエラー | Arcade SDKが復元されていない | restoreを実行してから再試行 |
| 3 | ツールセットパスエラー | 無効なツールセットパス | toolset_dirを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（MSBuildに依存） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

1. エラーメッセージの確認（verbosityをdiagnosticに設定して詳細を取得）
2. artifacts/log配下のバイナリログ（.binlog）を確認
3. NuGetパッケージの復元状態を確認
4. global.jsonの.NET SDKバージョンが正しいか確認
5. CI環境では--preparemachineオプションを使用してクリーンな状態から再試行

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（ファイルシステム操作のみ） |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし（MSBuildのインクリメンタルビルド機構に依存） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | プロジェクト数に依存 |
| 目標処理時間 | プロジェクト規模に依存 |
| メモリ使用量上限 | .NET SDKおよびMSBuildの要件に準拠 |

## 排他制御

- node_reuse=trueの場合：MSBuildノードを再利用し、同一マシン上の他のビルドと共有される可能性がある
- node_reuse=false（CI環境）の場合：各ビルドが独立したMSBuildノードを使用
- 同一プロジェクトへの同時ビルドは推奨されない（ファイルロック競合の可能性）

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| MSBuild出力 | ビルド中 | コンパイル進捗、警告、エラー |
| バイナリログ | CI環境でのビルド完了時 | 詳細なビルド情報（.binlog形式） |
| エラーログ | エラー発生時 | "Build failed with exit code $exit_code. Check errors above." |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | CI/CDパイプライン失敗通知 |
| 処理時間 | プロジェクト固有の閾値 | CI/CDパイプラインタイムアウト |

## 備考

- このスクリプトはArcadeフレームワークの共通コンポーネントとして提供されている
- CI環境では自動的にnode_reuseがfalseに設定され、ビルドの決定性が向上する
- tools.shのMSBuild関数は、Arcadeログガーを自動的に追加してAzure DevOpsパイプラインとの統合を行う
- warn_as_errorのデフォルトがtrueであるため、警告も修正が必要
- バイナリログはCI環境でデフォルトで有効化され、ビルドの診断に使用できる
