CodeBuild時にGradleのバージョンが古くて失敗する

# 現象

- CodeBuildのbuildspec.ymlでgradleコマンドを実行した際に以下のようなエラーが発生した

```
[Container] 2022/10/07 02:43:03 Running command gradle build -x test
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details

FAILURE: Build failed with an exception.

* Where:
Build file '/codebuild/output/src757482764/src/app/build.gradle' line: 7

* What went wrong:
An exception occurred applying plugin request [id: 'com.diffplug.spotless', version: '6.11.0']
> Failed to apply plugin [id 'com.diffplug.spotless']
   > Spotless requires Gradle 6.1.1 or newer, this was 5.6.4
```

# 環境

- 言語：Java 11
- コードフォーマッター：com.diffplug.spotless 6.11.0
- ビルドツール：Gradle 7.4.2
- CodeBuildイメージ：aws/codebuild/amazonlinux2-x86_64-standard:3.0

# 原因

- SpotlessにはGradle 6.1.1以上が必要だけど、CodeBuildはデフォルトだとGradle 5.6.4なのでbuildが通らなかった

# 対応

- gradleコマンドではなくgradlewを使用する
- gradlewには、CodeBuildでも実行ができるように、実行権限をつけておく

# 詳細

- 以下のようなbuildspec.ymlを使用していた

``` yml: buildspec.yml
version: 0.2
phases:
  pre_build:
    # ...省略...
  build:
    commands:
      # Build
      - echo Build started on `date`
      - cd app
      # ロケールを設定しないとCodeBuild上でのcompileTestJavaに失敗する
      - export LANG='en_US.utf8'
      - gradle build -x test
      # ...省略...
  post_build:
      # ...省略...
```

- そのまま実行すると冒頭のエラーが発生したので、`gradle`→`gradlew`に変更して実行

``` yml: buildspec.yml
  # ...省略...
  build:
    commands:
      # ...省略...
      - ./gradlew build -x test
      # ...省略...
```

- 以下のようなエラーが発生

``` sh: 
[Container] 2022/10/07 03:43:28 Running command ./gradlew build -x test
/codebuild/output/tmp/script.sh: line 4: ./gradlew: Permission denied
```

- 実行時に権限を付与するように修正


``` yml: buildspec.yml
  # ...省略...
  build:
    commands:
      # ...省略...
      - chmod 755 ./gradlew
      - ./gradlew build -x test
      # ...省略...
```

- 実行できた！

## CodeBuildのgradleのバージョンについて

- 今回、CodeBuild時に使用するイメージは以下を指定していた
    - aws/codebuild/amazonlinux2-x86_64-standard:3.0
- 上記イメージはデフォルトではどのバージョンのgradleを使用しているのか？
- 以下のイメージの一覧から上記のイメージのDockerfileを参照してみる
    - [Docker images provided by CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html)
        - [al2/standard/3.0](https://github.com/aws/aws-codebuild-docker-images/tree/master/al2/x86_64/standard/3.0)
            - [aws-codebuild-docker-images/al2/x86_64/standard/3.0/Dockerfile](https://github.com/aws/aws-codebuild-docker-images/blob/master/al2/x86_64/standard/3.0/Dockerfile)
- gradle 5.6.4 を使用していることが分かった
    - 冒頭のエラーメッセージに出力されたバージョンとも一致する
    - 以下、設定に関する記述を抜粋

``` dockerfile: Dockerfile
# ...省略...
ENV JAVA_11_HOME="/usr/lib/jvm/java-11-amazon-corretto.x86_64" \
#    ...省略...
    INSTALLED_GRADLE_VERSIONS="4.10.3 5.6.4" \
    GRADLE_VERSION=5.6.4 \
#    ...省略...
    # Install default GRADLE_VERSION to path
    && ln -s /usr/local/gradle-$GRADLE_VERSION/bin/gradle /usr/bin/gradle \
#    ...省略...
```

## gradlewについて

- 簡潔にまとめている方がいたのでこちらを参照ください
    - [gradleとgradlewの違い](https://qiita.com/suin/items/266830c0ce37e823916d)

# まとめ

- gradlewを使おう！

# 未検証だけど代替手段になりそうなもの

- gradlewを使わずに自前でDockerImageを使っても解決できるようです
    - [CodeBuildで独自イメージを使ってビルドする](https://qiita.com/akikinyan/items/2ff72cf1129b66304616)
- aws/codebuild/amazonlinux2-x86_64-standard:4.0ならgradle 7.7.2なのでイメージを変えてもいけるかも

# 参考情報

- [aws codebuild runtime verison not supporting latest gradle version 7](https://stackoverflow.com/questions/71794905/aws-codebuild-runtime-verison-not-supporting-latest-gradle-version-7)
- [CodePipeline経由と直接実行の場合でCodeBuildのファイルパーミッションが異なるという話](https://jappy.hatenablog.com/entry/2019/01/14/150009)
- [Docker images provided by CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html)