# バッチ設計書 28-mark-shipped

## 概要

本ドキュメントは、Public APIを出荷済みとしてマークするためのスクリプト `scripts/PublicApi/mark-shipped.ps1` の設計を記述する。

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

このバッチは、PublicAPI.Unshipped.txt から PublicAPI.Shipped.txt へAPIエントリを移動することで、未出荷APIを出荷済みとしてマークする処理を実行する。

**業務上の目的・背景**：Roslynプロジェクトは、Public API Analyzersを使用してPublic APIの互換性を管理している。新しく追加されたPublic APIはPublicAPI.Unshipped.txtに記録され、リリース時にPublicAPI.Shipped.txtに移動することで出荷済みとしてマークされる。このプロセスにより、APIの破壊的変更を検出し、セマンティックバージョニングに従った適切なバージョン番号を決定できる。本バッチは、このリリースプロセスを自動化し、手動でのファイル編集によるエラーを防止する。

**バッチの実行タイミング**：本バッチは新しいバージョンのリリース時に実行される。リリースブランチの作成後、出荷準備が完了した時点で実行し、その変更をコミットする。

**主要な処理内容**：
1. リポジトリ内のすべてのPublicAPI.Shipped.txtファイルを検索
2. 各ディレクトリについて、対応するPublicAPI.Unshipped.txtの内容を読み込み
3. *REMOVED*プレフィックス付きのエントリを抽出し、Shipped.txtから該当APIを削除
4. その他のエントリをShipped.txtに追加
5. Shipped.txtをソートして保存
6. Unshipped.txtを空にする

**前後の処理との関連**：本バッチはリリースプロセスの一部として実行される。実行後、変更されたファイルはコミットされ、リリースブランチに含まれる。

**影響範囲**：本バッチはリポジトリ内のすべてのPublicAPI.Shipped.txtとPublicAPI.Unshipped.txtファイルを更新する。これらのファイルはPublic API Analyzersによって参照され、APIの破壊的変更の検出に使用される。

## バッチ種別

リリース管理（Public API出荷マーク）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（リリース時） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | 手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| PowerShell | PowerShell実行環境が利用可能であること |
| リポジトリ | Roslynリポジトリのルートで実行されること |

### 実行可否判定

PublicAPI.Shipped.txtファイルが1つ以上存在する必要がある。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 入力パラメータなし |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| PublicAPI.Shipped.txt | テキスト | 出荷済みPublic API一覧 |
| PublicAPI.Unshipped.txt | テキスト | 未出荷Public API一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| PublicAPI.Shipped.txt | テキスト | 更新された出荷済みAPI一覧 |
| PublicAPI.Unshipped.txt | テキスト | 空ファイル |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（1行1API） |
| 文字コード | ASCII |
| ソート順 | アルファベット順 |

## 処理フロー

### 処理シーケンス

```
1. スクリプト初期化
   └─ build-utils.ps1の読み込み、リポジトリルートへ移動
2. PublicAPI.Shipped.txtファイル検索
   └─ Get-ChildItem -re -in でファイル一覧取得
3. 各ディレクトリに対してMarkShipped関数実行
   └─ 3a. Shipped.txtの読み込み
   └─ 3b. Unshipped.txtの読み込み
   └─ 3c. *REMOVED*エントリの抽出
   └─ 3d. 通常エントリをShippedに追加
   └─ 3e. RemovedエントリをShippedから削除
   └─ 3f. Shipped.txtをソートして保存
   └─ 3g. Unshipped.txtを空にして保存
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[build-utils.ps1読み込み]
    B --> C[RepoRootへ移動]
    C --> D[PublicAPI.Shipped.txt検索]
    D --> E{ファイルあり?}
    E -->|なし| F[バッチ終了]
    E -->|あり| G[MarkShipped関数呼び出し]
    G --> H[Shipped.txt読み込み]
    H --> I[Unshipped.txt読み込み]
    I --> J[各エントリを処理]
    J --> K{*REMOVED*?}
    K -->|はい| L[removedリストに追加]
    K -->|いいえ| M[shippedリストに追加]
    L --> N[次のエントリ]
    M --> N
    N --> O{全エントリ処理完了?}
    O -->|いいえ| J
    O -->|はい| P[removedをshippedから除外]
    P --> Q[Shipped.txtをソートして保存]
    Q --> R[Unshipped.txtを空で保存]
    R --> S[次のディレクトリ]
    S --> E
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | ファイル操作エラー | ファイルの読み書きに失敗 | ファイルアクセス権限を確認 |

### リトライ仕様

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

### 障害時対応

エラー発生時は例外メッセージが出力される。ファイルのアクセス権限やパスを確認し、再実行する。Gitを使用してファイルを元の状態に戻すことが可能。

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | プロジェクト数（数十〜数百） |
| 目標処理時間 | 数秒〜数十秒 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

同一ファイルへの同時アクセスは避けるべきである。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 各ディレクトリ処理時 | "Processing {ディレクトリパス}" |
| エラーログ | 例外発生時 | 例外メッセージ |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 1 | 手動実行のため通知なし |

## 備考

- Public API Analyzers（RS0016等）がこれらのファイルを使用してAPI互換性を検証する
- *REMOVED*プレフィックスは、以前出荷されたAPIが削除されたことを示す
  - 例：`*REMOVED*Microsoft.CodeAnalysis.SomeClass.SomeMethod()`
- Unshipped.txtが空になることで、新しいリリースサイクルの開始を示す
- ファイルはASCIIエンコーディングで保存される（API署名は通常ASCIIのみで構成されるため）
- ソートはアルファベット順で行われ、ファイルの差分を見やすくする
- 実行後は`git diff`で変更内容を確認し、`git commit`でコミットする必要がある
