Configure CircleCI to Report RSpec Test Results to Coveralls in a Chef Cookbook

From Bonus Bits
Jump to: navigation, search

Purpose

This article gives the steps to configure CircleCI, RSpec and Coveralls in a Chef Cookbook to output ChefSpec test results from CircleCI to Coveralls code coverage monitoring solution.


Prerequisites

  • CircleCI Account
  • Sync Github/Bitbucket Repos in CircleCI Web Console
  • Include Github/Bitbucket Repo of project in CircleCI Web Console
    • Enable CircleCI Webhook access to Github/Bitbucket Org


Coveralls Config

  1. Create coveralls.yml config file in root of project
  2. Open the Coveralls Web Console
  3. Select the project repo
  4. If it's never received a report then it should have set up coveralls page. In this page grab the repo_token: 000000000000000000
  5. Add that one line to your coveralls.yml


Gem File

  1. Add coveralls gem to the Gemfile Ruby file in the root of the cookbook
    source 'https://rubygems.org'
    
    gem 'rake', '~> 11.3.0'
    gem 'berkshelf', '~> 5.1.0'
    
    group :style do
      gem 'foodcritic', '~> 7.1.0'
      gem 'rubocop', '~> 0.39.0'
      gem 'rainbow', '~> 2.1.0'
    end
    
    group :unit do
      gem 'chefspec', '~> 5.2.0'
      gem 'chef-sugar', '~> 3.4.0'
      gem 'fauxhai', '~> 3.9.0'
      gem 'coveralls', '~> 0.8.0'
      gem 'rspec_junit_formatter', '~> 0.2.3'
    end
    
    group :integration do
      gem 'test-kitchen', '~> 1.13.0'
      gem 'kitchen-docker', '~> 2.6.0'
    end
    

Gnome-sticky-notes-applet I had gem version struggles with CircleCI. So I include my Gemfile.lock in my github repo to force ever single gem to the version I want based on my Gemfile. Don't forget to not ignore the file in you .gitignore.


Spec Helper

  1. Add the following to the spec/spec_helper.rb Ruby file
    if ENV['CI']
      require 'coveralls'
      SimpleCov.formatter = Coveralls::SimpleCov::Formatter
      Coveralls.wear!
    end
    
    require 'chefspec'
    require 'chefspec/berkshelf'
    
    at_exit { ChefSpec::Coverage.report! }
    


CircleCI Config

  1. Add Webhook Notify to you circle.yml
    machine:
      services:
      - docker
      ruby:
        version: '2.3.1'
      timezone:
        America/Los_Angeles
    
    dependencies:
      override:
      - bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3 --without=ec2 vagrant:
          timeout: 900
    
    test:
      override:
      - bundle exec rake circleci:
          parallel: false
          timeout: 900
    
    notify:
      webhooks:
        - url: https://coveralls.io/webhook?repo_token=mCyigohBgcMwY3SXVlqmWVbmCNnudD0JF
    


Rake Task

I create a Rake task specific for CircleCi.

  1. Add Task or Create Rakefile Ruby file in the root of your cookbook.
    # For CircleCI
    require 'bundler/setup'
    
    # Style tests. Rubocop and Foodcritic
    namespace :style do
      require 'rubocop/rake_task'
      require 'foodcritic'
      desc 'RuboCop'
      RuboCop::RakeTask.new(:ruby)
    
      desc 'FoodCritic'
      FoodCritic::Rake::LintTask.new(:chef) do |task|
        task.options = {
          fail_tags: ['correctness'],
          chef_version: '12.14.89',
          tags: %w(~FC001 ~FC019)
        }
      end
    end
    
    # Rspec and ChefSpec
    namespace :unit do
      desc 'Unit Tests (Rspec & ChefSpec)'
      require 'rspec/core/rake_task'
      RSpec::Core::RakeTask.new(:rspec)
    
      desc 'Unit Tests for CircleCI'
      RSpec::Core::RakeTask.new(:circleci_rspec) do |test|
        # t.fail_on_error = false
        test.rspec_opts = '--no-drb -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml'
      end
    end
    
    # Integration Tests - Kitchen
    namespace :integration do
      require 'kitchen'
    
      # Load Specific Kitchen Configuration YAML
      def load_kitchen_config(yaml)
        Kitchen.logger = Kitchen.default_file_logger
        kitchen_loader = Kitchen::Loader::YAML.new(local_config: yaml)
        Kitchen::Config.new(loader: kitchen_loader, log_level: :info)
      end
    
      # Run Each Test Instance in All Test Suites from YAML
      desc 'kitchen - docker - test'
      task :docker do
        load_kitchen_config('.kitchen.yml').instances.each do |instance|
          instance.test(:always)
        end
      end
    end
    
    desc 'Circle CI Tasks'
    task circleci: %w(style:chef style:ruby unit:circleci_rspec integration:docker)
    
    desc 'Foodcritic, Rubocop & ChefSpec'
    task default: %w(style:chef style:ruby unit:rspec)
    
    desc 'Foodcritic & Rubocop'
    task style_only: %w(style:chef style:ruby)
    


Examples


Sources