Class: CIJoe
- Inherits:
-
Object
- Object
- CIJoe
- Defined in:
- lib/cijoe.rb,
lib/cijoe/build.rb,
lib/cijoe/queue.rb,
lib/cijoe/commit.rb,
lib/cijoe/config.rb,
lib/cijoe/server.rb,
lib/cijoe/version.rb,
lib/cijoe/campfire.rb
Defined Under Namespace
Classes: Build, Campfire, Commit, Config, Queue, Server
Constant Summary collapse
- Version =
VERSION = "0.9.5"
Instance Attribute Summary collapse
-
#campfire ⇒ Object
readonly
Returns the value of attribute campfire.
-
#current_build ⇒ Object
readonly
Returns the value of attribute current_build.
-
#last_build ⇒ Object
readonly
Returns the value of attribute last_build.
-
#project ⇒ Object
readonly
Returns the value of attribute project.
-
#url ⇒ Object
readonly
Returns the value of attribute url.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
Instance Method Summary collapse
-
#build(branch = nil) ⇒ Object
run the build but make sure only one is running at a time (if new one comes in we will park it).
-
#build!(branch = nil) ⇒ Object
update git then run the build.
-
#build_failed(output, error) ⇒ Object
build callbacks.
- #build_worked(output) ⇒ Object
-
#building? ⇒ Boolean
is a build running?.
- #finish_build(status, output) ⇒ Object
- #git_branch ⇒ Object
- #git_sha ⇒ Object
- #git_update ⇒ Object
- #git_user_and_project ⇒ Object
-
#initialize(project_path) ⇒ CIJoe
constructor
A new instance of CIJoe.
- #open_pipe(cmd) {|read, pid| ... } ⇒ Object
- #path_in_project(path) ⇒ Object
-
#pid ⇒ Object
the pid of the running child process.
-
#read_build(name) ⇒ Object
load build info from file.
- #repo_config ⇒ Object
-
#restore ⇒ Object
restore current / last build state from disk.
-
#run_hook(hook) ⇒ Object
massage our repo.
-
#runner_command ⇒ Object
shellin’ out.
-
#stop ⇒ Object
kill the child and exit.
-
#write_build(name, build) ⇒ Object
write build info for build to file.
Constructor Details
#initialize(project_path) ⇒ CIJoe
Returns a new instance of CIJoe.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/cijoe.rb', line 27 def initialize(project_path) @project_path = File.(project_path) @user, @project = git_user_and_project @url = "http://github.com/#{@user}/#{@project}" @campfire = CIJoe::Campfire.new(project_path) @last_build = nil @current_build = nil @queue = Queue.new(!repo_config.buildqueue.to_s.empty?, true) trap("INT") { stop } end |
Instance Attribute Details
#campfire ⇒ Object (readonly)
Returns the value of attribute campfire.
25 26 27 |
# File 'lib/cijoe.rb', line 25 def campfire @campfire end |
#current_build ⇒ Object (readonly)
Returns the value of attribute current_build.
25 26 27 |
# File 'lib/cijoe.rb', line 25 def current_build @current_build end |
#last_build ⇒ Object (readonly)
Returns the value of attribute last_build.
25 26 27 |
# File 'lib/cijoe.rb', line 25 def last_build @last_build end |
#project ⇒ Object (readonly)
Returns the value of attribute project.
25 26 27 |
# File 'lib/cijoe.rb', line 25 def project @project end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
25 26 27 |
# File 'lib/cijoe.rb', line 25 def url @url end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
25 26 27 |
# File 'lib/cijoe.rb', line 25 def user @user end |
Instance Method Details
#build(branch = nil) ⇒ Object
run the build but make sure only one is running at a time (if new one comes in we will park it)
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/cijoe.rb', line 85 def build(branch=nil) if building? @queue.append_unless_already_exists(branch) # leave anyway because a current build runs return end @current_build = Build.new(@project_path, @user, @project) write_build 'current', @current_build Thread.new { build!(branch) } end |
#build!(branch = nil) ⇒ Object
update git then run the build
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/cijoe.rb', line 111 def build!(branch=nil) @git_branch = branch build = @current_build output = '' git_update build.sha = git_sha build.branch = git_branch write_build 'current', build open_pipe("cd \"#{@project_path}\" && #{runner_command} 2>&1") do |pipe, pid| puts "#{Time.now.to_i}: Building #{build.branch} at #{build.short_sha}: pid=#{pid}" build.pid = pid write_build 'current', build output = pipe.read end Process.waitpid(build.pid, 1) status = $?.exitstatus.to_i @current_build = build puts "#{Time.now.to_i}: Built #{build.short_sha}: status=#{status}" status == 0 ? build_worked(output) : build_failed('', output) rescue Object => e puts "Exception building: #{e.} (#{e.class})" build_failed('', e.to_s) end |
#build_failed(output, error) ⇒ Object
build callbacks
59 60 61 62 |
# File 'lib/cijoe.rb', line 59 def build_failed(output, error) finish_build :failed, "#{error}\n\n#{output}" run_hook "build-failed" end |
#build_worked(output) ⇒ Object
64 65 66 67 |
# File 'lib/cijoe.rb', line 64 def build_worked(output) finish_build :worked, output run_hook "build-worked" end |
#building? ⇒ Boolean
is a build running?
43 44 45 |
# File 'lib/cijoe.rb', line 43 def building? !!@current_build end |
#finish_build(status, output) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/cijoe.rb', line 69 def finish_build(status, output) @current_build.finished_at = Time.now @current_build.status = status @current_build.output = output @last_build = @current_build @current_build = nil write_build 'current', @current_build write_build 'last', @last_build @campfire.notify(@last_build) if @campfire.valid? build(@queue.next_branch_to_build) if @queue.waiting? end |
#git_branch ⇒ Object
158 159 160 161 162 |
# File 'lib/cijoe.rb', line 158 def git_branch return @git_branch if @git_branch branch = repo_config.branch.to_s @git_branch = branch == '' ? "master" : branch end |
#git_sha ⇒ Object
145 146 147 |
# File 'lib/cijoe.rb', line 145 def git_sha `cd \"#{@project_path}\" && git rev-parse origin/#{git_branch}`.chomp end |
#git_update ⇒ Object
149 150 151 152 |
# File 'lib/cijoe.rb', line 149 def git_update `cd \"#{@project_path}\" && git fetch origin && git reset --hard origin/#{git_branch}` run_hook "after-reset" end |
#git_user_and_project ⇒ Object
154 155 156 |
# File 'lib/cijoe.rb', line 154 def git_user_and_project Config.remote(@project_path).origin.url.to_s.chomp('.git').split(':')[-1].split('/')[-2, 2] end |
#open_pipe(cmd) {|read, pid| ... } ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/cijoe.rb', line 96 def open_pipe(cmd) read, write = IO.pipe pid = fork do read.close $stdout.reopen write exec cmd end write.close yield read, pid end |
#path_in_project(path) ⇒ Object
202 203 204 |
# File 'lib/cijoe.rb', line 202 def path_in_project(path) File.join(@project_path, path) end |
#pid ⇒ Object
the pid of the running child process
48 49 50 |
# File 'lib/cijoe.rb', line 48 def pid building? and current_build.pid end |
#read_build(name) ⇒ Object
load build info from file.
222 223 224 |
# File 'lib/cijoe.rb', line 222 def read_build(name) Build.load(path_in_project(".git/builds/#{name}"), @project_path) end |
#repo_config ⇒ Object
217 218 219 |
# File 'lib/cijoe.rb', line 217 def repo_config Config.cijoe(@project_path) end |
#restore ⇒ Object
restore current / last build state from disk.
191 192 193 194 195 196 197 198 199 200 |
# File 'lib/cijoe.rb', line 191 def restore @last_build = read_build('last') @current_build = read_build('current') Process.kill(0, @current_build.pid) if @current_build && @current_build.pid rescue Errno::ESRCH # build pid isn't running anymore. assume previous # server died and reset. @current_build = nil end |
#run_hook(hook) ⇒ Object
massage our repo
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/cijoe.rb', line 165 def run_hook(hook) if File.exists?(file=path_in_project(".git/hooks/#{hook}")) && File.executable?(file) data = if @last_build && @last_build.commit { "MESSAGE" => @last_build.commit., "AUTHOR" => @last_build.commit., "SHA" => @last_build.commit.sha, "OUTPUT" => @last_build.env_output } else {} end orig_ENV = ENV.to_hash ENV.clear data.each{ |k, v| ENV[k] = v } output = `cd \"#{@project_path}\" && sh #{file}` ENV.clear orig_ENV.to_hash.each{ |k, v| ENV[k] = v} output end end |
#runner_command ⇒ Object
shellin’ out
140 141 142 143 |
# File 'lib/cijoe.rb', line 140 def runner_command runner = repo_config.runner.to_s runner == '' ? "rake -s test:units" : runner end |
#stop ⇒ Object
kill the child and exit
53 54 55 56 |
# File 'lib/cijoe.rb', line 53 def stop Process.kill(9, pid) if pid exit! end |
#write_build(name, build) ⇒ Object
write build info for build to file.
207 208 209 210 211 212 213 214 215 |
# File 'lib/cijoe.rb', line 207 def write_build(name, build) filename = path_in_project(".git/builds/#{name}") Dir.mkdir path_in_project('.git/builds') unless File.directory?(path_in_project('.git/builds')) if build build.dump filename elsif File.exist?(filename) File.unlink filename end end |