# 機能設計書 20-ビルドトリガー

## 概要

本ドキュメントは、Jenkinsにおけるビルドトリガー機能の設計について記述する。この機能は、ビルド完了後に他のプロジェクトのビルドをトリガーするビルド後処理を提供する。

### 本機能の処理概要

ビルドトリガー機能は、ビルド後処理（Recorder）として指定された下流プロジェクトのビルドをスケジュールする。DependencyGraphに依存関係を登録し、ビルド完了時に閾値条件を満たした場合に下流ビルドを開始する。

**業務上の目的・背景**：CI/CDパイプラインでは、上流プロジェクトのビルド完了を契機に下流プロジェクトをビルドする必要がある。ビルドトリガー機能により、プロジェクト間の依存関係に基づいた自動ビルドチェーンを構築できる。

**機能の利用シーン**：
- ライブラリビルド後の依存アプリケーションビルド
- 単体テスト成功後の統合テスト実行
- ビルドパイプラインの構築
- マルチモジュールプロジェクトの連携
- デプロイ前の依存サービスビルド

**主要な処理内容**：
1. DependencyGraphへの依存関係登録
2. ビルド結果閾値チェック（SUCCESS/UNSTABLE）
3. 下流プロジェクトのビルドスケジューリング
4. UpstreamCauseによるトリガー元情報付与
5. トポロジカルソートによる実行順序決定

**関連システム・外部連携**：DependencyGraph、ParameterizedJobMixIn、UpstreamCause。

**権限による制御**：Job.CONFIGURE権限でビルドステップの設定変更が可能。Item.BUILD権限で下流ビルドのトリガーが可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | ジョブ設定 | 主画面 | ビルドトリガー設定の追加・編集 |
| 10 | ビルド詳細 | 結果表示画面 | トリガーされたビルドの表示 |

## 機能種別

ビルド後処理 / ビルド連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| childProjects | String | Yes | カンマ区切りの下流プロジェクト名 | 存在するジョブ名 |
| threshold | String/Result | No | トリガー閾値 | SUCCESS/UNSTABLE/FAILURE |

### 入力データソース

- ジョブ設定画面からのユーザー入力
- DependencyGraph: 依存関係情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ビルドキュー | ScheduledBuild | 下流ビルドのスケジュール |
| UpstreamCause | Cause | トリガー元ビルド情報 |

### 出力先

- ビルドキュー: 下流プロジェクトのビルドスケジュール
- コンソールログ: トリガーメッセージ

## 処理フロー

### 処理シーケンス

```
1. BuildTrigger.perform()呼び出し
2. getChildJobs()で下流ジョブ取得
3. AbstractProject以外のジョブ処理
   └─ result.isBetterOrEqualTo(threshold)チェック
   └─ Item.BUILD権限チェック
   └─ scheduleBuild()でビルドスケジュール
4. buildDependencyGraph()による依存関係登録
5. execute()による下流ビルド実行
   └─ getDependencyGraph()取得
   └─ getDownstreamDependencies()
   └─ トポロジカルソート
   └─ shouldTriggerBuild()チェック
   └─ scheduleBuild()でビルドスケジュール
```

### フローチャート

```mermaid
flowchart TD
    A[ビルド完了] --> B[execute開始]
    B --> C[DependencyGraph取得]
    C --> D[getDownstreamDependencies]
    D --> E[トポロジカルソート]
    E --> F{各依存処理}
    F --> G[shouldTriggerBuild?]
    G -->|result >= threshold| H{isDisabled?}
    G -->|No| I[スキップ]
    H -->|Yes| J[Disabledログ]
    H -->|No| K[scheduleBuild]
    K --> L{scheduled?}
    L -->|Yes| M[Triggeringログ]
    L -->|No| N[InQueueログ]
    J --> O{次の依存?}
    I --> O
    M --> O
    N --> O
    O -->|Yes| F
    O -->|No| P[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-20-01 | 閾値チェック | result.isBetterOrEqualTo(threshold)でトリガー判定 | 常時 |
| BR-20-02 | デフォルト閾値 | thresholdがnullの場合はSUCCESS | 設定なし時 |
| BR-20-03 | 権限チェック | Item.BUILD権限がなければトリガースキップ | 常時 |
| BR-20-04 | 無効プロジェクト | isDisabled()=trueならトリガースキップ | 下流が無効時 |
| BR-20-05 | トポロジカルソート | 依存関係の逆順でビルドスケジュール | execute実行時 |
| BR-20-06 | AbstractProject分離 | AbstractProjectはDependencyGraphで処理 | perform時 |

### 計算ロジック

- 閾値比較: Result.isBetterOrEqualTo()
- ソート: DependencyGraph.compare()でトポロジカルソート

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

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

本機能はデータベースではなく、XMLファイルベースの設定永続化を使用。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定保存 | jobs/{job}/config.xml | UPDATE | BuildTrigger設定の永続化 |
| リネーム対応 | jobs/{job}/config.xml | UPDATE | 下流プロジェクトリネーム時の自動更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NoSuchProject | 下流プロジェクトが存在しない | バリデーションエラー表示 |
| - | NotBuildable | ビルド不可なプロジェクト | ログ出力、スキップ |
| - | NoPermission | Item.BUILD権限なし | ログ出力、スキップ |

### リトライ仕様

リトライはユーザーによる手動再実行のみ。

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

- BuildStepMonitor.NONEで排他制御なし
- needsToRunAfterFinalized()=trueでビルド完了後に実行

## パフォーマンス要件

- トポロジカルソートによる効率的な実行順序決定
- FutureDependencyGraphによる非同期依存グラフ計算

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

- Item.READ/Item.BUILD権限チェック
- Tasks.getAuthenticationOf2()によるビルド実行者権限確認
- 権限不足時は警告ログのみ、トリガーはスキップ

## 備考

- @Symbol("downstream")でPipeline DSLからはdownstreamとして参照可能
- ReverseBuildTriggerとの対になる機能
- DependencyDeclarerを実装し、依存関係グラフへの参加が可能
- ItemListenerでリネーム時の自動参照更新

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BuildTrigger.java | `core/src/main/java/hudson/tasks/BuildTrigger.java` | ビルドトリガーRecorder |
| 1-2 | DependencyGraph.java | `core/src/main/java/hudson/model/DependencyGraph.java` | 依存関係グラフ |
| 1-3 | Dependency | `core/src/main/java/hudson/model/DependencyGraph.java` 内部クラス | 依存関係情報 |

#### Step 2: perform()とexecute()を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | perform() | `core/src/main/java/hudson/tasks/BuildTrigger.java` | AbstractProject以外の処理（196-240行目） |
| 2-2 | execute() | `core/src/main/java/hudson/tasks/BuildTrigger.java` | メイン下流トリガー処理（258-311行目） |

**perform()の主要処理フロー**:
- **197-203行目**: AbstractProject以外のジョブ収集
- **204行目**: 閾値チェック
- **207-227行目**: 権限・状態チェックとビルドスケジュール

**execute()の主要処理フロー**:
- **262-276行目**: DependencyGraph取得（非同期対応）
- **278-287行目**: 下流依存取得とトポロジカルソート
- **289-308行目**: shouldTriggerBuild()とscheduleBuild()

#### Step 3: buildDependencyGraph()を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | buildDependencyGraph() | `core/src/main/java/hudson/tasks/BuildTrigger.java` | 依存関係登録（314-333行目） |

**主要処理フロー**:
- **315行目**: getChildProjects()で下流取得
- **316-332行目**: Dependencyオブジェクト作成・登録
- **319-330行目**: shouldTriggerBuild()実装（権限・閾値チェック）

#### Step 4: DescriptorImplを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | DescriptorImpl | `core/src/main/java/hudson/tasks/BuildTrigger.java` | 設定UIとバリデーション（375-477行目） |
| 4-2 | doCheck() | `core/src/main/java/hudson/tasks/BuildTrigger.java` | フォームバリデーション（411-443行目） |
| 4-3 | ItemListenerImpl | `core/src/main/java/hudson/tasks/BuildTrigger.java` | リネーム対応（450-476行目） |

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

```
AbstractBuild.run()
    │
    ├─ BuildTrigger.perform()  [AbstractProject以外のジョブ]
    │      │
    │      ├─ getChildJobs()
    │      │
    │      ├─ result.isBetterOrEqualTo(threshold)
    │      │
    │      └─ pj.scheduleBuild(quietPeriod, UpstreamCause)
    │
    └─ BuildTrigger.execute()  [AbstractProjectのジョブ]
           │
           ├─ Jenkins.getFutureDependencyGraph() / getDependencyGraph()
           │
           ├─ graph.getDownstreamDependencies()
           │
           ├─ downstreamProjects.sort()  [トポロジカルソート]
           │
           └─ 各Dependencyに対して
                  │
                  ├─ dep.shouldTriggerBuild()
                  │      │
                  │      ├─ Item.READ権限チェック
                  │      ├─ Item.BUILD権限チェック
                  │      └─ result.isBetterOrEqualTo(threshold)
                  │
                  └─ p.scheduleBuild(quietPeriod, UpstreamCause, actions)
```

### データフロー図

```
┌─────────────────┐     ┌──────────────────┐     ┌────────────────────┐
│ 上流ビルド完了   │────→│ BuildTrigger     │────→│ DependencyGraph    │
│ (AbstractBuild) │     │ .execute()       │     │ .getDownstream     │
└─────────────────┘     └──────────────────┘     │  Dependencies()    │
                                                  └────────────────────┘
                                                           │
                                                           ▼
┌─────────────────┐     ┌──────────────────┐     ┌────────────────────┐
│ 下流プロジェクト │←────│ トポロジカル      │←────│ Dependency[]       │
│ リスト          │     │ ソート           │     │                    │
└─────────────────┘     └──────────────────┘     └────────────────────┘
        │
        ▼
┌─────────────────┐     ┌──────────────────┐     ┌────────────────────┐
│ shouldTrigger   │────→│ 権限・閾値チェック │────→│ scheduleBuild()    │
│ Build()         │     │                  │     │ + UpstreamCause    │
└─────────────────┘     └──────────────────┘     └────────────────────┘
                                                           │
                                                           ▼
                                                  ┌────────────────────┐
                                                  │ ビルドキュー        │
                                                  │ (下流ビルド)        │
                                                  └────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BuildTrigger.java | `core/src/main/java/hudson/tasks/BuildTrigger.java` | ソース | ビルドトリガーRecorder |
| DependencyGraph.java | `core/src/main/java/hudson/model/DependencyGraph.java` | ソース | 依存関係グラフ |
| Recorder.java | `core/src/main/java/hudson/tasks/Recorder.java` | ソース | 結果変更Publisher基底クラス |
| DependencyDeclarer.java | `core/src/main/java/jenkins/model/DependencyDeclarer.java` | ソース | 依存関係宣言インターフェース |
| UpstreamCause.java | `core/src/main/java/hudson/model/Cause.java` | ソース | 上流ビルドCause |
| ReverseBuildTrigger.java | `core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java` | ソース | 逆方向トリガー |
| ParameterizedJobMixIn.java | `core/src/main/java/jenkins/model/ParameterizedJobMixIn.java` | ソース | パラメータ化ジョブミックスイン |
