shipit-engine 0.8.9 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/shipit_bs.js.coffee +2 -0
- data/app/assets/javascripts/task.js.coffee +14 -5
- data/app/assets/javascripts/task/search_bar.js.coffee +52 -0
- data/app/assets/javascripts/task/stream.js.coffee +9 -2
- data/app/assets/javascripts/task/tty.js.coffee +75 -28
- data/app/assets/stylesheets/_base/_forms.scss +5 -0
- data/app/assets/stylesheets/_pages/_commits.scss +1 -1
- data/app/assets/stylesheets/_pages/_deploy.scss +56 -24
- data/app/assets/stylesheets/_pages/_settings.scss +5 -0
- data/app/assets/stylesheets/_structure/_layout.scss +1 -0
- data/app/assets/stylesheets/_structure/_main.scss +4 -0
- data/app/assets/stylesheets/shipit.scss +2 -0
- data/app/assets/stylesheets/shipit_bs.scss +22 -0
- data/app/controllers/shipit/deploys_controller.rb +5 -1
- data/app/controllers/shipit/shipit_controller.rb +10 -3
- data/app/controllers/shipit/stacks_controller.rb +12 -3
- data/app/controllers/shipit/tasks_controller.rb +4 -0
- data/app/helpers/shipit/shipit_helper.rb +18 -0
- data/app/helpers/shipit/stacks_helper.rb +1 -1
- data/app/jobs/shipit/cache_deploy_spec_job.rb +2 -0
- data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -0
- data/app/jobs/shipit/git_mirror_update_job.rb +2 -0
- data/app/jobs/shipit/perform_task_job.rb +1 -0
- data/app/models/shipit/commit.rb +2 -2
- data/app/models/shipit/deploy.rb +1 -1
- data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -1
- data/app/models/shipit/duration.rb +28 -0
- data/app/models/shipit/stack.rb +33 -11
- data/app/models/shipit/task.rb +26 -3
- data/app/serializers/shipit/task_serializer.rb +14 -1
- data/app/views/bootstrap/shipit/missing_settings.html.erb +97 -0
- data/app/views/bootstrap/shipit/stacks/new.html.erb +44 -0
- data/app/views/layouts/shipit.html.erb +1 -1
- data/app/views/layouts/shipit_bootstrap.html.erb +44 -0
- data/app/views/shipit/commits/_commit.html.erb +3 -2
- data/app/views/shipit/deploys/_deploy.html.erb +11 -2
- data/app/views/shipit/deploys/show.html.erb +1 -1
- data/app/views/shipit/stacks/new.html.erb +12 -12
- data/app/views/shipit/stacks/settings.html.erb +5 -0
- data/app/views/shipit/stacks/show.html.erb +1 -1
- data/app/views/shipit/tasks/_task.html.erb +10 -2
- data/app/views/shipit/tasks/_task_output.html.erb +11 -1
- data/app/views/shipit/tasks/show.html.erb +1 -1
- data/config/routes.rb +1 -0
- data/db/migrate/20160324155046_add_started_at_and_ended_at_on_tasks.rb +25 -0
- data/lib/shipit.rb +13 -0
- data/lib/shipit/command.rb +13 -9
- data/lib/shipit/engine.rb +8 -0
- data/lib/shipit/template_renderer_extension.rb +16 -0
- data/lib/shipit/version.rb +1 -1
- data/test/controllers/deploys_controller_test.rb +11 -0
- data/test/controllers/stacks_controller_test.rb +5 -0
- data/test/controllers/tasks_controller_test.rb +6 -0
- data/test/dummy/config/secrets.example.yml +4 -0
- data/test/dummy/config/secrets.yml +2 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/bar.txt +2 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dkfdsf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dskjfsd +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dslkjfjsdf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/plopfizz +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sd +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdkfjsdf +1 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdlfjsdfdsfj +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdlkfjsdlkfjsdlkfjdsfsdfksdfjsldkfjsdlkfjsdf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/shipit.yml +32 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/toto.txt +2 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/bar.txt +1 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/shipit.yml +6 -1
- data/test/dummy/data/stacks/byroot/test/production/git/README.md +1 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +3 -1
- data/test/dummy/db/seeds.rb +6 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3-journal +0 -0
- data/test/fixtures/shipit/tasks.yml +11 -0
- data/test/models/commits_test.rb +1 -1
- data/test/models/deploys_test.rb +40 -0
- data/test/models/duration_test.rb +13 -0
- data/test/models/stacks_test.rb +3 -4
- data/test/unit/command_test.rb +14 -0
- data/vendor/assets/javascripts/clusterize.js +327 -0
- data/vendor/assets/javascripts/mousetrap-global-bind.js +43 -0
- data/vendor/assets/javascripts/mousetrap.js +1021 -0
- data/vendor/assets/javascripts/string_includes.js +14 -0
- data/vendor/assets/stylesheets/clusterize.css +27 -0
- metadata +100 -3
- data/app/assets/javascripts/task/sticky_element.js.coffee +0 -16
data/lib/shipit/command.rb
CHANGED
@@ -8,6 +8,9 @@ module Shipit
|
|
8
8
|
MAX_READ = 64.kilobytes
|
9
9
|
|
10
10
|
Error = Class.new(StandardError)
|
11
|
+
Failed = Class.new(Error)
|
12
|
+
NotFound = Class.new(Error)
|
13
|
+
Denied = Class.new(Error)
|
11
14
|
|
12
15
|
attr_reader :out, :code, :chdir, :env, :args, :pid, :timeout
|
13
16
|
|
@@ -72,8 +75,14 @@ module Shipit
|
|
72
75
|
child_in = @out = @pid = nil
|
73
76
|
FileUtils.mkdir_p(@chdir)
|
74
77
|
with_full_path do
|
75
|
-
|
76
|
-
|
78
|
+
begin
|
79
|
+
@out, child_in, @pid = PTY.spawn(@env, *interpolated_arguments, chdir: @chdir)
|
80
|
+
child_in.close
|
81
|
+
rescue Errno::ENOENT
|
82
|
+
raise NotFound, "#{Shellwords.split(interpolated_arguments.first).first}: command not found"
|
83
|
+
rescue Errno::EACCES
|
84
|
+
raise Denied, "#{Shellwords.split(interpolated_arguments.first).first}: Permission denied"
|
85
|
+
end
|
77
86
|
end
|
78
87
|
@started = true
|
79
88
|
self
|
@@ -93,21 +102,16 @@ module Shipit
|
|
93
102
|
|
94
103
|
_, status = Process.waitpid2(@pid)
|
95
104
|
@code = status.exitstatus
|
96
|
-
yield exit_message + "\n" unless success?
|
97
|
-
|
98
105
|
self
|
99
106
|
end
|
100
107
|
|
101
|
-
def check_status
|
102
|
-
end
|
103
|
-
|
104
108
|
def red(text)
|
105
109
|
"\033[1;31m#{text}\033[0m"
|
106
110
|
end
|
107
111
|
|
108
112
|
def stream!(&block)
|
109
113
|
stream(&block)
|
110
|
-
raise
|
114
|
+
raise Failed.new(exit_message) unless success?
|
111
115
|
self
|
112
116
|
end
|
113
117
|
|
@@ -146,7 +150,7 @@ module Shipit
|
|
146
150
|
Timeout.timeout(wait) do
|
147
151
|
read_stream(@out, &block)
|
148
152
|
end
|
149
|
-
rescue Timeout::Error
|
153
|
+
rescue Timeout::Error, Errno::EIO # Somewhat expected on Linux: http://stackoverflow.com/a/10306782
|
150
154
|
end
|
151
155
|
|
152
156
|
def kill(sig)
|
data/lib/shipit/engine.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'bootstrap'
|
2
|
+
|
1
3
|
module Shipit
|
2
4
|
class Engine < ::Rails::Engine
|
3
5
|
isolate_namespace Shipit
|
@@ -8,15 +10,21 @@ module Shipit
|
|
8
10
|
Rails.application.routes.default_url_options[:host] = Shipit.host
|
9
11
|
Shipit::Engine.routes.default_url_options[:host] = Shipit.host
|
10
12
|
|
13
|
+
app.config.assets.paths << Emoji.images_path
|
11
14
|
app.config.assets.precompile += %w(
|
12
15
|
favicon.ico
|
13
16
|
task.js
|
14
17
|
shipit.js
|
15
18
|
shipit.css
|
19
|
+
shipit_bs.js
|
20
|
+
shipit_bs.css
|
16
21
|
)
|
17
22
|
app.config.assets.precompile << proc do |path|
|
18
23
|
path =~ /\Aplugins\/[\-\w]+\.(js|css)\Z/
|
19
24
|
end
|
25
|
+
app.config.assets.precompile << proc do |path|
|
26
|
+
path.start_with?('emoji/') && path.end_with?('.png')
|
27
|
+
end
|
20
28
|
|
21
29
|
ActionDispatch::ExceptionWrapper.rescue_responses[Shipit::TaskDefinition::NotFound.name] = :not_found
|
22
30
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module TemplateRendererExtension
|
2
|
+
private
|
3
|
+
|
4
|
+
def render_template(template, layout_name = nil, *args)
|
5
|
+
if layout_name && bootstrap?(template)
|
6
|
+
layout_name = 'layouts/shipit_bootstrap'
|
7
|
+
end
|
8
|
+
super(template, layout_name, *args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def bootstrap?(template)
|
12
|
+
template.identifier.start_with?('bootstrap/') || template.identifier.start_with?("#{Shipit.bootstrap_view_path}/")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ActionView::TemplateRenderer.prepend(TemplateRendererExtension)
|
data/lib/shipit/version.rb
CHANGED
@@ -15,11 +15,22 @@ module Shipit
|
|
15
15
|
assert_response :success
|
16
16
|
end
|
17
17
|
|
18
|
+
test "deploys can be observed as raw text" do
|
19
|
+
get :show, stack_id: @stack, id: @deploy.id, format: "txt"
|
20
|
+
assert_response :success
|
21
|
+
assert_equal("text/plain", @response.content_type)
|
22
|
+
end
|
23
|
+
|
18
24
|
test ":new is success" do
|
19
25
|
get :new, stack_id: @stack.to_param, sha: @commit.sha
|
20
26
|
assert_response :success
|
21
27
|
end
|
22
28
|
|
29
|
+
test ":new works for not yet deployed stacks" do
|
30
|
+
@stack = shipit_stacks(:undeployed_stack)
|
31
|
+
get :new, stack_id: @stack.to_param, sha: @stack.commits.last.sha
|
32
|
+
end
|
33
|
+
|
23
34
|
test ":new shows a warning if a deploy is already running" do
|
24
35
|
shipit_deploys(:shipit_running).update_column(:status, 'running')
|
25
36
|
|
@@ -167,5 +167,10 @@ module Shipit
|
|
167
167
|
patch :update, id: @stack.to_param, stack: {ignore_ci: false}, return_to: stack_path(@stack)
|
168
168
|
assert_redirected_to stack_path(@stack)
|
169
169
|
end
|
170
|
+
|
171
|
+
test "#lookup redirects to the canonical URL" do
|
172
|
+
get :lookup, id: @stack.id
|
173
|
+
assert_redirected_to stack_path(@stack)
|
174
|
+
end
|
170
175
|
end
|
171
176
|
end
|
@@ -52,6 +52,12 @@ module Shipit
|
|
52
52
|
assert_response :ok
|
53
53
|
end
|
54
54
|
|
55
|
+
test "triggered tasks can be observed as raw text" do
|
56
|
+
get :show, stack_id: @stack, id: @task.id, format: "txt"
|
57
|
+
assert_response :success
|
58
|
+
assert_equal("text/plain", @response.content_type)
|
59
|
+
end
|
60
|
+
|
55
61
|
test ":abort call abort! on the deploy" do
|
56
62
|
@task = shipit_deploys(:shipit_running)
|
57
63
|
@task.pid = 42
|
@@ -13,6 +13,8 @@ development:
|
|
13
13
|
# api_endpoint:
|
14
14
|
host: 'http://localhost:3000'
|
15
15
|
redis_url: "redis://127.0.0.1:6379/7"
|
16
|
+
# features:
|
17
|
+
# - bootstrap
|
16
18
|
|
17
19
|
test:
|
18
20
|
secret_key_base: s3cr3ts3cr3ts3cr3ts3cr3ts3cr3ts3cr3t
|
@@ -29,3 +31,5 @@ test:
|
|
29
31
|
# -
|
30
32
|
# -
|
31
33
|
redis_url: "redis://127.0.0.1:6379/7"
|
34
|
+
# features:
|
35
|
+
# - bootstrap
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
dslkfnds
|
File without changes
|
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
review:
|
2
|
+
checklist:
|
3
|
+
- Blah Blah
|
4
|
+
checks:
|
5
|
+
- echo 42
|
6
|
+
|
7
|
+
deploy:
|
8
|
+
variables:
|
9
|
+
-
|
10
|
+
name: REBUILD
|
11
|
+
title: Force artifacts rebuild
|
12
|
+
default: '0'
|
13
|
+
pre:
|
14
|
+
- echo pre
|
15
|
+
override:
|
16
|
+
- echo 1
|
17
|
+
- env
|
18
|
+
- sleep 10
|
19
|
+
post:
|
20
|
+
- echo post
|
21
|
+
|
22
|
+
rollback:
|
23
|
+
override:
|
24
|
+
- echo done
|
25
|
+
|
26
|
+
|
27
|
+
tasks:
|
28
|
+
restart:
|
29
|
+
action: Restart application
|
30
|
+
description: Trigger the restart of both app and jobs servers
|
31
|
+
steps:
|
32
|
+
- cap $ENVIRONMENT deploy:restart
|
@@ -0,0 +1 @@
|
|
1
|
+
# test
|
Binary file
|
data/test/dummy/db/schema.rb
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
14
|
+
ActiveRecord::Schema.define(version: 20160324155046) do
|
15
15
|
|
16
16
|
create_table "api_clients", force: :cascade do |t|
|
17
17
|
t.text "permissions", limit: 65535
|
@@ -180,6 +180,8 @@ ActiveRecord::Schema.define(version: 20160303203940) do
|
|
180
180
|
t.text "env"
|
181
181
|
t.integer "confirmations", default: 0, null: false
|
182
182
|
t.boolean "allow_concurrency", default: false, null: false
|
183
|
+
t.datetime "started_at"
|
184
|
+
t.datetime "ended_at"
|
183
185
|
end
|
184
186
|
|
185
187
|
add_index "tasks", ["rolled_up", "created_at", "status"], name: "index_tasks_on_rolled_up_and_created_at_and_status"
|
data/test/dummy/db/seeds.rb
CHANGED
@@ -142,6 +142,8 @@ module Shipit
|
|
142
142
|
chunks: create_chunks,
|
143
143
|
additions: Faker::Number.number(3),
|
144
144
|
deletions: Faker::Number.number(3),
|
145
|
+
started_at: Random.rand(15.minutes.to_i).seconds.ago,
|
146
|
+
ended_at: Time.now.utc,
|
145
147
|
user: users.sample,
|
146
148
|
)
|
147
149
|
deploy.write("$ cap production deploy SHA=yolo")
|
@@ -154,6 +156,8 @@ module Shipit
|
|
154
156
|
status: 'success',
|
155
157
|
user: users.sample,
|
156
158
|
chunks: create_chunks,
|
159
|
+
started_at: Random.rand(15.minutes.to_i).seconds.ago,
|
160
|
+
ended_at: Time.now.utc,
|
157
161
|
)
|
158
162
|
|
159
163
|
stack.tasks.create!(
|
@@ -167,6 +171,8 @@ module Shipit
|
|
167
171
|
'steps' => ['cap $ENVIRONMENT restart'],
|
168
172
|
),
|
169
173
|
chunks: create_chunks,
|
174
|
+
started_at: Random.rand(15.minutes.to_i).seconds.ago,
|
175
|
+
ended_at: Time.now.utc,
|
170
176
|
)
|
171
177
|
end
|
172
178
|
end
|
data/test/dummy/db/test.sqlite3
CHANGED
Binary file
|
Binary file
|
@@ -19,6 +19,8 @@ shipit2:
|
|
19
19
|
additions: 12
|
20
20
|
deletions: 64
|
21
21
|
created_at: <%= (60 - 2).minutes.ago.to_s(:db) %>
|
22
|
+
started_at: <%= (60 - 2).minutes.ago.to_s(:db) %>
|
23
|
+
ended_at: <%= (60 - 4).minutes.ago.to_s(:db) %>
|
22
24
|
|
23
25
|
shipit_restart:
|
24
26
|
user: walrus
|
@@ -41,6 +43,8 @@ shipit_restart:
|
|
41
43
|
]
|
42
44
|
}
|
43
45
|
created_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
|
46
|
+
started_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
|
47
|
+
ended_at: <%= (60 - 4).minutes.ago.to_s(:db) %>
|
44
48
|
|
45
49
|
shipit_pending:
|
46
50
|
since_commit_id: 2 # second
|
@@ -62,6 +66,7 @@ shipit_running:
|
|
62
66
|
additions: 420
|
63
67
|
deletions: 342
|
64
68
|
created_at: <%= (60 - 5).minutes.ago.to_s(:db) %>
|
69
|
+
started_at: <%= (60 - 5).minutes.ago.to_s(:db) %>
|
65
70
|
|
66
71
|
shipit_complete:
|
67
72
|
user: bob
|
@@ -73,6 +78,8 @@ shipit_complete:
|
|
73
78
|
additions: 420
|
74
79
|
deletions: 342
|
75
80
|
created_at: <%= (60 - 6).minutes.ago.to_s(:db) %>
|
81
|
+
started_at: <%= (60 - 6).minutes.ago.to_s(:db) %>
|
82
|
+
ended_at: <%= (60 - 2).minutes.ago.to_s(:db) %>
|
76
83
|
|
77
84
|
shipit_aborted:
|
78
85
|
user: bob
|
@@ -85,6 +92,8 @@ shipit_aborted:
|
|
85
92
|
deletions: 342
|
86
93
|
rollback_once_aborted: true
|
87
94
|
created_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
|
95
|
+
started_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
|
96
|
+
ended_at: <%= (60 - 6).minutes.ago.to_s(:db) %>
|
88
97
|
|
89
98
|
shipit_rollback:
|
90
99
|
user: bob
|
@@ -97,3 +106,5 @@ shipit_rollback:
|
|
97
106
|
additions: 420
|
98
107
|
deletions: 342
|
99
108
|
created_at: <%= (60 - 8).minutes.ago.to_s(:db) %>
|
109
|
+
started_at: <%= (60 - 8).minutes.ago.to_s(:db) %>
|
110
|
+
ended_at: <%= (60 - 7).minutes.ago.to_s(:db) %>
|
data/test/models/commits_test.rb
CHANGED
data/test/models/deploys_test.rb
CHANGED
@@ -103,6 +103,16 @@ module Shipit
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
+
test "transitioning to success persists `ended_at`" do
|
107
|
+
deploy = shipit_deploys(:shipit_running)
|
108
|
+
|
109
|
+
assert_nil deploy.ended_at
|
110
|
+
deploy.complete!
|
111
|
+
deploy.reload
|
112
|
+
assert_instance_of ActiveSupport::TimeWithZone, deploy.ended_at
|
113
|
+
assert_in_delta Time.now.utc, deploy.ended_at, 2
|
114
|
+
end
|
115
|
+
|
106
116
|
test "transitioning to failed causes an event to be broadcasted" do
|
107
117
|
deploy = shipit_deploys(:shipit_pending)
|
108
118
|
|
@@ -113,6 +123,16 @@ module Shipit
|
|
113
123
|
end
|
114
124
|
end
|
115
125
|
|
126
|
+
test "transitioning to failed persists `ended_at`" do
|
127
|
+
deploy = shipit_deploys(:shipit_running)
|
128
|
+
|
129
|
+
assert_nil deploy.ended_at
|
130
|
+
deploy.failure!
|
131
|
+
deploy.reload
|
132
|
+
assert_instance_of ActiveSupport::TimeWithZone, deploy.ended_at
|
133
|
+
assert_in_delta Time.now.utc, deploy.ended_at, 2
|
134
|
+
end
|
135
|
+
|
116
136
|
test "transitioning to error causes an event to be broadcasted" do
|
117
137
|
deploy = shipit_deploys(:shipit_pending)
|
118
138
|
|
@@ -123,6 +143,16 @@ module Shipit
|
|
123
143
|
end
|
124
144
|
end
|
125
145
|
|
146
|
+
test "transitioning to error persists `ended_at`" do
|
147
|
+
deploy = shipit_deploys(:shipit_running)
|
148
|
+
|
149
|
+
assert_nil deploy.ended_at
|
150
|
+
deploy.error!
|
151
|
+
deploy.reload
|
152
|
+
assert_instance_of ActiveSupport::TimeWithZone, deploy.ended_at
|
153
|
+
assert_in_delta Time.now.utc, deploy.ended_at, 2
|
154
|
+
end
|
155
|
+
|
126
156
|
test "transitioning to running causes an event to be broadcasted" do
|
127
157
|
deploy = shipit_deploys(:shipit_pending)
|
128
158
|
|
@@ -133,6 +163,16 @@ module Shipit
|
|
133
163
|
end
|
134
164
|
end
|
135
165
|
|
166
|
+
test "transitioning to running persists `started_at`" do
|
167
|
+
deploy = shipit_deploys(:shipit_pending)
|
168
|
+
|
169
|
+
assert_nil deploy.started_at
|
170
|
+
deploy.run!
|
171
|
+
deploy.reload
|
172
|
+
assert_instance_of ActiveSupport::TimeWithZone, deploy.started_at
|
173
|
+
assert_in_delta Time.now.utc, deploy.started_at, 2
|
174
|
+
end
|
175
|
+
|
136
176
|
test "creating a deploy causes an event to be broadcasted" do
|
137
177
|
shipit = shipit_stacks(:shipit)
|
138
178
|
deploy = shipit.deploys.build(
|