この記事は Calendar for CircleCI Advent Calendar 2021 | Advent Calendar 2021 - Qiita の4日目の記事です。昨日は、おおはらぶちょーの 古いCircleCI Slack通知からの移行の道 でした。さすがぶちょー、ちゃんとしてるなぁ。相変わらずかっこいいです!
こんにちは
椎葉です。10月から CircleCI で Senior Full Stack Engineer として仕事をしてます。
フルリモートなので、まだ直接は誰とも合ったことがないんですけど、チームのみんなが優しかったり、オンラインの社内イベントが定期的に開催されてたり( CircleCIの週一回のチームチャレンジとは?! | CircleCI Japan )、世界中のみんなとチャットで話ができたりして、楽しく過ごしてます。その辺は、また気が向いたら書こうかな。
じつはこれまで CircleCI は雰囲気だけで使ってたので、細かいところとか全然知らなくて、今ドキュメントを読みながら「へー」とか「ほほー」とか言いつつ勉強してるところです。ということで、今日は入門者らしく Spring Boot プロジェクトの自動テストを CircleCI で始めてみようと思います!
準備 - プロジェクトを作る
とりあえず Spring Boot のプロジェクトが欲しいので Spring Initializr ( https://start.spring.io/ ) を開いて適当にこんな感じで用意
Java は17でいっか。なんとなく Spring Web を追加。最初からテストが1個入ってて ./mvnw test
を叩くと実行できるから、これでいこう
❯ ./mvnw test ... [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.801 s - in com.example.demo.DemoApplicationTests [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 13.910 s [INFO] Finished at: 2021-12-02T20:45:21+09:00 [INFO] ------------------------------------------------------------------------
これを GitHub に push しといた
GitHub - bufferings/springboot-cci-maven
じゃ、このプロジェクトを CircleCI で自動テストできるようにする。タイトルにも書いた通り2ステップ
ステップ1 - CircleCI の設定を追加
CircleCI の設定は .circleci/config.yml
に書く。Maven の Orb を使ったらこれだけでいけそう
version: 2.1 orbs: maven: circleci/maven@1.2.0 workflows: maven_test: jobs: - maven/test: executor: name: "maven/default" tag: "17.0.0"
デフォルトだと Java 13 みたいなので 17 を指定してる。commit して push。
ステップ2 - CircleCI を有効にする
CircleCI に GitHub アカウントでログインして Projects から対象のリポジトリの Set Up Project をクリック
main
ブランチに push しといたので、"main" って入力して Let's Go!
これで設定おわり。お疲れさまでした!
動作確認
設定が終わるとそのままパイプラインが実行される
テスト成功したーヽ(=´▽`=)ノ(実は設定ファイル何回か失敗した
これで GitHub に変更を push するたびにテストが実行される。main
ブランチだけじゃなくてどんなブランチでも動く。便利。
GitHub のブランチの履歴のところでも出るし
プルリクエストを作ったらそこにも出てくる
プルリクエスト出したときにテストが失敗すると、こんな感じ
テストが失敗してたらマージできないように GitHub で設定しておくと、ぽいかな!やってみよう
GitHub の Settings の Branch のとこで ci/circleci: test
を指定すると
テストがコケてたらマージできない(実際は管理者だからできるけど)
(๑•̀ㅂ•́)و✧
というわけで
Spring Boot プロジェクト(に限らず Maven プロジェクト。Gradle プロジェクトでも似たような感じだと思う)を GitHub に持ってる人(BitBucket でも同じ感じなのかな?)は、とても簡単なので、とりあえず自動テストを有効にするところから始めてみたら良いかなって思います!その後、ちょこちょこテストを足していけたら楽しそう。はい、以上ですー!
明日は @sogahisashi さんの「AWS Fargate への自動/手動デプロイ」です!楽しみー。
ここからはおまけ
そもそも↓が何をしてくれてるの?ってのが気になる
version: 2.1 orbs: maven: circleci/maven@1.2.0 workflows: maven_test: jobs: - maven/test: executor: name: "maven/default" tag: "17.0.0"
この maven/test
の内容を知りたい。ので Orb を確認
CircleCI Developer Hub - circleci/maven
circleci/maven
Orb の test
ジョブを実行してるってことだからここだな
test: description: | Checkout, build, test, and upload test results for a Maven project. executor: <<parameters.executor>> parameters: app_src_directory: default: "" description: Useful when the source of your maven project is nott in the root directory of your git repo. Supply the name of the directory or relative path of the directory containing your source code. type: string command: default: verify description: The maven command to run. type: string executor: default: default description: The name of custom executor to use type: executor maven_command: default: mvn description: Specify a custom path for invoking maven type: string settings_file: default: "" description: Specify a custom settings file to use (optional) type: string test_results_path: default: target/surefire-reports description: The path to the test results. type: string steps: - checkout - with_cache: app_src_directory: << parameters.app_src_directory >> maven_command: << parameters.maven_command >> settings_file: << parameters.settings_file >> steps: - run: command: | if [ -n "<< parameters.settings_file >>" ]; then set -- "$@" --settings "<< parameters.settings_file >>" fi << parameters.maven_command >> << parameters.command >> "$@" name: Run Tests working_directory: << parameters.app_src_directory >> - process_test_results: test_results_path: << parameters.test_results_path >>
パラメータの設定が色々あるけど、そこは心の目でなんとなく読めるのでいいとして、実際にやってることは
- ソースコードをチェックアウトして
with_cache
コマンドの中でmvn verify
を実行して- テスト結果を保存してる
ふむ。。。
with_cache
🤔
この with_cache
は何をやってるんだろう?ってことなんだけど、パラメータ部分は飛ばして step
のところだけ書くとこう:
steps: - run: command: find . -name 'pom.xml' | sort | xargs cat > /tmp/maven_cache_seed name: Generate Cache Checksum working_directory: $CIRCLE_WORKING_DIRECTORY/<< parameters.app_src_directory >> - restore_cache: key: 'maven-{{ checksum "/tmp/maven_cache_seed" }}' - run: command: | if [ -n "<< parameters.settings_file >>" ]; then set -- "$@" --settings "<< parameters.settings_file >>" fi name: Install Dependencies working_directory: << parameters.app_src_directory >> - when: condition: << parameters.verify_dependencies >> steps: - run: command: '<< parameters.maven_command >> dependency:go-offline "$@"' name: Verify dependencies working_directory: << parameters.app_src_directory >> - steps: << parameters.steps >> - save_cache: key: 'maven-{{ checksum "/tmp/maven_cache_seed" }}' paths: - ~/.m2/repository
pom.xml
のチェックサムをキーにして、キャッシュを読み込み & 保存してる。キャッシュの対象は ~/.m2/repository
。
つまり、pom.xml
が同じ間はキャッシュを使ってくれる。~/.m2/repository
には依存関係の JAR ファイルがいっぱい入ってるから、キャッシュを使うと2回目以降のビルドが短い時間で済む。さっきのプロジェクトを確認してみると、こんなシンプルなプロジェクトでも 42s → 18s になってる。大きなプロジェクトだともっと便利ね
キャッシュの有効期限は15日間なことに注意しておきたい
https://circleci.com/docs/ja/2.0/caching/#cache-expiration
実行環境は?
何をやってるかは分かった。今度は、それをどんな環境で実行してるのかが気になる。ので executor
をチェック。これだね
description: > The latest minor and patch update of the version 13 JDK image provided by CircleCI. docker: - image: 'cimg/openjdk:<<parameters.tag>>' parameters: tag: default: '13.0' description: > Can be changed to any of the available tags listed on the DockerHub for this image. https://hub.docker.com/r/cimg/openjdk/tags type: string
ということで、使ってるのは cimg/openjdk:13.0
のイメージってことだなー。なので、僕は tag: "17.0.0"
で Java 17 を使うようにしたのだった
ところで、どの JDK なの?
ってのがまぁ気になるので見てみる
❯ docker run --platform linux/x86_64 --rm -ti cimg/openjdk:17.0.0 java --version openjdk 17 2021-09-14 OpenJDK Runtime Environment Temurin-17+35 (build 17+35) OpenJDK 64-Bit Server VM Temurin-17+35 (build 17+35, mixed mode, sharing)
これ
あれ?AdoptOpenJDKって17ないの?って思ったら、Eclipse FoundationのEclipse Adoptiumってプロジェクトに移動して、Eclipse Temurinって名前で出してるのかー!https://t.co/RFoLcWP02w
— Mitsuyuki Shiiba (@bufferings) 2021年12月2日
ついでに、Maven と Gradle も見とくか
circleci@993619baf20e:~/project$ mvn --version Apache Maven 3.8.2 (ea98e05a04480131370aa0c110b8c54cf726c06f) Maven home: /opt/apache-maven Java version: 17, vendor: Eclipse Adoptium, runtime: /usr/local/jdk-17.0.0 Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "5.10.25-linuxkit", arch: "amd64", family: "unix"
circleci@993619baf20e:~/project$ gradle --version ------------------------------------------------------------ Gradle 7.2 ------------------------------------------------------------ Build time: 2021-08-17 09:59:03 UTC Revision: a773786b58bb28710e3dc96c4d1a7063628952ad Kotlin: 1.5.21 Groovy: 3.0.8 Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020 JVM: 17 (Eclipse Adoptium 17+35) OS: Linux 5.10.25-linuxkit amd64
なるほどー。気が済んだので、今日はこれくらいでー!楽しかった
次のステップ
簡単に自動テストを始められるとは言っても、まぁ、やっぱり細かく自分で色々やりたい気持ちなので、またアドベントカレンダーの空いてるところで続きやろうかなー!