Created
May 25, 2018 01:23
-
-
Save trev/9cc964a54c8d5b62f4def891eba6b976 to your computer and use it in GitHub Desktop.
CircleCI 2.0 with parallelism & simplecov for Rails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ruby CircleCI 2.0 configuration file | |
# | |
# Check https://circleci.com/docs/2.0/language-ruby/ for more details | |
defaults: &defaults | |
working_directory: ~/split_app | |
parallelism: 2 | |
docker: | |
- image: circleci/ruby:2.5.0-node-browsers | |
environment: | |
PGHOST: localhost | |
PGUSER: split | |
RAILS_ENV: test | |
- image: circleci/postgres:9.6 | |
environment: | |
POSTGRES_USER: split | |
POSTGRES_DB: split_test | |
POSTGRES_PASSWORD: "" | |
version: 2 | |
jobs: | |
test: | |
<<: *defaults | |
steps: | |
- checkout | |
- save_cache: | |
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }} | |
paths: | |
- ~/split_app | |
- restore_cache: | |
keys: | |
- gem-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }} | |
- gem-cache-{{ arch }}-{{ .Branch }} | |
- gem-cache | |
- run: bundle install --path vendor/bundle | |
- save_cache: | |
key: gem-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }} | |
paths: | |
- ~/split_app/vendor/bundle | |
- restore_cache: | |
keys: | |
- yarn-cache-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} | |
- yarn-cache-{{ arch }}-{{ .Branch }} | |
- yarn-cache | |
- run: | |
name: Yarn Install | |
command: yarn install --cache-folder ~/.cache/yarn | |
- save_cache: | |
key: yarn-cache-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} | |
paths: | |
- ~/split_app/.cache/yarn | |
- run: cp .env.test .env | |
- run: bundle exec rubocop | |
- run: bundle exec brakeman -z | |
- run: dockerize -wait tcp://localhost:5432 -timeout 1m | |
- run: bundle exec rake db:schema:load | |
- run: | |
name: Parallel Rspec | |
environment: | |
- RAILS_ENV: test | |
- RACK_ENV: test | |
command: | | |
mkdir -p /tmp/rspec | |
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)" | |
bundle exec rspec --profile 10 \ | |
--format RspecJunitFormatter \ | |
--out /tmp/rspec/rspec.xml \ | |
--format progress \ | |
-- \ | |
$TEST_FILES | |
- store_test_results: | |
path: /tmp/rspec | |
- run: | |
name: Stash Coverage Results | |
command: | | |
mkdir coverage_results | |
cp -R coverage/.resultset.json coverage_results/.resultset-${CIRCLE_NODE_INDEX}.json | |
- persist_to_workspace: | |
root: . | |
paths: | |
- coverage_results | |
coverage: | |
<<: *defaults | |
steps: | |
- attach_workspace: | |
at: . | |
- restore_cache: | |
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }} | |
- restore_cache: | |
keys: | |
- gem-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }} | |
- gem-cache-{{ arch }}-{{ .Branch }} | |
- gem-cache | |
- run: bundle install --path vendor/bundle | |
- run: | |
name: Merge and check coverage | |
command: | | |
RUN_COVERAGE=true bundle exec rake simplecov:report_coverage | |
- store_artifacts: | |
path: ~/split_app/coverage | |
destination: coverage | |
workflows: | |
version: 2 | |
build_and_test: | |
jobs: | |
- test | |
- coverage: | |
requires: | |
- test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# spec/rails_helper.rb | |
require 'active_support/inflector' | |
require 'simplecov' | |
SimpleCov.start 'rails' do | |
add_filter '/spec/' | |
add_filter '/config/' | |
add_filter '/vendor/' | |
Dir['app/*'].each do |dir| | |
add_group File.basename(dir).humanize, dir | |
end | |
minimum_coverage 100 unless ENV['CIRCLE_JOB'] | |
end | |
# ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# spec/simplecov_helper.rb | |
require 'active_support/inflector' | |
require "simplecov" | |
class SimpleCovHelper | |
def self.report_coverage(base_dir: "./coverage_results") | |
SimpleCov.start 'rails' do | |
skip_check_coverage = ENV.fetch("SKIP_COVERAGE_CHECK", "false") | |
add_filter '/spec/' | |
add_filter '/config/' | |
add_filter '/vendor/' | |
Dir['app/*'].each do |dir| | |
add_group File.basename(dir).humanize, dir | |
end | |
minimum_coverage(100) unless skip_check_coverage | |
merge_timeout(3600) | |
end | |
new(base_dir: base_dir).merge_results | |
end | |
attr_reader :base_dir | |
def initialize(base_dir:) | |
@base_dir = base_dir | |
end | |
def all_results | |
Dir["#{base_dir}/.resultset*.json"] | |
end | |
def merge_results | |
results = all_results.map { |file| SimpleCov::Result.from_hash(JSON.parse(File.read(file))) } | |
SimpleCov::ResultMerger.merge_results(*results).tap do |result| | |
SimpleCov::ResultMerger.store_result(result) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# lib/tasks/simplecov_parallel.rake | |
if Rails.env.test? | |
require_relative "../../spec/simplecov_helper" | |
namespace :simplecov do | |
desc "merge_results" | |
task report_coverage: :environment do | |
SimpleCovHelper.report_coverage | |
end | |
end | |
end |
@FGoessler you can make it even tidier by using SimpleCov.collate
.
Here's our latest simplecov_helper.rb
:
# frozen_string_literal: true
require 'active_support/inflector'
require 'active_model/type'
require 'simplecov'
require 'parallel_tests'
module SimpleCovHelper
def self.process_coverage
skip_check_coverage = ActiveModel::Type::Boolean.new.cast(
ENV.fetch('SKIP_COVERAGE_CHECK', 'false'),
)
SimpleCov.start 'rails' do
enable_coverage :branch
coverage_criterion :branch
add_filter '/config/'
add_filter '/spec/'
add_filter '/vendor/'
Dir['app/*'].each do |dir|
add_group File.basename(dir).humanize, dir
end
minimum_coverage(line: 100, branch: 87.89) unless skip_check_coverage
merge_timeout 3600
end
end
def self.merge_coverage_results(base_dir: './coverage_results', file_pattern: '.resultset*.json')
SimpleCov.collate(Dir["#{base_dir}/#{file_pattern}"])
end
end
and the lib/tasks/simplecov_parallel.rake
:
# frozen_string_literal: true
if Rails.env.test?
require_relative '../../spec/simplecov_helper'
namespace :simplecov do
desc 'Merge coverage results'
task merge_coverage_results: :environment do
SimpleCovHelper.merge_coverage_results
end
desc 'Process coverage results'
task process_coverage: :environment do
SimpleCovHelper.process_coverage
end
end
end
@FGoessler Since you added a merge_coverage_results
to your rake file, what does your new config file look like?
Thanks @trev :), I referred this and implemented for Github action using artifacts
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For others running into similar issues:
simplecov 0.19.0 introduced breaking changes in this commit/this PR and the script here won't fully work anymore. The symptom was an empty (0% coverage) report as the result.
We were able to fix it by using the following
merge_results
code instead:This issue on the simplecov repo was very helpful and special thanks to @mobilutz!