バフェット・コードのブログ

企業分析やプロダクト開発にまつわる記事を配信中

CircleCIからGitHub Actionsに移行しました

こんにちは!kosappiです。

こどもの乗った三輪車を押して坂を登ったら、足が筋肉痛になってしまいました。よろしくお願いします。

CircleCIからGitHub Actionsに移行しました

バフェットコードではCIを整理して、利用するプラットフォームをGitHub Actionsに統一しました。 その際にGitHub Actionsのmatrixを導入することで、rspecの実行時間を圧縮することができました。

背景

バフェットコードの開発が始まった頃は、CIといえばCircleCIがスタンダードで、GitHub Actionsはまだリリースされていませんでした。 その後開発が進むにつれ、おおむねGitHub Actionsを利用していたのですが、1リポジトリだけCircleCIの利用が残っていました。

GitHub Actionsの標準インスタンスはCircleCIと比較すると非力で、単純な引っ越しではCIの待ち時間が増えることが予想されていました。 都合の良いことに、GitHub Actionsにはmatrixという並列処理が用意されており、これを利用して待ち時間を圧縮できます。 引っ越しと同時にmatrixを利用してCIの待ち時間も短くしてしまおう、という魂胆です。

ポイントをまとめると、↓のような感じです。こういった内容を期待して、CircleCIで稼働している処理をGitHub Actionsに移行することに決めました。

  • CIプラットフォームをGitHub Actionsに統一して管理コストを下げる
  • GitHub Actionsのmatrixを使ってrspecを並列実行することで、CIの待ち時間を削減する

CIで何をやっているのか

バフェットコードのCIでは、主に下記の内容を実行しています。この内容は変更せず、CircleCIからGitHub Actionsに移行します。

  • linterやformatterなど
    • typos
    • rubocop
    • slim-lint
    • biome check
    • stylelint
  • テスト
    • rspec
      • 約700ファイルのspecがある(小さいチームですがテストは割としっかり書きます)
      • 約10分と非常に時間がかかっている
    • vitest
      • Reactコンポーネントのspecを書いています

できあがったパイプライン

↓のようなパイプラインをPRごとに実行しています。 本当は比較用にCircleCIのパイプラインも見せたかったのですが、移行から時間が経っており画像を用意できませんでした...スミマセン。

GitHub Actions ワークフロー

rspecは4種類に分類して、それぞれmatrixで実行しています。

  • system spec以外
  • system specかつJava Script動作を必要としないもの
  • system specかつJava Script動作を必要とし実行に時間がさほどかからないもの
  • system specかつJava Script動作を必要とし実行に時間がかかるもの

比較

実行時間

  • CircleCI: 10m~12m
  • GitHub Actions: 6m~8m

おおむね30~40%ほど時間を短くできました。

今後やりたいこと

matrixで分配した先でさらに並列実行する

matrixで分配することによって時間を圧縮しましたが、さらにCPUごとに処理を分配して時間を削減したいです。 parallel_testsの利用を想定しています。

rspecの分配を工夫してより実行時間を圧縮する

現在のmatrixの分配は「重いspecを分離する」程度の大雑把な分配になっており、実行時間もまちまちです。 たとえば、↓の結果では、速いものは1分足らずで終わり、遅いものは5分以上かかっています。 実行時間をきれいに4等分すれば3分程度なので、分配を工夫すれば2分前後の圧縮が可能なはずです。

rspec matrix サンプル

たとえば、過去の実行時間を計測して、分配を整理するGitHub Actionを利用することで、時間が圧縮できそうです。

split-tests-by-timings

インスタンスを強化する

GitHub Actionsでは処理を実行する環境をランナーと呼んでいます。 このランナーを、より能力の高いものに変更することで、CIの時間が圧縮できるはずです。 (もちろん料金も増えます💸)

参考:より大きなランナーを管理する

なるべく軽いspecを利用する

system specやrequest specは多機能で便利ですが、実行コストが高いです。 より細かい単位でユニットテストが書けるように設計を見直して、より軽いspecに引っ越すことでもテストの時間を圧縮できます。

最後に

バフェットコードではCIを整理してプラットフォームをGitHub Actionsに統一し、rspecをmatrixで並列実行することで、CIの待ち時間を約30%削減することができました。 まだCIの待ち時間を減らす余地があるのは明らかなので、折を見てチャレンジしたいです。

宣伝

バフェットコードではCIを爆速にしてくれるエンジニアを募集しています!!

光速のCIでユーザーに価値を届けましょう💪

career.buffett-code.com