ciquantum 0.0.16 → 0.0.17
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/bin/ciquantum +1 -0
- data/lib/ciquantum.rb +1 -0
- data/lib/ciquantum/build.rb +4 -4
- data/lib/ciquantum/commit.rb +6 -3
- data/lib/ciquantum/config.rb +4 -0
- data/lib/ciquantum/core.rb +39 -55
- data/lib/ciquantum/git.rb +64 -0
- data/lib/ciquantum/server.rb +13 -4
- data/lib/ciquantum/unfuddle.rb +13 -9
- data/lib/ciquantum/unfuddle/changeset.rb +1 -1
- data/lib/ciquantum/version.rb +1 -1
- data/lib/ciquantum/views/build.erb +1 -1
- data/lib/ciquantum/views/json.erb +2 -2
- data/lib/ciquantum/views/mailer/html.erb +1 -1
- data/lib/ciquantum/views/template.erb +18 -13
- metadata +3 -2
data/bin/ciquantum
CHANGED
data/lib/ciquantum.rb
CHANGED
data/lib/ciquantum/build.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
module CIQuantum
|
4
|
-
class Build < Struct.new(:project_path, :
|
4
|
+
class Build < Struct.new(:project_path, :started_at, :finished_at, :sha, :status, :output, :pid, :branch)
|
5
5
|
def initialize(*args)
|
6
6
|
super
|
7
7
|
self.started_at ||= Time.now
|
@@ -30,7 +30,7 @@ module CIQuantum
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def id
|
33
|
-
|
33
|
+
finished_at.to_i.to_s
|
34
34
|
end
|
35
35
|
|
36
36
|
def short_sha
|
@@ -52,7 +52,7 @@ module CIQuantum
|
|
52
52
|
|
53
53
|
def commit
|
54
54
|
return if sha.nil?
|
55
|
-
@commit ||= Commit.new(sha,
|
55
|
+
@commit ||= Commit.new(sha, project_path)
|
56
56
|
end
|
57
57
|
|
58
58
|
def test_results
|
@@ -68,7 +68,7 @@ module CIQuantum
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def dump file
|
71
|
-
config = [
|
71
|
+
config = [started_at, finished_at, sha, status, output, pid, branch]
|
72
72
|
data = YAML.dump(config)
|
73
73
|
File.open(file, 'wb') { |io| io.write(data) }
|
74
74
|
end
|
data/lib/ciquantum/commit.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module CIQuantum
|
2
|
-
class Commit < Struct.new(:sha, :
|
3
|
-
|
4
|
-
|
2
|
+
class Commit < Struct.new(:sha, :project_path)
|
3
|
+
|
4
|
+
attr_reader :url
|
5
|
+
|
6
|
+
def get_url! adapter
|
7
|
+
@url = adapter.commit_url self
|
5
8
|
end
|
6
9
|
|
7
10
|
def author
|
data/lib/ciquantum/config.rb
CHANGED
data/lib/ciquantum/core.rb
CHANGED
@@ -2,24 +2,26 @@ require 'fileutils'
|
|
2
2
|
|
3
3
|
module CIQuantum
|
4
4
|
class Core
|
5
|
-
attr_reader :
|
6
|
-
attr_reader :project
|
5
|
+
attr_reader :adapter
|
7
6
|
attr_reader :url
|
8
7
|
attr_reader :current_build
|
9
8
|
attr_reader :last_build
|
10
9
|
attr_reader :projectname
|
11
10
|
attr_reader :coverage_path
|
11
|
+
attr_reader :git
|
12
|
+
attr_reader :is_building
|
12
13
|
attr_accessor :shared_path
|
13
14
|
|
14
|
-
HistoryLimit =
|
15
|
+
HistoryLimit = 20
|
15
16
|
|
16
17
|
def initialize(project_path)
|
18
|
+
@is_building = false
|
17
19
|
@project_path = File.expand_path(project_path)
|
20
|
+
@adapter = Unfuddle.from_config(repo_config)
|
18
21
|
|
19
|
-
@user, @project = git_user_and_project
|
20
|
-
@url = project_url
|
21
22
|
@projectname = repo_config.projectname.to_s
|
22
23
|
@coverage_path = repo_config.coveragepath.to_s
|
24
|
+
@git = Git.new(@project_path)
|
23
25
|
|
24
26
|
@last_build = nil
|
25
27
|
@current_build = nil
|
@@ -28,23 +30,26 @@ module CIQuantum
|
|
28
30
|
trap("INT") { stop }
|
29
31
|
end
|
30
32
|
|
31
|
-
# is a build running?
|
32
33
|
def building?
|
33
34
|
!!@current_build
|
34
35
|
end
|
35
36
|
|
36
|
-
# the pid of the running child process
|
37
37
|
def pid
|
38
38
|
building? and current_build.pid
|
39
39
|
end
|
40
40
|
|
41
|
-
# kill the child and exit
|
42
41
|
def stop
|
43
|
-
|
42
|
+
stop_build
|
44
43
|
exit!
|
45
44
|
end
|
46
45
|
|
47
|
-
|
46
|
+
def stop_build
|
47
|
+
@is_building = false
|
48
|
+
Process.kill(9, @current_build.pid) if @current_build && @current_build.pid
|
49
|
+
write_build 'current', nil
|
50
|
+
@current_build = nil
|
51
|
+
end
|
52
|
+
|
48
53
|
def build_failed(output, error)
|
49
54
|
finish_build :failed, "#{error}\n\n#{output}"
|
50
55
|
run_hook "build-failed"
|
@@ -66,23 +71,28 @@ module CIQuantum
|
|
66
71
|
write_last_build
|
67
72
|
run_hook "postbuild"
|
68
73
|
save_coverage_for_build @last_build
|
74
|
+
@is_building = false
|
69
75
|
|
70
76
|
build(@queue.next_branch_to_build) if @queue.waiting?
|
71
77
|
end
|
72
78
|
|
73
79
|
def build(branch=nil)
|
80
|
+
branch ||= tracked_branch
|
81
|
+
puts "Preparing branch build with param:#{branch}"
|
74
82
|
if building?
|
75
83
|
@queue.append_unless_already_exists(branch)
|
76
|
-
# leave anyway because a current build runs
|
77
84
|
return
|
78
85
|
end
|
79
|
-
|
86
|
+
|
87
|
+
@is_building = true
|
88
|
+
@current_build = Build.new(@project_path)
|
80
89
|
write_current_build
|
81
90
|
|
82
91
|
Thread.new {
|
83
92
|
build!(branch)
|
84
93
|
}
|
85
94
|
|
95
|
+
@current_build = read_current_build
|
86
96
|
end
|
87
97
|
|
88
98
|
def open_pipe(cmd)
|
@@ -99,14 +109,13 @@ module CIQuantum
|
|
99
109
|
yield read, pid
|
100
110
|
end
|
101
111
|
|
102
|
-
|
103
|
-
def build!(branch=nil)
|
104
|
-
@git_branch = branch
|
112
|
+
def build!(branch)
|
105
113
|
build = @current_build
|
106
|
-
|
114
|
+
update_tracked_branch branch
|
115
|
+
@current_build = read_current_build
|
107
116
|
output = ''
|
108
|
-
build.sha =
|
109
|
-
build.branch =
|
117
|
+
build.sha = @git.sha
|
118
|
+
build.branch = @git.branch
|
110
119
|
write_build 'current', build
|
111
120
|
run_hook "prebuild"
|
112
121
|
|
@@ -135,26 +144,13 @@ module CIQuantum
|
|
135
144
|
runner == '' ? "rake -s --color test:units" : runner
|
136
145
|
end
|
137
146
|
|
138
|
-
def git_update
|
139
|
-
`cd #{@project_path} && git fetch origin && git reset --hard origin/#{git_branch} && git submodule update --init`
|
140
|
-
run_hook "after-reset"
|
141
|
-
end
|
142
|
-
|
143
|
-
def git_user_and_project
|
144
|
-
config = repo_config.send Unfuddle.name
|
145
|
-
Unfuddle.git_user_and_project config
|
146
|
-
end
|
147
|
-
|
148
|
-
def project_url
|
149
|
-
Unfuddle.project_url @user, @project
|
150
|
-
end
|
151
|
-
|
152
147
|
# massage our repo
|
153
148
|
def run_hook(hook)
|
154
149
|
file = path_in_project(".git/hooks/#{hook}")
|
155
150
|
if File.exists?(file) && File.executable?(file)
|
156
151
|
data =
|
157
152
|
if @last_build && @last_build.commit
|
153
|
+
@last_build.commit.get_url! @adapter
|
158
154
|
{
|
159
155
|
"MESSAGE" => @last_build.commit.message,
|
160
156
|
"AUTHOR" => @last_build.commit.author,
|
@@ -178,7 +174,6 @@ module CIQuantum
|
|
178
174
|
end
|
179
175
|
end
|
180
176
|
|
181
|
-
# restore current / last build state from disk.
|
182
177
|
def restore
|
183
178
|
@last_build = read_last_build
|
184
179
|
@current_build = read_current_build
|
@@ -217,27 +212,16 @@ module CIQuantum
|
|
217
212
|
Config.ciquantum(@project_path)
|
218
213
|
end
|
219
214
|
|
220
|
-
def
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
branches = `cd #{@project_path} && git branch -r`.split("\n")
|
226
|
-
branches.collect{|s| s =~ /(?:\s|^)origin\/(?!HEAD)(\w+)(?:\s|$)/ ? $1.strip : nil}.compact
|
215
|
+
def update_tracked_branch branch
|
216
|
+
new_branch = branch.strip
|
217
|
+
repo_config.branch.set new_branch
|
218
|
+
@tracked_branch = new_branch
|
219
|
+
@git.checkout new_branch
|
227
220
|
end
|
228
221
|
|
229
|
-
def
|
230
|
-
return @git_branch if @git_branch
|
222
|
+
def tracked_branch
|
231
223
|
branch = repo_config.branch.to_s
|
232
|
-
@
|
233
|
-
end
|
234
|
-
|
235
|
-
def is_current_git_branch? branch
|
236
|
-
return branch.eql? git_branch
|
237
|
-
end
|
238
|
-
|
239
|
-
def git_sha
|
240
|
-
`cd #{@project_path} && git rev-parse origin/#{git_branch}`.chomp
|
224
|
+
@tracked_branch ||= (branch.empty? ? "master" : branch.strip)
|
241
225
|
end
|
242
226
|
|
243
227
|
def read_build(name)
|
@@ -261,8 +245,8 @@ module CIQuantum
|
|
261
245
|
old_builds.each do |build_file|
|
262
246
|
build = read_build(build_file)
|
263
247
|
active_builds << build
|
264
|
-
if build.status == :worked
|
265
|
-
|
248
|
+
if build.status == :worked || active_builds.size >= HistoryLimit
|
249
|
+
remove_elder_builds build
|
266
250
|
break
|
267
251
|
end
|
268
252
|
end
|
@@ -287,7 +271,7 @@ module CIQuantum
|
|
287
271
|
|
288
272
|
def write_build(name, build)
|
289
273
|
filename = path_in_project(".git/builds/#{name}")
|
290
|
-
|
274
|
+
FileUtils.mkdir_p path_in_project('.git/builds')
|
291
275
|
if build
|
292
276
|
build.dump filename
|
293
277
|
elsif File.exist?(filename)
|
@@ -295,7 +279,7 @@ module CIQuantum
|
|
295
279
|
end
|
296
280
|
end
|
297
281
|
|
298
|
-
def
|
282
|
+
def remove_elder_builds limit_build
|
299
283
|
old_builds.each do |build_file|
|
300
284
|
build = read_build(build_file)
|
301
285
|
if build.finished_at < limit_build.finished_at
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module CIQuantum
|
2
|
+
class Git < Struct.new(:path)
|
3
|
+
|
4
|
+
def exec command
|
5
|
+
puts "Executing git command: #{command}"
|
6
|
+
res = `#{command}`
|
7
|
+
puts "Result for git command:\n#{res}"
|
8
|
+
res
|
9
|
+
end
|
10
|
+
|
11
|
+
def sha
|
12
|
+
exec("cd #{path} && git rev-parse origin/#{branch}").chomp
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
fetch
|
17
|
+
exec("cd #{path} && git reset --hard origin/#{branch} && git submodule update --init")
|
18
|
+
end
|
19
|
+
|
20
|
+
def branches
|
21
|
+
branches_to_list `cd #{path} && git branch -r`
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch
|
25
|
+
exec("cd #{path} && git fetch origin")
|
26
|
+
end
|
27
|
+
|
28
|
+
def branch
|
29
|
+
if !@branch && exec("cd #{path} && git branch 2>/dev/null | grep -e '\*' ") =~ /^\*\s(\w+)/
|
30
|
+
@branch = $1.strip
|
31
|
+
end
|
32
|
+
@branch
|
33
|
+
end
|
34
|
+
|
35
|
+
def is_current_branch? other_branch
|
36
|
+
return branch.eql? other_branch
|
37
|
+
end
|
38
|
+
|
39
|
+
def checkout other_branch
|
40
|
+
unless is_current_branch?(other_branch)
|
41
|
+
fetch
|
42
|
+
exec("cd #{path} && git checkout #{other_branch}") if branches.include?(other_branch)
|
43
|
+
@branch = nil
|
44
|
+
end
|
45
|
+
update
|
46
|
+
end
|
47
|
+
|
48
|
+
def branches_with_commit commit_sha
|
49
|
+
fetch
|
50
|
+
branches_to_list exec("cd #{path} && git branch -r --contains #{commit_sha}")
|
51
|
+
end
|
52
|
+
|
53
|
+
def current_branch_contains_commit? commit_sha
|
54
|
+
branches_with_commit(commit_sha).include?(branch)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def branches_to_list branch_output
|
59
|
+
raw_branches = branch_output.split("\n")
|
60
|
+
raw_branches.collect{|s| s =~ /^\s*(?:origin\/)?(\w+)\s*$/ ? $1.strip : nil}.compact.uniq
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/lib/ciquantum/server.rb
CHANGED
@@ -53,13 +53,20 @@ module CIQuantum
|
|
53
53
|
end
|
54
54
|
|
55
55
|
post '/build' do
|
56
|
-
|
56
|
+
puts "Building!"
|
57
|
+
quantum.build
|
57
58
|
redirect '/'
|
58
59
|
end
|
59
60
|
|
60
61
|
post '/switch_branch' do
|
61
|
-
|
62
|
-
quantum.build params[:branch]
|
62
|
+
puts "Switching branch! params: #{params.inspect}"
|
63
|
+
quantum.build params[:branch].strip
|
64
|
+
redirect '/'
|
65
|
+
end
|
66
|
+
|
67
|
+
post '/cancel_build' do
|
68
|
+
puts "Stop build!"
|
69
|
+
quantum.stop_build
|
63
70
|
redirect '/'
|
64
71
|
end
|
65
72
|
|
@@ -78,7 +85,9 @@ module CIQuantum
|
|
78
85
|
begin
|
79
86
|
xml = request.body.read
|
80
87
|
changeset = Unfuddle::Changeset.new(xml)
|
81
|
-
quantum.
|
88
|
+
if quantum.git.current_branch_contains_commit? changeset.commit
|
89
|
+
quantum.build
|
90
|
+
end
|
82
91
|
rescue Unfuddle::ChangesetError => e
|
83
92
|
logger.error "[error] Changeset error: #{e.inspect}, Content: #{xml.inspect}"
|
84
93
|
halt 400, "Changeset Error: #{e.message}"
|
data/lib/ciquantum/unfuddle.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
module CIQuantum
|
2
|
-
|
2
|
+
class Unfuddle < Struct.new(:config)
|
3
3
|
|
4
|
-
def self.
|
5
|
-
|
4
|
+
def self.config_name
|
5
|
+
'unfuddle'
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.
|
9
|
-
|
8
|
+
def self.from_config config
|
9
|
+
self.new config[config_name]
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def commit_url commit
|
13
|
+
"http://#{config.user}.unfuddle.com/a#/repositories/#{config.project}/commit?commit=#{commit.sha}"
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
"https://#{user}.unfuddle.com/a#/repositories/#{project}/browse"
|
16
|
+
def url
|
17
|
+
"https://#{config.user}.unfuddle.com/a#/repositories/#{config.project}/browse"
|
18
|
+
end
|
19
|
+
|
20
|
+
def [] command
|
21
|
+
return @config[command]
|
18
22
|
end
|
19
23
|
|
20
24
|
end
|
data/lib/ciquantum/version.rb
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
<% end %>
|
13
13
|
<div class="results">
|
14
14
|
<h4 class="result">Test results: <%= build.test_results %></h4>
|
15
|
-
<a href="<%= quantum.coverage_for_build(build) %>">Show coverage</a> |
|
15
|
+
<a href="<%= quantum.coverage_for_build(build) %>">Show coverage</a> |
|
16
16
|
<a href="#" onclick="toggleVisibility('<%= build.id %>')">Show output</a>
|
17
17
|
<div id="<%= build.id %>" style="display:none">
|
18
18
|
<pre class="terminal"><code><%= ansi_color_codes h(build.output) %></code></pre>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<% if quantum.last_build %>
|
4
4
|
{
|
5
5
|
"name":"<%= quantum.projectname || quantum.project %>",
|
6
|
-
"url":"<%= quantum.url %>",
|
6
|
+
"url":"<%= quantum.adapter.url %>",
|
7
7
|
"color":"<%= quantum.last_build.status.to_s == "failed" ? 'red' : 'blue' %>",
|
8
8
|
"status":"<%= quantum.last_build.status %>",
|
9
9
|
"started_at":"<%= pretty_time(quantum.last_build.started_at) %>",
|
@@ -11,7 +11,7 @@
|
|
11
11
|
"duration":"<%= quantum.last_build.duration if quantum.last_build.duration %>",
|
12
12
|
"sha":"<%= quantum.last_build.sha %>",
|
13
13
|
"short_sha":"<%= quantum.last_build.short_sha %>",
|
14
|
-
"commit_url":"<%= quantum.last_build.commit
|
14
|
+
"commit_url":"<%= quantum.adapter_commit_url(quantum.last_build.commit) if quantum.last_build.commit %>",
|
15
15
|
"branch":"<%= quantum.last_build.branch %>"
|
16
16
|
}
|
17
17
|
<% end %>
|
@@ -15,28 +15,32 @@
|
|
15
15
|
<div id="home">
|
16
16
|
<h1><a href="<%= quantum.url %>"><%= quantum.projectname %></a></h1>
|
17
17
|
<ul class="posts">
|
18
|
-
<% if quantum.
|
18
|
+
<% if quantum.is_building %>
|
19
19
|
<li>
|
20
|
-
<span class="date"><%= pretty_time(quantum.current_build
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
<span class="date"><%= pretty_time(quantum.current_build ? quantum.current_build.started_at : Time.now) %></span> »
|
21
|
+
Current branch: <%= quantum.git.branch %>.
|
22
|
+
<% if quantum.current_build %>
|
23
|
+
Building <%= quantum.current_build.branch %> at <a href="<%= quantum.current_build.commit.url %>"><%= quantum.current_build.short_sha %></a> <small>(pid: <%= quantum.pid %>)</small>
|
24
|
+
<% else %>
|
25
|
+
Build starting...
|
26
|
+
<% end %>
|
27
|
+
<form method="POST" action="/cancel_build">
|
28
|
+
<input type="submit" name="cancel" value="Cancel"/>
|
29
|
+
</form>
|
26
30
|
</li>
|
27
31
|
<% else %>
|
28
32
|
<li>
|
29
33
|
<form method="POST" action="/build">
|
30
|
-
<span class="branch">Current branch: <%= quantum.
|
31
|
-
<input type="submit" name="
|
34
|
+
<span class="branch">Current branch: <%= quantum.git.branch %></span>
|
35
|
+
<input type="submit" name="build" value="Build"/>
|
32
36
|
</form>
|
33
37
|
</li>
|
34
38
|
<li>
|
35
39
|
<% if can_change_branch %>
|
36
40
|
<form method="POST" action="/switch_branch">
|
37
41
|
<select name="branch">
|
38
|
-
<% for @branch in quantum.
|
39
|
-
<option value="<%= @branch %>" <%= 'selected="selected"' if quantum.
|
42
|
+
<% for @branch in quantum.git.branches %>
|
43
|
+
<option value="<%= @branch %>" <%= 'selected="selected"' if quantum.git.is_current_branch?(@branch.strip) %>>"<%= @branch %>"</option>
|
40
44
|
<% end %>
|
41
45
|
</select>
|
42
46
|
<input type="submit" name="switch" value="Switch branch and build"/>
|
@@ -45,8 +49,9 @@
|
|
45
49
|
</li>
|
46
50
|
<% end %>
|
47
51
|
|
48
|
-
<%
|
49
|
-
|
52
|
+
<% builds = quantum.active_builds %>
|
53
|
+
<% if ! builds.empty?%>
|
54
|
+
<% for @build in builds %>
|
50
55
|
<ul><%= erb(:build, {}, :quantum => quantum, :build => @build) %></ul>
|
51
56
|
<% end %>
|
52
57
|
<% end %>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ciquantum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.17
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-06-
|
14
|
+
date: 2012-06-22 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -197,6 +197,7 @@ files:
|
|
197
197
|
- lib/ciquantum/commit.rb
|
198
198
|
- lib/ciquantum/config.rb
|
199
199
|
- lib/ciquantum/core.rb
|
200
|
+
- lib/ciquantum/git.rb
|
200
201
|
- lib/ciquantum/public/javascript.js
|
201
202
|
- lib/ciquantum/public/screen.css
|
202
203
|
- lib/ciquantum/queue.rb
|