altria 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +41 -0
- data/LICENSE.txt +22 -0
- data/Procfile +4 -0
- data/README.md +40 -0
- data/Rakefile +6 -0
- data/altria.gemspec +50 -0
- data/app/assets/images/rails.png +0 -0
- data/app/assets/javascripts/altria.js.coffee +1 -0
- data/app/assets/javascripts/altria/build_view.js.coffee +13 -0
- data/app/assets/javascripts/altria/job_view.js.coffee +10 -0
- data/app/assets/javascripts/altria/server_event.js.coffee +8 -0
- data/app/assets/javascripts/application.js +20 -0
- data/app/assets/javascripts/events.js.coffee +13 -0
- data/app/assets/stylesheets/application.css +14 -0
- data/app/assets/stylesheets/builds.scss +35 -0
- data/app/assets/stylesheets/common.scss +69 -0
- data/app/assets/stylesheets/jobs.scss +129 -0
- data/app/assets/stylesheets/layout.scss +19 -0
- data/app/assets/stylesheets/mixin.scss +26 -0
- data/app/controllers/application_controller.rb +24 -0
- data/app/controllers/builds_controller.rb +48 -0
- data/app/controllers/events_controller.rb +27 -0
- data/app/controllers/jobs_controller.rb +50 -0
- data/app/helpers/application_helper.rb +5 -0
- data/app/models/build.rb +72 -0
- data/app/models/job.rb +141 -0
- data/app/views/builds/show.html.slim +36 -0
- data/app/views/jobs/_form.html.slim +22 -0
- data/app/views/jobs/edit.html.slim +9 -0
- data/app/views/jobs/index.html.slim +19 -0
- data/app/views/jobs/new.html.slim +7 -0
- data/app/views/jobs/show.html.slim +28 -0
- data/app/views/layouts/application.html.slim +11 -0
- data/app/workers/build_worker.rb +13 -0
- data/app/workers/job_enqueue_worker.rb +13 -0
- data/bin/altria +6 -0
- data/config.ru +4 -0
- data/config/application.rb +52 -0
- data/config/boot.rb +6 -0
- data/config/database.yml +29 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +23 -0
- data/config/environments/production.rb +71 -0
- data/config/environments/test.rb +33 -0
- data/config/initializers/backtrace_silencers.rb +7 -0
- data/config/initializers/inflections.rb +15 -0
- data/config/initializers/mime_types.rb +5 -0
- data/config/initializers/redis.rb +1 -0
- data/config/initializers/secret_token.rb +8 -0
- data/config/initializers/session_store.rb +8 -0
- data/config/initializers/wrap_parameters.rb +14 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20130531143239_create_jobs.rb +10 -0
- data/db/migrate/20130531155155_create_builds.rb +14 -0
- data/db/migrate/20130608153135_change_job_column_name_from_config_to_properties.rb +9 -0
- data/db/migrate/20130608153655_add_column_properties_to_builds.rb +5 -0
- data/db/schema.rb +36 -0
- data/db/seeds.rb +7 -0
- data/lib/altria.rb +13 -0
- data/lib/altria/command.rb +61 -0
- data/lib/altria/configuration.rb +9 -0
- data/lib/altria/executer.rb +37 -0
- data/lib/altria/proprietary.rb +56 -0
- data/lib/altria/responder.rb +12 -0
- data/lib/altria/scheduler.rb +55 -0
- data/lib/altria/version.rb +3 -0
- data/lib/altria/workspace.rb +26 -0
- data/lib/tasks/resque.rake +3 -0
- data/public/404.html +26 -0
- data/public/422.html +26 -0
- data/public/500.html +25 -0
- data/public/favicon.ico +0 -0
- data/public/robots.txt +5 -0
- data/script/clock.rb +5 -0
- data/script/rails +6 -0
- data/spec/altria/command_spec.rb +53 -0
- data/spec/factories/build.rb +7 -0
- data/spec/factories/job.rb +7 -0
- data/spec/models/build_spec.rb +35 -0
- data/spec/models/job_spec.rb +101 -0
- data/spec/requests/builds_spec.rb +81 -0
- data/spec/requests/jobs_spec.rb +88 -0
- data/spec/spec_helper.rb +48 -0
- metadata +417 -0
data/public/500.html
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/500.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
23
|
+
</div>
|
24
|
+
</body>
|
25
|
+
</html>
|
data/public/favicon.ico
ADDED
File without changes
|
data/public/robots.txt
ADDED
data/script/clock.rb
ADDED
data/script/rails
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Altria::Command do
|
4
|
+
let(:command) do
|
5
|
+
described_class.new(arguments)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".call" do
|
9
|
+
it "delegates to #call" do
|
10
|
+
described_class.any_instance.should_receive(:call)
|
11
|
+
described_class.call(["setup"])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#call" do
|
16
|
+
let(:env) do
|
17
|
+
{ "WORKSPACE_PATH" => Dir.pwd }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with `setup`" do
|
21
|
+
let(:arguments) do
|
22
|
+
["setup"]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "executes setup script" do
|
26
|
+
command.should_receive(:system).with(env, "cd #{Dir.pwd} && bundle install && bundle exec rake db:create db:migrate")
|
27
|
+
command.call
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with `start`" do
|
32
|
+
let(:arguments) do
|
33
|
+
["start"]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "executes start script" do
|
37
|
+
command.should_receive(:system).with(env, "cd #{Dir.pwd} && bundle exec foreman start")
|
38
|
+
command.call
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with unknown arguments" do
|
43
|
+
let(:arguments) do
|
44
|
+
[]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "shows usage" do
|
48
|
+
command.should_receive(:puts).with("Usage: altria {setup|start}")
|
49
|
+
command.call
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Build do
|
4
|
+
let(:build) do
|
5
|
+
FactoryGirl.create(:build, job: job)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:job) do
|
9
|
+
FactoryGirl.create(:job, properties: { "script" => "true" })
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#run" do
|
13
|
+
context "with success" do
|
14
|
+
it "runs its job and sets status with true" do
|
15
|
+
build.run
|
16
|
+
build.started_at.should be_present
|
17
|
+
build.finished_at.should be_present
|
18
|
+
build.status.should == true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with failure" do
|
23
|
+
before do
|
24
|
+
build.job.script = "false"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "runs its job and sets status with false" do
|
28
|
+
build.run
|
29
|
+
build.started_at.should be_present
|
30
|
+
build.finished_at.should be_present
|
31
|
+
build.status.should == false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Job do
|
4
|
+
let(:job) do
|
5
|
+
FactoryGirl.create(:job, properties: { "script" => "true" })
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#run" do
|
9
|
+
context "without script" do
|
10
|
+
before do
|
11
|
+
job.script = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "raises Job::ScriptNotFound" do
|
15
|
+
expect { job.run }.to raise_error(Job::ScriptNotFound)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with script" do
|
20
|
+
before do
|
21
|
+
job.script = "true"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "runs its job" do
|
25
|
+
Altria::Executer.should_receive(:execute).with("true")
|
26
|
+
job.run
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#scheduled?" do
|
32
|
+
context "without schedule" do
|
33
|
+
it "returns false" do
|
34
|
+
job.should_not be_scheduled
|
35
|
+
end
|
36
|
+
end
|
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
|
+
|
48
|
+
context "with matched schedule" do
|
49
|
+
before do
|
50
|
+
job.schedule = "* * * * *"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns true" do
|
54
|
+
job.should be_scheduled
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "without matched schedule" do
|
59
|
+
before do
|
60
|
+
job.schedule = "0 0 0 0 0"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns false" do
|
64
|
+
job.should_not be_scheduled
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#enqueue_with_before_enqueues" do
|
70
|
+
before do
|
71
|
+
Job.before_enqueues.clear
|
72
|
+
end
|
73
|
+
|
74
|
+
after do
|
75
|
+
Job.before_enqueues.clear
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with successful hooks" do
|
79
|
+
before do
|
80
|
+
Job.before_enqueue { Job.hook_is_executed }
|
81
|
+
end
|
82
|
+
|
83
|
+
it "enqueues a new build" do
|
84
|
+
Job.should_receive(:hook_is_executed)
|
85
|
+
job.enqueue_with_before_enqueues
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "with failed hooks" do
|
90
|
+
before do
|
91
|
+
Job.before_enqueue { false }
|
92
|
+
Job.before_enqueue { Job.hook_is_executed }
|
93
|
+
end
|
94
|
+
|
95
|
+
it "stops at failed hook" do
|
96
|
+
Job.should_not_receive(:hook_is_executed)
|
97
|
+
job.enqueue_with_before_enqueues
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Builds" do
|
4
|
+
let(:params) do
|
5
|
+
{}
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:env) do
|
9
|
+
{ "HTTP_ACCEPT" => "application/json" }
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:job) do
|
13
|
+
FactoryGirl.create(:job, properties: { "script" => "true" })
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:build) do
|
17
|
+
job.builds.create(id: 1)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "GET /jobs/:job_id/builds" do
|
21
|
+
before do
|
22
|
+
build
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns builds of the job", :autodoc do
|
26
|
+
get "/jobs/#{job.id}/builds", params, env
|
27
|
+
response.status.should == 200
|
28
|
+
response.body.should be_json([Hash])
|
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
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "GET /jobs/:job_id/builds/:id" do
|
46
|
+
it "returns the build", :autodoc do
|
47
|
+
get "/jobs/#{job.id}/builds/#{build.id}", params, env
|
48
|
+
response.status.should == 200
|
49
|
+
response.body.should be_json(Hash)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "POST /jobs/:job_id/builds" do
|
54
|
+
it "creates a new build and queue it", :autodoc do
|
55
|
+
post "/jobs/#{job.id}/builds", params, env
|
56
|
+
response.status.should == 201
|
57
|
+
response.body.should be_json(Hash)
|
58
|
+
job.builds.should have(1).builds
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "PUT /jobs/:job_id/builds/:id" do
|
63
|
+
before do
|
64
|
+
params[:status] = 1
|
65
|
+
end
|
66
|
+
|
67
|
+
it "updates the build", :autodoc do
|
68
|
+
put "/jobs/#{job.id}/builds/#{build.id}", params, env
|
69
|
+
response.status.should == 204
|
70
|
+
build.reload.status.should == true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "DELETE /jobs/:job_id/builds/:id" do
|
75
|
+
it "deletes the build", :autodoc do
|
76
|
+
delete "/jobs/#{job.id}/builds/#{build.id}", params, env
|
77
|
+
response.status.should == 204
|
78
|
+
Build.should have(0).build
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Jobs" do
|
4
|
+
let(:params) do
|
5
|
+
{}
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:env) do
|
9
|
+
{ "HTTP_ACCEPT" => "application/json" }
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:job) do
|
13
|
+
FactoryGirl.create(:job)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "GET /jobs" do
|
17
|
+
before do
|
18
|
+
job
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns jobs", :autodoc do
|
22
|
+
get "/jobs", params, env
|
23
|
+
response.status.should == 200
|
24
|
+
response.body.should be_json([Hash])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "GET /jobs/:id" do
|
29
|
+
it "returns the job", :autodoc do
|
30
|
+
get "/jobs/#{job.id}", params, env
|
31
|
+
response.status.should == 200
|
32
|
+
response.body.should be_json(Hash)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "POST /jobs" do
|
37
|
+
before do
|
38
|
+
params[:name] = "name"
|
39
|
+
params[:description] = "description"
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with invalid params" do
|
43
|
+
before do
|
44
|
+
params.delete(:name)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns 400" do
|
48
|
+
post "/jobs", params, env
|
49
|
+
response.status.should == 400
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "with valid condition" do
|
54
|
+
it "creates a new job", :autodoc do
|
55
|
+
post "/jobs", params, env
|
56
|
+
response.status.should == 201
|
57
|
+
job = Job.first
|
58
|
+
job.name.should == "name"
|
59
|
+
job.description.should == "description"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "PUT /jobs/:id" do
|
65
|
+
before do
|
66
|
+
params[:name] = "name"
|
67
|
+
params[:description] = "description"
|
68
|
+
end
|
69
|
+
|
70
|
+
context "with valid condition" do
|
71
|
+
it "updates the job", :autodoc do
|
72
|
+
put "/jobs/#{job.id}", params, env
|
73
|
+
response.status.should == 204
|
74
|
+
job.reload
|
75
|
+
job.name.should == "name"
|
76
|
+
job.description.should == "description"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "DELETE /jobs/:id" do
|
82
|
+
it "deletes the job" do
|
83
|
+
delete "/jobs/#{job.id}", params, env
|
84
|
+
response.status.should == 204
|
85
|
+
Job.should_not be_exist(job.id)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "simplecov"
|
2
|
+
require "coveralls"
|
3
|
+
Coveralls.wear!
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
5
|
+
SimpleCov::Formatter::HTMLFormatter,
|
6
|
+
Coveralls::SimpleCov::Formatter,
|
7
|
+
]
|
8
|
+
SimpleCov.start
|
9
|
+
|
10
|
+
ENV["RAILS_ENV"] ||= "test"
|
11
|
+
require File.expand_path("../../config/environment", __FILE__)
|
12
|
+
require "rspec/rails"
|
13
|
+
require "rspec/autorun"
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
# If you"re not using ActiveRecord, or you"d prefer not to run each of your
|
17
|
+
# examples within a transaction, remove the following line or assign false
|
18
|
+
# instead of true.
|
19
|
+
config.use_transactional_fixtures = true
|
20
|
+
|
21
|
+
# If true, the base class of anonymous controllers will be inferred
|
22
|
+
# automatically. This will be the default behavior in future versions of
|
23
|
+
# rspec-rails.
|
24
|
+
config.infer_base_class_for_anonymous_controllers = false
|
25
|
+
|
26
|
+
# Enables :focus metadata filter.
|
27
|
+
config.filter_run :focus
|
28
|
+
config.run_all_when_everything_filtered = true
|
29
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
30
|
+
|
31
|
+
config.include RSpec::JsonMatcher, type: :request
|
32
|
+
config.include ResponseCodeMatchers, type: :request
|
33
|
+
|
34
|
+
config.before(:suite) do
|
35
|
+
Altria.configuration.workspace_path = Rails.root.join("tmp/workspace")
|
36
|
+
end
|
37
|
+
|
38
|
+
config.after(:suite) do
|
39
|
+
workspace = Rails.root.join("tmp/workspace")
|
40
|
+
workspace.rmtree if workspace.exist?
|
41
|
+
end
|
42
|
+
|
43
|
+
config.before do
|
44
|
+
$redis.stub(:publish)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Resque.inline = true
|