# バッチ設計書 8-release.sh

## 概要

本ドキュメントは、Node.jsプロジェクトのリリース署名・プロモートスクリプト「tools/release.sh」の設計仕様を記載したものである。

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

release.shは、Node.jsのリリースをプロモート（公開）し、GPG署名を行うためのシェルスクリプトである。ビルドジョブで準備されたリリースをステージングサーバーから本番サーバーにプロモートし、SHASUMS256.txtファイルにGPG署名を付与する。

**業務上の目的・背景**：Node.jsの公式リリースは、リリースチームメンバーによるGPG署名が必要である。release.shは、リリースのプロモート処理と署名処理を自動化し、セキュアなリリースプロセスを実現する。署名されたチェックサムファイルにより、ダウンロードしたバイナリの真正性を検証できる。Cloudflare R2へのアップロードもサポートしている。

**バッチの実行タイミング**：リリースマネージャーがリリースをプロモートする際に手動で実行される。

**主要な処理内容**：
1. GPGキーの選択と検証
2. Gitタグの署名検証
3. プロモート可能なリリースの検出
4. リリースのプロモート
5. SHASUMS256.txtの生成と署名
6. 署名ファイルのアップロード（ウェブサーバーおよびCloudflare R2）

**前後の処理との関連**：CIのビルドジョブでリリースが準備された後に実行される。ウェブサーバー上のdist-promotable、dist-promote、dist-signコマンドと連携する。

**影響範囲**：Node.jsの公開リリースファイル、署名ファイルに影響を与える。

## バッチ種別

リリース管理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | リリース時（不定期） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | リリースマネージャーによる手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| GPGキー | リリースに使用するGPGキーがインストールされていること |
| SSHアクセス | リリースサーバーへのSSHアクセス権があること |
| README登録 | GPGキーのフィンガープリントがREADME.mdに登録されていること |
| Gitタグ | リリースバージョンのGitタグが署名付きでプッシュされていること |

### 実行可否判定

- GPGキーが存在しない場合はエラー
- GPGキーのフィンガープリントがREADME.mdに登録されていない場合はエラー
- Gitタグが署名されていない、またはGPGキーが一致しない場合はエラー
- プロモート可能なリリースが存在しない場合は終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| -s | 文字列 | No | - | 署名のみ実行するバージョン（例：v20.0.0） |
| -i | 文字列 | No | デフォルトキー | カスタムSSH秘密鍵のパス |
| -r | 文字列 | No | README.md | READMEファイルのパス |
| -a | フラグ | No | false | 全てのローカルGPGキーを使用（サブキー用） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| README.md | Markdown | GPGキーフィンガープリントの登録確認 |
| リモートサーバー | SSH | プロモート可能なリリース一覧 |
| GitHub | HTTPS | タグされたバージョンの確認 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| リリースサーバー | バイナリ | プロモートされたリリースファイル |
| SHASUMS256.txt.asc | GPG署名 | クリア署名されたチェックサム |
| SHASUMS256.txt.sig | GPG署名 | デタッチ署名 |
| Cloudflare R2 | バイナリ | CDN用の署名ファイル |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | SHASUMS256.txt, SHASUMS256.txt.asc, SHASUMS256.txt.sig |
| 出力先 | /home/dist/nodejs/release/{version}/ |
| 文字コード | UTF-8 |
| 区切り文字 | 改行 |

## 処理フロー

### 処理シーケンス

```
1. オプション解析
   └─ getoptsでコマンドラインオプションを解析
2. GPGキー選択
   └─ README.mdに登録されたフィンガープリントと照合
3. キー検証
   └─ 複数キーがある場合はユーザーに選択を促す
4. -sオプション時：署名のみ実行
   └─ 指定バージョンのGitタグを検証して署名処理へ
5. プロモート可能リリース検出
   └─ SSHでdist-promotableコマンドを実行
6. バージョンごとにプロモート確認
   └─ ユーザーに確認を求める
7. Gitタグ検証
   └─ タグがGPGキーで署名されているか確認
8. プロモート実行
   └─ SSHでdist-promoteコマンドを実行
9. SHASUMS256.txt生成
   └─ dist-signコマンドでチェックサムファイルを生成
10. GPG署名
    └─ クリア署名（.asc）とデタッチ署名（.sig）を作成
11. アップロード
    └─ SCPでサーバーに、rcloneでCloudflare R2にアップロード
12. クリーンアップ
    └─ 一時ディレクトリを削除
```

### フローチャート

```mermaid
flowchart TD
    A[release.sh開始] --> B[オプション解析]
    B --> C[GPGキー選択]
    C --> D{キー数}
    D -->|0| E[エラー：キーなし]
    D -->|1以上| F{-sオプション?}
    F -->|Yes| G[指定バージョンの署名のみ]
    F -->|No| H[プロモート可能リリース検出]
    H --> I{リリースあり?}
    I -->|No| J[終了：プロモート対象なし]
    I -->|Yes| K[バージョン選択]
    K --> L{プロモート確認}
    L -->|No| M[スキップ]
    L -->|Yes| N[Gitタグ検証]
    N --> O{検証OK?}
    O -->|No| P[エラー：タグ無効]
    O -->|Yes| Q[dist-promote実行]
    Q --> R[SHASUMS256.txt生成]
    G --> R
    R --> S[GPG署名作成]
    S --> T{アップロード確認}
    T -->|No| U[署名ファイル保持]
    T -->|Yes| V[SCP/R2アップロード]
    V --> W[一時ディレクトリ削除]
    M --> X[次バージョンへ]
    U --> X
    W --> X
    X --> Y[終了]
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | GPGエラー | GPGキーが存在しない | gpg --gen-keyでキーを作成 |
| 1 | 認証エラー | GPGフィンガープリントがREADMEにない | READMEにフィンガープリントを追加 |
| 1 | タグエラー | Gitタグが署名されていない | 署名付きタグを作成 |
| 1 | GitHub確認エラー | GitHubでタグが見つからない | タグをプッシュ |
| 1 | SHASUMSエラー | dist-signがSHASUMS返さない | サーバー管理者に連絡 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（対話式のため） |
| リトライ間隔 | N/A |
| リトライ対象エラー | なし |

### 障害時対応

- GPGキーの問題：gpg --list-secret-keysでキー状態を確認
- SSHの問題：カスタムキーを-iオプションで指定
- サーバーの問題：NODEJS_RELEASE_HOST環境変数で別サーバーを指定

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1〜数バージョン/実行 |
| 目標処理時間 | ネットワーク速度依存 |
| メモリ使用量上限 | 数MB |

## 排他制御

同一バージョンの同時プロモートはサーバー側で制御される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 処理中 | GPGキー選択、プロモート状況 |
| 署名内容 | 署名後 | SHASUMS256.txt.ascの内容表示 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | リリースマネージャー |

## 備考

- デフォルトのリリースホストはNODEJS_RELEASE_HOST環境変数で設定可能（デフォルト：direct.nodejs.org）
- Cloudflare R2バケットはr2:dist-prod
- GPG署名にはSHA256ダイジェストアルゴリズムを使用
- -aオプションはサブキーで署名する場合に使用
- 一時ディレクトリは/tmp/_node_release.$$に作成される
- GitHub上でタグされたバージョンとsrc/node_version.hの内容を照合して検証
