Skip to content

Commit

Permalink
Add circle CI setup
Browse files Browse the repository at this point in the history
  • Loading branch information
mbj authored and Jeff Dutil committed Oct 22, 2014
1 parent 3b2fc61 commit 6c36d5a
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 0 deletions.
184 changes: 184 additions & 0 deletions build-ci.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!/usr/bin/env ruby

require 'pathname'

class Project
attr_reader :name

NODE_TOTAL = Integer(ENV.fetch('CIRCLE_NODE_TOTAL', 1))
NODE_INDEX = Integer(ENV.fetch('CIRCLE_NODE_INDEX', 0))

ROOT = Pathname.pwd.freeze
VENDOR_BUNDLE = ROOT.join('vendor', 'bundle').freeze

BUNDLER_JOBS = 4
BUNDLER_RETRIES = 3

DEFAULT_MODE = 'test'.freeze

def initialize(name)
@name = name
end

ALL = %w[api backend core frontend sample].map(&method(:new)).freeze

# Install subproject
#
# @raise [RuntimeError]
# in case of failure
#
# @return [self]
# otherwise
def install
chdir do
bundle_check or bundle_install or fail 'Cannot finish gem installation'
end
self
end

# Test subproject for passing its tests
#
# @return [Boolean]
# the success of the build
def pass?
chdir do
setup_test_app
run_tests
end
end

private

# Check if current bundle is already usable
#
# @return [Boolean]
def bundle_check
system(%W[bundle check --path=#{VENDOR_BUNDLE}])
end

# Install the current bundle
#
# @return [Boolean]
# the success of the installation
def bundle_install
system(%W[
bundle
install
--path=#{VENDOR_BUNDLE}
--jobs=#{BUNDLER_JOBS}
--retry=#{BUNDLER_RETRIES}
])
end

# Setup the test app
#
# @return [undefined]
def setup_test_app
system(%w[bundle exec rake test_app]) or fail 'Failed to setup the test app'
end

# Run tests for subproject
#
# @return [Boolean]
# the success of the tests
def run_tests
system(%w[bundle exec rspec spec])
end

# Execute system command via execve
#
# No shell interpolation gets done this way. No escapes needed.
#
# @return [Boolean]
# the success of the system command
def system(arguments)
Kernel.system(*arguments)
end

# Change to subproject directory and execute block
#
# @return [undefined]
def chdir(&block)
Dir.chdir(ROOT.join(name), &block)
end

# Install subprojects
#
# @return [self]
def self.install
current_projects.each do |project|
log("Installing project: #{project.name}")
project.install
end
self
end
private_class_method :install

# Execute tests on subprojects
#
# @return [Boolean]
# the success of ALL subprojects
def self.test
projects = current_projects
suffix = "#{projects.length} projects(s) on node #{NODE_INDEX.succ} / #{NODE_TOTAL}"

log("Running #{suffix}")
projects.each do |project|
log("- #{project.name}")
end

builds = projects.map do |project|
log("Building: #{project.name}")
project.pass?
end
log("Finished running #{suffix}")

projects.zip(builds).each do |project, build|
log("- #{project.name} #{build ? 'SUCCESS' : 'FAILURE'}")
end

builds.all?
end
private_class_method :test

# Return the projects active on current node
#
# @return [Array<Project>]
def self.current_projects
NODE_INDEX.step(ALL.length - 1, NODE_TOTAL).map(&ALL.method(:fetch))
end
private_class_method :current_projects

# Log a progress message to stderr
#
# @param [String] message
#
# @return [undefined]
def self.log(message)
$stderr.puts(message)
end
private_class_method :log

# Process CLI arguments
#
# @param [Array<String>] arguments
#
# @return [Boolean]
# the success of the CLI run
def self.run_cli(arguments)
fail ArgumentError if arguments.length > 1
mode = arguments.fetch(0, DEFAULT_MODE)

case mode
when 'install'
install
true
when 'test'
test
else
fail "Unknown mode: #{mode.inspect}"
end
end
end # Project

exit Project.run_cli(ARGV)
15 changes: 15 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
machine:
environment:
DB: postgres
services:
- postgresql
ruby:
version: 2.1.3
dependencies:
override:
- ./build-ci.rb install
test:
override:
- './build-ci.rb test':
parallel: true

0 comments on commit 6c36d5a

Please sign in to comment.