# バッチ設計書 56-ServicingPipeline

## 概要

本ドキュメントは、サービシングブランチのチェリーピック・コンフリクト解決を支援するPowerShellスクリプト「ServicingPipeline.ps1」のバッチ設計書である。

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

本バッチは、GitHub ProjectV2のサービシングパイプラインボードと連携し、「To Cherry Pick」ステータスのカードからコミットを取得して、リリースブランチへの自動チェリーピックを実行する。コンフリクト発生時は対話的なシェルに入り、手動でのコンフリクト解決・スキップ・拒否を可能にする。チェリーピック完了後はGitHub ProjectV2のステータスを自動更新する。

**業務上の目的・背景**：Windows Terminalのサービシングリリースでは、mainブランチの修正をリリースブランチにバックポート（チェリーピック）する必要がある。多数のコミットを手動でチェリーピックするのは煩雑でエラーが起きやすいため、GitHub Projectとの連携による自動化・ステータス管理を行う本バッチが必要である。

**バッチの実行タイミング**：サービシングリリースの準備時にリリースエンジニアが手動で実行する。リリースブランチ上で実行される。

**主要な処理内容**：
1. バージョン推定（ブランチ名から自動推定、または手動指定）
2. GitHub GraphQL APIでサービシングパイプラインProjectV2を検索
3. ProjectV2のアイテム（Issue/PR/DraftIssue）を全件取得
4. "To Cherry Pick"ステータスのカードからコミットSHAを抽出
5. git rev-list --no-walk=sorted でコミット順序をソート
6. 各コミットを順次 git cherry-pick -x で適用
7. コンフリクト発生時は対話的シェルに入る（done/skip/abort/reject）
8. 成功時はGitHub ProjectV2のステータスを"Cherry Picked"に更新
9. reject時はステータスを"Rejected"に更新

**前後の処理との関連**：リリースブランチの最新状態（git fetch --all）が前提。チェリーピック後はビルド・テスト・リリースのパイプラインに進む。

**影響範囲**：ローカルのリリースブランチにコミットが追加される。GitHub ProjectV2のカードステータスが更新される。

## バッチ種別

リリースエンジニアリング / Git操作自動化

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（サービシングリリース時） |
| 実行時刻 | N/A |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| PowerShell 7以上 | #Requires -Version 7 |
| PSGitHubモジュール | #Requires -Modules PSGitHub（GraphQL API用） |
| リリースブランチ | release-{version} ブランチ上で実行すること |
| ブランチ最新 | ローカルブランチがリモートと同期していること |
| GitHub認証 | PSGitHubモジュールの認証が設定されていること |

### 実行可否判定

- ブランチ名からバージョンを推定できない場合はエラー終了（-Versionパラメータで指定も可能）
- ローカルブランチがリモートに対して遅延している場合はエラー終了
- サービシングパイプラインProjectV2が見つからない場合はエラー終了
- "To Cherry Pick"のカードがない場合は"Nothing to do."で正常終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| Version | string | No | ブランチ名から推定 | サービシングバージョン（例："1.18"） |
| SourceBranch | string | No | "origin/main" | チェリーピック元ブランチ |
| GpgSign | switch | No | $False | GPG署名を行うか |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| GitHub ProjectV2 | GraphQL API | サービシングパイプラインのカード情報 |
| Git repository | Git | コミット情報・ブランチ情報 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| ローカルGitリポジトリ | Git commits | チェリーピックされたコミット |
| GitHub ProjectV2 | GraphQL API | カードステータスの更新 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| 出力先 | ローカルリリースブランチ |
| コミットトレーラー | Service-Card-Id:{カードID}, Service-Version:{バージョン} |

## 処理フロー

### 処理シーケンス

```
1. バージョン推定
   └─ ブランチ名 "release-X.Y" からバージョンを抽出
2. ブランチ同期チェック
   └─ git fetch --all → リモートとの差分チェック
3. ProjectV2検索
   └─ GraphQL APIで "{Version} Servicing Pipeline" を検索
4. カード取得
   └─ ProjectV2のアイテムを全件取得（ページネーション対応）
5. コミット抽出
   └─ "To Cherry Pick" のカードからコミットSHAを抽出
6. コミットソート
   └─ git rev-list --no-walk=sorted で時系列順にソート
7. チェリーピックループ
   ├─ git cherry-pick -x でコミット適用
   ├─ 成功 → Service-Card-Id/Service-Version トレーラー追加 → "Cherry Picked"に更新
   └─ 失敗 → 対話的シェル（done/skip/abort/reject）
8. 対話的コンフリクト解決
   ├─ done → cherry-pick --continue
   ├─ skip → cherry-pick --skip
   ├─ abort → cherry-pick --abort → 終了
   └─ reject → skip + "Rejected"にステータス更新
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[バージョン推定]
    B --> C[git fetch --all]
    C --> D{ブランチ最新?}
    D -->|No| E[エラー終了]
    D -->|Yes| F[GraphQLでProjectV2検索]
    F --> G[カード全件取得]
    G --> H[To Cherry Pickのコミット抽出]
    H --> I{チェリーピック対象あり?}
    I -->|No| J[Nothing to do 終了]
    I -->|Yes| K[コミットソート]
    K --> L[git cherry-pick -x]
    L --> M{成功?}
    M -->|Yes| N[トレーラー追加・ステータス更新]
    N --> O{次のコミット?}
    M -->|No| P[対話的シェル]
    P --> Q{done/skip/abort/reject}
    Q -->|done| R[cherry-pick --continue]
    Q -->|skip| S[cherry-pick --skip]
    Q -->|abort| T[cherry-pick --abort → 終了]
    Q -->|reject| U[Rejected更新 → skip]
    R --> O
    S --> O
    U --> O
    O -->|あり| L
    O -->|なし| V[バッチ終了]
```

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

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

本バッチはデータベース操作を行わない。GitHub GraphQL APIを通じたProjectV2の操作を行う。

| 処理 | 対象 | 操作種別 | 概要 |
|-----|------|---------|------|
| ProjectV2検索 | GitHub ProjectV2 | READ | サービシングパイプラインの検索 |
| カード取得 | GitHub ProjectV2 Items | READ | プロジェクトアイテムの全件取得 |
| ステータス更新 | GitHub ProjectV2 Item | UPDATE | カードステータスの変更 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Exit 1 | バージョン推定失敗 | ブランチ名がrelease-X.Y形式でない | -Versionパラメータを指定 |
| Exit 1 | ブランチ遅延 | ローカルブランチがリモートより古い | git pull実行 |
| Throw | ProjectV2未発見 | サービシングパイプラインが存在しない | GitHub上でProjectを作成 |
| N/A | チェリーピック失敗 | マージコンフリクト | 対話的シェルで解決 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（対話的にコンフリクト解決） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

abort選択時は"YOU'RE ON YOUR OWN"メッセージが表示される。手動でgit resetやcherry-pick --abortで状態を復旧する必要がある。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | コミット単位 |
| コミットタイミング | 各cherry-pick成功時 |
| ロールバック条件 | abort選択時にcherry-pick --abort |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数十コミット程度 |
| 目標処理時間 | 対話的処理のため不定 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

リリースブランチのgit操作を伴うため、同一ブランチでの同時実行は不可。GitHub ProjectV2のステータス更新は楽観的ロック。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | バージョン推定時 | "Inferred servicing version {version}" |
| 情報ログ | コンフリクト検出時 | "CONFLICT RESOLUTION REQUIRED"（ANSI装飾付き） |
| 情報ログ | チェリーピック時 | "PICK {コミット情報}"（ANSI装飾付き） |
| 情報ログ | 成功時 | " OK "（ANSI装飾付き） |
| 警告ログ | カード不完全時 | "Cards to cherry pick are not associated with commits:" |
| 情報ログ | 考慮キュー表示時 | "CONSIDERATION QUEUE" + カード一覧 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 特になし | N/A | N/A |

## 備考

- GitHub GraphQL APIを多用しており、PSGitHubモジュールのInvoke-GitHubGraphQlApiを使用
- ServicingStatusは6段階（Unknown/ToConsider/ToCherryPick/CherryPicked/Validated/Shipped/Rejected）
- ServicingItemTypeは5種類（Unknown/DraftIssue/Issue/PullRequest/Redacted）
- コンフリクト解決シェルはPowerShellのネストプロンプト（$Host.EnterNestedPrompt）を使用
- チェリーピック成功時にService-Card-IdとService-Versionのトレーラーをコミットに追加
- -GpgSignオプションでGPG署名付きコミットに対応
- 同一コミットが複数カードに関連付けられている場合のハンドリングに対応
- ANSIエスケープシーケンスでカラフルなターミナル出力を行う
