脆弱性診断及び各種テストを自動化する

## 目次
* [概要](#概要)
* [環境](#環境)
* [構成](#構成)
* [設定](#設定)
* [実行結果](#実行結果)
* [参考](#参考)

## 概要
[前回投稿した内容](https://qiita.com/omoikane245/items/6ad9f7c7116d145d2c67)へプラスアルファした内容になります。
また、脆弱性診断には[snyk](https://snyk.io/)を使用しております。
詳しい設定内容などの詳細が知りたい方は[ソースコード](https://github.com/omoikane245/junit-example)をご確認お願いいたします。

## 環境
* Kotlin 1.8.21
* Spring Boot 3.3.5
* Docker 20.10.23
* Docker Compose 2.15.1

## 構成
ざっくり以下のような形式になっています。
[前回同様](https://qiita.com/omoikane245/items/6ad9f7c7116d145d2c67)CIで、テストが全て正常終了しなければマージできないようにしてあります。
※理想はCIでECR等にDocker imageをプッシュやE2Eテストも実施する。

```mermaid
stateDiagram-v2
  [*] --> 脆弱性診断: Snyk実行
  脆弱性診断 --> ビルド: gradle build実行
  脆弱性診断 --> 異常終了: エラー発生
  ビルド --> 静的解析: detekt実行
  静的解析 --> UT実行: junit実行
　静的解析 --> 異常終了: エラー発生
　UT実行 --> 異常終了: エラー発生
  UT実行 --> レポート出力: jacoco実行
  レポート出力 --> 正常終了: 各種停止
```

## 設定
```pre-merge.yml
name: PR Checks
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - '*'

jobs:
  # SEE: https://docs.snyk.io/integrations/ci-cd-integrations/github-actions-integration/snyk-gradle-jdk17-action
  security-check:
    name: Run Security Check
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@master
      - name: Make gradlew executable
        run: chmod +x ./gradlew
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/gradle-jdk17@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high
  tests:
    name: Run tests
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Make gradlew executable
        run: chmod +x ./gradlew
      - name: Run detekt
        run: ./gradlew detekt
      - name: Run test
        run: ./gradlew test
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          DATABASE_USERNAME: ${{ secrets.DATABASE_USERNAME }}
          DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
      - name: Run jacocoTestReport
        run: ./gradlew jacocoTestReport
      - name: Archive unit test results
        uses: actions/upload-artifact@v4
        with:
          name: unit-test-report
          path: build/reports/tests/test
      - name: Archive coverage results
        uses: actions/upload-artifact@v4
        with:
          name: code-coverage-report
          path: build/reports/jacoco/test/html
```

## 実行結果
* 脆弱性診断
以下のような形式で脆弱性を検知し、エラーで弾いてくれる。
なお、4段階のレベルを指定でき、下記キャプチャは3番目の"high"を指定した結果です。
詳しくは[こちら](https://docs.snyk.io/snyk-cli/test-for-vulnerabilities/set-severity-thresholds-for-cli-tests)を参照お願いします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534209/a948068c-dc27-94e3-7d39-6ce0e480f025.png)

指摘箇所を解消すると、マージできるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534209/5c2b54ce-a7c7-da5c-b26b-afbbe3870b95.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534209/a0eff392-baf8-0eaa-58d1-6a0b77fe29d0.png)

* UT
UTとカバレッジ計測も同様にCIで実行している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534209/6a19b150-1d3e-5b28-e400-86f3109c5118.png)

また、テスト実行結果やカバレッジレポートは、[SummaryのArtifacts](https://github.com/omoikane245/junit-example/actions/runs/11541608322)にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534209/86e1e686-09f0-3d87-d47e-d1f4fe235d8e.png)

## 参考
[snyk](https://docs.snyk.io/integrations/ci-cd-integrations/github-actions-integration)
[GitHub Actionsを用いた自動テストの実行と結果集計](https://qiita.com/vZke/items/868eb9fd5289d2a25660)