# バッチ設計書 31-automated-update-workflow

## 概要

本ドキュメントは、Next.jsリポジトリにおける汎用的な自動更新ワークフロー（automated-update-workflow）バッチの設計について記載する。指定されたスクリプトを実行し、変更がある場合にGitHub PRを自動作成する処理を定義する。

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

このバッチは、依存関係の更新やコード生成など、自動化された更新処理を汎用的に実行し、変更があった場合にGitHub Pull Requestを自動的に作成するワークフローである。

**業務上の目的・背景**：Next.jsプロジェクトでは、Google Fontsデータの更新やReact依存関係の同期など、定期的に外部リソースやパッケージを最新状態に保つ必要がある。これらの更新作業を手動で行うと、作業漏れや遅延が発生しやすい。本バッチは汎用的な自動更新フレームワークとして、任意の更新スクリプトを実行し、変更が検出された場合にPRを作成する仕組みを提供する。これにより、定期的なメンテナンス作業の自動化と品質の維持を実現する。

**バッチの実行タイミング**：CI/CDパイプライン（GitHub Actions）から随時実行される。スケジュールトリガー（cron）やワークフローディスパッチにより定期的または手動で起動される。

**主要な処理内容**：
1. 環境変数（GITHUB_TOKEN、SCRIPT）の検証
2. 指定されたスクリプト（SCRIPT環境変数）をNode.jsで実行
3. Git設定（ユーザー名: nextjs-bot、メール: it+nextjs-bot@vercel.com）
4. 更新用ブランチ（`update/{BRANCH_NAME}-{timestamp}`）の作成
5. 変更ファイルのステージングとコミット
6. 変更ファイルの有無を確認（変更なしの場合はスキップ）
7. リモートリポジトリへのプッシュ
8. GitHub APIを使用してPRを作成（base: canary）
9. PRに`run-react-18-tests`ラベルを付与
10. 同一タイトルのnextjs-botによる既存PRを自動クローズ

**前後の処理との関連**：本バッチは、sync-react（No.29）やupdate-google-fonts（No.30）などの更新スクリプトと組み合わせて使用される。SCRIPT環境変数に具体的な更新スクリプトのパスを指定することで、様々な更新処理を統一的にハンドリングする。

**影響範囲**：GitHubリポジトリ（vercel/next.js）のブランチ、Pull Request、ラベルに影響を与える。既存の同種PRがクローズされる。

## バッチ種別

データ連携 / 自動更新PR作成

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（CI/CDトリガー） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | GitHub Actionsワークフロー（cron/手動） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| GITHUB_TOKEN環境変数 | GitHub API認証用トークンが設定されていること |
| SCRIPT環境変数 | 実行対象の更新スクリプトパスが設定されていること |
| Git環境 | Gitが利用可能でリポジトリがクローンされていること |
| Node.js | Node.jsランタイムが利用可能であること |
| octokitパッケージ | octokitパッケージがインストールされていること |

### 実行可否判定

GITHUB_TOKENとSCRIPT環境変数が設定されていない場合、エラーメッセージを出力してexit code 1で終了する。スクリプト実行後に変更ファイルがない場合は、PR作成をスキップして正常終了する。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| GITHUB_TOKEN | string | Yes | なし | GitHub API認証トークン |
| SCRIPT | string | Yes | なし | 実行する更新スクリプトのパス |
| BRANCH_NAME | string | No | "unknown" | ブランチ名のプレフィックス |
| PR_TITLE | string | No | "Automated update" | PR作成時のタイトル |
| PR_BODY | string | No | "" | PR作成時の本文 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| 更新スクリプト | JS/MJS | SCRIPT環境変数で指定されたNode.jsスクリプトファイル |
| Gitリポジトリ | Git | vercel/next.jsリポジトリのローカルクローン |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| GitHubブランチ | Git | `update/{BRANCH_NAME}-{timestamp}`形式のブランチ |
| GitHub Pull Request | GitHub API | canaryブランチへのPR |
| コンソール出力 | テキスト | 処理結果のログメッセージ |

### 出力ファイル仕様

本バッチはファイル出力を行わず、GitHub API経由でPRを作成する。

| 項目 | 内容 |
|-----|------|
| ファイル名 | N/A |
| 出力先 | GitHub Pull Request |
| 文字コード | N/A |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. 環境変数バリデーション
   └─ GITHUB_TOKEN、SCRIPT環境変数の存在確認。未設定時はexit(1)
2. Octokitクライアント初期化
   └─ GITHUB_TOKENを使用してGitHub APIクライアントを生成
3. 更新スクリプト実行
   └─ `node ${SCRIPT}` でSCRIPT環境変数に指定されたスクリプトを実行
4. Git設定
   └─ ユーザー名(nextjs-bot)とメールアドレスを設定
5. ブランチ作成
   └─ `update/{BRANCH_NAME}-{timestamp}`形式のブランチを作成
6. 変更のコミット
   └─ 全変更ファイルをステージングしてコミット
7. 変更ファイル確認
   └─ `git diff HEAD~ --name-only`で変更ファイルを確認。0件の場合はスキップ
8. リモートプッシュ
   └─ ブランチをoriginにプッシュ
9. PR作成
   └─ GitHub APIでcanaryブランチへのPRを作成
10. ラベル付与
    └─ PRに`run-react-18-tests`ラベルを追加
11. 既存PRクローズ
    └─ 同一タイトルのnextjs-botによる既存PRを検索してクローズ
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{GITHUB_TOKEN/SCRIPT存在?}
    B -->|なし| C[エラー終了 exit 1]
    B -->|あり| D[Octokitクライアント初期化]
    D --> E[更新スクリプト実行]
    E --> F[Git設定・ブランチ作成]
    F --> G[変更をコミット]
    G --> H{変更ファイルあり?}
    H -->|なし| I[スキップして正常終了]
    H -->|あり| J[リモートプッシュ]
    J --> K[PR作成]
    K --> L[ラベル付与]
    L --> M[既存PRクローズ]
    M --> N[正常終了]
```

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

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

本バッチはデータベースを使用しない。GitHub APIを介したリモート操作のみ。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EXIT_1 | 環境変数不足 | GITHUB_TOKENが未設定 | GITHUB_TOKEN環境変数を設定して再実行 |
| EXIT_1 | 環境変数不足 | SCRIPTが未設定 | SCRIPT環境変数を設定して再実行 |
| EXIT_1 | スクリプト実行エラー | main()関数内で例外発生 | エラーログを確認し原因を特定 |
| N/A | Git操作エラー | コミットやプッシュの失敗 | Git設定やリポジトリ状態を確認 |
| N/A | GitHub APIエラー | PR作成やラベル付与の失敗 | トークンの権限やAPIレート制限を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構なし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

バッチ失敗時はexit code 1で終了する。main()関数のcatchブロックでエラーを出力後にprocess.exit(1)を呼び出す。ワークフロー失敗として記録されるため、CI/CDダッシュボードで確認し、手動で再実行する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（Git操作とAPI呼び出しの組み合わせ） |
| コミットタイミング | Git commitは1回（全変更を一括コミット） |
| ロールバック条件 | なし（部分的に実行されたGit操作やPR作成は手動でクリーンアップが必要） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回の実行で1つのPRを作成 |
| 目標処理時間 | 更新スクリプトの実行時間に依存（通常数分以内） |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

同時実行の制御は本スクリプト自体には実装されていない。GitHub Actionsのconcurrencyグループにより、同一ワークフローの同時実行を制御する想定。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラーログ | 環境変数不足時 | "missing GITHUB_TOKEN env" / "missing SCRIPT env" |
| 情報ログ | 変更なし時 | "No files changed skipping." |
| 情報ログ | PR作成成功時 | "Created pull request {url}" |
| 情報ログ | 既存PRクローズ時 | "Closing previous pull request: {html_url}" |
| エラーログ | 異常終了時 | エラーオブジェクトの内容 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ワークフロー失敗 | 1回 | GitHub Actionsの通知 |
| 実行時間 | ワークフローのタイムアウト設定に依存 | GitHub Actions |

## 備考

- 本バッチはvercel/next.jsリポジトリのCI/CD環境（GitHub Actions）での使用を前提としている。
- 既存PRのクローズ処理では、直近100件のオープンPRを検索対象としている（per_page: 100）。
- ブランチ名にはDate.now()によるタイムスタンプが含まれるため、一意性が保証される。
- PRのbaseブランチはcanaryに固定されている。
