トヨタ自動車でリサーチャーをしている鳥越です。
Scalaで研究開発しているフレームワーク「ArkTwin」をOSS化するにあたり、GitHub Actionsを色々と設定してみました。しっかりCI組むのは久々だったのですが、昔よりも多くのことが簡単に自動化できて感動したので、その設定を10個ほど紹介します!
ちなみにArkTwinは、多種多様なシミュレータ・VRを繋いで街規模のシミュレーションを実現するためのメッセージングフレームワークです。
この写真は、交通流シミュレータ・仮想インフラカメラ・人流シミュレータ・VR歩行者・ドライブシミュレータをArkTwinによって繋いだデモの様子です。みんな同じ一つの仮想世界にいるため、お互いを視認したり避けたりすることができます。このデモでは各PCをLAN接続していますが、もちろんインターネット越しで接続することも可能です。
つまり雑に言うと、みんなが思い思いのシミュレータ・VRを繋いでオンラインゲームみたいなことができちゃいます(ということを目指しています)
ArkTwinについて詳しく知りたい方は、ぜひ次のリンクもご覧ください
1. 単体テスト (ScalaTest)
ScalaのテストフレームワークScalaTestによる単体テストです。CIの基本ですね。
設定
- name: sbt test
working-directory: arktwin
run: sbt test
.github/workflows/scala-ci.yaml
実行例
2. 結合テスト (Gatling)
GitHub Actionsのランナーでは、nohupコマンドによりバックグラウンドプロセスとしてサーバーも動かせるため、ローカル通信による結合テストが可能です。
ArkTwinにはCenterとEdgeという二つのモジュールがあり相互通信します。その結合テストを負荷試験ツールGatlingにより、次の手順で行なっています。
- ArkTwin Centerをバックグラウンド実行
- ArkTwin Centerのヘルスチェックが成功するまで待つ
- ArkTwin Edgeをバックグラウンド実行してCenterへ接続
- ArkTwin Edgeのヘルスチェックが成功するまで待つ
- GatlingでArkTwin EdgeのREST APIをテスト
設定
- name: sbt center/run in the background
working-directory: arktwin
run: |
nohup sbt center/run &
curl --retry 180 --retry-delay 1 --retry-all-errors http://localhost:2236/health
- name: sbt edge/run in the background
working-directory: arktwin
run: |
nohup sbt edge/run &
curl --retry 180 --retry-delay 1 --retry-all-errors http://localhost:2237/health
- name: sbt e2e/Gatling/test
working-directory: arktwin
run: sbt e2e/Gatling/test
.github/workflows/scala-ci.yaml
実行例
3. REST API仕様変更検出 (oasdiff-action)
ArkTwin Edgeには、シミュレータ・VR接続用のREST APIがあります。
改修時に意図しないREST API変更を引き起こしていないか確認するため、ArkTwin EdgeにOpenAPI仕様書を出力させたのち、OpenAPI変更検出ツールoasdiff-actionによってmainブランチおよび最新リリースとの比較を行っています。
この情報はプルリクエストのマージ前に確認するほか、リリースノートに記載するAPI変更履歴としても利用しています。
設定(抜粋)
- name: Generate OpenAPI YAML files
working-directory: arktwin
run: |
sbt "edge/run generate-openapi-edge ../temp/arktwin-edge-head.yaml"
git checkout $(git tag -l "v*" --sort=-v:refname | head -n 1)
sbt clean "edge/run generate-openapi-edge ../temp/arktwin-edge-release.yaml"
- name: Generate /api/edge changelog from latest relase
uses: oasdiff/oasdiff-action/changelog@v0.0.19
with:
base: arktwin/temp/arktwin-edge-release.yaml
revision: arktwin/temp/arktwin-edge-head.yaml
output-to-file: arktwin/temp/arktwin-edge-changelog-from-release.txt
- name: Display /api/edge changelog from latest release
run: cat arktwin/temp/arktwin-edge-changelog-from-release.txt
.github/workflows/scala-ci.yaml
実行例
4. REST API仕様公開 (deploy-pages)
リリースタグを打った際、OpenAPI仕様書を参照するSwagger UIの静的ページを生成し、deploy-pagesによってGitHub Pagesにて公開しています。
このSwagger UIページはArkTwin Edge自身も配信しているのですが、起動することなく最新の仕様を確認できるのは便利なため、私自身が開発や説明によく利用しています。
設定
- name: Generate OpenAPI YAML files
working-directory: arktwin/arktwin
run: sbt "edge/run openapi-center ../../pages/dist/swagger-ui/center/arktwin-center.yaml" "edge/run openapi-edge ../../pages/dist/swagger-ui/edge/arktwin-edge.yaml"
- uses: actions/checkout@v4
with:
repository: swagger-api/swagger-ui
ref: v5.17.14
path: swagger-ui
- name: Copy Swagger UI static files
run: |
mkdir arktwin/pages/dist/swagger-ui/bundle
cp swagger-ui/dist/* arktwin/pages/dist/swagger-ui/bundle
rm arktwin/pages/dist/swagger-ui/bundle/index.html
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: arktwin/pages/dist
- uses: actions/deploy-pages@v4
id: deployment
.github/workflows/github-pages.yaml
実行例
5. コードフォーマットのチェック (Scalafix & Scalafmt)
sbtのビルド設定にて、コードフォーマッターScalafix & Scalafmtによりコンパイル時に自動でコードフォーマットするようにしています。
そのため基本的にはフォーマット済みのコードがコミットされるはずなのですが念のため、未フォーマットのファイルが残っているとエラーになるコマンドを利用してCIでもチェックしています。
設定
- name: sbt scalafixAll --check
working-directory: arktwin
run: sbt "scalafixAll --check"
- name: sbt scalafmtCheckAll
working-directory: arktwin
run: sbt scalafmtCheckAll
.github/workflows/scala-ci.yaml
6. ファイルヘッダのチェック (sbt-header)
現状、Scalaファイルヘッダにて下記のライセンス表示をしています。
// SPDX-License-Identifier: Apache-2.0
// Copyright 2024 TOYOTA MOTOR CORPORATION
sbtのビルド設定にて、sbt-headerによりヘッダをコンパイル時に自動挿入するようにしています。
そのため基本的にはヘッダ挿入済みのコードがコミットされるはずなのですが念のため、未挿入のファイルが残っているとエラーになるコマンドを利用してCIでもチェックしています。
設定
- name: sbt headerCheck
working-directory: arktwin
run: sbt center/headerCheck center/Test/headerCheck common/headerCheck common/Test/headerCheck e2e/Test/headerCheck edge/headerCheck edge/Test/headerCheck
.github/workflows/scala-ci.yaml
7. 依存ライブラリのライセンスチェック (sbt-license-report)
ArkTwinのライセンスはApache License 2.0なのですが、依存ライブラリについても使いやすいライセンスのものに留める方針です。
そのためsbt-license-reportによって、ホワイトリストに載せていないライセンスのライブラリへの依存が発生した場合はエラーになるようにしています。
設定
- name: sbt center/licenseCheck
working-directory: arktwin
run: sbt center/licenseCheck
.github/workflows/scala-ci.yaml
8. Dependency Graph更新 (sbt-dependency-submission)
GitHubにはレポジトリ全体の依存を検出する機能Dependency Graphがあるものの、sbtは残念ながらサポートされていません。そこでsbt-dependency-submissionによって、Scalaの依存ライブラリを追加するようにしています。
なお、Dependency GraphはテストライブラリやGitHub Actionsなどの依存も対象とするため、ソフトウェアそのものの依存よりも対象が広いことには留意してください。
設定
- uses: scalacenter/sbt-dependency-submission@v3
with:
working-directory: arktwin
.github/workflows/dependency-submission.yaml
実行例
9. Dockerイメージビルド (build-push-action)
build-push-actionによってDockerイメージをビルドしています。
名前のとおりプッシュもできるのですが、現状はDockerfileの公開のみでイメージの配布は行なっていないため、ビルド成功するかどうかのみテストしています。
設定
- uses: docker/build-push-action@v6
with:
file: docker/center.dockerfile
tags: arktwin-center
push: false
.github/workflows/scala-ci.yaml
10. CLA同意確認 (contributor-assistant)
プルリクエストを送ってくださった方にCLA (Contributor License Agreement)への同意と確認を自動で行うbotをcontributor-assistantによって動かしています。
ちなみに導入時のバグがあるものの回避策を見つけたので報告済みです。 #155
設定
- uses: contributor-assistant/github-action@v2.6.1
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
path-to-signatures: signatures/version1/cla.json
path-to-document: https://github.com/arktwin/arktwin/blob/main/CLA.md
branch: main
allowlist: dependabot[bot], scala-steward
.github/workflows/cla-assistant.yaml
実行例
おわりに
本記事が何かしら参考になったよという方は、ぜひGitHubの方でもスターいただけると嬉しいです