# 通知設計書 105-autodevops_disabled_email

## 概要

本ドキュメントは、GitLabのAuto DevOps機能において、パイプラインの失敗によりAuto DevOpsが自動的に無効化された際に送信される通知メールの設計を記載するものです。

### 本通知の処理概要

本通知は、Auto DevOpsパイプラインが失敗し、その結果としてプロジェクトのAuto DevOps機能が自動的に無効化されたことをユーザーに知らせるための通知です。

**業務上の目的・背景**：Auto DevOpsは、プロジェクトに対して自動的にCI/CDパイプラインを構成する便利な機能ですが、プロジェクトの構成によっては正常に動作しない場合があります。パイプラインが繰り返し失敗する場合、自動的にAuto DevOpsを無効化することで、リソースの無駄遣いを防ぎます。この通知により、ユーザーは無効化の事実を把握し、プロジェクトの設定を見直すか、手動でCI/CDを構成するかを判断できます。

**通知の送信タイミング**：`AutoDevops::DisableWorker`がパイプラインの失敗を検知し、`Projects::AutoDevops::DisableService`によってAuto DevOpsが無効化された直後に、非同期で送信されます。

**通知の受信者**：パイプラインをトリガーしたユーザー、およびプロジェクトがパーソナルプロジェクトの場合はプロジェクトオーナーも含まれます。

**通知内容の概要**：Auto DevOpsが無効化されたこと、対象のパイプラインとプロジェクト、サポートされている言語へのリンク、CI/CD設定ページへのリンク、Auto DevOpsの詳細ドキュメントへのリンクが含まれます。

**期待されるアクション**：受信者はサポートされている言語のドキュメントを確認し、プロジェクトが要件を満たしているか確認します。必要に応じてプロジェクトを調整するか、手動でCI/CD設定を行い、必要であればCI/CD設定でAuto DevOpsを再度有効化できます。

## 通知種別

メール通知

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（deliver_later） |
| 優先度 | 中 |
| リトライ | Sidekiqのデフォルト設定に準拠 |

### 送信先決定ロジック

1. `pipeline.user.email`でパイプラインをトリガーしたユーザーのメールアドレスを取得
2. プロジェクトがパーソナルプロジェクト（`project.personal?`）の場合、`project.owners.map(&:email)`でオーナーのメールアドレスも追加
3. `flatten.uniq.compact`で重複とnilを除去

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | GitLabのデフォルトメールアドレス |
| 送信元名称 | GitLab |
| 件名 | `Auto DevOps pipeline was disabled for {project_name}` |
| 形式 | HTML/テキスト（マルチパート） |

### 本文テンプレート

#### HTML版（autodevops_disabled_email.html.haml）
```
[アラートバナー: Auto DevOps pipeline was disabled for {project_name}]

The Auto DevOps pipeline failed for pipeline #{pipeline_iid} and has been disabled for {project_name}.
In order to use the Auto DevOps pipeline with your project, please review the currently supported languages,
adjust your project accordingly, and turn on the Auto DevOps pipeline within your CI/CD project settings.

[Learn more about Auto DevOps ボタン]

Pipeline #{pipeline_id} triggered by [ユーザーアバター] {user_name}

[失敗したビルドの一覧]
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 本通知には添付ファイルはありません |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| @pipeline | 対象のパイプライン | 引数として渡される | Yes |
| @project | 対象プロジェクト | @pipeline.project | Yes |
| pipeline_link | パイプラインへのリンク | pipeline_url(@pipeline) | Yes |
| project_link | プロジェクトへのリンク | project_url(@project) | Yes |
| supported_langs_link | サポート言語ドキュメントへのリンク | help_page_url(...) | Yes |
| settings_link | CI/CD設定ページへのリンク | project_settings_ci_cd_url(@project) | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| バッチ/Worker | AutoDevops::DisableWorker.perform | DisableService.executeがtrueを返した | Auto DevOps無効化成功時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| project.emails_disabled? | プロジェクトでメール通知が無効化されている場合 |
| recipients.empty? | 送信先が空の場合 |
| DisableService.execute が false | Auto DevOpsが既に無効の場合等 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[パイプライン失敗] --> B[AutoDevops::DisableWorker.perform]
    B --> C{Pipeline存在?}
    C -->|No| D[警告ログ出力・終了]
    C -->|Yes| E[DisableService.execute]
    E --> F{無効化成功?}
    F -->|No| G[終了]
    F -->|Yes| H[send_notification_email]
    H --> I[email_receivers_for]
    I --> J[pipeline.user.email取得]
    J --> K{project.personal?}
    K -->|Yes| L[project.owners.email追加]
    K -->|No| M[recipients確定]
    L --> M
    M --> N{recipients.any?}
    N -->|No| O[終了]
    N -->|Yes| P[NotificationService.new.autodevops_disabled]
    P --> Q{project.emails_disabled?}
    Q -->|Yes| R[終了]
    Q -->|No| S[recipients.each]
    S --> T[mailer.autodevops_disabled_email]
    T --> U[deliver_later]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| ci_pipelines | パイプライン情報の取得 | |
| projects | プロジェクト情報の取得 | |
| users | パイプラインユーザー、オーナー情報の取得 | |
| members | プロジェクトオーナーの特定 | |
| ci_builds | 失敗したビルドの取得 | |

### テーブル別参照項目詳細

#### ci_pipelines

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | パイプラインID | WHERE id = pipeline_id |
| iid | パイプライン内部ID | |
| user_id | トリガーユーザーID | |
| project_id | プロジェクトID | |

#### ci_builds（latest_statuses.failed経由）

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| name | ビルド名 | status = 'failed' |
| stage | ステージ名 | |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| project_auto_devops | UPDATE | auto_devops_enabled = false |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| Pipeline未検出 | Ci::Pipeline.find_by_id が nil | 警告ログを出力して終了 |
| 送信失敗 | SMTP接続エラー等 | Sidekiqによるリトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Worker: 3回、メール送信: Sidekiqデフォルト |
| リトライ間隔 | Sidekiqの設定に準拠 |
| リトライ対象エラー | 一時的なエラー全般 |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | GitLab全体のメール送信レート制限に準拠 |
| 1日あたり上限 | GitLab全体のメール送信レート制限に準拠 |

### 配信時間帯

特に制限なし（イベント発生時に即時送信）

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

- パイプラインおよびプロジェクトへのリンクが含まれるが、受信者はアクセス権を持つユーザーのみ
- パイプラインのトリガーがAPIの場合、ユーザー情報は「API」と表示される

## 備考

- 失敗したビルドの一覧が本文に含まれる（`_failed_builds`パーシャル使用）
- Auto DevOpsのドキュメントページへのリンクが含まれる
- サポートされている言語のドキュメントへのリンクが含まれる

---

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

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

### 推奨読解順序

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

パイプラインとプロジェクトの関係を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pipeline.rb | `app/models/ci/pipeline.rb` | userアソシエーション、latest_statuses |
| 1-2 | project.rb | `app/models/project.rb` | personal?メソッド、owners |

**読解のコツ**: パイプラインからユーザーとプロジェクトへの参照パスを理解する。

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

Workerからの処理フローを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | disable_worker.rb | `app/workers/auto_devops/disable_worker.rb` | perform、send_notification_email |

**主要処理フロー**:
1. **12-27行目**: performメソッド - パイプライン取得、無効化、通知
2. **35-41行目**: send_notification_email - 受信者取得と通知送信
3. **43-50行目**: email_receivers_for - 受信者決定ロジック

#### Step 3: NotificationServiceを理解する

通知サービスの処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | notification_service.rb | `app/services/notification_service.rb` | autodevops_disabledメソッド |

**主要処理フロー**:
- **592-598行目**: autodevops_disabled - emails_disabled?チェックと送信

#### Step 4: メーラーを理解する

通知メールの生成処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | auto_devops.rb | `app/mailers/emails/auto_devops.rb` | autodevops_disabled_emailメソッド |

**主要処理フロー**:
- **5-14行目**: autodevops_disabled_email
- **6-7行目**: @pipeline, @project設定
- **9行目**: add_project_headers
- **11-13行目**: email_with_layout

#### Step 5: ビューテンプレートを理解する

メール本文のテンプレートを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | autodevops_disabled_email.html.haml | `app/views/notify/autodevops_disabled_email.html.haml` | アラートバナー、リンク、失敗ビルド一覧 |
| 5-2 | _failed_builds.html.haml | `app/views/notify/_failed_builds.html.haml` | 失敗ビルドのパーシャル |

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

```
AutoDevops::DisableWorker#perform(pipeline_id)
    │
    ├─ Ci::Pipeline.find_by_id(pipeline_id)
    │
    ├─ disable_service(project).execute
    │      └─ Projects::AutoDevops::DisableService
    │
    └─ send_notification_email(pipeline, project)
           │
           ├─ email_receivers_for(pipeline, project)
           │      ├─ pipeline.user&.email
           │      └─ project.owners.map(&:email)（personal?の場合）
           │
           └─ NotificationService.new.autodevops_disabled(pipeline, recipients)
                  │
                  ├─ project.emails_disabled? チェック
                  │
                  └─ recipients.each
                         └─ mailer.autodevops_disabled_email(pipeline, recipient)
                                │
                                ├─ @pipeline, @project設定
                                │
                                ├─ add_project_headers
                                │
                                └─ email_with_layout
                                       └─ deliver_later
```

### データフロー図

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

pipeline_id             AutoDevops::DisableWorker         Auto DevOps無効化
（失敗パイプライン）───▶        #perform              ───▶ （project_auto_devops更新）
                                   │
                                   │                      ───▶  通知メール送信
                                   │                            （各受信者へ）
                                   │
pipeline.user           ───▶       │
project.owners          ───▶       │
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| disable_worker.rb | `app/workers/auto_devops/disable_worker.rb` | ソース | 無効化ワーカー |
| notification_service.rb | `app/services/notification_service.rb` | ソース | 通知サービス（592-598行目） |
| auto_devops.rb | `app/mailers/emails/auto_devops.rb` | ソース | Auto DevOpsメーラー |
| autodevops_disabled_email.html.haml | `app/views/notify/autodevops_disabled_email.html.haml` | テンプレート | HTML本文テンプレート |
| autodevops_disabled_email.text.erb | `app/views/notify/autodevops_disabled_email.text.erb` | テンプレート | テキスト本文テンプレート |
| _failed_builds.html.haml | `app/views/notify/_failed_builds.html.haml` | テンプレート | 失敗ビルドパーシャル |
| disable_service.rb | `app/services/projects/auto_devops/disable_service.rb` | ソース | Auto DevOps無効化サービス |
