perkins 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.ruby-version +1 -0
- data/.vagrant/machines/default/virtualbox/action_provision +1 -0
- data/.vagrant/machines/default/virtualbox/action_set_name +1 -0
- data/.vagrant/machines/default/virtualbox/id +1 -0
- data/Gemfile +0 -1
- data/README.md +11 -4
- data/Rakefile +3 -2
- data/TODO.md +2 -2
- data/Vagrantfile +53 -0
- data/db/migrate/20150220143050_add_status_fields_to_repos.rb +11 -0
- data/db/schema.rb +3 -1
- data/examples/Gemfile +4 -0
- data/examples/Gemfile.lock +164 -0
- data/examples/Procfile +4 -0
- data/examples/boot.rb +15 -0
- data/examples/config.ru +22 -0
- data/examples/database.yml +2 -2
- data/examples/sidekiq.yml +9 -0
- data/lib/core_ext/string/color.rb +22 -0
- data/lib/perkins/application.rb +27 -3
- data/lib/perkins/assets/images/error.gif +0 -0
- data/lib/perkins/assets/images/working.gif +0 -0
- data/lib/perkins/assets/javascripts/app.js +17 -1
- data/lib/perkins/assets/javascripts/config.js.coffee +14 -0
- data/lib/perkins/assets/javascripts/log_view.js.coffee +1 -2
- data/lib/perkins/assets/javascripts/perkings.js.coffee +129 -20
- data/lib/perkins/assets/javascripts/perkins/helpers.js.coffee +21 -0
- data/lib/perkins/assets/javascripts/perkins/m/models.js.coffee +50 -0
- data/lib/perkins/assets/javascripts/perkins/router.js.coffee +10 -0
- data/lib/perkins/assets/javascripts/perkins/v/dashboard.js.coffee +17 -0
- data/lib/perkins/assets/javascripts/perkins/v/err.js.coffee +12 -0
- data/lib/perkins/assets/javascripts/perkins/v/menu.js.coffee +10 -0
- data/lib/perkins/assets/javascripts/perkins/v/my_repos.js.coffee +41 -0
- data/lib/perkins/assets/javascripts/perkins/v/orgs.js.coffee +39 -0
- data/lib/perkins/assets/javascripts/perkins/v/profile.js.coffee +20 -0
- data/lib/perkins/assets/javascripts/perkins/v/repo.js.coffee +192 -0
- data/lib/perkins/assets/javascripts/perkins/v/sidebar.js.coffee +33 -0
- data/lib/perkins/assets/javascripts/templates/dashboard.hamlc +11 -0
- data/lib/perkins/assets/javascripts/templates/error.hamlc +22 -0
- data/lib/perkins/assets/javascripts/templates/menu.hamlc +18 -0
- data/lib/perkins/assets/javascripts/templates/org.hamlc +77 -0
- data/lib/perkins/assets/javascripts/templates/profile.hamlc +28 -0
- data/lib/perkins/assets/javascripts/templates/repo.hamlc +37 -0
- data/lib/perkins/assets/javascripts/templates/repos/build_row.hamlc +19 -0
- data/lib/perkins/assets/javascripts/templates/repos/builds.hamlc +25 -0
- data/lib/perkins/assets/javascripts/templates/repos/config.hamlc +77 -0
- data/lib/perkins/assets/javascripts/templates/repos/gb_repo.hamlc +31 -0
- data/lib/perkins/assets/javascripts/templates/repos/github.hamlc +7 -0
- data/lib/perkins/assets/javascripts/templates/repos/menu.hamlc +17 -0
- data/lib/perkins/assets/javascripts/templates/repos/report_detail.hamlc +53 -0
- data/lib/perkins/assets/javascripts/templates/sidebar.hamlc +14 -0
- data/lib/perkins/assets/javascripts/templates/sidebar_repo.hamlc +4 -0
- data/lib/perkins/assets/javascripts/vendor/backbone-min.js +2 -0
- data/lib/perkins/assets/javascripts/vendor/backbone.marionette.js +2891 -0
- data/lib/perkins/assets/javascripts/vendor/hamlcoffee.js.coffee.erb +138 -0
- data/lib/perkins/assets/javascripts/vendor/livequery.jquery.js +8 -0
- data/lib/perkins/assets/javascripts/vendor/log.js +1 -1
- data/lib/perkins/assets/javascripts/vendor/md5.js +207 -0
- data/lib/perkins/assets/javascripts/vendor/nprogress.js +476 -0
- data/lib/perkins/assets/javascripts/vendor/underscore.js +6 -0
- data/lib/perkins/assets/stylesheets/app.css +3 -0
- data/lib/perkins/assets/stylesheets/bootstrap-overrides.css.scss +13 -0
- data/lib/perkins/assets/stylesheets/styles.css.scss +30 -3
- data/lib/perkins/assets/stylesheets/vendor/nprogress.css +74 -0
- data/lib/perkins/assets.rb +42 -0
- data/lib/perkins/build/script/ruby.rb +1 -1
- data/lib/perkins/build_report.rb +13 -0
- data/lib/perkins/{worker.rb → build_worker.rb} +9 -5
- data/lib/perkins/cli.rb +4 -2
- data/lib/perkins/commit.rb +8 -1
- data/lib/perkins/git_loader_worker.rb +29 -0
- data/lib/perkins/repo.rb +23 -9
- data/lib/perkins/runner.rb +16 -25
- data/lib/perkins/server.rb +121 -116
- data/lib/perkins/version.rb +1 -1
- data/lib/perkins/views/builds.haml +0 -3
- data/lib/perkins/views/layout.haml +25 -36
- data/lib/perkins/views/menu.haml +1 -1
- data/lib/perkins/views/repos/github.haml +0 -31
- data/lib/perkins/views/repos/repo.haml +1 -1
- data/lib/perkins.rb +4 -2
- data/perkins.gemspec +5 -2
- data/spec/lib/repo_spec.rb +27 -6
- data/spec/lib/runner_spec.rb +1 -0
- data/spec/lib/server_spec.rb +6 -23
- data/spec/spec_helper.rb +14 -3
- metadata +160 -70
- data/examples/config.rb +0 -12
- data/examples/mongo.yml +0 -13
- data/lib/perkins/listener.rb +0 -38
- data/spec/lib/listener_spec.rb +0 -30
data/lib/perkins/server.rb
CHANGED
@@ -9,48 +9,11 @@ require 'coffee_script'
|
|
9
9
|
require "sass"
|
10
10
|
require "rdiscount"
|
11
11
|
require "perkins/auth/github"
|
12
|
+
require "perkins/assets"
|
13
|
+
require "eventmachine"
|
12
14
|
|
13
15
|
module Perkins
|
14
16
|
|
15
|
-
class Assets < Sinatra::Base
|
16
|
-
|
17
|
-
configure do
|
18
|
-
set :assets, (Sprockets::Environment.new { |env|
|
19
|
-
env.append_path(settings.root + "/assets/images")
|
20
|
-
env.append_path(settings.root + "/assets/javascripts")
|
21
|
-
env.append_path(settings.root + "/assets/stylesheets")
|
22
|
-
# compress everything in production
|
23
|
-
if ENV["RACK_ENV"] == "production"
|
24
|
-
env.js_compressor = YUI::JavaScriptCompressor.new
|
25
|
-
env.css_compressor = YUI::CssCompressor.new
|
26
|
-
end
|
27
|
-
})
|
28
|
-
end
|
29
|
-
|
30
|
-
get "/assets/app.js" do
|
31
|
-
content_type("application/javascript")
|
32
|
-
settings.assets["app.js"]
|
33
|
-
end
|
34
|
-
|
35
|
-
get "/assets/app.css" do
|
36
|
-
content_type("text/css")
|
37
|
-
settings.assets["app.css"]
|
38
|
-
end
|
39
|
-
|
40
|
-
%w{jpg png}.each do |format|
|
41
|
-
get "/assets/:image.#{format}" do |image|
|
42
|
-
content_type("image/#{format}")
|
43
|
-
settings.assets["#{image}.#{format}"]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
get "/assets/:image.svg" do |image|
|
48
|
-
content_type("image/svg+xml")
|
49
|
-
settings.assets["#{image}.svg"]
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
17
|
class Server < Sinatra::Application
|
55
18
|
|
56
19
|
attr_reader :app
|
@@ -61,12 +24,30 @@ module Perkins
|
|
61
24
|
#set :environment, :production
|
62
25
|
set :session_secret, '*&(^B234'
|
63
26
|
|
27
|
+
configure :development do
|
28
|
+
#register Sinatra::Reloader
|
29
|
+
end
|
30
|
+
|
64
31
|
use Perkins::Assets
|
65
32
|
|
66
33
|
register Perkins::Auth::Github
|
67
34
|
|
35
|
+
#authenticate all -
|
36
|
+
before do
|
37
|
+
unless %w[stream sse logout unauthenticated /auth/github/callback /repos/receiver badge].include? request.path_info.split('/')[1]
|
38
|
+
authenticate!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#render index if not ajax request!
|
43
|
+
before do
|
44
|
+
return if %w[stream sse logout unauthenticated /auth/github/callback /repos/receiver badge config].include? request.path_info.split('/')[1]
|
45
|
+
unless request.xhr?
|
46
|
+
halt 200, haml( :index , locals: default_data)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
68
50
|
get '/' do
|
69
|
-
authenticate!
|
70
51
|
haml :index , locals: default_data
|
71
52
|
end
|
72
53
|
|
@@ -74,19 +55,23 @@ module Perkins
|
|
74
55
|
settings.perkins_application.to_json
|
75
56
|
end
|
76
57
|
|
77
|
-
get '/repos/sync' do
|
78
|
-
|
58
|
+
#get '/repos/sync' do
|
59
|
+
# @github_repos = build_data
|
60
|
+
#end
|
61
|
+
|
62
|
+
get '/repos' do
|
63
|
+
content_type :json
|
64
|
+
repos = Perkins::Repo.added.all
|
65
|
+
repos.to_json
|
79
66
|
end
|
80
67
|
|
81
68
|
post '/repos/receiver' do
|
82
69
|
#NEEDS VALIDATIONS
|
83
70
|
payload = JSON.parse request.body.read
|
84
71
|
repo = Perkins::Repo.added.find_by(gb_id: payload["repository"]["id"])
|
85
|
-
repo.load_git
|
86
|
-
|
72
|
+
#repo.load_git
|
87
73
|
pushed_branch = payload["ref"].split('/').last
|
88
74
|
repo.add_commit(payload["after"], pushed_branch)
|
89
|
-
#binding.pry
|
90
75
|
"received post #{payload}"
|
91
76
|
end
|
92
77
|
|
@@ -96,42 +81,57 @@ module Perkins
|
|
96
81
|
Repo.sync_github_repo(repo)
|
97
82
|
r = Repo.add_from_github(params[:id])
|
98
83
|
r.to_json
|
99
|
-
redirect "/me"
|
100
84
|
end
|
101
85
|
|
102
86
|
get '/repos/:login/:name' do
|
87
|
+
content_type :json
|
103
88
|
repo = find_repo(params)
|
104
|
-
|
105
|
-
|
89
|
+
#detects a recently added repo (no dir and no prev builds)
|
90
|
+
enqueue_git_clone(repo) if !repo.exists? && repo.last_report_id.blank?
|
91
|
+
repo.as_json(methods: [:last_report_id, :http_url]).to_json
|
92
|
+
end
|
93
|
+
|
94
|
+
get '/badge' do
|
95
|
+
content_type "image/svg+xml"
|
96
|
+
repo = Repo.find_by(name: params[:repo])
|
97
|
+
build = repo.build_reports.last
|
98
|
+
request_badge({status: build.status ? "passing" : "error" , color: build.status ? "green" : "red" })
|
106
99
|
end
|
107
100
|
|
108
101
|
get '/repos/:login/:name/builds' do
|
102
|
+
content_type :json
|
109
103
|
repo = find_repo(params)
|
110
|
-
|
104
|
+
#respond or delay git load
|
105
|
+
repo.exists? ? repo.build_reports.to_json : enqueue_git_clone(repo)
|
111
106
|
end
|
112
107
|
|
113
108
|
get '/repos/:login/:name/builds/:build_id' do
|
109
|
+
content_type :json
|
114
110
|
repo = find_repo(params)
|
115
111
|
record = repo.build_reports.find(params[:build_id])
|
116
|
-
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
get '/repos/:login/:name/run_commit' do
|
121
|
-
repo = find_repo(params)
|
122
|
-
sha = repo.git.log.map(&:sha).first
|
123
|
-
repo.add_commit(sha, "master")
|
124
|
-
redirect "/repos/#{repo.name}"
|
112
|
+
#record.to_json
|
113
|
+
repo.exists? ? record.to_json : enqueue_git_clone(repo)
|
125
114
|
end
|
126
115
|
|
127
116
|
get '/repos/:login/:name/config' do
|
117
|
+
content_type :json
|
128
118
|
repo = find_repo(params)
|
129
119
|
#find by id
|
130
120
|
hook = github_user.api.hooks("#{repo.name}").detect{|o| o[:name] == "web"}
|
121
|
+
hook.to_attrs.to_json
|
122
|
+
end
|
131
123
|
|
132
|
-
|
124
|
+
#TODO send this through bg job
|
125
|
+
get '/repos/:login/:name/run_commit' do
|
126
|
+
content_type :json
|
127
|
+
repo = find_repo(params)
|
128
|
+
repo.load_git
|
129
|
+
sha = repo.git.log.map(&:sha).first
|
130
|
+
repo.add_commit(sha, "master")
|
131
|
+
repo.to_json
|
133
132
|
end
|
134
133
|
|
134
|
+
#TODO for json
|
135
135
|
post '/repos/:login/:name/add_hook' do
|
136
136
|
repo = find_repo(params)
|
137
137
|
hook = github_user.api.hooks("#{repo.name}").detect{|o| o[:name] == "web"}
|
@@ -155,56 +155,52 @@ module Perkins
|
|
155
155
|
end
|
156
156
|
|
157
157
|
get '/repos/:login/:name/builds/:build_id/restart' do
|
158
|
+
content_type :json
|
158
159
|
repo = find_repo(params)
|
160
|
+
#repo.load_git
|
159
161
|
record = repo.build_reports.find(params[:build_id])
|
160
162
|
repo.add_commit(record['sha'], record['branch'])
|
161
|
-
|
162
|
-
end
|
163
|
-
|
164
|
-
get '/stream', provides: 'text/event-stream' do
|
165
|
-
stream :keep_open do |out|
|
166
|
-
settings.connections << out
|
167
|
-
out.callback { settings.connections.delete(out) }
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
post '/sse' do
|
172
|
-
settings.connections.each { |out| out << "data: #{params[:msg]}\n\n" }
|
173
|
-
204 # response without entity body
|
163
|
+
record.to_json
|
174
164
|
end
|
175
165
|
|
176
166
|
get '/me' do
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
#"Hello There, #{github_user.name}! You have access to the #{params['id']} organization."
|
183
|
-
end
|
184
|
-
|
185
|
-
get '/myrepos' do
|
186
|
-
authenticate!
|
187
|
-
repos = github_user.api.repos
|
188
|
-
haml :"repos/github", locals: { user: github_user.api, repos: repos }
|
167
|
+
content_type :json
|
168
|
+
a = github_user.api
|
169
|
+
@user = a.user
|
170
|
+
@orgs = a.orgs.map(&:login)
|
171
|
+
@user.to_attrs.merge({orgs: @orgs}).to_json
|
189
172
|
end
|
190
173
|
|
191
174
|
get '/orgs/:id' do
|
175
|
+
content_type :json
|
192
176
|
github_organization_authenticate!(params['id'])
|
193
|
-
#"Hello There, #{github_user.name}! You have access to the #{params['id']} organization."
|
194
177
|
org = github_user.api.organization(params['id'])
|
195
|
-
orgs = github_user.api.orgs
|
196
|
-
repos = github_user.api.org_repos(params["id"])
|
197
|
-
|
178
|
+
#orgs = github_user.api.orgs
|
179
|
+
repos = github_user.api.org_repos(params["id"]).map(&:to_attrs)
|
180
|
+
org.to_attrs.merge({repos: repos}).to_json
|
198
181
|
end
|
199
182
|
|
200
|
-
|
201
|
-
|
202
|
-
|
183
|
+
#TODO for json
|
184
|
+
get '/myrepos' do
|
185
|
+
repos = github_user.api.repos.map(&:to_attrs)
|
186
|
+
github_user.api.user.to_attrs.merge({repos: repos}).to_json
|
203
187
|
end
|
204
188
|
|
205
|
-
|
206
|
-
|
207
|
-
|
189
|
+
|
190
|
+
get '/stream', provides: 'text/event-stream' do
|
191
|
+
stream :keep_open do |out|
|
192
|
+
#EM.run {
|
193
|
+
# EventMachine::PeriodicTimer.new(20) { out << "data: \n\n" } # added
|
194
|
+
#}
|
195
|
+
settings.connections << out
|
196
|
+
out.callback { settings.connections.delete(out) }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
post '/sse' do
|
201
|
+
puts "connections #{settings.connections.size}".yellow
|
202
|
+
settings.connections.each { |out| out << "data: #{params[:msg]}\n\n" }
|
203
|
+
204 # response without entity body
|
208
204
|
end
|
209
205
|
|
210
206
|
get '/logout' do
|
@@ -212,11 +208,17 @@ module Perkins
|
|
212
208
|
redirect 'https://github.com'
|
213
209
|
end
|
214
210
|
|
215
|
-
def initialize(
|
211
|
+
def initialize(args={})
|
216
212
|
super
|
217
|
-
|
218
|
-
#
|
219
|
-
|
213
|
+
return if args.blank?
|
214
|
+
puts "PerkinsCI environment loaded on #{args[:host]}:#{args[:port]}".green
|
215
|
+
app = Perkins::Application.instance
|
216
|
+
self.class.set :perkins_application, app
|
217
|
+
self.class.set :github_options, {
|
218
|
+
:scopes => "admin:repo_hook,repo,user:email",
|
219
|
+
:secret => app.github_client_secret,
|
220
|
+
:client_id => app.github_client_id,
|
221
|
+
}
|
220
222
|
end
|
221
223
|
|
222
224
|
def github_repos
|
@@ -235,26 +237,32 @@ module Perkins
|
|
235
237
|
def find_repo(params)
|
236
238
|
id = "#{params[:login]}/#{params[:name]}"
|
237
239
|
repo = Repo.find_by(name: id)
|
238
|
-
repo.load_git
|
240
|
+
#repo.load_git #it seems that we dont need this here
|
239
241
|
repo
|
240
242
|
end
|
241
243
|
|
242
|
-
def
|
244
|
+
def enqueue_git_clone(repo)
|
245
|
+
GitLoaderWorker.perform_async(repo.id )
|
246
|
+
end
|
247
|
+
|
248
|
+
def request_badge(opts={})
|
249
|
+
begin
|
250
|
+
url = URI.parse("https://img.shields.io/badge/build-#{opts[:status]}-#{opts[:color]}.svg?style=flat-square")
|
251
|
+
result = Net::HTTP.get(url)
|
252
|
+
rescue => e
|
253
|
+
e
|
254
|
+
end
|
255
|
+
end
|
243
256
|
|
257
|
+
####################################
|
258
|
+
#TODO: deprecate this
|
259
|
+
def self.start(app, options)
|
244
260
|
options = options.dup
|
245
261
|
ENV['RACK_ENV'] = options.delete("e")
|
246
262
|
|
247
|
-
app = eval(File.open(config_file).read)
|
248
|
-
self.start_listener(app)
|
249
|
-
|
250
|
-
set :perkins_application, app
|
251
|
-
set :github_options, {
|
252
|
-
:scopes => "admin:repo_hook,repo,user:email",
|
253
|
-
:secret => app.github_client_secret,
|
254
|
-
:client_id => app.github_client_id,
|
255
|
-
}
|
256
|
-
|
257
263
|
register Sinatra::ActiveRecordExtension
|
264
|
+
app = app.is_a?(String) ? eval(File.open(app).read) : app
|
265
|
+
self.start_listener(app)
|
258
266
|
|
259
267
|
configure :development do
|
260
268
|
#register Sinatra::Reloader
|
@@ -269,7 +277,8 @@ module Perkins
|
|
269
277
|
#set :database, 'sqlite:///db/test.sqlite3'
|
270
278
|
end
|
271
279
|
|
272
|
-
Perkins::Server.run!
|
280
|
+
#::Perkins::Server.run!(options)
|
281
|
+
|
273
282
|
end
|
274
283
|
|
275
284
|
def self.start_listener(app_config)
|
@@ -279,11 +288,8 @@ module Perkins
|
|
279
288
|
listener.run!
|
280
289
|
end
|
281
290
|
end
|
291
|
+
####################################
|
282
292
|
|
283
|
-
##use in rack
|
284
|
-
##And a corresponding config.ru:
|
285
|
-
#require './app'
|
286
|
-
#run Sinatra::Application
|
287
293
|
def default_data
|
288
294
|
{author: "miguel michelson", year: Time.now.year, app: @app}
|
289
295
|
end
|
@@ -299,7 +305,6 @@ module Perkins
|
|
299
305
|
status ? "glyphicon glyphicon-ok" : "glyphicon glyphicon-remove"
|
300
306
|
end
|
301
307
|
|
302
|
-
|
303
308
|
def avatar_url(email, size)
|
304
309
|
gravatar_id = Digest::MD5.hexdigest(email.downcase)
|
305
310
|
"http://gravatar.com/avatar/#{gravatar_id}.png?s=#{size}"
|
data/lib/perkins/version.rb
CHANGED
@@ -15,39 +15,28 @@
|
|
15
15
|
minispade.require('log')
|
16
16
|
|
17
17
|
%body
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
.clearfix
|
45
|
-
#footer
|
46
|
-
-#= render 'footer'
|
47
|
-
.pull-right
|
48
|
-
Copyright © #{Time.now.year} Perkins
|
49
|
-
%strong
|
50
|
-
Redis connection:
|
51
|
-
%span
|
52
|
-
= $redis.client.host
|
53
|
-
= $redis.client.port
|
18
|
+
#perkins-layout
|
19
|
+
%nav#main-menu.navbar.navbar-fixed-top{role:"navigation"}
|
20
|
+
|
21
|
+
-#= haml :menu
|
22
|
+
|
23
|
+
.container
|
24
|
+
#content
|
25
|
+
#left-wrap.col-sm-3
|
26
|
+
#sidebar.affix.col-sm-3
|
27
|
+
|
28
|
+
#main-content.col-sm-9
|
29
|
+
-#= yield
|
30
|
+
|
31
|
+
#inner
|
32
|
+
|
33
|
+
.clearfix
|
34
|
+
#footer
|
35
|
+
-#= render 'footer'
|
36
|
+
.pull-right
|
37
|
+
Copyright © #{Time.now.year} Perkins
|
38
|
+
%strong
|
39
|
+
Redis connection:
|
40
|
+
%span
|
41
|
+
= $redis.client.host
|
42
|
+
= $redis.client.port
|
data/lib/perkins/views/menu.haml
CHANGED
@@ -6,37 +6,6 @@
|
|
6
6
|
%span.glyphicon.glyphicon-refresh
|
7
7
|
SYNC
|
8
8
|
|
9
|
-
-#
|
10
|
-
- repos.each do |repo|
|
11
|
-
%ul.list-group
|
12
|
-
%li.list-group-item
|
13
|
-
|
14
|
-
.pull-right
|
15
|
-
%a.btn{href: "/repos/add/#{repo.gb_id}"}
|
16
|
-
ADD REPO
|
17
|
-
%span.btn.glyphicon.glyphicon-plus-sign
|
18
|
-
|
19
|
-
.row
|
20
|
-
%span.col-sm-1
|
21
|
-
%a{src: repo.github_data["owner"]["url"] }
|
22
|
-
%img{ src: repo.github_data["owner"]["avatar_url"], width: 66 }
|
23
|
-
%span.col-sm-8
|
24
|
-
%h4= repo.name
|
25
|
-
%a{href: repo.url}
|
26
|
-
view on github
|
27
|
-
%p
|
28
|
-
.clearfix
|
29
|
-
.well
|
30
|
-
%p= repo.github_data["description"]
|
31
|
-
-#
|
32
|
-
%p
|
33
|
-
clone url:
|
34
|
-
= repo.github_data["clone_url"]
|
35
|
-
|
36
|
-
%span
|
37
|
-
= repo.github_data["fork"]
|
38
|
-
= repo.github_data["private"]
|
39
|
-
|
40
9
|
- if repos.any?
|
41
10
|
%h2 Repositories:
|
42
11
|
|
data/lib/perkins.rb
CHANGED
@@ -7,12 +7,14 @@ require 'redis'
|
|
7
7
|
require 'redis-namespace'
|
8
8
|
require "travis/yaml"
|
9
9
|
require "active_record"
|
10
|
+
require "sidekiq"
|
10
11
|
|
11
12
|
require 'dotenv'
|
12
13
|
Dotenv.load
|
13
14
|
require 'octokit'
|
14
15
|
Octokit.auto_paginate = true
|
15
16
|
#require 'core_ext/hash/deep_symbolize_keys'
|
17
|
+
require 'core_ext/string/color'
|
16
18
|
|
17
19
|
module Perkins
|
18
20
|
autoload :VERSION, 'perkins/version.rb'
|
@@ -22,8 +24,8 @@ module Perkins
|
|
22
24
|
autoload :Build, 'perkins/build.rb'
|
23
25
|
autoload :Commit, 'perkins/commit.rb'
|
24
26
|
autoload :Server, 'perkins/server.rb'
|
25
|
-
autoload :
|
26
|
-
autoload :
|
27
|
+
autoload :BuildWorker, 'perkins/build_worker.rb'
|
28
|
+
autoload :GitLoaderWorker, 'perkins/git_loader_worker.rb'
|
27
29
|
autoload :ThorUtils, 'perkins/thor_utils.rb'
|
28
30
|
autoload :Logger, 'perkins/logger.rb'
|
29
31
|
autoload :Application, 'perkins/application.rb'
|
data/perkins.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Perkins::VERSION
|
9
9
|
spec.authors = ["miguel michelson"]
|
10
10
|
spec.email = ["miguelmichelson@gmail.com"]
|
11
|
-
spec.summary = "
|
12
|
-
spec.description = "
|
11
|
+
spec.summary = "A travis compatible standalone CI solution for ruby"
|
12
|
+
spec.description = "Continous integration solution compatible with travis.ci"
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -33,11 +33,14 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_runtime_dependency("sinatra")
|
34
34
|
spec.add_runtime_dependency("haml")
|
35
35
|
spec.add_runtime_dependency("sprockets")
|
36
|
+
spec.add_runtime_dependency("haml_coffee_assets")
|
36
37
|
spec.add_runtime_dependency("yui-compressor")
|
37
38
|
spec.add_runtime_dependency("rdiscount")
|
38
39
|
spec.add_runtime_dependency("travis-yaml")
|
39
40
|
spec.add_runtime_dependency("redis-namespace")
|
40
41
|
spec.add_runtime_dependency("thin")
|
42
|
+
spec.add_runtime_dependency("sidekiq")
|
43
|
+
spec.add_runtime_dependency("dotenv-rails")
|
41
44
|
|
42
45
|
spec.add_dependency "warden-github", "~>1.0"
|
43
46
|
|
data/spec/lib/repo_spec.rb
CHANGED
@@ -47,6 +47,22 @@ describe "Repo" do
|
|
47
47
|
#expect(r.local_path).to_not be_blank
|
48
48
|
end
|
49
49
|
|
50
|
+
context "load git" do
|
51
|
+
before :each do
|
52
|
+
@repo = Perkins::Repo.first
|
53
|
+
end
|
54
|
+
|
55
|
+
it "will not be downloaded" do
|
56
|
+
expect(@repo.download_status).to be_blank
|
57
|
+
expect(@repo.downloaded?).to be == false
|
58
|
+
end
|
59
|
+
|
60
|
+
it "will be downloaded after load_git" do
|
61
|
+
@repo.load_git
|
62
|
+
expect(@repo.downloaded?).to be == true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
50
66
|
context "loaded repo" do
|
51
67
|
before :each do
|
52
68
|
@repo = Perkins::Repo.first
|
@@ -56,7 +72,7 @@ describe "Repo" do
|
|
56
72
|
end
|
57
73
|
|
58
74
|
it "should download repo" do
|
59
|
-
expect(File.
|
75
|
+
expect(File.exist?(@path)).to be_present
|
60
76
|
end
|
61
77
|
|
62
78
|
it "should have a default runner" do
|
@@ -82,11 +98,15 @@ describe "Repo" do
|
|
82
98
|
expect(@repo.runner).to be_instance_of(Perkins::Runner)
|
83
99
|
end
|
84
100
|
|
85
|
-
it "
|
101
|
+
it "runner true" do
|
86
102
|
sha = @repo.git.log.map(&:sha).first
|
87
|
-
|
88
|
-
|
89
|
-
|
103
|
+
allow_any_instance_of(Perkins::Runner).to receive(:run_script).and_return("stubbed")
|
104
|
+
allow_any_instance_of(Perkins::Runner).to receive(:successful_command?).and_return(true)
|
105
|
+
runner = @repo.runner
|
106
|
+
runner.run(sha)
|
107
|
+
expect(runner.response).to be == "stubbed"
|
108
|
+
expect(runner.status).to be == true
|
109
|
+
expect(@repo.build_status).to be == "stopped"
|
90
110
|
end
|
91
111
|
end
|
92
112
|
|
@@ -99,10 +119,11 @@ describe "Repo" do
|
|
99
119
|
@path = @repo.git.dir.path
|
100
120
|
end
|
101
121
|
|
102
|
-
it "receive commit" do
|
122
|
+
it "will increment Worker jobs when receive commit " do
|
103
123
|
sha = @repo.git.log.map(&:sha).first
|
104
124
|
@repo.add_commit(sha, "master")
|
105
125
|
expect(@repo.new_commit).to be_instance_of(Perkins::Commit)
|
126
|
+
expect(Perkins::Worker.jobs.size).to be > 0
|
106
127
|
end
|
107
128
|
|
108
129
|
end
|
data/spec/lib/runner_spec.rb
CHANGED
data/spec/lib/server_spec.rb
CHANGED
@@ -55,36 +55,18 @@ describe 'Server App' do
|
|
55
55
|
it "profile" do
|
56
56
|
allow_any_instance_of(Warden::GitHub::User).to receive(:api).and_return(user_api)
|
57
57
|
get "/me"
|
58
|
-
#puts last_response.body
|
59
58
|
expect(last_response).to be_ok
|
60
59
|
end
|
61
60
|
|
62
61
|
describe "github" do
|
63
62
|
|
64
|
-
it "sync" do
|
65
|
-
|
66
|
-
allow_any_instance_of(Warden::GitHub::User).to receive(:api).and_return(user_api)
|
67
|
-
|
68
|
-
get "/repos/sync"
|
69
|
-
|
70
|
-
follow_redirect!
|
71
|
-
|
72
|
-
expect("http://example.org/me").to be == last_request.url
|
73
|
-
|
74
|
-
expect(last_response).to be_ok
|
75
|
-
|
76
|
-
expect(Perkins::Repo.synced_records).to be_any
|
77
|
-
end
|
78
|
-
|
79
63
|
it "add repo" do
|
80
64
|
allow_any_instance_of(Warden::GitHub::User).to receive(:api).and_return(user_api)
|
81
65
|
a = Warden::GitHub::User.new
|
82
66
|
Perkins::Repo.sync_github_repos(a)
|
83
67
|
repo = Perkins::Repo.synced_records.first
|
84
|
-
|
85
|
-
|
86
|
-
expect("http://example.org/me").to be == last_request.url
|
87
|
-
expect(last_response).to be_ok
|
68
|
+
xhr("/repos/add/#{repo.gb_id}")
|
69
|
+
expect(last_response.body).to be == "true"
|
88
70
|
expect(Perkins::Repo.find(repo.id).github_data).to_not be_blank
|
89
71
|
end
|
90
72
|
|
@@ -92,9 +74,10 @@ describe 'Server App' do
|
|
92
74
|
allow_any_instance_of(Warden::GitHub::User).to receive(:api).and_return(user_api)
|
93
75
|
a = Warden::GitHub::User.new
|
94
76
|
Perkins::Repo.sync_github_repos(a)
|
95
|
-
|
96
|
-
|
97
|
-
|
77
|
+
repo = Perkins::Repo.synced_records.first
|
78
|
+
allow_any_instance_of(Perkins::Server).to receive(:find_repo).and_return(repo)
|
79
|
+
xhr "/repos/name/any_repo"
|
80
|
+
expect(last_response.body).to include(repo.name)
|
98
81
|
end
|
99
82
|
|
100
83
|
it "receive hook" do
|