ユニットテストをGitHub ActionsからCodeBuildに移行し、実行時間を35%削減した

こんにちは。NewsPicks SREチームの 海老澤 です。

今回はGithub Actionsで実行していたテストを高速化したので紹介したいと思います。

課題

NewsPicksでは Junitのテスト等をGithub Actions から実行しているのですが、2013年のサービス開始当初から存在する、一番コードベースが大きいリポジトリのビルド・テストの実行時間に 20~30分ほどかかっていました。

テスト自体はバグを産まないためにも必要なものですが、時間がかかるため開発効率が下がってしまいます。そのためテスト高速化の取り組みを行いました。

取り組み

テストの高速化をする上でやったことは大きく下の二つです

  1. テストの並列化
  2. GitHub Actionsから AWS CodeBuild への移行

テストの並列化

maven-surefire-pluginを使うと、pom.xml上での設定を変更するだけ並列実行が可能になります。後述のCodeBuildのコンピューティングタイプとの兼ね合いもあり、今回はスレッド数を8にしています。

pom.xml

                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                ~~
                <configuration>
                    ~~
                    <parallel>classes</parallel>
                    <threadCount>8</threadCount>
                </configuration>

AWS CodeBuildへの移行

GitHub ActionsのLinux 環境はドキュメントによると下記のようになっています。

  • 2-core CPU (x86_64)
  • 7 GB of RAM
  • 14 GB of SSD space

リソースを増やして、ユニットテスト高速化をするためにGitHub ActionsからAWS CodeBuildに移行しました。

CodeBuildの設定

CodeBuildを実行する上での設定を一部抜粋して紹介していきます。その他の設定方法等についてはAWS CodeBuildのドキュメント等を参照ください

コンピューティングタイプ

CodeBuildの設定でコンピューティングタイプを選びます。

コストとしてはGitHub Actionsでは 0.008ドル / 分*1 、 CodeBuild の Largeでは 0.02ドル / 分 *2 かかります。 (2022年11月 現在)

実行時間も加味しても GitHub Actions: 0.0008 ドル × 25 分 = 0.024ドル CodeBuild: 0.02 ドル × 16分 = 0.34 ドル となり、これまでよりコストはかかりますが開発効率が上がることを考慮してCodeBuild の LARGE(15 GB メモリ、8 vCPU)を選択しました。

トリガー

CodeBuildのトリガーは GitHub のウェブフックでPR作成時(PULL_REQUEST_CREATED)、更新時(PULL_REQUEST_UPDATED)、リオープン時(PULL_REQUEST_REOPENED)に実行されるように設定します。

結果はGitHubのPR上でも確認することができます。

GitHub上で設定すれば 失敗したときにマージできないようにするために required にすることも可能です。設定方法は こちら 参照ください

buildspec.yml

buildspec.ymlは下記のように設定しました。

{
  "version": 0.2,
  "phases": {
    ~
    "build": {
      "commands": [
        "mvn package", # ①
    }
  },
  "reports": {
    "junit-report": { # ②
      "files": [
        "**/surefire-reports/*.xml"
      ],
      "file-format": "JunitXml"
    }
  },
  "cache": {
    "paths": [
      "/root/.m2/**/*" # ③
    ]
  }
}

① commands 部分でテストを実行します。今回は mvn packageコマンドでテストまで実行しています。

② CodeBuildにはレポート機能があり AWS マネジメントコンソールの CodeBuild 実行結果 > レポートから参照することができます。 今回はJunitのテストなのでJunitXmlを選んでいますが、他にも Cucumber JSON, NUNITXMLなどの形式が選べます。詳細はドキュメントを参照お願いします

③ cacheの取り方も速度に大きく関係してきます。キャッシュを持たせるために /root/.m2 以下をキャッシュに持たせるようにします

結果

これらの取り組みによって平均35%ほど削減できました。

テストに限らず、GitHub Actionsはリソースが不十分と感じた場合はCodeBuildに移行することでリソースを増やすことができます。ぜひ参考にしてみてください。

Before: GitHub Actionsでの実行
After: CodeBuildでの実行

Page top