# 機能設計書 17-Mavenビルド

## 概要

本ドキュメントは、JenkinsにおけるMavenビルド機能の設計について記述する。この機能は、Apache Mavenを使用してJavaプロジェクトをビルドするビルドステップを提供する。

### 本機能の処理概要

Mavenビルド機能は、ビルドステップとしてMavenコマンドを実行する。グローバル設定されたMavenインストールから適切なバージョンを選択し、指定されたターゲット（clean, compile, test, package等）を実行する。

**業務上の目的・背景**：Javaプロジェクトの標準ビルドツールであるMavenをJenkinsから利用できるようにする。プロジェクトのライフサイクル管理、依存関係解決、テスト実行、パッケージングなどをCIパイプラインに組み込む。

**機能の利用シーン**：
- Javaプロジェクトのコンパイルとパッケージング
- 単体テスト・統合テストの実行
- 依存関係の自動ダウンロードと管理
- ローカルリポジトリの分離によるビルド隔離
- settings.xmlによるカスタム設定の適用

**主要な処理内容**：
1. MavenInstallationの選択と環境変数設定
2. ターゲット、POMファイル、プロパティの組み立て
3. settings.xml/globalSettings.xmlの適用
4. ArgumentListBuilderによるコマンドライン構築
5. Launcher経由でのMavenプロセス起動
6. MavenConsoleAnnotatorによるログ装飾

**関連システム・外部連携**：Mavenセントラルリポジトリ、カスタムリポジトリ、JDK。

**権限による制御**：Job.CONFIGURE権限でビルドステップの設定変更が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | ジョブ設定 | 主画面 | Mavenビルドステップの追加・編集 |
| 30 | グローバルツール設定 | 設定画面 | Mavenインストールの設定 |

## 機能種別

ビルドステップ / プロセス実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| targets | String | Yes | Mavenターゲット（goals） | - |
| mavenName | String | No | MavenInstallation名 | 登録済みインストール名 |
| pom | String | No | POMファイルパス（相対） | - |
| properties | String | No | システムプロパティ | Properties形式 |
| jvmOptions | String | No | MAVEN_OPTS | - |
| usePrivateRepository | boolean | No | プライベートリポジトリ使用 | - |
| settings | SettingsProvider | No | settings.xmlプロバイダ | - |
| globalSettings | GlobalSettingsProvider | No | globalSettings.xmlプロバイダ | - |
| injectBuildVariables | boolean | No | ビルド変数をプロパティとして注入 | - |

### 入力データソース

- ジョブ設定画面からのユーザー入力
- GlobalMavenConfig: グローバル設定
- MavenInstallation: インストール情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 終了コード | int | Mavenの終了コード |
| ビルド成果物 | Files | target/配下の成果物 |
| コンソールログ | String | Maven実行ログ（アノテーション付き） |

### 出力先

- BuildListener: コンソールログへの出力（MavenConsoleAnnotator経由）
- ワークスペース: ビルド成果物

## 処理フロー

### 処理シーケンス

```
1. Maven.perform()呼び出し
2. 変数解決とターゲット展開
   └─ build.getBuildVariableResolver()で変数解決
   └─ env.expand()で環境変数展開
3. MavenInstallationの取得と環境適応
   └─ mi.forNode()でノード固有パス解決
   └─ mi.forEnvironment()で環境変数展開
4. コマンドライン構築
   └─ 実行ファイルパス（mvn/maven）
   └─ -f pomオプション
   └─ -s settings.xmlオプション
   └─ -gs globalSettings.xmlオプション
   └─ -Dプロパティオプション
   └─ ターゲット
5. 環境変数設定
   └─ M2_HOME, MAVEN_HOME, PATH+MAVEN
   └─ MAVEN_OPTS（jvmOptions）
   └─ MAVEN_TERMINATE_CMD=on
6. Launcher.launch()でプロセス起動
7. MavenConsoleAnnotatorでログ装飾
```

### フローチャート

```mermaid
flowchart TD
    A[Maven.perform開始] --> B[変数・環境変数展開]
    B --> C{MavenInstallation指定?}
    C -->|Yes| D[mi.forNode/forEnvironment]
    C -->|No| E[DecideDefaultMavenCommand]
    D --> F[getExecutable]
    E --> G[mvn or maven判定]
    F --> H[ArgumentListBuilder構築]
    G --> H
    H --> I{-f pomオプション}
    I --> J{-s settingsオプション}
    J --> K{-D プロパティ}
    K --> L{usePrivateRepository?}
    L -->|Yes| M[-Dmaven.repo.local追加]
    L -->|No| N[ターゲット追加]
    M --> N
    N --> O[buildEnvVars]
    O --> P[Launcher.launch]
    P --> Q[MavenConsoleAnnotator]
    Q --> R{終了コード?}
    R -->|0| S[SUCCESS]
    R -->|非0| T[FAILURE]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-17-01 | Maven1/2自動判定 | project.xml存在でMaven1、それ以外はMaven2として判定 | MavenInstallation未指定時 |
| BR-17-02 | パイプ区切り | ターゲット文字列を\|で区切って複数回Maven実行 | \|を含む場合 |
| BR-17-03 | settingsパラメータ重複回避 | ターゲットに-sが含まれる場合はsettings追加をスキップ | -s検出時 |
| BR-17-04 | プライベートリポジトリ | usePrivateRepository=trueで-Dmaven.repo.local=.repository追加 | 設定時 |
| BR-17-05 | ビルド変数注入 | injectBuildVariables=trueでビルド変数を-Dプロパティとして追加 | 設定時 |
| BR-17-06 | Windows対応 | 非Unix環境ではargs.toWindowsCommand()で変換 | Windows実行時 |

### 計算ロジック

- 実行コマンド判定: project.xml存在 → maven、それ以外 → mvn
- パス解決: M2_HOME/bin/mvn(.bat/.cmd)

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

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

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

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ビルドステップ保存 | jobs/{jobName}/config.xml | UPDATE | Mavenステップ設定の永続化 |
| インストール保存 | hudson.tasks.Maven.xml | UPDATE | MavenInstallation設定の永続化 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 実行ファイル不在 | mvn/mavenが見つからない | fatalError出力、ビルド失敗 |
| - | 非0終了コード | Mavenビルド失敗 | ビルド失敗 |
| - | IOException | プロセス起動失敗 | displayIOException、ビルド失敗 |

### リトライ仕様

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

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

特になし。

## パフォーマンス要件

- usePrivateRepository=trueでリポジトリ競合を回避
- MAVEN_TERMINATE_CMD=onでContinuum検出対応

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

- sensitiveVarsでパスワード等のマスキング
- SettingsProviderによるsettings.xmlの安全な管理

## 備考

- @Symbol("maven")でPipeline DSLからはmavenとして参照可能
- MavenInstallationは自動インストール（MavenInstaller）をサポート
- MAVEN_20, MAVEN_21, MAVEN_30のバージョン定数でバージョン判定可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Maven.java | `core/src/main/java/hudson/tasks/Maven.java` | Mavenビルドステップ |
| 1-2 | MavenInstallation | `core/src/main/java/hudson/tasks/Maven.java` 内部クラス | Mavenインストール情報 |

#### Step 2: perform()メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | perform() | `core/src/main/java/hudson/tasks/Maven.java` | メイン実行処理（291-381行目） |

**主要処理フロー**:
- **292-298行目**: 変数解決とターゲット展開
- **302-380行目**: パイプ区切りループ
- **314-327行目**: MavenInstallation取得と実行ファイル解決
- **332-343行目**: settings/globalSettings追加
- **348-358行目**: プロパティ追加
- **369行目**: Launcher.launch()実行

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MavenInstallation | `core/src/main/java/hudson/tasks/Maven.java` | ToolInstallation継承（496-756行目） |
| 3-2 | buildEnvVars() | `core/src/main/java/hudson/tasks/Maven.java` | 環境変数設定（540-548行目） |
| 3-3 | getExecutable() | `core/src/main/java/hudson/tasks/Maven.java` | 実行ファイルパス取得（621-644行目） |

**主要処理フロー**:
- **540-548行目**: M2_HOME, MAVEN_HOME, PATH+MAVENを設定
- **621-644行目**: mvn/maven(.bat/.cmd)の存在確認

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

```
AbstractBuild.run()
    │
    └─ Maven.perform()
           │
           ├─ getMaven() → MavenInstallation
           │      │
           │      ├─ mi.forNode()
           │      └─ mi.forEnvironment()
           │
           ├─ [MavenInstallation未指定時]
           │      └─ DecideDefaultMavenCommand.invoke()
           │
           ├─ ArgumentListBuilder構築
           │      │
           │      ├─ getExecutable() → mvn/maven パス
           │      ├─ -f pom
           │      ├─ -s settings.xml
           │      ├─ -gs globalSettings.xml
           │      ├─ -D properties
           │      └─ targets
           │
           ├─ buildEnvVars()
           │      │
           │      ├─ M2_HOME, MAVEN_HOME
           │      ├─ MAVEN_OPTS
           │      └─ MAVEN_TERMINATE_CMD
           │
           └─ Launcher.launch()
                  │
                  └─ MavenConsoleAnnotator
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Maven.java | `core/src/main/java/hudson/tasks/Maven.java` | ソース | Mavenビルドステップ |
| MavenConsoleAnnotator.java | `core/src/main/java/hudson/tasks/_maven/MavenConsoleAnnotator.java` | ソース | コンソールログアノテータ |
| GlobalMavenConfig.java | `core/src/main/java/jenkins/mvn/GlobalMavenConfig.java` | ソース | グローバルMaven設定 |
| SettingsProvider.java | `core/src/main/java/jenkins/mvn/SettingsProvider.java` | ソース | settings.xmlプロバイダ |
| GlobalSettingsProvider.java | `core/src/main/java/jenkins/mvn/GlobalSettingsProvider.java` | ソース | globalSettings.xmlプロバイダ |
| ToolInstallation.java | `core/src/main/java/hudson/tools/ToolInstallation.java` | ソース | ツールインストール基底クラス |
