magi 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -3
- data/README.md +13 -18
- data/app/assets/javascripts/application.js +2 -0
- data/app/assets/javascripts/events.js.coffee +9 -0
- data/app/assets/javascripts/magi/job_model.js.coffee +12 -0
- data/app/assets/javascripts/magi/job_view.js.coffee +9 -0
- data/app/assets/javascripts/magi/server_event.js.coffee +11 -0
- data/app/assets/javascripts/magi.js.coffee +1 -0
- data/app/assets/stylesheets/jobs.scss +4 -0
- data/app/controllers/application_controller.rb +2 -0
- data/app/controllers/builds_controller.rb +1 -1
- data/app/controllers/events_controller.rb +34 -0
- data/app/controllers/jobs_controller.rb +1 -1
- data/app/helpers/application_helper.rb +3 -0
- data/app/models/build.rb +21 -6
- data/app/models/job.rb +3 -5
- data/app/views/jobs/index.html.slim +1 -1
- data/app/views/jobs/show.html.slim +4 -2
- data/app/views/layouts/application.html.slim +1 -1
- data/app/workers/build_worker.rb +1 -1
- data/config/application.rb +1 -13
- data/config/environments/development.rb +3 -17
- data/config/environments/production.rb +4 -0
- data/config/environments/test.rb +2 -6
- data/config/initializers/redis.rb +1 -0
- data/config/initializers/secret_token.rb +1 -0
- data/config/routes.rb +2 -0
- data/lib/magi/configuration.rb +9 -0
- data/lib/magi/responder.rb +12 -0
- data/lib/magi/version.rb +1 -1
- data/lib/magi.rb +4 -8
- data/magi.gemspec +10 -7
- data/plugins/git/git.rb +2 -2
- data/spec/models/build_spec.rb +5 -5
- data/spec/models/job_spec.rb +14 -4
- data/spec/requests/builds_spec.rb +13 -0
- data/spec/spec_helper.rb +13 -0
- metadata +70 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2f3aa7e90d1b48ae6d264fe18d45927e151fe74
|
4
|
+
data.tar.gz: e08af400fadaf5e4ba012227a1a5ca827e988147
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8aaacf0941adfe403a1949c99ae5b742a6dae0fbcfc983de921f7037cec182b719a5234bdbc7922761d4e74d414b2f64cc85522cf448dd881d76a6d2e5a011e6
|
7
|
+
data.tar.gz: 25ce48204fb196d6133df7f04e004c1020f446dd79f33e582087a86fd62e5a10d6e10f57a4fa72635e988923b29693b7ff4cf528b13f6a2787d39598326f0585
|
data/Gemfile
CHANGED
@@ -6,6 +6,7 @@ gemspec
|
|
6
6
|
|
7
7
|
gem "font-awesome-rails"
|
8
8
|
gem "jquery-rails"
|
9
|
+
gem "kaminari"
|
9
10
|
gem "quiet_assets"
|
10
11
|
gem "resque"
|
11
12
|
gem "slim"
|
@@ -25,9 +26,9 @@ group :test do
|
|
25
26
|
end
|
26
27
|
|
27
28
|
group :assets do
|
28
|
-
gem "sass-rails"
|
29
|
-
gem "coffee-rails"
|
30
|
-
gem "uglifier"
|
29
|
+
gem "sass-rails"
|
30
|
+
gem "coffee-rails"
|
31
|
+
gem "uglifier"
|
31
32
|
end
|
32
33
|
|
33
34
|
# Put Gemfile in plugins/:name/Gemfile to use arbitrary gems in your plugin.
|
data/README.md
CHANGED
@@ -1,31 +1,26 @@
|
|
1
1
|
# Magi
|
2
2
|
A continuous integration server implementation.
|
3
3
|
|
4
|
-
![](http://dl.dropbox.com/u/5978869/image/20130607_012059.png)
|
5
|
-
|
6
|
-
## Install
|
7
|
-
```
|
8
|
-
$ gem install magi
|
9
|
-
$ brew install mysql redis # or other commands to install MySQL and Redis
|
10
|
-
```
|
11
|
-
|
12
4
|
## Usage
|
13
5
|
```
|
14
|
-
$ magi
|
15
|
-
$
|
6
|
+
$ gem install magi # install magi.gem
|
7
|
+
$ brew install mysql redis # install MySQL and Redis
|
8
|
+
$ magi setup # create mysql tables
|
9
|
+
$ magi start # launch server on http://localhost:3000
|
16
10
|
```
|
17
11
|
|
18
|
-
##
|
12
|
+
## Development
|
19
13
|
Magi is just a rails application with some middlewares.
|
20
14
|
|
21
|
-
*
|
15
|
+
* rails4: notify build start/finish events via live streaming
|
16
|
+
* clockwork: cron scheduler
|
22
17
|
* foreman: process manager
|
23
18
|
* mysql: store jobs & builds
|
24
19
|
* resque: background worker using redis
|
20
|
+
* autodoc: generate [RESTful API documents](https://github.com/r7kamura/magi/blob/master/doc) from request-specs
|
21
|
+
* jquery: ajax updated view
|
25
22
|
|
26
|
-
|
27
|
-
*
|
28
|
-
*
|
29
|
-
|
30
|
-
## API
|
31
|
-
[API documents](https://github.com/r7kamura/magi/blob/master/doc)
|
23
|
+
### TODO
|
24
|
+
* build stop button
|
25
|
+
* self-repairing system
|
26
|
+
* plugin updater
|
@@ -0,0 +1,9 @@
|
|
1
|
+
$ ->
|
2
|
+
$('.jobs_controller.index_action').each ->
|
3
|
+
job = new Magi.JobModel()
|
4
|
+
view = new Magi.JobView(job)
|
5
|
+
job.onChange -> view.render()
|
6
|
+
|
7
|
+
event = new Magi.ServerEvent()
|
8
|
+
event.onBuildStart (attributes) -> job.set(attributes)
|
9
|
+
event.onBuildFinish (attributes) -> job.set(attributes)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class window.Magi.ServerEvent
|
2
|
+
constructor: ->
|
3
|
+
@source = new EventSource('/events')
|
4
|
+
|
5
|
+
onBuildStart: (callback) ->
|
6
|
+
@source.addEventListener 'build.start', (event) ->
|
7
|
+
callback($.parseJSON(event.data))
|
8
|
+
|
9
|
+
onBuildFinish: (callback) ->
|
10
|
+
@source.addEventListener 'build.finish', (event) ->
|
11
|
+
callback($.parseJSON(event.data))
|
@@ -0,0 +1 @@
|
|
1
|
+
window.Magi = {}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class EventsController < ApplicationController
|
2
|
+
include ActionController::Live
|
3
|
+
|
4
|
+
before_filter :require_event_stream
|
5
|
+
|
6
|
+
def index
|
7
|
+
redis = Redis.new
|
8
|
+
redis.psubscribe("build.*") do |on|
|
9
|
+
on.pmessage do |pattern, event, data|
|
10
|
+
response.stream.write("event: #{event}\n")
|
11
|
+
response.stream.write("data: #{data}\n\n")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
rescue IOError
|
15
|
+
rescue Redis::CannotConnectError
|
16
|
+
head 503
|
17
|
+
ensure
|
18
|
+
redis.quit rescue nil
|
19
|
+
response.stream.close
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def index_with_redis_exception
|
25
|
+
index_without_redis_exception
|
26
|
+
rescue Redis::CannotConnectError
|
27
|
+
head 503
|
28
|
+
end
|
29
|
+
alias_method_chain :index, :redis_exception
|
30
|
+
|
31
|
+
def require_event_stream
|
32
|
+
response.headers["Content-Type"] = "text/event-stream"
|
33
|
+
end
|
34
|
+
end
|
data/app/models/build.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
class Build < ActiveRecord::Base
|
2
2
|
include Magi::Proprietary
|
3
3
|
|
4
|
-
attr_accessible :finished_at, :started_at, :output, :properties, :status
|
5
|
-
|
6
4
|
serialize :properties, Hash
|
7
5
|
|
8
6
|
validates :job_id, presence: true
|
@@ -19,6 +17,8 @@ class Build < ActiveRecord::Base
|
|
19
17
|
|
20
18
|
scope :running, -> { started.unfinished }
|
21
19
|
|
20
|
+
paginates_per 10
|
21
|
+
|
22
22
|
def self.latest
|
23
23
|
recent.first
|
24
24
|
end
|
@@ -29,10 +29,9 @@ class Build < ActiveRecord::Base
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# Runs this build, usually called from BuildWorker#perform.
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
reload.update_attributes!(finished_at: Time.now, status: result[:status], output: result[:output])
|
32
|
+
def run
|
33
|
+
start
|
34
|
+
finish(job.run)
|
36
35
|
end
|
37
36
|
|
38
37
|
# Returns elapsed sec as a Float or nil.
|
@@ -50,4 +49,20 @@ class Build < ActiveRecord::Base
|
|
50
49
|
"unfinished"
|
51
50
|
end
|
52
51
|
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def notify(type)
|
56
|
+
$redis.publish("build.#{type}", { id: id, job_id: job.id, status: status_name }.to_json)
|
57
|
+
end
|
58
|
+
|
59
|
+
def start
|
60
|
+
update_attributes!(started_at: Time.now)
|
61
|
+
notify(:start)
|
62
|
+
end
|
63
|
+
|
64
|
+
def finish(result)
|
65
|
+
reload.update_attributes!(finished_at: Time.now, output: result[:output], status: result[:status])
|
66
|
+
notify(:finish)
|
67
|
+
end
|
53
68
|
end
|
data/app/models/job.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
class Job < ActiveRecord::Base
|
2
2
|
include Magi::Proprietary
|
3
3
|
|
4
|
-
attr_accessible :name, :properties
|
5
|
-
|
6
4
|
serialize :properties, Hash
|
7
5
|
|
8
6
|
validates :name, presence: true
|
@@ -63,12 +61,12 @@ class Job < ActiveRecord::Base
|
|
63
61
|
|
64
62
|
property(:script)
|
65
63
|
|
66
|
-
def
|
64
|
+
def run
|
67
65
|
script ? execute : raise_script_not_found
|
68
66
|
end
|
69
67
|
|
70
68
|
def scheduler
|
71
|
-
Magi::Scheduler.new(schedule) if schedule
|
69
|
+
Magi::Scheduler.new(schedule) if schedule.present?
|
72
70
|
end
|
73
71
|
|
74
72
|
def enqueue
|
@@ -115,7 +113,7 @@ class Job < ActiveRecord::Base
|
|
115
113
|
private
|
116
114
|
|
117
115
|
def workspace_path
|
118
|
-
Magi.
|
116
|
+
Magi.configuration.workspace_path + "jobs/#{id}"
|
119
117
|
end
|
120
118
|
|
121
119
|
def execute
|
@@ -14,11 +14,13 @@ section.builds
|
|
14
14
|
.buttons
|
15
15
|
= link_to "Run", [@resource, :builds], method: "POST", class: "button run"
|
16
16
|
= link_to "Settings", [:edit, @resource], class: "button settings"
|
17
|
-
= link_to "Delete", @resource, method: "DELETE", confirm: "Are you sure?", class: "button delete"
|
17
|
+
= link_to "Delete", @resource, method: "DELETE", data: { confirm: "Are you sure?" }, class: "button delete"
|
18
18
|
|
19
19
|
ul
|
20
|
-
- @resource.builds.recent.limit(10).each do |build|
|
20
|
+
- @resource.builds.page(params[:page]).recent.limit(10).each do |build|
|
21
21
|
li class = build.status_name
|
22
22
|
= link_to [@resource, build] do
|
23
23
|
span.id ##{build.id}
|
24
24
|
span= build.finished_at
|
25
|
+
|
26
|
+
= paginate @resource.builds.page(params[:page])
|
data/app/workers/build_worker.rb
CHANGED
data/config/application.rb
CHANGED
@@ -3,10 +3,7 @@ require File.expand_path('../boot', __FILE__)
|
|
3
3
|
require 'rails/all'
|
4
4
|
|
5
5
|
if defined?(Bundler)
|
6
|
-
|
7
|
-
# Bundler.require(*Rails.groups(:assets => %w(development test)))
|
8
|
-
# If you want your assets lazily compiled in production, use this line
|
9
|
-
Bundler.require(:default, :assets, Rails.env)
|
6
|
+
Bundler.require(:default, Rails.env)
|
10
7
|
end
|
11
8
|
|
12
9
|
module Magi
|
@@ -47,15 +44,6 @@ module Magi
|
|
47
44
|
# like if you have constraints or database-specific column types
|
48
45
|
# config.active_record.schema_format = :sql
|
49
46
|
|
50
|
-
# Enforce whitelist mode for mass assignment.
|
51
|
-
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
52
|
-
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
53
|
-
# parameters by using an attr_accessible or attr_protected declaration.
|
54
|
-
config.active_record.whitelist_attributes = true
|
55
|
-
|
56
|
-
# Enable the asset pipeline
|
57
|
-
config.assets.enabled = true
|
58
|
-
|
59
47
|
# Version of your assets, change this if you want to expire all your assets
|
60
48
|
config.assets.version = '1.0'
|
61
49
|
end
|
@@ -4,10 +4,7 @@ Magi::Application.configure do
|
|
4
4
|
# In the development environment your application's code is reloaded on
|
5
5
|
# every request. This slows down response time but is perfect for development
|
6
6
|
# since you don't have to restart the web server when you make code changes.
|
7
|
-
config.cache_classes =
|
8
|
-
|
9
|
-
# Log error messages when you accidentally call methods on nil.
|
10
|
-
config.whiny_nils = true
|
7
|
+
config.cache_classes = true
|
11
8
|
|
12
9
|
# Show full error reports and disable caching
|
13
10
|
config.consider_all_requests_local = true
|
@@ -19,19 +16,8 @@ Magi::Application.configure do
|
|
19
16
|
# Print deprecation notices to the Rails logger
|
20
17
|
config.active_support.deprecation = :log
|
21
18
|
|
22
|
-
# Only use best-standards-support built into browsers
|
23
|
-
config.action_dispatch.best_standards_support = :builtin
|
24
|
-
|
25
|
-
# Raise exception on mass assignment protection for Active Record models
|
26
|
-
config.active_record.mass_assignment_sanitizer = :strict
|
27
|
-
|
28
|
-
# Log the query plan for queries taking more than this (works
|
29
|
-
# with SQLite, MySQL, and PostgreSQL)
|
30
|
-
config.active_record.auto_explain_threshold_in_seconds = 0.5
|
31
|
-
|
32
|
-
# Do not compress assets
|
33
|
-
config.assets.compress = false
|
34
|
-
|
35
19
|
# Expands the lines which load the assets
|
36
20
|
config.assets.debug = true
|
21
|
+
|
22
|
+
config.eager_load = true
|
37
23
|
end
|
@@ -64,4 +64,8 @@ Magi::Application.configure do
|
|
64
64
|
# Log the query plan for queries taking more than this (works
|
65
65
|
# with SQLite, MySQL, and PostgreSQL)
|
66
66
|
# config.active_record.auto_explain_threshold_in_seconds = 0.5
|
67
|
+
|
68
|
+
config.eager_load = true
|
69
|
+
|
70
|
+
config.assets.js_compressor = :uglifier
|
67
71
|
end
|
data/config/environments/test.rb
CHANGED
@@ -11,9 +11,6 @@ Magi::Application.configure do
|
|
11
11
|
config.serve_static_assets = true
|
12
12
|
config.static_cache_control = "public, max-age=3600"
|
13
13
|
|
14
|
-
# Log error messages when you accidentally call methods on nil
|
15
|
-
config.whiny_nils = true
|
16
|
-
|
17
14
|
# Show full error reports and disable caching
|
18
15
|
config.consider_all_requests_local = true
|
19
16
|
config.action_controller.perform_caching = false
|
@@ -29,9 +26,8 @@ Magi::Application.configure do
|
|
29
26
|
# ActionMailer::Base.deliveries array.
|
30
27
|
config.action_mailer.delivery_method = :test
|
31
28
|
|
32
|
-
# Raise exception on mass assignment protection for Active Record models
|
33
|
-
config.active_record.mass_assignment_sanitizer = :strict
|
34
|
-
|
35
29
|
# Print deprecation notices to the stderr
|
36
30
|
config.active_support.deprecation = :stderr
|
31
|
+
|
32
|
+
config.eager_load = false
|
37
33
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
$redis = Redis.new
|
@@ -5,3 +5,4 @@
|
|
5
5
|
# Make sure the secret is at least 30 characters and all random,
|
6
6
|
# no regular words or you'll be exposed to dictionary attacks.
|
7
7
|
Magi::Application.config.secret_token = '52e56b4c387efb5ac8eb96c71963f58de5432808e97bc5d971ea8e04997bab457094ed4da841829ce98933564259a213dd249fb2a1079bd895e703eebfc4e8a2'
|
8
|
+
Magi::Application.config.secret_key_base = 'e856f5fcd6c1e77a152fb5726fe8b14e149463de77df20bf6ee8ee73cc985d09219df9a247f2f29b0349634dc794ec7909804d14c03615c2c2a9bed4451cc790'
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "action_controller"
|
2
|
+
|
3
|
+
module Magi
|
4
|
+
class Responder < ActionController::Responder
|
5
|
+
def initialize(controller, resources, *args)
|
6
|
+
if resources[0].respond_to?(:page)
|
7
|
+
resources[0] = resources[0].page(controller.params[:page])
|
8
|
+
end
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/magi/version.rb
CHANGED
data/lib/magi.rb
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
require "magi/command"
|
2
|
+
require "magi/configuration"
|
2
3
|
require "magi/plugin_manager"
|
4
|
+
require "magi/responder"
|
3
5
|
require "magi/version"
|
4
6
|
require "magi/workspace"
|
5
7
|
|
6
8
|
module Magi
|
7
9
|
class << self
|
8
|
-
def
|
9
|
-
@
|
10
|
+
def configuration
|
11
|
+
@configuration ||= Magi::Configuration.new
|
10
12
|
end
|
11
13
|
|
12
14
|
def plugin_manager
|
13
15
|
@plugin_manager ||= Magi::PluginManager.new
|
14
16
|
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def workspace_path
|
19
|
-
ENV["WORKSPACE_PATH"] || "."
|
20
|
-
end
|
21
17
|
end
|
22
18
|
end
|
data/magi.gemspec
CHANGED
@@ -27,20 +27,23 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.require_paths = ["lib"]
|
28
28
|
|
29
29
|
spec.add_dependency "clockwork"
|
30
|
-
spec.add_dependency "coffee-rails", "
|
30
|
+
spec.add_dependency "coffee-rails", ">= 4.0.0"
|
31
31
|
spec.add_dependency "font-awesome-rails"
|
32
32
|
spec.add_dependency "foreman"
|
33
33
|
spec.add_dependency "jquery-rails"
|
34
|
+
spec.add_dependency "kaminari"
|
34
35
|
spec.add_dependency "mysql2"
|
36
|
+
spec.add_dependency "puma"
|
35
37
|
spec.add_dependency "quiet_assets"
|
36
|
-
spec.add_dependency "rails", "
|
38
|
+
spec.add_dependency "rails", ">= 4.0.0.rc2"
|
37
39
|
spec.add_dependency "rake"
|
40
|
+
spec.add_dependency "redis"
|
38
41
|
spec.add_dependency "resque"
|
39
|
-
spec.add_dependency "sass-rails", "
|
42
|
+
spec.add_dependency "sass-rails", ">= 4.0.0.rc1"
|
40
43
|
spec.add_dependency "slim"
|
41
|
-
spec.add_dependency "uglifier", ">= 1.0
|
42
|
-
spec.add_dependency "weak_parameters"
|
43
|
-
|
44
|
+
spec.add_dependency "uglifier", ">= 1.3.0"
|
45
|
+
spec.add_dependency "weak_parameters"
|
46
|
+
|
47
|
+
spec.add_development_dependency "bundler"
|
44
48
|
spec.add_development_dependency "pry-rails"
|
45
|
-
spec.add_development_dependency "thin"
|
46
49
|
end
|
data/plugins/git/git.rb
CHANGED
@@ -21,7 +21,7 @@ module Magi
|
|
21
21
|
command("cd #{job.workspace.path} && git rev-parse HEAD").rstrip
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def updated_since_last_finished_build?
|
25
25
|
revision != job.last_finished_build.try(:revision)
|
26
26
|
end
|
27
27
|
|
@@ -54,7 +54,7 @@ Job.class_eval do
|
|
54
54
|
if git_url.present?
|
55
55
|
repository.clone unless repository.cloned?
|
56
56
|
repository.update
|
57
|
-
repository.
|
57
|
+
repository.updated_since_last_finished_build?
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
data/spec/models/build_spec.rb
CHANGED
@@ -9,10 +9,10 @@ describe Build do
|
|
9
9
|
FactoryGirl.create(:job, properties: { "script" => "true" })
|
10
10
|
end
|
11
11
|
|
12
|
-
describe "#
|
12
|
+
describe "#run" do
|
13
13
|
context "with success" do
|
14
|
-
it "
|
15
|
-
build.
|
14
|
+
it "runs its job and sets status with true" do
|
15
|
+
build.run
|
16
16
|
build.started_at.should be_present
|
17
17
|
build.finished_at.should be_present
|
18
18
|
build.status.should == true
|
@@ -24,8 +24,8 @@ describe Build do
|
|
24
24
|
build.job.script = "false"
|
25
25
|
end
|
26
26
|
|
27
|
-
it "
|
28
|
-
build.
|
27
|
+
it "runs its job and sets status with false" do
|
28
|
+
build.run
|
29
29
|
build.started_at.should be_present
|
30
30
|
build.finished_at.should be_present
|
31
31
|
build.status.should == false
|
data/spec/models/job_spec.rb
CHANGED
@@ -5,14 +5,14 @@ describe Job do
|
|
5
5
|
FactoryGirl.create(:job, properties: { "script" => "true" })
|
6
6
|
end
|
7
7
|
|
8
|
-
describe "#
|
8
|
+
describe "#run" do
|
9
9
|
context "without script" do
|
10
10
|
before do
|
11
11
|
job.script = nil
|
12
12
|
end
|
13
13
|
|
14
14
|
it "raises Job::ScriptNotFound" do
|
15
|
-
expect { job.
|
15
|
+
expect { job.run }.to raise_error(Job::ScriptNotFound)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -21,9 +21,9 @@ describe Job do
|
|
21
21
|
job.script = "true"
|
22
22
|
end
|
23
23
|
|
24
|
-
it "
|
24
|
+
it "runs its job" do
|
25
25
|
Magi::Executer.should_receive(:execute).with("true")
|
26
|
-
job.
|
26
|
+
job.run
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -35,6 +35,16 @@ describe Job do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
context "with empty schedule" do
|
39
|
+
before do
|
40
|
+
job.schedule = ""
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns false" do
|
44
|
+
job.should_not be_scheduled
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
38
48
|
context "with matched schedule" do
|
39
49
|
before do
|
40
50
|
job.schedule = "* * * * *"
|
@@ -27,6 +27,19 @@ describe "Builds" do
|
|
27
27
|
response.status.should == 200
|
28
28
|
response.body.should be_json([Hash])
|
29
29
|
end
|
30
|
+
|
31
|
+
context "with page" do
|
32
|
+
before do
|
33
|
+
params[:page] = 2
|
34
|
+
10.times { job.builds.create }
|
35
|
+
end
|
36
|
+
|
37
|
+
it "paginates builds" do
|
38
|
+
get "/jobs/#{job.id}/builds", params, env
|
39
|
+
response.status.should == 200
|
40
|
+
response.body.should be_json([Hash])
|
41
|
+
end
|
42
|
+
end
|
30
43
|
end
|
31
44
|
|
32
45
|
describe "GET /jobs/:job_id/builds/:id" do
|
data/spec/spec_helper.rb
CHANGED
@@ -24,6 +24,19 @@ RSpec.configure do |config|
|
|
24
24
|
|
25
25
|
config.include RSpec::JsonMatcher, type: :request
|
26
26
|
config.include ResponseCodeMatchers, type: :request
|
27
|
+
|
28
|
+
config.before(:suite) do
|
29
|
+
Magi.configuration.workspace_path = Rails.root.join("tmp/workspace")
|
30
|
+
end
|
31
|
+
|
32
|
+
config.after(:suite) do
|
33
|
+
workspace = Rails.root.join("tmp/workspace")
|
34
|
+
workspace.rmtree if workspace.exist?
|
35
|
+
end
|
36
|
+
|
37
|
+
config.before do
|
38
|
+
$redis.stub(:publish)
|
39
|
+
end
|
27
40
|
end
|
28
41
|
|
29
42
|
Resque.inline = true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clockwork
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: coffee-rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 4.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 4.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: font-awesome-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: kaminari
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: mysql2
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +108,20 @@ dependencies:
|
|
94
108
|
- - '>='
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: puma
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: quiet_assets
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,16 +140,16 @@ dependencies:
|
|
112
140
|
name: rails
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
|
-
- - '
|
143
|
+
- - '>='
|
116
144
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
145
|
+
version: 4.0.0.rc2
|
118
146
|
type: :runtime
|
119
147
|
prerelease: false
|
120
148
|
version_requirements: !ruby/object:Gem::Requirement
|
121
149
|
requirements:
|
122
|
-
- - '
|
150
|
+
- - '>='
|
123
151
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
152
|
+
version: 4.0.0.rc2
|
125
153
|
- !ruby/object:Gem::Dependency
|
126
154
|
name: rake
|
127
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,7 +165,7 @@ dependencies:
|
|
137
165
|
- !ruby/object:Gem::Version
|
138
166
|
version: '0'
|
139
167
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
168
|
+
name: redis
|
141
169
|
requirement: !ruby/object:Gem::Requirement
|
142
170
|
requirements:
|
143
171
|
- - '>='
|
@@ -151,77 +179,77 @@ dependencies:
|
|
151
179
|
- !ruby/object:Gem::Version
|
152
180
|
version: '0'
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
182
|
+
name: resque
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
156
184
|
requirements:
|
157
|
-
- -
|
185
|
+
- - '>='
|
158
186
|
- !ruby/object:Gem::Version
|
159
|
-
version:
|
187
|
+
version: '0'
|
160
188
|
type: :runtime
|
161
189
|
prerelease: false
|
162
190
|
version_requirements: !ruby/object:Gem::Requirement
|
163
191
|
requirements:
|
164
|
-
- -
|
192
|
+
- - '>='
|
165
193
|
- !ruby/object:Gem::Version
|
166
|
-
version:
|
194
|
+
version: '0'
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
196
|
+
name: sass-rails
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
170
198
|
requirements:
|
171
199
|
- - '>='
|
172
200
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
201
|
+
version: 4.0.0.rc1
|
174
202
|
type: :runtime
|
175
203
|
prerelease: false
|
176
204
|
version_requirements: !ruby/object:Gem::Requirement
|
177
205
|
requirements:
|
178
206
|
- - '>='
|
179
207
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
208
|
+
version: 4.0.0.rc1
|
181
209
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
210
|
+
name: slim
|
183
211
|
requirement: !ruby/object:Gem::Requirement
|
184
212
|
requirements:
|
185
213
|
- - '>='
|
186
214
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
215
|
+
version: '0'
|
188
216
|
type: :runtime
|
189
217
|
prerelease: false
|
190
218
|
version_requirements: !ruby/object:Gem::Requirement
|
191
219
|
requirements:
|
192
220
|
- - '>='
|
193
221
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
222
|
+
version: '0'
|
195
223
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
224
|
+
name: uglifier
|
197
225
|
requirement: !ruby/object:Gem::Requirement
|
198
226
|
requirements:
|
199
227
|
- - '>='
|
200
228
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
229
|
+
version: 1.3.0
|
202
230
|
type: :runtime
|
203
231
|
prerelease: false
|
204
232
|
version_requirements: !ruby/object:Gem::Requirement
|
205
233
|
requirements:
|
206
234
|
- - '>='
|
207
235
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
236
|
+
version: 1.3.0
|
209
237
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
238
|
+
name: weak_parameters
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
212
240
|
requirements:
|
213
|
-
- -
|
241
|
+
- - '>='
|
214
242
|
- !ruby/object:Gem::Version
|
215
|
-
version: '
|
216
|
-
type: :
|
243
|
+
version: '0'
|
244
|
+
type: :runtime
|
217
245
|
prerelease: false
|
218
246
|
version_requirements: !ruby/object:Gem::Requirement
|
219
247
|
requirements:
|
220
|
-
- -
|
248
|
+
- - '>='
|
221
249
|
- !ruby/object:Gem::Version
|
222
|
-
version: '
|
250
|
+
version: '0'
|
223
251
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
252
|
+
name: bundler
|
225
253
|
requirement: !ruby/object:Gem::Requirement
|
226
254
|
requirements:
|
227
255
|
- - '>='
|
@@ -235,7 +263,7 @@ dependencies:
|
|
235
263
|
- !ruby/object:Gem::Version
|
236
264
|
version: '0'
|
237
265
|
- !ruby/object:Gem::Dependency
|
238
|
-
name:
|
266
|
+
name: pry-rails
|
239
267
|
requirement: !ruby/object:Gem::Requirement
|
240
268
|
requirements:
|
241
269
|
- - '>='
|
@@ -258,6 +286,11 @@ extra_rdoc_files: []
|
|
258
286
|
files:
|
259
287
|
- app/assets/images/rails.png
|
260
288
|
- app/assets/javascripts/application.js
|
289
|
+
- app/assets/javascripts/events.js.coffee
|
290
|
+
- app/assets/javascripts/magi/job_model.js.coffee
|
291
|
+
- app/assets/javascripts/magi/job_view.js.coffee
|
292
|
+
- app/assets/javascripts/magi/server_event.js.coffee
|
293
|
+
- app/assets/javascripts/magi.js.coffee
|
261
294
|
- app/assets/stylesheets/application.css
|
262
295
|
- app/assets/stylesheets/builds.scss
|
263
296
|
- app/assets/stylesheets/common.scss
|
@@ -266,6 +299,7 @@ files:
|
|
266
299
|
- app/assets/stylesheets/mixin.scss
|
267
300
|
- app/controllers/application_controller.rb
|
268
301
|
- app/controllers/builds_controller.rb
|
302
|
+
- app/controllers/events_controller.rb
|
269
303
|
- app/controllers/jobs_controller.rb
|
270
304
|
- app/helpers/application_helper.rb
|
271
305
|
- app/models/build.rb
|
@@ -291,6 +325,7 @@ files:
|
|
291
325
|
- config/initializers/inflections.rb
|
292
326
|
- config/initializers/load_plugins.rb
|
293
327
|
- config/initializers/mime_types.rb
|
328
|
+
- config/initializers/redis.rb
|
294
329
|
- config/initializers/secret_token.rb
|
295
330
|
- config/initializers/session_store.rb
|
296
331
|
- config/initializers/wrap_parameters.rb
|
@@ -303,9 +338,11 @@ files:
|
|
303
338
|
- db/schema.rb
|
304
339
|
- db/seeds.rb
|
305
340
|
- lib/magi/command.rb
|
341
|
+
- lib/magi/configuration.rb
|
306
342
|
- lib/magi/executer.rb
|
307
343
|
- lib/magi/plugin_manager.rb
|
308
344
|
- lib/magi/proprietary.rb
|
345
|
+
- lib/magi/responder.rb
|
309
346
|
- lib/magi/scheduler.rb
|
310
347
|
- lib/magi/version.rb
|
311
348
|
- lib/magi/workspace.rb
|