GitHub ActionsとGradleによるCI設定のトラブルシューティング

## はじめに

GitHub ActionsとGradleを組み合わせることで、JavaプロジェクトのCI/CD環境を効率的に構築できます。しかし、設定時にいくつかの落とし穴があります。この記事では、特に以下の問題について詳しく解説します：

1. GitHub Actionsにおけるアクションのv4バージョンへの移行必要性
2. Gradleビルド設定でのCI向け最適化
3. Java/Gradleプロジェクトのテスト自動化のベストプラクティス

実際に遭遇したエラーとその解決策を紹介し、CI環境の安定した運用方法について説明します。

## 1. GitHub Actionsアクションのバージョン問題

### 1.1 エラー事例

以下のようなエラーが発生することがあります：

```
Current runner version: '2.323.0'
Operating System
Runner Image
Runner Image Provisioner
GITHUB_TOKEN Permissions
Secret source: Actions
Prepare workflow directory
Prepare all required actions
Getting action download info
Download immutable action package 'actions/checkout@v3'
Download immutable action package 'actions/setup-java@v3'
Download action repository 'EnricoMi/publish-unit-test-result-action@v2' (SHA:afb2984f4d89672b2f9d9c13ae23d53779671984)
Error: Missing download info for actions/upload-artifact@v3
```

これは、**v3系アクションが非推奨化され、利用できなくなっていることが主な原因です**。

### 1.2 原因と解決策

GitHub Actionsのv3系アクションは非推奨となり、**v4への完全移行が必要**になっています。特に、`actions/checkout`、`actions/setup-java`、`actions/upload-artifact`などのコアアクションはv4を使用する必要があります。

v3系アクションが非推奨となった主な理由：

- Node.js 16のサポート終了（2023年9月）[1]
- パフォーマンスとセキュリティの大幅な向上
- 内部APIとアーキテクチャの刷新
- v3系はGitHub自身による正式サポート対象外

#### 修正例：

```yaml
# 問題のある設定（v3系アクションを使用）
steps:
- uses: actions/checkout@v3  # ← v3は非推奨
- uses: actions/setup-java@v3  # ← v3は非推奨
- uses: actions/upload-artifact@v3  # ← v3は非推奨

# 正しい設定（v4系アクションを使用）
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/upload-artifact@v4
```

### 1.3 主要アクションの最新バージョン情報（2023年12月現在）

| アクション名 | 最新バージョン | リリース日 | 主な変更点 |
|------------|--------------|-----------|----------|
| actions/checkout | v4 | 2023年8月 | Git 2.42.0対応、LFSサポート改善 |
| actions/setup-java | v4 | 2023年11月 | Java 21完全対応、Node.js 20ベース |
| actions/upload-artifact | v4 | 2023年11月 | 大容量ファイル転送改善、Node.js 20 |
| actions/cache | v3 | 2022年5月 | v4はまだリリースされていない |

### 1.4 参考文献

- [GitHub Actions: Node.js 20への移行](https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/)
- [アーティファクトv3の非推奨通知](https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/)
- [GitHub Actions: アーティファクトv4が一般提供開始](https://github.blog/changelog/2023-12-14-github-actions-artifacts-v4-is-now-generally-available/)
- [@actions/cacheパッケージの非推奨通知](https://github.com/actions/toolkit/discussions/1890) 

## 2. Gradleビルド設定の最適化

### 2.1 JUnitレポート設定エラー

次のようなエラーに遭遇することがあります：

```
Could not set unknown property 'enabled' for Report junitXml of type org.gradle.api.internal.tasks.testing.DefaultJUnitXmlReport.
```

これは、Gradleのバージョンによって設定プロパティが変更されたことが原因です。

### 2.2 build.gradleの修正

#### 問題のあるコード：

```gradle
test {
    reports {
        junitXml.enabled = true  // 古い構文
        html.enabled = true      // 古い構文
    }
}
```

#### 修正後のコード：

```gradle
test {
    reports {
        junitXml.required = true  // 新しい構文
        html.required = true      // 新しい構文
    }
}
```

Gradle 7.0以降では、レポート設定のプロパティが`enabled`から`required`に変更されています[2]。

### 2.3 Java互換性とJaCoCo設定

JaCoCoによるカバレッジレポート生成時に以下のエラーが発生することがあります：

```
Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 65
```

これは、JaCoCoのバージョンがプロジェクトで使用しているJavaバージョンをサポートしていないことを示します。

#### Java/JDKバージョンとクラスファイルバージョンの対応：

| Java/JDK バージョン | クラスファイルメジャーバージョン |
|--------------------|----------------------------|
| Java 8  | 52 |
| Java 11 | 55 |
| Java 17 | 61 |
| Java 21 | 65 |

#### 解決策：最新のJaCoCoバージョンを使用

```gradle
jacoco {
    toolVersion = "0.8.11"  // Java 21をサポートする最新バージョン
}
```

### 2.4 CI環境とローカル環境の同期

CIとローカル環境でJavaバージョンが一致していないと、「ローカルではビルドできるのにCIでは失敗する」といった問題が発生します。

#### GitHub Actionsでのバージョン指定：

```yaml
- name: Set up JDK 21
  uses: actions/setup-java@v4
  with:
    java-version: '21'
    distribution: 'temurin'
    cache: gradle
```

### 2.5 参考文献

- [Gradle レポート設定ドキュメント](https://docs.gradle.org/current/dsl/org.gradle.api.reporting.ReportingExtension.html)
- [JaCoCo Release Notes](https://www.jacoco.org/jacoco/trunk/doc/changes.html)
- [OpenJDK クラスファイルバージョン一覧](https://javaalmanac.io/bytecode/versions/)

## 3. CI設定の完全な例

以下は、GitHub ActionsとGradleを使用したJavaプロジェクトの完全なCI設定例です：

### 3.1 GitHub Actions ワークフロー (.github/workflows/gradle-ci.yml)

```yaml
name: Java CI with Gradle

on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    
    - name: Set up JDK 21
      uses: actions/setup-java@v4
      with:
        java-version: '21'
        distribution: 'temurin'
        cache: gradle
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
      
    - name: Build and Test with Gradle
      run: ./gradlew build
      
    - name: Upload test results
      uses: actions/upload-artifact@v4
      if: always()
      with:
        name: test-results
        path: |
          **/build/reports/tests/
          **/build/test-results/
        retention-days: 7
```

### 3.2 最適化されたGradleビルド設定 (build.gradle)

```gradle
plugins {
    id 'java'
    id 'application'
    id 'jacoco'
}

repositories {
    mavenCentral()
}

dependencies {
    // JUnit 5
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.8.2'
    
    // JUnit 5 Parameterized Tests
    testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2'
    
    // Mockito
    testImplementation 'org.mockito:mockito-core:4.6.1'
    
    // その他の依存関係...
}

application {
    mainClass = 'com.example.Application'
}

// JaCoCoの設定 - Java 21をサポートする最新バージョン
jacoco {
    toolVersion = "0.8.11"
}

jacocoTestReport {
    reports {
        xml.required = true
        html.required = true
    }
    
    dependsOn test
}

test {
    useJUnitPlatform()
    testLogging {
        events "passed", "skipped", "failed", "standardOut", "standardError"
        showStandardStreams = true
        exceptionFormat = 'full'
    }
    
    // JUnit XMLレポート設定
    reports {
        junitXml.required = true
        html.required = true
    }
    
    finalizedBy jacocoTestReport
}
```

## 4. トラブルシューティングのためのチェックリスト

CI/CD設定で問題が発生した場合、以下の点を確認してください：

1. **GitHub Actionsのバージョン更新**
   - すべてのコアアクション（checkout, setup-java, upload-artifact）がv4に更新されているか
   - 古いv3系アクションを使用していないか
   - サードパーティアクションの互換性は確認したか

2. **Javaバージョンの一致**
   - ローカル環境とCI環境で同じJavaバージョンを使用しているか
   - 使用しているツール（JaCoCo, Spotbugs等）がそのJavaバージョンをサポートしているか

3. **Gradle設定**
   - Gradleの文法が使用しているGradleバージョンに適合しているか
   - レポート設定で`enabled`ではなく`required`を使用しているか

4. **依存関係**
   - テストランナーや依存ライブラリが互いに互換性があるか
   - 古いプラグインを使用していないか

5. **権限設定**
   - GitHub Actionsに必要な権限が付与されているか

## 5. まとめ

GitHub ActionsとGradleを使用したCI環境設定では、以下の点に注意することで多くの問題を回避できます：

1. GitHub Actionsのアクションはすべてv4に移行する（v3は非推奨）
2. Gradleの設定はバージョンに合わせて最新の構文を使用する
3. Java環境とツールの互換性を確認する
4. ローカル環境とCI環境で同じバージョンを使用する

これらの点に注意することで、より安定したCI/CD環境を構築し、「ローカルでは動くのにCIでは失敗する」といった問題を減らすことができます。

---

## 参考文献

[1] GitHub ActionsはNode.js 16からNode.js 20への移行を完了しました。v3系アクションはNode.js 16をベースにしており、2023年9月にサポートが終了したため、v4への移行が必要です。詳細は[GitHub公式ブログ](https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/)を参照。

[2] [Upgrading your build from Gradle 7.x to 8.0](https://docs.gradle.org/current/userguide/upgrading_version_7.html)にて、"The deprecated destination, and enabled properties of the Report type have been removed. Use the outputLocation and required properties instead."と記載がある。