# 通知設計書 33-タイマー原因（TimerTriggerCause）

## 概要

本ドキュメントは、Jenkins のビルド原因通知機能のうち、タイマースケジュール（cron 式）によってビルドがトリガーされた場合に記録・表示される `TimerTriggerCause` の設計について記述する。

### 本通知の処理概要

タイマー原因（TimerTriggerCause）は、Jenkins のビルドがどのような理由で開始されたかを追跡するための `Cause` クラス階層の一部であり、`TimerTrigger` によって定期的にビルドがトリガーされた場合に使用される。

**業務上の目的・背景**：CI/CD パイプラインでは、定期的なビルド（ナイトリービルド、定期テスト、スケジュールされたデプロイなど）を自動化することが一般的である。TimerTriggerCause は、ビルドがスケジュールに基づいて自動的に開始されたことを記録し、ビルド履歴画面やコンソールログに表示することで、手動トリガーや他のトリガーとの区別を可能にする。これにより、ビルドのトリガー原因の追跡と監査が容易になる。

**通知の送信タイミング**：`TimerTrigger` がスケジュールに従って実行され、ビルドをトリガーした時点で `TimerTriggerCause` が生成される。cron 式で定義されたスケジュールに一致するタイミングで、Jenkins の内部タイマーが `TimerTrigger.run()` メソッドを呼び出し、その中で `TimerTriggerCause` が作成される。

**通知の受信者**：この通知は特定の受信者に送信されるものではなく、ビルド履歴画面やビルドの詳細ページを閲覧するすべてのユーザーが確認できる形で表示される。ビルドのコンソールログにも出力される。

**通知内容の概要**：通知には、ビルドがタイマーによってトリガーされたことを示すメッセージが含まれる。メッセージの形式は「Started by timer」となる。

**期待されるアクション**：受信者（ビルド履歴閲覧者）は、ビルドがスケジュールに基づいて自動的に開始されたことを認識し、必要に応じてスケジュール設定の確認や調整を行うことができる。

## 通知種別

- アプリ内通知（ビルド履歴画面、ビルド詳細ページ）
- コンソールログ出力

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ビルド開始時に即時記録） |
| 優先度 | 中 |
| リトライ | 無（永続化された情報のため） |

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

送信先は決定されない。ビルド原因情報はビルドオブジェクトに関連付けられ、ビルドの詳細ページやコンソールログを閲覧する全ユーザーに表示される。

## 通知テンプレート

### コンソールログ出力の場合

| 項目 | 内容 |
|-----|------|
| 形式 | テキスト |

### 本文テンプレート

```
Started by timer
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | TimerTriggerCauseは追加のパラメータを持たない | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| スケジュール | cron 式に基づくタイマー発火 | 常に記録 | TimerTrigger が cron スケジュールに従って実行された場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| jobがnull | TimerTrigger.run()メソッドでjobがnullの場合は処理をスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Jenkins内部タイマーがcronスケジュールをチェック] --> B[TimerTrigger.run実行]
    B --> C{jobがnull?}
    C -->|Yes| D[処理終了]
    C -->|No| E[TimerTriggerCauseインスタンス生成]
    E --> F[job.scheduleBuild 0, TimerTriggerCause]
    F --> G[ビルドキューに投入]
    G --> H[ビルド開始時にCauseがログに出力]
    H --> I[終了]
```

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

### 参照テーブル一覧

Jenkinsはファイルベースの永続化を使用しており、従来のRDBMSは使用しない。

| ストレージ | 用途 | 備考 |
|-----------|------|------|
| jobs/{jobName}/config.xml | ジョブ設定（TimerTriggerのcron式） | トリガー設定の参照 |
| jobs/{jobName}/builds/{buildNumber}/build.xml | ビルド情報とCauseの永続化 | XStreamでシリアライズ |

### 参照項目詳細

該当なし（TimerTriggerCauseは追加のパラメータを持たない）

### 更新テーブル一覧

| ストレージ | 操作 | 概要 |
|-----------|------|------|
| jobs/{jobName}/builds/{buildNumber}/build.xml | INSERT | ビルド情報にCauseを含めて永続化 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ジョブ未設定 | TimerTrigger.run()でjobがnullの場合 | 処理をスキップ（return） |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | cron スケジュールに従って実行されるため、設定に依存 |

### 配信時間帯

cron 式で定義されたスケジュールに従う

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

- TimerTriggerCause は追加のユーザー入力を含まないため、XSS リスクは低い
- cron 式の設定はジョブの設定権限を持つユーザーのみが変更可能

## 備考

- `TimerTrigger` は `@Symbol("cron")` アノテーションを持ち、Pipeline や JCasC で `cron` として参照可能
- スケジュールの構文チェックは `CronTabList.create()` で行われる
- スケジュールの妥当性チェック（実行頻度の警告など）は `ctl.checkSanity()` で行われる

---

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

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

### 推奨読解順序

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

まず、ビルド原因を表現するデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Cause.java | `core/src/main/java/hudson/model/Cause.java` | Causeクラス階層の基底クラス |
| 1-2 | TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` 125-140行 | TimerTriggerCauseの定義 |

**読解のコツ**: TimerTriggerCause は非常にシンプルなクラスで、追加のフィールドを持たない。equals() と hashCode() は全ての TimerTriggerCause を等価とみなす。

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

処理の起点となる TimerTrigger.run() メソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` 60-67行 | run()メソッドの実装 |

**主要処理フロー**:
1. **62行**: `if (job == null)` でジョブの存在チェック
2. **66行**: `job.scheduleBuild(0, new TimerTriggerCause())` でビルドをスケジュール

#### Step 3: 表示ロジックを理解する

ビルド履歴画面やコンソールログへの出力方法を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` 126-129行 | getShortDescription()の実装 |

**主要処理フロー**:
- **127-128行**: `Messages.TimerTrigger_TimerTriggerCause_ShortDescription()` を返す

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

```
Jenkins内部タイマー（Trigger.Cron）
    │
    └─ TimerTrigger.run()
           │
           ├─ if (job == null) return
           │
           └─ job.scheduleBuild(0, new TimerTriggerCause())
                  │
                  └─ CauseAction に追加
                         │
                         └─ Build.run()
                                └─ cause.print(listener)
                                       └─ getShortDescription()
```

### データフロー図

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

cronスケジュール ───▶ TimerTrigger.run() ───▶ TimerTriggerCause
                          │
                          ▼
                    job.scheduleBuild()
                          │
                          ▼
                    CauseAction
                          │
                          ▼
                    Build.run()
                          │
                          ▼
                    getShortDescription()
                          │
                          ▼
                    [コンソールログ]
                    "Started by timer"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TimerTrigger.java | `core/src/main/java/hudson/triggers/TimerTrigger.java` | ソース | TimerTriggerおよびTimerTriggerCauseの定義 |
| Cause.java | `core/src/main/java/hudson/model/Cause.java` | ソース | Cause基底クラス |
| Trigger.java | `core/src/main/java/hudson/triggers/Trigger.java` | ソース | Trigger基底クラス |
| CronTabList.java | `core/src/main/java/hudson/scheduler/CronTabList.java` | ソース | cronスケジュールの解析 |
| Messages.properties | `core/src/main/resources/hudson/triggers/Messages.properties` | リソース | メッセージ定義 |
