# バッチ設計書 19-prepare_release.sh

## 概要

本ドキュメントは、Juliaプロジェクトにおける `contrib/prepare_release.sh` のバッチ設計書である。このシェルスクリプトは、リリース用バイナリおよびソースtarballの準備、ダウンロード、署名、AWS S3へのアップロードを一括処理するリリース準備バッチである。

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

`prepare_release.sh` は、タグ付きコミットからJuliaの公式リリースに必要な全てのアーティファクト（ソースtarball、各プラットフォーム向けバイナリ）を収集・署名・アップロードする「バケットダンス」（julianightliesからjulialangへの移行）を自動化するバッチ処理である。

**業務上の目的・背景**：Juliaの正式リリースプロセスでは、CI/CDでビルドされたナイトリーバイナリをリリース用のS3バケットに移行し、ソースtarballを作成してGitHubリリースに添付する必要がある。この作業は複数のプラットフォーム（Linux x86_64/i686/ARM/ppc64le、macOS、Windows 64/32bit）のバイナリダウンロード、チェックサム生成、GPG署名、S3アップロード、CDNキャッシュパージなど多数のステップを含むため、自動化が不可欠である。

**バッチの実行タイミング**：タグ付きコミットでの正式リリース時に手動実行される。VERSIONファイルの内容とgitタグが一致していることが必須条件である。

**主要な処理内容**：
1. タグ付きコミットの検証（gitタグとVERSIONファイルの一致確認）
2. リリースリポジトリのクローンとソースtarball作成（full-source-dist、light-source-dist）
3. 各プラットフォーム向けバイナリのダウンロード（julianightlies S3バケットから）
4. latestコピーの作成（`julia-{majmin}-latest-*`）
5. SHA256およびMD5チェックサムの生成
6. GPG署名の生成（ソースtarballおよびLinuxバイナリ）
7. AWS S3へのアップロード（各プラットフォーム別ディレクトリ）
8. CDNキャッシュのパージ（latestファイル）

**前後の処理との関連**：リリース手順の全ステップの集約バッチ。前提として、VERSIONのバンプ（ステップ3-4）、SPDXの更新（ステップ5、No.18）、タグ作成・プッシュ（ステップ6）が完了している必要がある。ソースtarball作成では `full-source-dist`（No.13）と `light-source-dist`（No.12）を内部的に呼び出す。

**影響範囲**：AWS S3の `julialang` バケット内の対応バージョンディレクトリにバイナリとソースtarballがアップロードされる。CDNキャッシュがパージされる。GitHubリリースへの添付は手動で行う（スクリプト終了時にメッセージ表示）。

## バッチ種別

リリース準備 / 配布物管理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（正式リリース時のみ） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | 手動（`sh contrib/prepare_release.sh`） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| タグ付きコミット | 現在のHEADにgitタグが付与されていること |
| タグとVERSION一致 | gitタグの値が `v$(cat VERSION)` と一致すること |
| ネットワーク接続 | ナイトリーバイナリのダウンロードとS3アップロードに必要 |
| AWS CLI | `aws` コマンドが利用可能であること |
| GPG | `gpg` コマンドと `julia` 署名鍵が利用可能であること |
| curl | `curl` コマンドが利用可能であること |
| git | `git` コマンドが利用可能であること |
| shasum/md5sum | チェックサム生成コマンドが利用可能であること |

### 実行可否判定

- HEADにタグが付与されていない場合、エラーメッセージを出力して終了コード1で終了
- タグの値が `v$(cat VERSION)` と一致しない場合、エラーメッセージを出力して終了コード1で終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| N/A | - | - | - | コマンドライン引数は受け取らない（全てgitリポジトリとVERSIONファイルから取得） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| VERSION | テキストファイル | Juliaバージョン番号 |
| gitリポジトリ | git | タグ情報とコミットハッシュ |
| julianightlies S3バケット | バイナリファイル群 | CI/CDでビルドされたナイトリーバイナリ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| `julia-$version-full.tar.gz` | gzip圧縮tarball | 完全ソース配布物 |
| `julia-$version.tar.gz` | gzip圧縮tarball | 軽量ソース配布物 |
| `julia-$version-linux-{arch}.tar.gz` | gzip圧縮tarball | Linux各アーキテクチャ向けバイナリ |
| `julia-$version-mac64.dmg` | DMGイメージ | macOS向けバイナリ |
| `julia-$version-win{32,64}.exe` | インストーラ | Windows向けバイナリ |
| `julia-$majmin-latest-*` | 各形式 | latest版コピー |
| `julia-$version.sha256` | テキスト | SHA256チェックサム |
| `julia-$version.md5` | テキスト | MD5チェックサム |
| `*.asc` | GPG署名 | GPG detached signature |
| S3 `julialang` バケット | 各形式 | アップロードされた全アーティファクト |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | `julia-{version}-{platform}.{ext}` |
| 出力先 | カレントディレクトリ（ローカル）、S3 `julialang/bin/{os}/{arch}/{majmin}/` |
| 文字コード | バイナリ |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. タグ検証
   └─ HEADのgitタグとVERSIONファイルの一致を確認
2. バージョン情報抽出
   └─ version, majmin, majminpatch を VERSION ファイルから取得
3. ソースtarball作成
   └─ タグからリポジトリをクローンし、full-source-distとlight-source-distを実行
4. バイナリダウンロード
   └─ Linux(x86_64, i686, arm, ppc64le)、macOS(x64)、Windows(x64, x86)
5. latestコピー作成
   └─ 各バイナリの julia-$majmin-latest-* コピーを作成
6. チェックサム生成
   └─ SHA256とMD5のチェックサムファイルを生成
7. GPG署名
   └─ ソースtarballとLinuxバイナリにGPG署名を生成
8. AWS認証設定
   └─ aws configure の実行
9. S3アップロード
   └─ チェックサム、各プラットフォームバイナリ、署名をS3にアップロード
10. CDNキャッシュパージ
    └─ latestファイルのCDNキャッシュをPURGEリクエストでパージ
11. 完了メッセージ
    └─ GitHubリリースへのtarball添付を促すメッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[prepare_release開始] --> B{タグ付きコミット?}
    B -->|No| C[エラー終了]
    B -->|Yes| D{タグ == v$VERSION?}
    D -->|No| C
    D -->|Yes| E[バージョン情報抽出]
    E --> F[リポジトリクローン]
    F --> G[full-source-dist作成]
    G --> H[light-source-dist作成]
    H --> I[各プラットフォームバイナリダウンロード]
    I --> J[latestコピー作成]
    J --> K[SHA256/MD5チェックサム生成]
    K --> L[GPG署名生成]
    L --> M[aws configure]
    M --> N[S3アップロード]
    N --> O[CDNキャッシュパージ]
    O --> P[完了メッセージ表示]
```

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

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

本バッチはデータベース操作を行わない。ファイルシステムとAWS S3操作を行う。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | タグエラー | HEADにタグが未付与 | タグ付きコミットをチェックアウト |
| 1 | バージョン不一致 | タグとVERSIONファイルが不一致 | VERSIONファイルまたはタグを修正 |
| N/A | ダウンロードエラー | ナイトリーバイナリのダウンロード失敗 | URLを確認し再実行 |
| N/A | S3エラー | S3アップロード失敗 | AWS認証情報を確認し再実行 |
| N/A | GPGエラー | julia署名鍵が利用不可 | GPGキーリングを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 自動リトライなし（`set -e` で最初のエラーで停止） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. エラー発生箇所を特定する
2. ローカルに既にダウンロード済みのファイルは再利用可能
3. S3アップロードは冪等であるため、再実行で上書きされる
4. 部分的な再実行が必要な場合は、スクリプトの該当部分を手動で実行する

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 全体（`set -e` でエラー時停止） |
| コミットタイミング | 各S3アップロード完了時 |
| ロールバック条件 | S3からのファイル削除は手動対応 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 7プラットフォームバイナリ + 2ソースtarball + チェックサム + 署名 |
| 目標処理時間 | 30分〜1時間程度（ネットワーク速度に大きく依存） |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

同一バージョンに対する同時実行は不可。S3上のファイルが上書きされる可能性がある。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラーログ | タグ検証失敗時 | `error: this script must be run with a tagged commit checked out` |
| エラーログ | バージョン不一致時 | `error: tagged commit does not match content of VERSION file` |
| 完了ログ | 処理完了時 | `All files prepared. Attach julia-$version.tar.gz and julia-$version-full.tar.gz to github releases.` |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理結果 | 終了コード != 0 | 実行者（手動実行のため） |

## 備考

- 対応プラットフォーム: Linux x86_64, Linux i686, Linux ARM, Linux ppc64le, macOS x64, Windows x64, Windows x86
- ナイトリーバイナリのダウンロード元: `https://julialangnightlies-s3.julialang.org/bin/`
- S3アップロード先: `s3://julialang/bin/{os}/{arch}/{majmin}/`
- CDNパージ先: `https://julialang-s3.julialang.org/bin/`
- GPG署名はソースtarballとLinuxバイナリのみに対して生成される
- `set -e` により、いずれかのコマンドが失敗した時点でスクリプトが停止する
- `aws configure` はスクリプト内で対話的に実行される（AWS認証情報の入力が必要）
- GitHubリリースへのtarball添付は手動で行う必要がある
- `-rc` サフィックスはmajminpatchの計算時に除去される
