TL;DR
GitHub Actions で RuboCop を実行する際,デフォルトでは Gemfile に記載されている gem を余剰にインストールする必要があり冗長性が生じる.そこでBundlerのグループ機能を使って最小限の gem をインストールし,ジョブの最適化を行う.
具体的な手順は次のとおりである,RuboCopの関連gemを:rubocop
グループに入れる.bundle config
コマンドを使用して,with
とwithout
を設定することで,:default
グループに属するgemを除いて:rubocop
グループのgemのみをインストールすることができる.GitHub Actionsでは,ruby/setup-ruby@v1
アクションを使用してRubyを設定し,bundler-cache
フィールドの値をfalse
に設定する.
以上の手順により,bundle install
の所要時間が20秒程度に短縮された.
諸言
CI ツール (GitHub Actions,Circle CI など) で Rubocop を実行する場合,実行環境 (Ubunbu など) に Rubocop gem 群をインストールする必要がある.ただし,デフォルトでは Gemfile に記載された gem (または,RAILS_ENV
などの環境変数に指定された test
などのグループに属する gem) がインストールされ,冗長性が生じる.本稿では,Bundler のグループ機能によってインストールする gem を最小化し,CI ジョブの実行最適化を図る.
Gemfile
本稿では,rubocop
のほかに,rubocop-{capybara, factory_bot, performance, rails, rspec}
gem をバンドルしている.これらの gem 群を rubocop
グループに入れる.
- group :development, :test do
+ group :development, :test, :rubocop do
gem "rubocop", require: false
gem "rubocop-capybara", require: false
gem "rubocop-factory_bot", require: false
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false
end
Bundler のドキュメントによれば,明示的にグループに属していない gem は, :default
グループに属している.
# These gems are in the :default group gem 'nokogiri' gem 'sinatra'
したがって,:rubocop
グループの gem 群のみをインストールするには,:default
グループに属す gem 群を除き,:rubocop
グループの gem 群のみをインストールするよう指定すればよい.
指定する方法には,次の2つがある.
1
編集後に気づいたが,この方法のほうが良い.
BUNDLE_WITH
と BUNDLE_WITHOUT
を指定する
次のように,環境変数 BUNDLE_WITH
の値に rubocop
を, BUNDLE_WITHOUT
の値に default
を設定すれば,:default
グループに属す gem 群を除き,:rubocop
群のみをインストールすることができる.
rubocop
ジョブは次のようになる.
# (省略)
jobs:
rubocop:
runs-on: ubuntu-latest
env:
BUNDLE_WITHOUT: "default development test production"
BUNDLE_WITH: rubocop
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
- name: Install dependencies
run: bundle install --jobs 4 --retry 3
- name: Run rubocop
run: bundle exec rubocop
2
bundle config で with
と without
を指定する
次のように,bundle config の with
の値に rubocop
を, without
の値に default
を設定すれば,:default
グループに属す gem 群を除き,:rubocop
群のみをインストールすることができる.local
オプションは,設定がローカルに行われるよう指示する.
bundle config set --local without default
bundle config set --local with rubocop
ruby/setup-ruby@v1 の bundler-cache
を偽に設定する
GitHub Actions で Ruby を利用可能するためのアクション ruby/setup-ruby@v1 を用いることにする.
デフォルトでは,ruby/setup-ruby@v1 は Gemfile 及び Gemfile.lock を参照して
:default
を除かずに bundle install
してしまうため,bundler-cache
フィールドの値を false
に設定する必要がある. (bundle
コマンドは,ruby/setup-ruby@v1
を実行したのちに利用可能になる.)
- uses: ruby/setup-ruby@v1
with:
bundler-cache: false
rubocop
ジョブ
以上から,rubocop
ジョブは次のようになる.
# (省略)
jobs:
rubocop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
bundler-cache: false
- name: Set up Ruby
run: |
bundle config set --local without "default development test production"
bundle config set --local with rubocop
- name: Install dependencies
run: bundle install --jobs 4 --retry 3
- name: Run rubocop
run: bundle exec rubocop
結語
これによって,1分以上掛かっていた bundle install
が 20秒ほどに短縮された.