# 帳票設計書 8-Coverage Report

## 概要

本ドキュメントは、GitLabのCIパイプラインにおけるコードカバレッジレポートをJSON形式で生成する機能の帳票設計書である。

### 本帳票の処理概要

本帳票は、CIパイプラインで生成されたコードカバレッジ情報を集約し、マージリクエストで変更されたファイルに対するカバレッジ情報をJSON形式で保存する。このレポートはパイプラインアーティファクトとして保存され、マージリクエストのカバレッジビジュアライゼーションに使用される。

**業務上の目的・背景**：コードレビュープロセスにおいて、変更されたコードがテストでカバーされているかを確認することは重要である。この帳票により、開発者はマージリクエストの変更箇所に対するテストカバレッジを視覚的に確認でき、テスト不足の箇所を特定できる。品質管理の観点から、カバレッジ情報はプロジェクトの品質指標として活用される。

**帳票の利用シーン**：マージリクエストのレビュー時にカバレッジ情報を確認する際、CIパイプラインの品質チェックとして使用する際、プロジェクトのテストカバレッジ傾向を分析する際などに利用される。

**主要な出力内容**：
1. ファイルパスとカバレッジ情報のマッピング
2. 各ファイルの行別カバレッジステータス
3. マージリクエストの変更ファイルに限定したカバレッジ情報

**帳票の出力タイミング**：CIパイプラインの完了時に自動的に生成され、パイプラインアーティファクトとして保存される。

**帳票の利用者**：開発者、コードレビュアー、品質管理担当者

## 帳票種別

品質レポート（JSON出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Merge Request Diffs | `/:namespace/:project/-/merge_requests/:id/diffs` | 自動表示（カバレッジバー） |
| - | Pipeline Details | `/:namespace/:project/-/pipelines/:id` | アーティファクトとして表示 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON |
| 用紙サイズ | - |
| 向き | - |
| ファイル名 | code_coverage.json |
| 出力方法 | パイプラインアーティファクト |
| 文字コード | UTF-8 |

### JSON構造

```json
{
  "files": {
    "path/to/file.rb": {
      "1": 5,
      "2": 0,
      "3": null
    }
  }
}
```

| フィールド | 説明 |
|-----------|------|
| files | ファイルパスをキーとしたオブジェクト |
| 行番号 | カバレッジ回数（0=未カバー、正数=カバー回数、null=対象外） |

## 帳票レイアウト

### レイアウト概要

JSONファイルはファイルパスをキーとした階層構造を持つ。

```
{
  "files": {
    "ファイルパス1": {
      "行番号": カバレッジ回数,
      ...
    },
    "ファイルパス2": {
      ...
    }
  }
}
```

### データ項目

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | files | ファイル別カバレッジ情報 | CoverageReport | オブジェクト |
| 2 | ファイルパス | プロジェクトルートからの相対パス | job artifacts | 文字列キー |
| 3 | 行番号 | ソースコードの行番号 | job artifacts | 数値キー |
| 4 | カバレッジ回数 | テスト実行回数 | job artifacts | 数値/null |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| パイプライン | 対象パイプライン | Yes |
| マージリクエスト | 対象MR（変更ファイルのフィルタ用） | No |
| カバレッジアーティファクト | ジョブのカバレッジレポート | Yes |

### フィルタリング

| 優先度 | 項目 | 説明 |
|-------|------|-----|
| 1 | 子パイプライン除外 | 子パイプラインの場合はレポートを生成しない |
| 2 | MR変更ファイル | マージリクエストの変更ファイルのみを対象 |

### 改ページ条件

JSON形式のため該当なし

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| ci_pipelines | パイプライン情報 | 主テーブル |
| ci_builds | ジョブ情報 | ci_pipelines.id = ci_builds.commit_id |
| ci_job_artifacts | アーティファクト | ci_builds.id = ci_job_artifacts.job_id |
| merge_requests | MR情報 | ci_pipelines経由 |
| ci_pipeline_artifacts | レポート保存先 | ci_pipelines.id = ci_pipeline_artifacts.pipeline_id |

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

#### ci_pipeline_artifacts

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| file_type | - | :code_coverage | ファイル種別 |
| file | カバレッジJSON | - | CarrierWaveファイル |
| size | - | - | ファイルサイズ |
| locked | - | pipeline.locked | ロック状態 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| レポートデータ | CoverageReportGenerator.new(pipeline).report | - | カバレッジ情報の集約 |
| JSONデータ | Gitlab::Json.dump(report) | - | JSON文字列化 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[パイプライン完了] --> B[CoverageReportService.execute]
    B --> C{子パイプライン?}
    C -->|Yes| D[空レポート返却]
    C -->|No| E{MR変更ファイルあり?}
    E -->|No| D
    E -->|Yes| F[CoverageReportGenerator.new]
    F --> G[latest_report_builds取得]
    G --> H[各ビルドのカバレッジレポート解析]
    H --> I[MR変更ファイルでフィルタ]
    I --> J[CoverageReport生成]
    J --> K[Gitlab::Json.dump]
    K --> L[CarrierWaveStringFile作成]
    L --> M[PipelineArtifact.create_or_replace_for_pipeline!]
    M --> N[ログ出力]
    N --> O[完了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| レポート空 | カバレッジデータがない | - | 処理をスキップ |
| 子パイプライン | pipeline.child?がtrue | - | 空レポート返却 |
| MR変更ファイルなし | merge_request_file_pathsが空 | - | 空レポート返却 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 変更ファイル数に依存 |
| 目標出力時間 | パイプライン処理内で完了 |
| 同時出力数上限 | パイプライン単位 |

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

- パイプラインへのアクセス権限が必要
- カバレッジ情報はソースコードの構造を間接的に示すため、適切なアクセス制御が必要
- pipeline.lockedの状態をアーティファクトに引き継ぐ

## 備考

- StrongMemoizeを使用してレポートをキャッシュ
- DEFAULT_FILE_NAMESで定義されたファイル名を使用
- create_or_replace_for_pipeline!で既存レポートを置換
- ログにはproject_id、pipeline_id、pipeline_artifact_idを記録

---

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

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

### 推奨読解順序

#### Step 1: サービスクラスを理解する

レポート生成のエントリーポイントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | coverage_report_service.rb | `app/services/ci/pipeline_artifacts/coverage_report_service.rb` | executeメソッド（11-17行目） |

**読解のコツ**: executeメソッドがレポート生成のエントリーポイント。report.empty?の場合は処理をスキップする。

#### Step 2: レポートジェネレーターを理解する

カバレッジデータの収集ロジックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | coverage_report_generator.rb | `lib/gitlab/ci/reports/coverage_report_generator.rb` | reportメソッド（13-37行目） |
| 2-2 | coverage_report_generator.rb | `lib/gitlab/ci/reports/coverage_report_generator.rb` | merge_request_file_paths（45-53行目） |

**主要処理フロー**:
1. **13-19行目**: 子パイプラインや変更ファイルなしの場合は空レポート
2. **23-36行目**: 各ビルドのカバレッジレポートを解析
3. **45-53行目**: マージリクエストの変更ファイルパスを取得

#### Step 3: アーティファクト保存を理解する

パイプラインアーティファクトとしての保存ロジックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | coverage_report_service.rb | `app/services/ci/pipeline_artifacts/coverage_report_service.rb` | pipeline_artifact_params（29-36行目） |
| 3-2 | coverage_report_service.rb | `app/services/ci/pipeline_artifacts/coverage_report_service.rb` | carrierwave_file（38-46行目） |

**主要処理フロー**:
- **29-36行目**: アーティファクト作成パラメータ（file_type: :code_coverage）
- **38-46行目**: JSON文字列をCarrierWaveファイルに変換

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

```
Ci::PipelineArtifacts::CoverageReportService
    │
    ├─ initialize(pipeline)
    │
    ├─ execute
    │      │
    │      ├─ report (memoized)
    │      │      └─ CoverageReportGenerator.new(pipeline).report
    │      │             ├─ pipeline.child? チェック
    │      │             ├─ merge_request_file_paths
    │      │             │      └─ merge_requests_as_head_pipeline
    │      │             │             └─ modified_paths
    │      │             └─ report_builds.find_each
    │      │                    └─ Gitlab::Ci::Parsers.fabricate!
    │      │
    │      └─ PipelineArtifact.create_or_replace_for_pipeline!
    │             └─ carrierwave_file
    │                    └─ CarrierWaveStringFile.new_file
    │
    └─ log_params
```

### データフロー図

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

パイプライン ───▶ CoverageReportService.execute
    │                      │
    ▼                      ▼
ジョブアーティファクト ───▶ CoverageReportGenerator
    │                      │
    ▼                      ▼
MR変更ファイル ───▶ フィルタリング ───▶ JSON生成
    │                                      │
    │                                      ▼
    └──────────────────────────────▶ PipelineArtifact保存
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| coverage_report_service.rb | `app/services/ci/pipeline_artifacts/coverage_report_service.rb` | ソース | レポート生成サービス |
| coverage_report_generator.rb | `lib/gitlab/ci/reports/coverage_report_generator.rb` | ソース | カバレッジ収集 |
| coverage_report.rb | `lib/gitlab/ci/reports/coverage_report.rb` | ソース | レポートモデル |
| pipeline_artifact.rb | `app/models/ci/pipeline_artifact.rb` | ソース | アーティファクトモデル |
| carrier_wave_string_file.rb | `lib/carrier_wave_string_file.rb` | ソース | ファイル変換 |
