Java開発者向け: GitHub ActionsでGraldeとSpotBugsを使ったCI静的解析の実装方法

### はじめに
- GitHub Actionsの詳細な説明は行いません
- Gradleを中心した説明になります。Mavenの説明は行いません。
- 私のイメージも交えて話します。誤っていたら指摘していただけると記事も私のイメージも修正できるのでありがたいです


<a id="#Chapter1"></a>
# GitHubActionsのイメージ

![スクリーンショット 2024-03-05 12.35.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641519/02a83b99-199c-0916-2777-c2c98c3ef22e.png)


### 項目の説明

**ワークフロー(Workflow)**
ディレクトリにあるYAMLファイルで定義され、一連のジョブを含みます。
GitHubActionsにおける一番大きな枠組みです

https://docs.github.com/ja/actions/using-workflows/about-workflows

**イベント(Event)**
いつCIが実行されるかを定義します。
PR、commit、push、cloneなど様々なトリガーを設定できます。

https://docs.github.com/ja/actions/using-workflows/triggering-a-workflow

**ジョブ (Job)**
ワークフロー内で定義される独立したタスクのグループで、それぞれ異なるランナー(環境)で実行できます。

https://docs.github.com/ja/actions/using-jobs/using-jobs-in-a-workflow

**ランナー（Runner）**
GitHub Actionsのジョブが実行されるサーバー環境を指します

https://docs.github.com/ja/actions/using-jobs/choosing-the-runner-for-a-job

**ステップ(Step)**
各ジョブ内で実行される個々のタスクやアクションです。これには、独自のスクリプトの実行や、特定のアクションの使用が含まれます。
ここが具体的に何を実行するか命令する場所になります。

### 具体的なコード
```yaml
name: Java CI with SpotBugs
on: [ push, pull_request ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: My first step - check out repository
        uses: actions/checkout@v4

      - name: List files
        run: ls -R

      - name: Set up Java 17
        uses: actions/setup-java@v3
        with:
          distribution: "temurin"
          java-version: "17"
          cache: "gradle"

      - name: Generate gradle wrapper
        run: gradle wrapper --gradle-version=7.6

      - name: Execute  SpotBugs
        run: ./gradlew spotbugsMain

```
先ほどの説明を踏まえて解説します。

**ワークフロー(Workflow)**
このファイル全体が一連のワークフローとなります

**イベント(Event)**
`on: [push, pull_request]` の箇所がトリガーになります。push、PRの時にこのCIは実行されます

**ジョブ (Job)**
`jobs:`でタスクを構成しています。

**ランナー（Runner）**
` runs-on: ubuntu-latest`今回はUbuntuの最新版を実行環境としています

**ステップ(Step)**
`steps:`以降では実際に何を行うかを定義しています。



私が注目して欲しい部分はstepu部分です。
`uses: actions/checkout@v4`のように特殊な書き方をしているように見えますが、これは既にGitHubやその他のサードパーティーが実際の実行に必要な機能を用意してくれているものを使用しています。このほかにも様々なactionをGitHub Action用に既に用意してくれて、大体はこれらを組み合わせて使用していくだけなので、意外と単純な構造になります。
その下に`with:`などもありますが、これらもそこのサイトで指定された引数を渡してカスタマイズしているだけなので、相当高度なことをしなければそんなに難しくないと思います。
それと、ここにあるnameは実際にGitHubでCIを確認した時に見えるものなのでわかりやすい名前が良いです。


<a id="#Chapter2"></a>
# SpotBugsの設定方法
GitHub Actionsでは、多くのツールやライブラリに対応する公式またはサードパーティ製のアクションが用意されていますが、SpotBugsについては専用のアクションがない場合があります。SpotBugsをGitHub Actionsのワークフローに統合したい場合、以下の手順に従う必要があります。

1. **ビルドツールへのSpotBugsの統合:** まず、プロジェクトで使用しているビルドツール（例えば、GradleやMavenなど）にSpotBugsプラグインを追加します。これにより、ビルドプロセス中に自動的にコードの静的解析が行われるようになります

2. **GitHub ActionsからのSpotBugsの呼び出し:** 次に、GitHub Actionsのワークフローファイル内で、ビルドツールを実行するステップを設定し、その中でSpotBugsタスクを呼び出します。これにより、GitHub ActionsのCIプロセス中にSpotBugsによる解析が実行され、問題があれば報告されます

具体的には、Gradleを使用している場合は、build.gradleファイルにSpotBugsプラグインを追加し、GitHub Actionsのワークフローファイル内で./gradlew spotbugsMainのようにSpotBugsタスクを実行するコマンドを含めることになります。

### ビルドツールへのSpotBugsの統合
##### Gradleのbuild設定ファイル
Gradleのビルド設定ファイルには、`Kotlin`と`Groovy`の2種類の言語で書かれたものがあります。これはプロジェクトによって異なり、また新しいプロジェクトを作成する際には、どちらの言語を使うか選択することになります。プロジェクト内にbuild.gradleファイルが存在する場合はGroovyで書かれており、build.gradle.ktsファイルがあればKotlinで書かれています。Gradleの公式ドキュメントでは、KotlinとGroovyの両方のDSL（ドメイン固有言語）が提供されているため、使用している言語に応じたドキュメントを参照してください。

https://plugins.gradle.org/plugin/com.github.spotbugs

https://github.com/spotbugs/spotbugs-gradle-plugin

#### SpotBugsプラグインをGradleに統合する
実際にbuild.gradleファイルに設定していきます。
上記のURLの通りに設定すれば問題ないのですが記法に注意が必要です。最新のGradleではDSL記法を推奨しています。
以下を追加するだけでプラグインの設定は完了です。versionはお好みで変更してください。

```groovy
plugins {
    id 'java'
    id "com.github.spotbugs" version "6.0.8"
}
```

#### SpotBugsをCIで使う
```yaml
      - name: Run SpotBugs
        run: |
          ./gradlew spotbugsMain
```
Gradleのコマンドの`spotbugsMain`はSpotBugsをプラグインに追加すると自動的に生成されるタスクです。
spotbugsMain タスクはメインソースセット（通常は src/main/java）に対する静的コード分析を実行し、spotbugsTest タスクはテストソースセット（通常は src/test/java）に対して実行されます。 

上記設定後にpushするとCIが走るようになります。詳しくはドキュメントを参照ください。

### GradleでBuild時にSpotBugsを走らせたい

```groovy
      - name: Execute Build and SpotBugs 
        run: ./gradlew 
```
build時にSpotBugsを実行するにはコマンドを変更する必要があります。


### マルチプロジェクトの場合
```
subprojects {
    apply plugin: 'java'
    apply plugin: 'com.github.spotbugs'

    spotbugs {
        toolVersion = '4.8.3'
    }
}
```

Javaでのプロジェクト管理で、serverディレクトリをルートとして、app、apiなど複数のプロジェクトを管理していることもあるでしょう。この場合はbuild.gradleに一手間加える必要があります。
注意しなくてはいけないのが、`toolVersion = '4.8.3'`です。これはSpotBugsのバージョンであり、gradle　プラグインのバージョンではないということです。SpotBugs内のプロパティは好きに設定してください


https://docs.github.com/ja/actions

https://plugins.gradle.org/plugin/com.github.spotbugs-base

https://github.com/spotbugs/spotbugs-gradle-plugin

https://spotbugs.readthedocs.io/ja/latest/gradle.html