.circleci/config.ymlファイル
.circleci/config.yml
が設定ファイル。
Railsプロジェクトでの設定例。
Gemfileのgroup :test
にgem 'rspec_junit_formatter'
を追加しておくこと。
version: 2
jobs:
# 前準備 ============================================================
build:
docker:
- image: circleci/ruby:2.7.2-node
steps:
- checkout
# Bundle Install
- restore_cache:
keys:
- gem-v1-dependencies-{{ checksum "Gemfile.lock" }}
- gem-v1-dependencies-
- run:
name: bundle install
command: |
bundle install --jobs=4 --retry=3 --path vendor/bundle
- save_cache:
paths:
- ./vendor/bundle
key: gem-v1-dependencies-{{ checksum "Gemfile.lock" }}
# Yarn Install
- restore_cache:
keys:
- yarn-v1-dependencies-{{ checksum "yarn.lock" }}
- yarn-v1-dependencies-
- run:
name: yarn install
command: yarn
- save_cache:
paths:
- ./node_modules
key: yarn-v1-dependencies-{{ checksum "yarn.lock" }}
# Rubocop ============================================================
lint:
docker:
- image: circleci/ruby:2.7.2-node
steps:
- checkout
# キャッシュしたGemの復元
- restore_cache:
keys:
- gem-v1-dependencies-{{ checksum "Gemfile.lock" }}
- gem-v1-dependencies-
# Bundleの参照先変更
- run:
name: config bundler
command: |
bundle config set path vendor/bundle
# Rubocop結果をHTMLで出力しアーティファクトに追加
- run:
name: Rubocop
command: |
mkdir -p /tmp/rubocop-results/
bundle exec rubocop -f html -o /tmp/rubocop-results/rubocop.html
- store_artifacts:
path: /tmp/rubocop-results
# Rspec ============================================================
rspec:
docker:
- image: circleci/ruby:2.7.2-node
steps:
- checkout
# キャッシュしたGemの復元
- restore_cache:
keys:
- gem-v1-dependencies-{{ checksum "Gemfile.lock" }}
- gem-v1-dependencies-
# キャッシュしたnode_modulesの復元
- restore_cache:
keys:
- yarn-v1-dependencies-{{ checksum "yarn.lock" }}
- yarn-v1-dependencies-
# Bundleの参照先変更
- run:
name: config bundler
command: |
bundle config set path vendor/bundle
# Railsで使うDBの作成
- run:
name: create db
command: bin/rails db:schema:load
# Rspecの実行
# 実行結果をJUnit XMLで出力(/tmp/rspec-results/rspec.xml)
# => TESTSタブで利用する
# profile結果も出力(/tmp/rspec-results/rspec-profile.txt)
# => ARTIFACTSタブで表示する
- run:
name: run rspec
command: |
mkdir -p /tmp/rspec-results/
bundle exec rspec \
--profile \
--format RspecJunitFormatter \
--out /tmp/rspec-results/rspec.xml \
$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings) \
> /tmp/rspec-results/rspec-profile.txt
- store_test_results:
path: /tmp/rspec-results
- store_artifacts:
path: /tmp/rspec-results
# ============================================================
workflows:
version: 2
build_and_test:
jobs:
- build
- lint:
requires:
- build
- rspec:
requires:
- build
jobs.[JOB-NAME]
ワークフローの単位。
jobs
直下のbuild
やlint
などは任意の文字列を指定可能。workflows
で実行の依存関係などを指定するのに使う。
jobs.[JOB-NAME].docker
使用するDockerイメージを指定する。複数指定可能。CircleCIのイメージだけでなく、DockerHubにある他のイメージも指定可能。自作イメージをDockerHubにあげておけば指定することもできる。
jobs.[JOB-NAME].working_directory
ステップを実行するディレクトリ。デフォルトは~/project
。
jobs.[JOB-NAME].steps
実行するコマンドなどを指定する。配列。
checkout
- リポジトリからコードを取得する。
save_cache
paths
のファイルやディレクトリをkey
に紐づけてキャッシュする。- 数ヶ月保持される。
restore_cache
key
に紐づいたキャッシュを復元する(save_cache
と対で指定する)
run
- コマンドの実行
store_artifacts
path
で指定されたディレクトリにあるファイルをARTIFACTSタブから表示できるようにするdestination
に指定した値はARTIFACTSタブで表示される時のabc/file-name
のabc
部分になる。未指定ならpath
のディレクトリ名になる。
store_test_results
path
で指定されたディレクトリにあるJUnit XML を読み込んでTESTタブに結果を表示する
workflows.[WORKFLOW-name].jobs
ジョブの依存関係を指定する。以下の例ならbuild
を実行してからlint
とrspec
が並列に実行される(無料版だとコンテナ数が1つなので並列にはならない。Performanceプランだと80並列実行できるっぽい?)。
build_and_test:
jobs:
- build
- lint:
requires:
- build
- rspec:
requires:
- build
早く終わるようにする
コスト削減のために早く終わるようにする
CircleCIは無料プランだと1週間に2500クレジット分利用できる。無料プランで利用できるマシンは10クレジット/分のMediumだけなので、結論としては週250分間(4時間10分)だけ実行できることになる。
Performanceプランにすると25000クレジット単位で購入となるため、利用料金を抑えるためには、やはり実行時間に気をつけなければならない。
コスト削減のために早く終わるようにする方法
save_cache
とrestore_cache
を用いて、bundle install
の結果などをキャッシュさせる。- 無闇にジョブを分けたり、コンテナを作らない(効果があるか不明)。
- コンテナの起動や
restore_cache
のオーバーヘッド分時間がかかる。
- コンテナの起動や
待機時間削減のために早く終わるようにする
実行時間(コスト)の削減にはならないが、並列でジョブやステップを実行することで完了までの時間を短縮させることができる。
待機時間削減のために早く終わるようにする方法
無料プランでは方法はない。
Performanceプランでは並列実行ができるため、workflows
でジョブの並列化させたり、parallelism
を指定してステップの並列化ができる。参考:テストの並列実行