cijoe 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/README.markdown +0 -18
- data/Rakefile +34 -1
- data/deps.rip +0 -1
- data/examples/cijoe.ru +15 -0
- data/examples/cijoed +53 -0
- data/lib/cijoe.rb +53 -14
- data/lib/cijoe/build.rb +18 -2
- data/lib/cijoe/commit.rb +3 -3
- data/lib/cijoe/config.rb +19 -1
- data/lib/cijoe/public/favicon.ico +0 -0
- data/lib/cijoe/server.rb +3 -0
- data/lib/cijoe/version.rb +1 -1
- data/lib/cijoe/views/template.erb +1 -0
- data/test/helper.rb +9 -0
- data/test/test_cijoe.rb +17 -0
- metadata +11 -14
data/.gitignore
ADDED
data/README.markdown
CHANGED
@@ -89,24 +89,6 @@ Multiple Projects
|
|
89
89
|
Want CI for multiple projects? Just start multiple instances of Joe!
|
90
90
|
He can run on any port - try `cijoe -h` for more options.
|
91
91
|
|
92
|
-
Thanks to Dean Strelau you can also run multiple instances of CI Joe using
|
93
|
-
a single `config.ru` file.
|
94
|
-
|
95
|
-
In particular, it is possible to mount Server at a subpath:
|
96
|
-
|
97
|
-
map '/foo' do
|
98
|
-
run CIJoe::Server.set(:project_path => 'projects/foo')
|
99
|
-
end
|
100
|
-
|
101
|
-
and you can even run multiple instances of Joe if you subclass:
|
102
|
-
|
103
|
-
map '/foo' do
|
104
|
-
run Class.new(CIJoe::Server).set(:project_path => 'projects/foo')
|
105
|
-
end
|
106
|
-
map '/bar' do
|
107
|
-
run Class.new(CIJoe::Server).set(:project_path => 'projects/bar')
|
108
|
-
end
|
109
|
-
|
110
92
|
|
111
93
|
HTTP Auth
|
112
94
|
---------
|
data/Rakefile
CHANGED
@@ -16,10 +16,43 @@ begin
|
|
16
16
|
gemspec.authors = ["Chris Wanstrath"]
|
17
17
|
gemspec.add_dependency 'choice'
|
18
18
|
gemspec.add_dependency 'sinatra'
|
19
|
-
gemspec.add_dependency 'open4'
|
20
19
|
gemspec.version = CIJoe::Version.to_s
|
21
20
|
end
|
22
21
|
rescue LoadError
|
23
22
|
puts "Jeweler not available."
|
24
23
|
puts "Install it with: gem install jeweler"
|
25
24
|
end
|
25
|
+
|
26
|
+
require 'rake/testtask'
|
27
|
+
Rake::TestTask.new(:test) do |test|
|
28
|
+
test.libs << 'lib' << 'test'
|
29
|
+
test.pattern = 'test/**/test_*.rb'
|
30
|
+
test.verbose = true
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
require 'rcov/rcovtask'
|
35
|
+
Rcov::RcovTask.new do |test|
|
36
|
+
test.libs << 'test'
|
37
|
+
test.pattern = 'test/**/test_*.rb'
|
38
|
+
test.verbose = true
|
39
|
+
end
|
40
|
+
rescue LoadError
|
41
|
+
task :rcov do
|
42
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
task :test => :check_dependencies
|
47
|
+
|
48
|
+
task :default => :test
|
49
|
+
|
50
|
+
require 'rake/rdoctask'
|
51
|
+
Rake::RDocTask.new do |rdoc|
|
52
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
53
|
+
|
54
|
+
rdoc.rdoc_dir = 'rdoc'
|
55
|
+
rdoc.title = "someproject #{version}"
|
56
|
+
rdoc.rdoc_files.include('README*')
|
57
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
58
|
+
end
|
data/deps.rip
CHANGED
data/examples/cijoe.ru
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Example CI Joe rackup config. Drop a cijoe.ru file
|
2
|
+
# in your projects direct
|
3
|
+
require 'cijoe'
|
4
|
+
|
5
|
+
# setup middleware
|
6
|
+
use Rack::CommonLogger
|
7
|
+
|
8
|
+
# configure joe
|
9
|
+
CIJoe::Server.configure do |config|
|
10
|
+
config.set :project_path, File.dirname(__FILE__)
|
11
|
+
config.set :show_exceptions, true
|
12
|
+
config.set :lock, true
|
13
|
+
end
|
14
|
+
|
15
|
+
run CIJoe::Server
|
data/examples/cijoed
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
### BEGIN INIT INFO
|
3
|
+
# Provides: cijoe
|
4
|
+
# Required-Start: $syslog $local_fs $network
|
5
|
+
# Required-Stop: $syslog $local_fs $network
|
6
|
+
# Default-Start: 2 3 4 5
|
7
|
+
# Default-Stop: 0 1
|
8
|
+
# Description: Run the CIJoe CI server. Yo Joe!!
|
9
|
+
### END INIT INFO
|
10
|
+
|
11
|
+
. /lib/lsb/init-functions
|
12
|
+
|
13
|
+
REPO=/path/to/your/git/repository
|
14
|
+
PORT=4567
|
15
|
+
|
16
|
+
NAME=cijoe
|
17
|
+
INSTALL_DIR=/usr/sbin
|
18
|
+
DAEMON=$INSTALL_DIR/$NAME
|
19
|
+
DAEMON_ARGS="-p $PORT $REPO"
|
20
|
+
PIDFILE=/var/run/$NAME.pid
|
21
|
+
DAEMON_USER=www-data
|
22
|
+
DAEMON_GROUP=$DAEMON_USER
|
23
|
+
|
24
|
+
# test -f $DAEMON || exit 0
|
25
|
+
# test -f $PROJECT_DIR || exit 0
|
26
|
+
|
27
|
+
case "$1" in
|
28
|
+
start)
|
29
|
+
log_daemon_msg "Starting cijoe" "cijoe"
|
30
|
+
start-stop-daemon --background --make-pidfile --exec $DAEMON --start --name $NAME --pidfile $PIDFILE --chuid $DAEMON_USER:$DAEMON_GROUP -- $DAEMON_ARGS
|
31
|
+
log_end_msg $?
|
32
|
+
;;
|
33
|
+
stop)
|
34
|
+
log_daemon_msg "Stopping cijoe" "cijoe"
|
35
|
+
start-stop-daemon --stop --pidfile $PIDFILE --quiet --retry 10
|
36
|
+
log_end_msg $?
|
37
|
+
;;
|
38
|
+
restart)
|
39
|
+
log_daemon_msg "Restarting cijoe" "cijoe"
|
40
|
+
start-stop-daemon --stop --pidfile $PIDFILE --quiet --retry 10
|
41
|
+
start-stop-daemon --background --make-pidfile --exec $DAEMON --start --name $NAME --pidfile $PIDFILE --chuid $DAEMON_USER:$DAEMON_GROUP -- $DAEMON_ARGS
|
42
|
+
log_end_msg $?
|
43
|
+
;;
|
44
|
+
status)
|
45
|
+
status_of_proc $DAEMON $NAME && exit 0 || exit $?
|
46
|
+
;;
|
47
|
+
*)
|
48
|
+
log_action_msg "Usage: /etc/init.d/cijoe (start|stop|restart)"
|
49
|
+
exit 2
|
50
|
+
;;
|
51
|
+
esac
|
52
|
+
|
53
|
+
exit 0
|
data/lib/cijoe.rb
CHANGED
@@ -13,12 +13,6 @@
|
|
13
13
|
#
|
14
14
|
# Seriously, I'm gonna be nuts about keeping this simple.
|
15
15
|
|
16
|
-
begin
|
17
|
-
require 'open4'
|
18
|
-
rescue LoadError
|
19
|
-
abort "** Please install open4"
|
20
|
-
end
|
21
|
-
|
22
16
|
require 'cijoe/version'
|
23
17
|
require 'cijoe/config'
|
24
18
|
require 'cijoe/commit'
|
@@ -49,7 +43,7 @@ class CIJoe
|
|
49
43
|
|
50
44
|
# the pid of the running child process
|
51
45
|
def pid
|
52
|
-
building? and
|
46
|
+
building? and current_build.pid
|
53
47
|
end
|
54
48
|
|
55
49
|
# kill the child and exit
|
@@ -75,6 +69,8 @@ class CIJoe
|
|
75
69
|
@current_build.output = output
|
76
70
|
@last_build = @current_build
|
77
71
|
@current_build = nil
|
72
|
+
write_build 'current', @current_build
|
73
|
+
write_build 'last', @last_build
|
78
74
|
@last_build.notify if @last_build.respond_to? :notify
|
79
75
|
end
|
80
76
|
|
@@ -83,21 +79,25 @@ class CIJoe
|
|
83
79
|
def build
|
84
80
|
return if building?
|
85
81
|
@current_build = Build.new(@user, @project)
|
82
|
+
write_build 'current', @current_build
|
86
83
|
Thread.new { build! }
|
87
84
|
end
|
88
85
|
|
89
86
|
# update git then run the build
|
90
87
|
def build!
|
91
|
-
|
88
|
+
build = @current_build
|
89
|
+
output = ''
|
92
90
|
git_update
|
93
|
-
|
91
|
+
build.sha = git_sha
|
92
|
+
write_build 'current', build
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
94
|
+
IO.popen("#{runner_command} 2>&1") do |pipe|
|
95
|
+
build.pid = pid
|
96
|
+
write_build 'current', build
|
97
|
+
output = pipe.read
|
98
98
|
end
|
99
99
|
|
100
|
-
|
100
|
+
$?.exitstatus.to_i == 0 ? build_worked(output) : build_failed('', output)
|
101
101
|
rescue Object => e
|
102
102
|
build_failed('', e.to_s)
|
103
103
|
end
|
@@ -129,7 +129,46 @@ class CIJoe
|
|
129
129
|
# massage our repo
|
130
130
|
def run_hook(hook)
|
131
131
|
if File.exists?(file=".git/hooks/#{hook}") && File.executable?(file)
|
132
|
-
|
132
|
+
data =
|
133
|
+
if @last_build && @last_build.commit
|
134
|
+
{
|
135
|
+
"MESSAGE" => @last_build.commit.message,
|
136
|
+
"AUTHOR" => @last_build.commit.author,
|
137
|
+
"SHA" => @last_build.commit.sha,
|
138
|
+
"OUTPUT" => @last_build.clean_output
|
139
|
+
}
|
140
|
+
else
|
141
|
+
{}
|
142
|
+
end
|
143
|
+
env = data.collect { |k, v| %(#{k}=#{v.inspect}) }.join(" ")
|
144
|
+
`#{env} sh #{file}`
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# restore current / last build state from disk.
|
149
|
+
def restore
|
150
|
+
@last_build = read_build('last')
|
151
|
+
@current_build = read_build('current')
|
152
|
+
Process.kill(0, @current_build.pid) if @current_build && @current_build.pid
|
153
|
+
rescue Errno::ESRCH
|
154
|
+
# build pid isn't running anymore. assume previous
|
155
|
+
# server died and reset.
|
156
|
+
@current_build = nil
|
157
|
+
end
|
158
|
+
|
159
|
+
# write build info for build to file.
|
160
|
+
def write_build(name, build)
|
161
|
+
filename = ".git/builds/#{name}"
|
162
|
+
Dir.mkdir '.git/builds' unless File.directory?('.git/builds')
|
163
|
+
if build
|
164
|
+
build.dump filename
|
165
|
+
elsif File.exist?(filename)
|
166
|
+
File.unlink filename
|
133
167
|
end
|
134
168
|
end
|
169
|
+
|
170
|
+
# load build info from file.
|
171
|
+
def read_build(name)
|
172
|
+
Build.load(".git/builds/#{name}")
|
173
|
+
end
|
135
174
|
end
|
data/lib/cijoe/build.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
class CIJoe
|
2
|
-
class Build < Struct.new(:user, :project, :started_at, :finished_at, :sha, :status, :output)
|
4
|
+
class Build < Struct.new(:user, :project, :started_at, :finished_at, :sha, :status, :output, :pid)
|
3
5
|
def initialize(*args)
|
4
6
|
super
|
5
|
-
self.started_at
|
7
|
+
self.started_at ||= Time.now
|
6
8
|
end
|
7
9
|
|
8
10
|
def status
|
@@ -27,7 +29,21 @@ class CIJoe
|
|
27
29
|
end
|
28
30
|
|
29
31
|
def commit
|
32
|
+
return if sha.nil?
|
30
33
|
@commit ||= Commit.new(sha, user, project)
|
31
34
|
end
|
35
|
+
|
36
|
+
def dump(file)
|
37
|
+
config = [user, project, started_at, finished_at, sha, status, output, pid]
|
38
|
+
data = YAML.dump(config)
|
39
|
+
File.open(file, 'wb') { |io| io.write(data) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.load(file)
|
43
|
+
if File.exist?(file)
|
44
|
+
config = YAML.load(File.read(file))
|
45
|
+
new *config
|
46
|
+
end
|
47
|
+
end
|
32
48
|
end
|
33
49
|
end
|
data/lib/cijoe/commit.rb
CHANGED
@@ -5,15 +5,15 @@ class CIJoe
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def author
|
8
|
-
raw_commit_lines
|
8
|
+
raw_commit_lines.grep(/Author:/).first.split(':', 2)[-1]
|
9
9
|
end
|
10
10
|
|
11
11
|
def committed_at
|
12
|
-
raw_commit_lines
|
12
|
+
raw_commit_lines.grep(/Date:/).first.split(':', 2)[-1]
|
13
13
|
end
|
14
14
|
|
15
15
|
def message
|
16
|
-
|
16
|
+
raw_commit.split("\n\n", 3)[1].to_s.strip
|
17
17
|
end
|
18
18
|
|
19
19
|
def raw_commit
|
data/lib/cijoe/config.rb
CHANGED
@@ -14,11 +14,29 @@ class CIJoe
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def to_s
|
17
|
-
|
17
|
+
git_command = "git config #{config_string}"
|
18
|
+
result = `#{git_command} 2>&1`.chomp
|
19
|
+
process_status = $?
|
20
|
+
|
21
|
+
if successful_command?(process_status) || config_command_with_empty_value?(result,process_status)
|
22
|
+
return result
|
23
|
+
else
|
24
|
+
raise "Error calling git config, is a recent version of git installed? Command: #{git_command}, Error: #{result}"
|
25
|
+
end
|
18
26
|
end
|
19
27
|
|
20
28
|
def config_string
|
21
29
|
@parent ? "#{@parent.config_string}.#{@command}" : @command
|
22
30
|
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def successful_command?(process_status)
|
35
|
+
process_status.exitstatus.to_i == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def config_command_with_empty_value?(result, process_status)
|
39
|
+
process_status.exitstatus.to_i == 1 && result.empty?
|
40
|
+
end
|
23
41
|
end
|
24
42
|
end
|
Binary file
|
data/lib/cijoe/server.rb
CHANGED
data/lib/cijoe/version.rb
CHANGED
data/test/helper.rb
ADDED
data/test/test_cijoe.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestCIJoe < Test::Unit::TestCase
|
4
|
+
def test_raise_error_on_invalid_command
|
5
|
+
assert_raise RuntimeError, LoadError do
|
6
|
+
CIJoe::Config.new('--invalid').to_s
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_return_value_of_config
|
11
|
+
assert_equal `git config blame`.chomp, CIJoe::Config.new('blame').to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_return_empty_string_when_config_does_not_exist
|
15
|
+
assert_equal '', CIJoe::Config.new('invalid').to_s
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cijoe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Wanstrath
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-24 00:00:00 -08:00
|
13
13
|
default_executable: cijoe
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,16 +32,6 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: "0"
|
34
34
|
version:
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: open4
|
37
|
-
type: :runtime
|
38
|
-
version_requirement:
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: "0"
|
44
|
-
version:
|
45
35
|
description: CI Joe is a simple Continuous Integration server.
|
46
36
|
email: chris@ozmm.org
|
47
37
|
executables:
|
@@ -52,21 +42,27 @@ extra_rdoc_files:
|
|
52
42
|
- LICENSE
|
53
43
|
- README.markdown
|
54
44
|
files:
|
45
|
+
- .gitignore
|
55
46
|
- LICENSE
|
56
47
|
- README.markdown
|
57
48
|
- Rakefile
|
58
49
|
- bin/cijoe
|
59
50
|
- deps.rip
|
51
|
+
- examples/cijoe.ru
|
52
|
+
- examples/cijoed
|
60
53
|
- lib/cijoe.rb
|
61
54
|
- lib/cijoe/build.rb
|
62
55
|
- lib/cijoe/campfire.rb
|
63
56
|
- lib/cijoe/commit.rb
|
64
57
|
- lib/cijoe/config.rb
|
58
|
+
- lib/cijoe/public/favicon.ico
|
65
59
|
- lib/cijoe/public/octocat.png
|
66
60
|
- lib/cijoe/public/screen.css
|
67
61
|
- lib/cijoe/server.rb
|
68
62
|
- lib/cijoe/version.rb
|
69
63
|
- lib/cijoe/views/template.erb
|
64
|
+
- test/helper.rb
|
65
|
+
- test/test_cijoe.rb
|
70
66
|
has_rdoc: true
|
71
67
|
homepage: http://github.com/defunkt/cijoe
|
72
68
|
licenses: []
|
@@ -95,5 +91,6 @@ rubygems_version: 1.3.5
|
|
95
91
|
signing_key:
|
96
92
|
specification_version: 3
|
97
93
|
summary: CI Joe is a simple Continuous Integration server.
|
98
|
-
test_files:
|
99
|
-
|
94
|
+
test_files:
|
95
|
+
- test/helper.rb
|
96
|
+
- test/test_cijoe.rb
|