Class: CIJoe
- Inherits:
-
Object
- Object
- CIJoe
- Defined in:
- lib/cijoe.rb,
lib/cijoe/build.rb,
lib/cijoe/commit.rb,
lib/cijoe/config.rb,
lib/cijoe/server.rb,
lib/cijoe/version.rb,
lib/cijoe/campfire.rb
Defined Under Namespace
Modules: Campfire Classes: Build, Commit, Config, Server
Constant Summary collapse
- Version =
VERSION = "0.8.1"
Instance Attribute Summary collapse
-
#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.
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/cijoe.rb', line 26 def initialize(project_path) @project_path = File.(project_path) @user, @project = git_user_and_project @url = "http://github.com/#{@user}/#{@project}" @last_build = nil @current_build = nil trap("INT") { stop } end |
Instance Attribute Details
#current_build ⇒ Object (readonly)
Returns the value of attribute current_build.
24 25 26 |
# File 'lib/cijoe.rb', line 24 def current_build @current_build end |
#last_build ⇒ Object (readonly)
Returns the value of attribute last_build.
24 25 26 |
# File 'lib/cijoe.rb', line 24 def last_build @last_build end |
#project ⇒ Object (readonly)
Returns the value of attribute project.
24 25 26 |
# File 'lib/cijoe.rb', line 24 def project @project end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
24 25 26 |
# File 'lib/cijoe.rb', line 24 def url @url end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
24 25 26 |
# File 'lib/cijoe.rb', line 24 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)
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/cijoe.rb', line 92 def build(branch=nil) if building? # only if switched on to build all incoming requests if !repo_config.buildallfile.to_s.empty? # and there is no previous request return if File.exist?(repo_config.buildallfile.to_s) # we will mark awaiting builds FileUtils.touch(repo_config.buildallfile.to_s) end # 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
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/cijoe.rb', line 124 def build!(branch=nil) @git_branch = branch build = @current_build output = '' git_update build.sha = git_sha write_build 'current', build open_pipe("cd #{@project_path} && #{runner_command} 2>&1") do |pipe, pid| puts "#{Time.now.to_i}: Building #{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
61 62 63 64 |
# File 'lib/cijoe.rb', line 61 def build_failed(output, error) finish_build :failed, "#{error}\n\n#{output}" run_hook "build-failed" end |
#build_worked(output) ⇒ Object
66 67 68 69 |
# File 'lib/cijoe.rb', line 66 def build_worked(output) finish_build :worked, output run_hook "build-worked" end |
#building? ⇒ Boolean
is a build running?
39 40 41 |
# File 'lib/cijoe.rb', line 39 def building? !!@current_build end |
#finish_build(status, output) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/cijoe.rb', line 71 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 @last_build.notify if @last_build.respond_to? :notify # another build waits if !repo_config.buildallfile.to_s.empty? && File.exist?(repo_config.buildallfile.to_s) # clean out before new build FileUtils.rm(repo_config.buildallfile.to_s) build end end |
#git_branch ⇒ Object
170 171 172 173 174 |
# File 'lib/cijoe.rb', line 170 def git_branch return @git_branch if @git_branch branch = repo_config.branch.to_s @git_branch = branch == '' ? "master" : branch end |
#git_sha ⇒ Object
157 158 159 |
# File 'lib/cijoe.rb', line 157 def git_sha `cd #{@project_path} && git rev-parse origin/#{git_branch}`.chomp end |
#git_update ⇒ Object
161 162 163 164 |
# File 'lib/cijoe.rb', line 161 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
166 167 168 |
# File 'lib/cijoe.rb', line 166 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
109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/cijoe.rb', line 109 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
210 211 212 |
# File 'lib/cijoe.rb', line 210 def path_in_project(path) File.join(@project_path, path) end |
#pid ⇒ Object
the pid of the running child process
44 45 46 |
# File 'lib/cijoe.rb', line 44 def pid building? and current_build.pid end |
#read_build(name) ⇒ Object
load build info from file.
230 231 232 |
# File 'lib/cijoe.rb', line 230 def read_build(name) Build.load(path_in_project(".git/builds/#{name}"), @project_path) end |
#repo_config ⇒ Object
225 226 227 |
# File 'lib/cijoe.rb', line 225 def repo_config Config.cijoe(@project_path) end |
#restore ⇒ Object
restore current / last build state from disk.
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/cijoe.rb', line 199 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
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/cijoe.rb', line 177 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 data.each{ |k, v| ENV[k] = v } ret = `cd #{@project_path} && sh #{file}` data.each{ |k, v| ENV[k] = nil } ret end end |
#runner_command ⇒ Object
shellin’ out
152 153 154 155 |
# File 'lib/cijoe.rb', line 152 def runner_command runner = repo_config.runner.to_s runner == '' ? "rake -s test:units" : runner end |
#stop ⇒ Object
kill the child and exit
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/cijoe.rb', line 49 def stop # another build waits if !repo_config.buildallfile.to_s.empty? && File.exist?(repo_config.buildallfile.to_s) # clean out on stop FileUtils.rm(repo_config.buildallfile.to_s) end Process.kill(9, pid) if pid exit! end |
#write_build(name, build) ⇒ Object
write build info for build to file.
215 216 217 218 219 220 221 222 223 |
# File 'lib/cijoe.rb', line 215 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 |