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
Classes: Build, Campfire, Commit, Config, Server
Constant Summary collapse
- Version =
VERSION = "0.9.2"
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.
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# 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}" @campfire = CIJoe::Campfire.new(project_path) @last_build = nil @current_build = nil trap("INT") { stop } end |
Instance Attribute Details
#campfire ⇒ Object (readonly)
Returns the value of attribute campfire.
24 25 26 |
# File 'lib/cijoe.rb', line 24 def campfire @campfire end |
#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)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/cijoe.rb', line 94 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
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/cijoe.rb', line 126 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
63 64 65 66 |
# File 'lib/cijoe.rb', line 63 def build_failed(output, error) finish_build :failed, "#{error}\n\n#{output}" run_hook "build-failed" end |
#build_worked(output) ⇒ Object
68 69 70 71 |
# File 'lib/cijoe.rb', line 68 def build_worked(output) finish_build :worked, output run_hook "build-worked" end |
#building? ⇒ Boolean
is a build running?
41 42 43 |
# File 'lib/cijoe.rb', line 41 def building? !!@current_build end |
#finish_build(status, output) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/cijoe.rb', line 73 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? # 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
173 174 175 176 177 |
# File 'lib/cijoe.rb', line 173 def git_branch return @git_branch if @git_branch branch = repo_config.branch.to_s @git_branch = branch == '' ? "master" : branch end |
#git_sha ⇒ Object
160 161 162 |
# File 'lib/cijoe.rb', line 160 def git_sha `cd #{@project_path} && git rev-parse origin/#{git_branch}`.chomp end |
#git_update ⇒ Object
164 165 166 167 |
# File 'lib/cijoe.rb', line 164 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
169 170 171 |
# File 'lib/cijoe.rb', line 169 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
111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/cijoe.rb', line 111 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
212 213 214 |
# File 'lib/cijoe.rb', line 212 def path_in_project(path) File.join(@project_path, path) end |
#pid ⇒ Object
the pid of the running child process
46 47 48 |
# File 'lib/cijoe.rb', line 46 def pid building? and current_build.pid end |
#read_build(name) ⇒ Object
load build info from file.
232 233 234 |
# File 'lib/cijoe.rb', line 232 def read_build(name) Build.load(path_in_project(".git/builds/#{name}"), @project_path) end |
#repo_config ⇒ Object
227 228 229 |
# File 'lib/cijoe.rb', line 227 def repo_config Config.cijoe(@project_path) end |
#restore ⇒ Object
restore current / last build state from disk.
201 202 203 204 205 206 207 208 209 210 |
# File 'lib/cijoe.rb', line 201 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
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/cijoe.rb', line 180 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 ENV.clear data.each{ |k, v| ENV[k] = v } `cd #{@project_path} && sh #{file}` end end |
#runner_command ⇒ Object
shellin’ out
155 156 157 158 |
# File 'lib/cijoe.rb', line 155 def runner_command runner = repo_config.runner.to_s runner == '' ? "rake -s test:units" : runner end |
#stop ⇒ Object
kill the child and exit
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/cijoe.rb', line 51 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.
217 218 219 220 221 222 223 224 225 |
# File 'lib/cijoe.rb', line 217 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 |