# バッチ設計書 4-beta.ts

## 概要

本ドキュメントは、OpenCodeプロジェクトのベータブランチ同期バッチ（beta.ts）の設計仕様を定義する。このバッチはベータラベルの付いたPRをdevブランチにマージし、ベータブランチを更新する。

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

このバッチは、GitHubのベータラベルが付与されたオープンPRを収集し、devブランチをベースにしたベータブランチに順次マージする自動化スクリプトである。マージに失敗したPRには自動的にコメントが投稿され、失敗理由が通知される。

**業務上の目的・背景**：OpenCodeプロジェクトでは、安定版リリース前にベータチャンネルでテストを行う。ベータテストに含めたいPRにベータラベルを付与することで、開発者は容易にベータリリースへの含有を制御できる。本バッチにより、ベータラベルPRの自動マージとベータブランチの維持が自動化され、ベータリリースプロセスが効率化される。

**バッチの実行タイミング**：毎時0分にGitHub Actions（beta.yml）からスケジュール実行される。手動実行も可能。

**主要な処理内容**：
1. ベータラベルの付いたオープンPRをgh CLIで取得
2. origin/devブランチを取得し、ベータブランチとしてチェックアウト
3. 各PRのHEADをフェッチし、順次マージを試行
4. マージ失敗時はPRにコメントを投稿
5. 成功したPRのコミットを作成
6. ローカルベータブランチとリモートを比較
7. 変更がある場合のみforce pushでベータブランチを更新

**前後の処理との関連**：beta.ymlワークフローから呼び出される。ベータブランチへのプッシュは、publish.ymlのベータチャンネルリリースをトリガーする可能性がある。

**影響範囲**：GitHubリポジトリのベータブランチ、ベータラベルPRのコメント欄に影響を与える。

## バッチ種別

ブランチ管理 / PR自動マージ

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 毎時 |
| 実行時刻 | 毎時0分 |
| 実行曜日 | 毎日 |
| 実行日 | 毎日 |
| トリガー | cron（0 * * * *）、手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| gh CLI | gh CLIがインストール・認証済みであること |
| Git | gitコマンドが利用可能であること |
| リポジトリクローン | fetch-depth: 0でクローンされていること |
| 書き込み権限 | contents: write、pull-requests: write権限 |

### 実行可否判定

ベータラベルのオープンPRが0件の場合は"No team PRs to merge"を出力して終了。PRが存在する場合はマージ処理を続行。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 引数は受け取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| gh pr list | JSON | ベータラベルPR一覧 |
| origin/dev | gitブランチ | ベースブランチ |
| pull/{number}/head | gitリファレンス | 各PRのHEAD |
| origin/beta | gitブランチ | リモートベータブランチ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| origin/beta | gitブランチ | 更新されたベータブランチ |
| PR comments | テキスト | マージ失敗時の通知コメント |
| 標準出力 | テキスト | 処理ログ |

### 出力ファイル仕様

ファイル出力なし。Git操作とGitHub API操作のみ。

## 処理フロー

### 処理シーケンス

```
1. ベータラベルPRの取得
   └─ gh pr list --state open --label beta --limit 100

2. PR存在チェック
   └─ 0件の場合は終了

3. devブランチのフェッチ
   └─ git fetch origin dev

4. ベータブランチ作成
   └─ git checkout -B beta origin/dev

5. 各PRの処理（ループ）
   ├─ PRヘッドのフェッチ
   ├─ マージ試行（--no-commit --no-ff）
   ├─ 失敗時: マージ中止、クリーンアップ、コメント投稿
   ├─ 成功時: ステージング、コミット
   └─ 結果記録（applied/failed配列）

6. サマリー出力
   └─ 成功・失敗PR一覧の表示

7. リモートベータブランチとの比較
   ├─ ツリーハッシュを比較
   └─ 同一内容の場合はプッシュスキップ

8. ベータブランチのプッシュ
   └─ git push origin beta --force --no-verify
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[gh pr list --label beta]
    B --> C{PR存在?}
    C -->|No| D[終了]
    C -->|Yes| E[git fetch origin dev]
    E --> F[git checkout -B beta origin/dev]
    F --> G[PRループ開始]
    G --> H[git fetch PR head]
    H --> I{フェッチ成功?}
    I -->|No| J[コメント投稿・失敗記録]
    I -->|Yes| K[git merge --no-commit --no-ff]
    K --> L{マージ成功?}
    L -->|No| M[マージ中止・クリーンアップ]
    M --> J
    L -->|Yes| N{MERGE_HEAD存在?}
    N -->|No| O[スキップ]
    N -->|Yes| P[git add -A]
    P --> Q[git commit]
    Q --> R[成功記録]
    O --> S{次のPR?}
    J --> S
    R --> S
    S -->|Yes| G
    S -->|No| T[サマリー出力]
    T --> U{失敗あり?}
    U -->|Yes| V[エラー終了]
    U -->|No| W[リモート比較]
    W --> X{変更あり?}
    X -->|No| Y[プッシュスキップ]
    X -->|Yes| Z[git push --force]
    Y --> D
    Z --> D
```

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

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

本バッチはデータベース操作を行わない。Git操作とGitHub API操作のみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | フェッチ失敗 | PRヘッドの取得失敗 | ネットワーク確認、PR状態確認 |
| - | マージコンフリクト | devとPRの競合 | PR側で競合解決が必要 |
| - | ステージング失敗 | git add失敗 | ファイルシステム確認 |
| - | コミット失敗 | git commit失敗 | 変更内容確認 |
| - | プッシュ失敗 | force push失敗 | 認証・権限確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（即時失敗） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

1. 個別PRマージ失敗：該当PRにコメントが投稿され、他のPRの処理は継続
2. 1つ以上のPR失敗：サマリー出力後にprocess.exit(1)でエラー終了
3. プッシュ失敗：認証トークンの確認、リポジトリ権限の確認

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | PR単位 |
| コミットタイミング | 各PRマージ成功後 |
| ロールバック条件 | マージ失敗時にgit merge --abort、git checkout -- .、git clean -fd |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | PR数: 1-20件/実行 |
| 目標処理時間 | 5分以内 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

GitHub Actionsのconcurrency設定により同時実行は制御される可能性あり。ベータブランチへのforce pushは最後の実行結果が反映される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | PR取得時 | "Fetching open PRs with beta label..." |
| PR数ログ | PR取得後 | "Found {n} open PRs with beta label" |
| 処理ログ | 各PR処理時 | "Processing PR #{number}: {title}" |
| フェッチログ | PRヘッド取得時 | "Fetching PR head..." |
| マージログ | マージ試行時 | "Merging..." |
| 成功ログ | マージ成功時 | "Applied successfully" |
| 失敗ログ | マージ失敗時 | "Failed to merge (conflicts)" |
| サマリーログ | 処理完了時 | "--- Summary ---" |
| 完了ログ | プッシュ後 | "Successfully synced beta branch" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ワークフロー失敗 | 発生時 | GitHub Actions通知 |
| PR失敗 | 1件以上 | PRコメント経由でPR作成者に通知 |

## 備考

- PRはnumber順（昇順）でソートされて処理される
- --no-ffオプションによりマージコミットが作成される
- MERGE_HEADが存在しない場合は変更なしとしてスキップ
- 失敗したPRへのコメントは"Blocking Beta Release"という見出しで投稿される
- ベータブランチのツリーハッシュがリモートの履歴内に存在する場合はプッシュをスキップ
- git clean -fdでuntracked filesも削除される
- マージ中止処理は各コマンドでエラーを無視（try-catch内で.nothrow()相当）
