groundcontrol 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/groundcontrol ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'yaml'
5
+ require 'groundcontrol'
6
+
7
+ module GroundControl
8
+
9
+ class Command
10
+
11
+ def self.run
12
+ repositories = YAML.load_file("config/projects.yml")['projects']
13
+ FileUtils.mkdir_p "builds"
14
+
15
+ repositories.each do |project, config|
16
+
17
+ build_task = GroundControl::Builder.new(project, config)
18
+ build_task.build
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ GroundControl::Command.run
@@ -0,0 +1,25 @@
1
+ module GroundControl
2
+
3
+ class BuildReport
4
+
5
+ attr_reader :project_name, :branch, :testunit_success, :cucumber_success, :commit
6
+
7
+ def initialize(project_name, branch, testunit_success, cucumber_success, commit)
8
+ @project_name = project_name
9
+ @branch = branch
10
+ @testunit_success = testunit_success
11
+ @cucumber_success = cucumber_success
12
+ @commit = commit
13
+ end
14
+
15
+ def success?
16
+ testunit_success && cucumber_success
17
+ end
18
+
19
+ def failed?
20
+ !success?
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,165 @@
1
+ require 'rubygems'
2
+ require 'git'
3
+ require 'tinder'
4
+ require 'grit'
5
+ require 'net/http'
6
+
7
+ module GroundControl
8
+
9
+ class Builder
10
+
11
+ def initialize(project_name, config)
12
+ @project_name = project_name
13
+ @config = config
14
+ @workspace = File.join("builds", project_name)
15
+ @build_directory = File.join(@workspace, "build")
16
+ @reports_directory = File.join(@workspace, "reports")
17
+ @git_url = @config['git']
18
+ end
19
+
20
+ def build
21
+ create_workspace()
22
+
23
+ clone_repository()
24
+
25
+ prepare_build_environment()
26
+
27
+ test_report = run_tests_and_report()
28
+
29
+ notify_campfire_of_build_result(test_report, @project_name, @repository)
30
+ end
31
+
32
+ private
33
+
34
+ def notify_campfire_of_build_result(test_report, project_name, repository)
35
+ campfire_config = @config['campfire']
36
+
37
+ campfire = Tinder::Campfire.new campfire_config['subdomain'], :token => campfire_config['token']
38
+ room = campfire.find_room_by_name(campfire_config['room'])
39
+
40
+ last_commit = repository.commits.first
41
+
42
+ if test_report.success?
43
+ room.speak "Build SUCCEEDED. +1 for #{last_commit.author.name}."
44
+ else
45
+ room.speak "Build FAILED for #{project_name}/#{repository.head.name} #{@config['github']}/commit/#{test_report.commit.sha}. #{last_commit.author.name} is definitely not the best developer."
46
+ end
47
+ end
48
+
49
+ def start_virtual_screen
50
+ ENV['DISPLAY'] = ":5"
51
+
52
+ xvfb_pid = fork do
53
+ exec 'Xvfb :5 -ac -screen 0 1024x768x8'
54
+ end
55
+ end
56
+
57
+ def run_unit_tests()
58
+ ENV['CI_REPORTS'] = "../reports/testunit"
59
+
60
+ test_output = `cd #{@build_directory}; bundle exec rake ci:setup:testunit test`
61
+ return $?.to_i
62
+ end
63
+
64
+ def run_cucumber_tests()
65
+ screen_pid = start_virtual_screen()
66
+
67
+ ENV['CUCUMBER_OPTS'] = "--format junit --out ../reports/features"
68
+
69
+ cucumber_output = `cd #{@build_directory}; bundle exec rake cucumber`
70
+ cucumber_status = $?.to_i
71
+
72
+ Process.kill "TERM", screen_pid
73
+
74
+ return cucumber_status
75
+ end
76
+
77
+ def run_tests_and_report()
78
+ testunit_return_code = run_unit_tests()
79
+ cucumber_return_code = run_cucumber_tests()
80
+
81
+ return BuildReport.new(@project_name, @repository.head.name, testunit_return_code == 0, cucumber_return_code == 0, @repository.commits.first)
82
+ end
83
+
84
+ def clone_repository
85
+ Git.clone(@git_url, @build_directory)
86
+ @repository = Grit::Repo.new(@build_directory)
87
+ end
88
+
89
+ def create_workspace
90
+ FileUtils.rm_rf @workspace
91
+
92
+ FileUtils.mkdir_p(@build_directory)
93
+ FileUtils.mkdir_p(@reports_directory)
94
+ end
95
+
96
+ def initialize_rvm
97
+ system "cd #{@build_directory}; rvm rvmrc trust"
98
+ system "cd #{@build_directory}; rvm reload"
99
+ end
100
+
101
+ def install_bundler_gems()
102
+ system "cd #{@build_directory}; bundle install --without production"
103
+ end
104
+
105
+ def inject_ci_reporter()
106
+ doc = <<EOF
107
+ require 'rubygems'
108
+ require 'ci/reporter/rake/test_unit' # use this if you're using Test::Unit
109
+ EOF
110
+
111
+ File.open("#{@build_directory}/lib/tasks/ci_reporter.rake", 'w') { |f| f.write(doc) }
112
+ end
113
+
114
+ def inject_database_config()
115
+
116
+ database = <<EOF
117
+ test: &test
118
+ adapter: mysql2
119
+ encoding: utf8
120
+ reconnect: false
121
+ database: #{@project_name}_test
122
+ pool: 5
123
+ username: root
124
+ password:
125
+
126
+ cucumber:
127
+ <<: *test
128
+ EOF
129
+
130
+ File.open("#{@build_directory}/config/database.yml", 'w') { |f| f.write(database) }
131
+
132
+ end
133
+
134
+ def load_empty_schema()
135
+ system "cd #{@build_directory}; bundle exec rake db:schema:load"
136
+ end
137
+
138
+ def setup_database()
139
+ inject_database_config()
140
+ load_empty_schema()
141
+ end
142
+
143
+ def inject_thinking_sphinx_config
144
+ sphinx_config = <<EOF
145
+ test:
146
+ port: 9312
147
+ EOF
148
+
149
+ File.open("#{@build_directory}/config/sphinx.yml", 'w') { |f| f.write(sphinx_config) }
150
+ end
151
+
152
+ def prepare_build_environment
153
+ ENV['RAILS_ENV'] = "test"
154
+
155
+ initialize_rvm()
156
+ install_bundler_gems()
157
+ inject_ci_reporter()
158
+
159
+ setup_database()
160
+ inject_thinking_sphinx_config()
161
+ end
162
+
163
+ end
164
+
165
+ end
@@ -0,0 +1,46 @@
1
+ require "nokogiri"
2
+
3
+ module GroundControl
4
+
5
+ class TestResult
6
+
7
+ attr_reader :name, :message
8
+
9
+ def self.read_from_xml(xml_string)
10
+ doc = Nokogiri::XML.parse(xml_string)
11
+ tests = []
12
+
13
+ doc.xpath('//testcase').each do |testcase|
14
+ failure = testcase.xpath('//failure')
15
+ if failure.blank?
16
+ tests << TestResult.new(testcase['name'])
17
+ else
18
+ tests << TestResult.new(testcase['name'], failure.first.content)
19
+ end
20
+ end
21
+
22
+
23
+ return tests
24
+ end
25
+
26
+ def initialize(name, failure_message = nil)
27
+ @name = name
28
+ @failed = false
29
+
30
+ if failure_message
31
+ @failed = true
32
+ @message = failure_message
33
+ end
34
+ end
35
+
36
+ def failed?
37
+ return @failed
38
+ end
39
+
40
+ def success?
41
+ return true if not @failed
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ require "groundcontrol/builder"
2
+ require "groundcontrol/build_report"
3
+ require "groundcontrol/test_result"
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: groundcontrol
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Michiel Sikkes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-12-15 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: grit
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: git
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: tinder
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: nokogiri
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :runtime
59
+ version_requirements: *id004
60
+ description: Groundcontrol powers test builds for Rails projects
61
+ email: michiel@firmhouse.com
62
+ executables:
63
+ - groundcontrol
64
+ extensions: []
65
+
66
+ extra_rdoc_files: []
67
+
68
+ files:
69
+ - lib/groundcontrol.rb
70
+ - lib/groundcontrol/builder.rb
71
+ - lib/groundcontrol/build_report.rb
72
+ - lib/groundcontrol/test_result.rb
73
+ - bin/groundcontrol
74
+ has_rdoc: true
75
+ homepage: http://github.com/Firmhouse/groundcontrol
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options: []
80
+
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.6.2
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Runs automated Rails tests and reports back.
102
+ test_files: []
103
+