# 機能設計書 73-リリース作成

## 概要

本ドキュメントは、GitLabのリリース作成機能について、その処理概要、入出力仕様、処理フロー、データベース操作仕様を定義する。

### 本機能の処理概要

リリース作成機能は、プロジェクトのバージョンリリースを作成・管理するための機能である。Gitタグと連動してリリースを作成し、リリースノートの記載、アセットの添付、マイルストーンとの関連付けを行う。

**業務上の目的・背景**：ソフトウェア開発において、特定のバージョンを正式にリリースする際には、そのリリースの内容（変更点、新機能、バグ修正など）を明確に記録し、関係者に通知する必要がある。リリース機能は、Gitタグを基盤としてリリース情報を体系的に管理し、ダウンロード可能なアセット（バイナリ、ドキュメントなど）を添付することで、ソフトウェア配布のハブとして機能する。

**機能の利用シーン**：
- 新バージョンのソフトウェアを正式リリースする場合
- リリースノートを作成して変更内容を文書化する場合
- ビルド済みバイナリやパッケージを配布する場合
- マイルストーンで管理していた機能をリリースとして公開する場合
- CI/CDパイプラインからの自動リリース

**主要な処理内容**：
1. リリースの作成（タグ名、リリース名、説明、リリース日時の設定）
2. タグの自動作成（既存タグがない場合）
3. リリースアセット（リンク）の添付
4. マイルストーンとの関連付け
5. リリースエビデンスの自動生成
6. Webhook/通知の実行
7. CIカタログへの公開（対応プロジェクトの場合）

**関連システム・外部連携**：
- Gitリポジトリ（タグ管理）
- CI/CDパイプライン（エビデンス用パイプライン情報）
- Webhooks（リリースフック）
- 通知サービス（メール通知）
- CI/CDカタログ（カタログリソースの公開）

**権限による制御**：
- リリースの作成: プロジェクトへのリリース作成権限（Developer以上）
- タグの作成: タグ作成権限（保護タグの場合は追加権限必要）
- リリースの編集: リリース更新権限
- リリースの閲覧: プロジェクトへの読み取り権限

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 85 | リリース一覧 | 主画面 | プロジェクトのリリース一覧表示 |
| 86 | リリース新規作成 | 入力画面 | 新規リリースの作成 |
| 87 | リリース詳細 | 結果表示画面 | リリースの詳細表示 |
| 88 | リリース編集 | 入力画面 | リリースの編集 |
| 39 | タグ詳細 | 遷移先画面 | リリース作成への遷移 |

## 機能種別

CRUD操作 / イベント発行 / 外部連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tag | String | Yes | タグ名 | 必須、プロジェクト内で一意 |
| name | String | No | リリース名 | 最大255文字 |
| description | String | No | リリースノート（Markdown） | 最大文字数制限あり |
| ref | String | No | タグを作成するブランチ/コミット | タグが存在しない場合に使用 |
| released_at | DateTime | No | リリース日時 | デフォルトは作成日時 |
| milestones | Array | No | 関連付けるマイルストーンのタイトルまたはID | 存在するマイルストーンであること |
| assets.links | Array | No | リリースリンク | 名前、URL、ファイルパス |

### 入力データソース

- 画面入力（新規作成フォーム）
- API リクエスト
- CI/CDパイプライン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | リリースID |
| tag | String | タグ名 |
| name | String | リリース名（未設定の場合はタグ名） |
| description | String | リリースノート |
| sha | String | コミットSHA |
| author | User | 作成者 |
| created_at | DateTime | 作成日時 |
| released_at | DateTime | リリース日時 |
| upcoming_release | Boolean | 将来のリリースかどうか |
| assets | Object | アセット情報（リンク、ソース） |
| evidences | Array | エビデンス情報 |
| milestones | Array | 関連マイルストーン |

### 出力先

- 画面表示（HTML）
- JSON API レスポンス
- Atom フィード

## 処理フロー

### 処理シーケンス

```
1. 権限確認
   └─ リリース作成権限とタグ作成権限を確認
2. バリデーション
   └─ タグの重複チェック、マイルストーン存在確認
3. エビデンスパイプライン取得
   └─ リリースに関連付けるパイプライン情報を取得
4. タグの作成または取得
   └─ 既存タグがなければ新規作成
5. リリースレコード作成
   └─ DBにリリース情報を保存
6. カタログ公開（該当する場合）
   └─ CI/CDカタログへの公開処理
7. 通知送信
   └─ 新規リリース通知の非同期送信
8. Webhook実行
   └─ リリースフックの実行
9. エビデンス作成
   └─ 非同期でリリースエビデンスを生成
10. 監査ログ記録
    └─ リリース作成の監査イベント記録
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{作成権限あり?}
    B -->|No| C[403エラー]
    B -->|Yes| D{タグ作成権限あり?}
    D -->|No| C
    D -->|Yes| E{リリース存在?}
    E -->|Yes| F[409エラー: 既存リリース]
    E -->|No| G{マイルストーン確認}
    G -->|不正| H[400エラー]
    G -->|正常| I[エビデンスパイプライン取得]
    I --> J{既存タグ?}
    J -->|No| K{ref指定あり?}
    K -->|No| L[422エラー]
    K -->|Yes| M[タグ作成]
    J -->|Yes| N[タグ取得]
    M --> N
    N --> O[リリースレコード作成]
    O --> P{カタログ公開?}
    P -->|Yes| Q[カタログリソース作成]
    P -->|No| R[保存]
    Q --> R
    R --> S[通知送信]
    S --> T[Webhook実行]
    T --> U[エビデンス作成]
    U --> V[監査ログ]
    V --> W[成功レスポンス]
    W --> X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | タグ一意制約 | 同一プロジェクト内でタグ名は一意 | リリース作成時 |
| BR-73-02 | 保護タグ制限 | 保護タグへのリリースは追加権限が必要 | 保護タグの場合 |
| BR-73-03 | エビデンス自動生成 | 現在のリリースにはエビデンスが自動生成される | released_atが過去でも未来でもない場合 |
| BR-73-04 | 名前デフォルト | name未指定時はタグ名をリリース名として使用 | リリース表示時 |
| BR-73-05 | リリース日時デフォルト | released_at未指定時はcreated_atを使用 | リリース作成時 |

### 計算ロジック

- `upcoming_release?`: released_at > 現在時刻
- `historical_release?`: released_at < created_at

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リリース作成 | releases | INSERT | リリースレコード作成 |
| リリース作成 | releases_links | INSERT | リリースリンク作成 |
| リリース作成 | milestone_releases | INSERT | マイルストーン関連付け |
| リリース作成 | releases_evidences | INSERT | エビデンス作成（非同期） |
| リリース編集 | releases | UPDATE | リリース情報更新 |
| リリース削除 | releases | DELETE | リリースレコード削除 |

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

#### releases

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | project_id | プロジェクトID | 必須 |
| INSERT | tag | タグ名 | 必須、一意 |
| INSERT | name | リリース名 | 任意 |
| INSERT | description | リリースノート | 任意 |
| INSERT | sha | コミットSHA | タグから取得 |
| INSERT | author_id | 作成者ID | current_user |
| INSERT | released_at | リリース日時 | デフォルトはcreated_at |
| INSERT | created_at | 作成日時 | 自動設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | 権限エラー | リリース作成権限なし | エラーメッセージ表示 |
| 403 | 権限エラー | 保護タグへの作成権限なし | エラーメッセージ表示 |
| 400 | バリデーションエラー | マイルストーンが存在しない | 正しいマイルストーン指定を促す |
| 409 | 競合エラー | 同一タグのリリースが既に存在 | 既存リリースの編集を促す |
| 422 | 処理不可エラー | タグ作成時にrefが未指定 | refの指定を促す |

### リトライ仕様

- エビデンス作成は非同期ワーカーで実行され、失敗時は自動リトライ
- Webhook実行は失敗しても本体処理には影響しない

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

- リリース作成とリンク作成は同一トランザクション内で実行
- エビデンス作成は非同期のため別トランザクション

## パフォーマンス要件

- リリース一覧: ページネーション適用
- リリース作成: タグ操作を含め5秒以内

## セキュリティ考慮事項

- 権限ベースのアクセス制御
- 保護タグへのアクセス制限
- 監査ログへの記録
- 外部URLへのリダイレクト警告

## 備考

- リリースはGitタグと1:1で対応
- リリースを削除してもタグは削除されない
- エビデンスはリリース時点のプロジェクト状態を記録するスナップショット

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | release.rb | `app/models/release.rb` | Releaseモデルの属性、バリデーション、関連定義を確認 |

**読解のコツ**:
- `belongs_to :project`, `belongs_to :author` で親子関係を確認
- `has_many :links`, `has_many :evidences` で関連リソースを確認
- `upcoming_release?`, `historical_release?` でリリース種別の判定ロジックを確認

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | releases_controller.rb | `app/controllers/projects/releases_controller.rb` | リリースコントローラーの構造を確認 |

**主要処理フロー**:
1. **7行目**: `authorize_read_release!` で閲覧権限確認
2. **8行目**: `authorize_update_release!` で更新権限確認
3. **9行目**: `authorize_create_release!` で作成権限確認
4. **20-33行目**: `index`アクションで一覧表示（HTML/JSON/Atom対応）
5. **35-43行目**: `downloads`アクションでリリースアセットダウンロード

#### Step 3: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create_service.rb | `app/services/releases/create_service.rb` | リリース作成のビジネスロジック |
| 3-2 | base_service.rb | `app/services/releases/base_service.rb` | 共通処理の確認 |

**主要処理フロー（create_service.rb）**:
- **5-32行目**: `execute`メソッドでリリース作成のメインフロー
- **6-7行目**: 権限チェック
- **8行目**: 既存リリースチェック
- **25行目**: エビデンスパイプライン取得
- **27-29行目**: タグの確保（ensure_tag）
- **31行目**: リリース作成
- **60-82行目**: `create_release`メソッドでDBへの保存と後処理
- **107-111行目**: エビデンス作成の非同期ジョブ投入

### プログラム呼び出し階層図

```
Projects::ReleasesController
    │
    ├─ index
    │      └─ ReleasesFinder
    │
    └─ (API経由での作成)
           │
           └─ Releases::CreateService
                  │
                  ├─ 権限チェック
                  │      └─ Ability.allowed?
                  │
                  ├─ タグ作成
                  │      └─ Tags::CreateService
                  │
                  ├─ リリース作成
                  │      ├─ Release.create
                  │      └─ Ci::Catalog::Resources::ReleaseService
                  │
                  ├─ 通知
                  │      └─ NotificationService
                  │
                  ├─ Webhook
                  │      └─ project.execute_hooks
                  │
                  └─ エビデンス作成
                         └─ Releases::CreateEvidenceWorker
```

### データフロー図

```
[入力]               [処理]                    [出力]

API/UI入力 ───▶ CreateService ───▶ リリース情報
    │                │
    │                ├─▶ Tags::CreateService ───▶ Gitタグ
    │                │
    │                ├─▶ Release.create ───▶ releasesテーブル
    │                │
    │                ├─▶ NotificationService ───▶ メール通知
    │                │
    │                ├─▶ execute_hooks ───▶ Webhook
    │                │
    │                └─▶ CreateEvidenceWorker ───▶ エビデンス
    │
    └── params[:release]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| releases_controller.rb | `app/controllers/projects/releases_controller.rb` | コントローラー | リリースのルーティング処理 |
| release.rb | `app/models/release.rb` | モデル | リリースのデータ構造定義 |
| create_service.rb | `app/services/releases/create_service.rb` | サービス | リリース作成処理 |
| update_service.rb | `app/services/releases/update_service.rb` | サービス | リリース更新処理 |
| destroy_service.rb | `app/services/releases/destroy_service.rb` | サービス | リリース削除処理 |
| base_service.rb | `app/services/releases/base_service.rb` | サービス | 共通処理 |
| create_evidence_service.rb | `app/services/releases/create_evidence_service.rb` | サービス | エビデンス作成 |
| releases_finder.rb | `app/finders/releases_finder.rb` | ファインダー | リリース検索 |
| release_serializer.rb | `app/serializers/release_serializer.rb` | シリアライザー | JSON出力形式定義 |
