shipit-engine 0.19.0 → 0.20.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/stylesheets/_pages/_deploy.scss +4 -0
- data/app/controllers/shipit/api/tasks_controller.rb +4 -0
- data/app/jobs/shipit/github_sync_job.rb +3 -9
- data/app/jobs/shipit/purge_old_deliveries_job.rb +11 -0
- data/app/models/shipit/delivery.rb +6 -2
- data/app/models/shipit/deploy.rb +2 -1
- data/app/models/shipit/deploy_spec/bundler_discovery.rb +10 -1
- data/app/models/shipit/deploy_spec/file_system.rb +1 -1
- data/app/models/shipit/hook.rb +8 -0
- data/app/models/shipit/rollback.rb +8 -0
- data/app/models/shipit/stack.rb +27 -6
- data/app/serializers/shipit/task_serializer.rb +1 -0
- data/app/views/shipit/deploys/_deploy.html.erb +1 -0
- data/app/views/shipit/stacks/_header.html.erb +1 -1
- data/app/views/shipit/tasks/_task.html.erb +2 -0
- data/db/migrate/20170629141736_add_ignored_safeties_on_tasks.rb +5 -0
- data/lib/shipit.rb +12 -0
- data/lib/shipit/stack_commands.rb +3 -3
- data/lib/shipit/task_commands.rb +1 -0
- data/lib/shipit/version.rb +1 -1
- data/lib/tasks/cron.rake +1 -6
- data/test/controllers/api/tasks_controller_test.rb +8 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +2 -1
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3-journal +0 -0
- data/test/fixtures/shipit/deliveries.yml +1 -0
- data/test/jobs/purge_old_deliveries_job_test.rb +15 -0
- data/test/models/deploy_spec_test.rb +29 -2
- data/test/models/deploys_test.rb +15 -0
- data/test/models/hook_test.rb +8 -0
- data/test/models/rollbacks_test.rb +34 -0
- data/test/models/stacks_test.rb +24 -1
- data/test/unit/deploy_commands_test.rb +6 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32c15d6ba8aee487f4738a05b978cb87ce525c51
|
4
|
+
data.tar.gz: 4652419bd067b12dc0e8689f1bc76befdfa96657
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d815536be09f672e39a8eaa61347321765a884707720f22d88985908b6eb0065426c0252d6906e8a9485fd2e178aa5aa64401eb1f92c054e57a5a93e58cb048
|
7
|
+
data.tar.gz: c4ab143452da7c46d36374cc4b778bed710d1fe8144a043d22af140dda730e37610350c18787e20a635eb91e1f6d2421de754facc1fccbf61caf4ac0931d1381
|
@@ -17,6 +17,10 @@ module Shipit
|
|
17
17
|
end
|
18
18
|
def trigger
|
19
19
|
render_resource stack.trigger_task(params[:task_name], current_user, env: params.env), status: :accepted
|
20
|
+
rescue Shipit::Task::ConcurrentTaskRunning
|
21
|
+
render status: :conflict, json: {
|
22
|
+
message: 'A task is already running.',
|
23
|
+
}
|
20
24
|
end
|
21
25
|
end
|
22
26
|
end
|
@@ -16,23 +16,17 @@ module Shipit
|
|
16
16
|
|
17
17
|
@stack.transaction do
|
18
18
|
shared_parent.try!(:detach_children!)
|
19
|
-
new_commits.
|
19
|
+
appended_commits = new_commits.map do |gh_commit|
|
20
20
|
append_commit(gh_commit)
|
21
21
|
end
|
22
|
+
@stack.lock_reverted_commits! if appended_commits.any?(&:revert?)
|
22
23
|
end
|
23
24
|
end
|
24
25
|
CacheDeploySpecJob.perform_later(@stack)
|
25
26
|
end
|
26
27
|
|
27
28
|
def append_commit(gh_commit)
|
28
|
-
|
29
|
-
if appended_commit.revert?
|
30
|
-
impacted_commits = @stack.undeployed_commits.reverse.drop_while { |c| !appended_commit.revert_of?(c) }
|
31
|
-
impacted_commits.pop # appended_commit
|
32
|
-
impacted_commits.each do |impacted_commit|
|
33
|
-
impacted_commit.update!(locked: true)
|
34
|
-
end
|
35
|
-
end
|
29
|
+
@stack.commits.create_from_github!(gh_commit)
|
36
30
|
end
|
37
31
|
|
38
32
|
def fetch_missing_commits(&block)
|
@@ -5,13 +5,13 @@ module Shipit
|
|
5
5
|
|
6
6
|
belongs_to :hook
|
7
7
|
|
8
|
-
scope :due_for_deletion, -> { where('created_at < ?', 1.month.ago) }
|
9
|
-
|
10
8
|
validates :url, presence: true, url: {no_local: true, allow_blank: true}
|
11
9
|
validates :content_type, presence: true
|
12
10
|
|
13
11
|
serialize :response_headers, JSON
|
14
12
|
|
13
|
+
after_commit :purge_old_deliveries, on: :create
|
14
|
+
|
15
15
|
def schedule!
|
16
16
|
DeliverHookJob.perform_later(self)
|
17
17
|
scheduled!
|
@@ -29,6 +29,10 @@ module Shipit
|
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
+
def purge_old_deliveries
|
33
|
+
PurgeOldDeliveriesJob.perform_later(hook)
|
34
|
+
end
|
35
|
+
|
32
36
|
def http
|
33
37
|
Faraday::Connection.new do |connection|
|
34
38
|
connection.headers = headers
|
data/app/models/shipit/deploy.rb
CHANGED
@@ -46,6 +46,7 @@ module Shipit
|
|
46
46
|
until_commit: until_commit,
|
47
47
|
env: env.try!(:to_h) || {},
|
48
48
|
allow_concurrency: force,
|
49
|
+
ignored_safeties: force,
|
49
50
|
)
|
50
51
|
end
|
51
52
|
|
@@ -117,7 +118,7 @@ module Shipit
|
|
117
118
|
end
|
118
119
|
|
119
120
|
def reject!
|
120
|
-
return if failed?
|
121
|
+
return if failed? || aborted?
|
121
122
|
transaction do
|
122
123
|
flap! unless flapping?
|
123
124
|
update!(confirmations: [confirmations - 1, -1].min)
|
@@ -54,7 +54,16 @@ module Shipit
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def coerce_task_definition(config)
|
57
|
-
|
57
|
+
coerced_steps = Array(config['steps']).map do |command|
|
58
|
+
should_prepend_bundle_exec?(command) ? bundle_exec(command) : command
|
59
|
+
end
|
60
|
+
config.merge('steps' => coerced_steps)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def should_prepend_bundle_exec?(command)
|
66
|
+
Shipit.automatically_prepend_bundle_exec && !command.start_with?('bundle exec')
|
58
67
|
end
|
59
68
|
end
|
60
69
|
end
|
data/app/models/shipit/hook.rb
CHANGED
@@ -2,6 +2,8 @@ module Shipit
|
|
2
2
|
class Hook < ActiveRecord::Base
|
3
3
|
default_scope { order :id }
|
4
4
|
|
5
|
+
DELIVERIES_LOG_SIZE = 500
|
6
|
+
|
5
7
|
CONTENT_TYPES = {
|
6
8
|
'json' => 'application/json',
|
7
9
|
'form' => 'application/x-www-form-urlencoded',
|
@@ -77,6 +79,12 @@ module Shipit
|
|
77
79
|
).schedule!
|
78
80
|
end
|
79
81
|
|
82
|
+
def purge_old_deliveries!(keep: DELIVERIES_LOG_SIZE)
|
83
|
+
if cut_off_time = deliveries.order(created_at: :desc).limit(1).offset(keep).pluck(:created_at).first
|
84
|
+
deliveries.where('created_at > ?', cut_off_time).delete_all
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
80
88
|
private
|
81
89
|
|
82
90
|
def serialize_payload(payload)
|
@@ -2,6 +2,10 @@ module Shipit
|
|
2
2
|
class Rollback < Deploy
|
3
3
|
belongs_to :deploy, foreign_key: :parent_id
|
4
4
|
|
5
|
+
state_machine :status do
|
6
|
+
after_transition to: :success, do: :lock_reverted_commits
|
7
|
+
end
|
8
|
+
|
5
9
|
def rollback?
|
6
10
|
true
|
7
11
|
end
|
@@ -30,6 +34,10 @@ module Shipit
|
|
30
34
|
|
31
35
|
private
|
32
36
|
|
37
|
+
def lock_reverted_commits
|
38
|
+
stack.lock_reverted_commits!
|
39
|
+
end
|
40
|
+
|
33
41
|
def create_commit_deployments
|
34
42
|
# Rollback events are confusing in GitHub
|
35
43
|
end
|
data/app/models/shipit/stack.rb
CHANGED
@@ -97,6 +97,7 @@ module Shipit
|
|
97
97
|
since_commit_id: commit.id,
|
98
98
|
env: definition.filter_envs(env),
|
99
99
|
allow_concurrency: definition.allow_concurrency? || force,
|
100
|
+
ignored_safeties: force,
|
100
101
|
)
|
101
102
|
task.enqueue
|
102
103
|
task
|
@@ -110,6 +111,7 @@ module Shipit
|
|
110
111
|
since_commit: since_commit,
|
111
112
|
env: filter_deploy_envs(env.try!(:to_h) || {}),
|
112
113
|
allow_concurrency: force,
|
114
|
+
ignored_safeties: force || !until_commit.deployable?,
|
113
115
|
)
|
114
116
|
end
|
115
117
|
|
@@ -196,14 +198,15 @@ module Shipit
|
|
196
198
|
commits.reachable.first.try!(:sha)
|
197
199
|
end
|
198
200
|
|
199
|
-
def merge_status
|
201
|
+
def merge_status(backlog_leniency_factor: 1.5)
|
200
202
|
return 'locked' if locked?
|
201
203
|
return 'failure' if %w(failure error).freeze.include?(branch_status)
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
204
|
+
return 'backlogged' if backlogged?(backlog_leniency_factor: backlog_leniency_factor)
|
205
|
+
'success'
|
206
|
+
end
|
207
|
+
|
208
|
+
def backlogged?(backlog_leniency_factor: 1.5)
|
209
|
+
maximum_commits_per_deploy && (undeployed_commits_count > maximum_commits_per_deploy * backlog_leniency_factor)
|
207
210
|
end
|
208
211
|
|
209
212
|
def branch_status
|
@@ -219,6 +222,24 @@ module Shipit
|
|
219
222
|
:default
|
220
223
|
end
|
221
224
|
|
225
|
+
def lock_reverted_commits!
|
226
|
+
commits_to_lock = []
|
227
|
+
|
228
|
+
backlog = undeployed_commits.to_a
|
229
|
+
until backlog.empty?
|
230
|
+
backlog = backlog.drop_while { |c| !c.revert? }
|
231
|
+
if revert = backlog.shift
|
232
|
+
commits_to_lock += backlog.reverse.drop_while { |c| !revert.revert_of?(c) }
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
unless commits_to_lock.empty?
|
237
|
+
if commits.where(id: commits_to_lock.map(&:id).uniq).update_all(locked: true) > 1
|
238
|
+
touch
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
222
243
|
def undeployed_commits
|
223
244
|
scope = commits.reachable.newer_than(last_deployed_commit).order(id: :asc)
|
224
245
|
yield scope if block_given?
|
@@ -20,6 +20,7 @@
|
|
20
20
|
<span class="sha"><%= link_to_github_deploy(deploy) %></span>
|
21
21
|
<span class="code-additions">+<%= deploy.additions %></span>
|
22
22
|
<span class="code-deletions">-<%= deploy.deletions %></span>
|
23
|
+
<% if deploy.ignored_safeties? %><span class="ignored-safeties">ignoring safeties</span><% end %>
|
23
24
|
</p>
|
24
25
|
<p class="commit-meta">
|
25
26
|
<% if read_only %>
|
@@ -21,7 +21,7 @@
|
|
21
21
|
</li>
|
22
22
|
<% if stack.merge_queue_enabled? %>
|
23
23
|
<li class="nav__list__item">
|
24
|
-
<%= link_to "
|
24
|
+
<%= link_to "Merge Queue (#{stack.pull_requests.queued.count})", stack_pull_requests_path(stack) %>
|
25
25
|
</li>
|
26
26
|
<% end %>
|
27
27
|
|
@@ -18,6 +18,7 @@
|
|
18
18
|
</span>
|
19
19
|
<p class="commit-meta">
|
20
20
|
ran a command
|
21
|
+
<% if task.ignored_safeties? %><span class="ignored-safeties">ignoring safeties</span><% end %>
|
21
22
|
</p>
|
22
23
|
<p class="commit-meta">
|
23
24
|
<% if read_only %>
|
@@ -25,6 +26,7 @@
|
|
25
26
|
<% else %>
|
26
27
|
<%= timeago_tag(task.created_at, force: true) %>
|
27
28
|
<% end %>
|
29
|
+
|
28
30
|
</p>
|
29
31
|
</div>
|
30
32
|
</li>
|
data/lib/shipit.rb
CHANGED
@@ -57,6 +57,7 @@ module Shipit
|
|
57
57
|
delegate :table_name_prefix, to: :secrets
|
58
58
|
|
59
59
|
attr_accessor :disable_api_authentication
|
60
|
+
attr_writer :automatically_prepend_bundle_exec
|
60
61
|
|
61
62
|
def app_name
|
62
63
|
@app_name ||= secrets.app_name || Rails.application.class.name.split(':').first || 'Shipit'
|
@@ -206,6 +207,17 @@ module Shipit
|
|
206
207
|
secrets.commands_inactivity_timeout || 5.minutes.to_i
|
207
208
|
end
|
208
209
|
|
210
|
+
def automatically_prepend_bundle_exec
|
211
|
+
unless defined?(@automatically_prepend_bundle_exec)
|
212
|
+
ActiveSupport::Deprecation.warn(
|
213
|
+
'Automatically prepending `bundle exec` will be removed in a future version of Shipit, '\
|
214
|
+
'set `Shipit.automatically_prepend_bundle_exec = false` to test the new behaviour.',
|
215
|
+
)
|
216
|
+
@automatically_prepend_bundle_exec = true
|
217
|
+
end
|
218
|
+
@automatically_prepend_bundle_exec
|
219
|
+
end
|
220
|
+
|
209
221
|
protected
|
210
222
|
|
211
223
|
def revision_file
|
@@ -42,9 +42,9 @@ module Shipit
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def with_temporary_working_directory(commit: nil)
|
45
|
-
|
46
|
-
|
47
|
-
fetch.run!
|
45
|
+
@stack.acquire_git_cache_lock do
|
46
|
+
if !commit || !fetched?(commit).tap(&:run).success?
|
47
|
+
fetch.run!
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
data/lib/shipit/task_commands.rb
CHANGED
data/lib/shipit/version.rb
CHANGED
data/lib/tasks/cron.rake
CHANGED
@@ -7,18 +7,13 @@ namespace :cron do
|
|
7
7
|
Shipit::PullRequest.schedule_merges
|
8
8
|
end
|
9
9
|
|
10
|
-
task hourly: [:rollup, :
|
10
|
+
task hourly: [:rollup, :refresh_users]
|
11
11
|
|
12
12
|
desc "Rolls-up output chunks for completed deploys older than an hour"
|
13
13
|
task rollup: :environment do
|
14
14
|
Shipit::Task.due_for_rollup.find_each(&:schedule_rollup_chunks)
|
15
15
|
end
|
16
16
|
|
17
|
-
desc "Delete old hook delivery records"
|
18
|
-
task purge_deliveries: :environment do
|
19
|
-
Shipit::Delivery.due_for_deletion.delete_all
|
20
|
-
end
|
21
|
-
|
22
17
|
task refresh_users: :environment do
|
23
18
|
Shipit::User.refresh_shard(Time.now.hour % 24, 24)
|
24
19
|
end
|
@@ -81,6 +81,14 @@ module Shipit
|
|
81
81
|
post :trigger, params: {stack_id: @stack.to_param, task_name: 'doesnt_exist'}
|
82
82
|
assert_response :not_found
|
83
83
|
end
|
84
|
+
|
85
|
+
test "#trigger returns 409 when a task is already running" do
|
86
|
+
shipit_deploys(:shipit_running).update!(allow_concurrency: false, status: 'running')
|
87
|
+
assert_predicate @stack, :active_task?
|
88
|
+
post :trigger, params: {stack_id: @stack.to_param, task_name: 'restart'}
|
89
|
+
assert_response :conflict
|
90
|
+
assert_json 'message', 'A task is already running.'
|
91
|
+
end
|
84
92
|
end
|
85
93
|
end
|
86
94
|
end
|
Binary file
|
data/test/dummy/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 20170629141736) do
|
14
14
|
|
15
15
|
create_table "api_clients", force: :cascade do |t|
|
16
16
|
t.text "permissions", limit: 65535
|
@@ -214,6 +214,7 @@ ActiveRecord::Schema.define(version: 20170524125249) do
|
|
214
214
|
t.boolean "allow_concurrency", default: false, null: false
|
215
215
|
t.datetime "started_at"
|
216
216
|
t.datetime "ended_at"
|
217
|
+
t.boolean "ignored_safeties", default: false, null: false
|
217
218
|
t.index ["rolled_up", "created_at", "status"], name: "index_tasks_on_rolled_up_and_created_at_and_status"
|
218
219
|
t.index ["since_commit_id"], name: "index_tasks_on_since_commit_id"
|
219
220
|
t.index ["stack_id", "allow_concurrency", "status"], name: "index_active_tasks"
|
data/test/dummy/db/test.sqlite3
CHANGED
Binary file
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Shipit
|
4
|
+
class PurgeOldDeliveriesJobTest < ActiveSupport::TestCase
|
5
|
+
setup do
|
6
|
+
@hook = shipit_hooks(:shipit_deploys)
|
7
|
+
@job = PurgeOldDeliveriesJob.new
|
8
|
+
end
|
9
|
+
|
10
|
+
test "calls #purge_old_deliveries! on the hook" do
|
11
|
+
@hook.expects(:purge_old_deliveries!).once
|
12
|
+
@job.perform(@hook)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -318,9 +318,36 @@ module Shipit
|
|
318
318
|
assert_equal 'SAFETY_DISABLED', variable_definition.name
|
319
319
|
end
|
320
320
|
|
321
|
-
test "task definitions prepend bundle exec
|
321
|
+
test "task definitions prepend bundle exec by default" do
|
322
322
|
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => %w(foo)}})
|
323
323
|
@spec.expects(:bundler?).returns(true).at_least_once
|
324
|
+
assert_deprecated(/Automatically prepending `bundle exec`/) do
|
325
|
+
definition = @spec.find_task_definition('restart')
|
326
|
+
assert_equal ['bundle exec foo'], definition.steps
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
test "task definitions prepend bundle exec if enabled" do
|
331
|
+
Shipit.expects(:automatically_prepend_bundle_exec).returns(true).at_least_once
|
332
|
+
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => %w(foo)}})
|
333
|
+
@spec.expects(:bundler?).returns(true).at_least_once
|
334
|
+
definition = @spec.find_task_definition('restart')
|
335
|
+
|
336
|
+
assert_equal ['bundle exec foo'], definition.steps
|
337
|
+
end
|
338
|
+
|
339
|
+
test "task definitions do not prepend bundle exec if disabled" do
|
340
|
+
Shipit.expects(:automatically_prepend_bundle_exec).returns(false).at_least_once
|
341
|
+
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => %w(foo)}})
|
342
|
+
definition = @spec.find_task_definition('restart')
|
343
|
+
|
344
|
+
assert_equal ['foo'], definition.steps
|
345
|
+
end
|
346
|
+
|
347
|
+
test "task definitions do not prepend bundle exec if the task already does" do
|
348
|
+
Shipit.expects(:automatically_prepend_bundle_exec).returns(true).at_least_once
|
349
|
+
@spec.expects(:load_config).returns('tasks' => {'restart' => {'steps' => ['bundle exec foo']}})
|
350
|
+
@spec.stubs(:bundler?).returns(true)
|
324
351
|
definition = @spec.find_task_definition('restart')
|
325
352
|
|
326
353
|
assert_equal ['bundle exec foo'], definition.steps
|
@@ -338,7 +365,7 @@ module Shipit
|
|
338
365
|
end
|
339
366
|
|
340
367
|
test "task definitions prepend bundle exec before serialization" do
|
341
|
-
@spec.expects(:
|
368
|
+
@spec.expects(:discover_task_definitions).returns('restart' => {'steps' => %w(foo)})
|
342
369
|
@spec.expects(:bundler?).returns(true).at_least_once
|
343
370
|
|
344
371
|
cached_spec = DeploySpec.load(DeploySpec.dump(@spec))
|
data/test/models/deploys_test.rb
CHANGED
@@ -339,6 +339,11 @@ module Shipit
|
|
339
339
|
assert_equal @user, @stack.lock_author
|
340
340
|
end
|
341
341
|
|
342
|
+
test "#trigger_rollback marks the rollback as `ignored_safeties` if the force option was used" do
|
343
|
+
rollback = @deploy.trigger_rollback(@user, force: true)
|
344
|
+
assert_predicate rollback, :ignored_safeties?
|
345
|
+
end
|
346
|
+
|
342
347
|
test "abort! transition to `aborting`" do
|
343
348
|
@deploy.ping
|
344
349
|
@deploy.abort!
|
@@ -426,6 +431,16 @@ module Shipit
|
|
426
431
|
end
|
427
432
|
end
|
428
433
|
|
434
|
+
test "#reject! bails out if the deploy is canceled already" do
|
435
|
+
@deploy = shipit_deploys(:shipit_aborted)
|
436
|
+
assert_predicate @deploy, :aborted?
|
437
|
+
|
438
|
+
Deploy::CONFIRMATIONS_REQUIRED.times do
|
439
|
+
@deploy.reject!
|
440
|
+
assert_predicate @deploy, :aborted?
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
429
444
|
test "#reject! first transition to flapping then ultimately to failed if the deploy was successful" do
|
430
445
|
assert_predicate @deploy, :success?
|
431
446
|
|
data/test/models/hook_test.rb
CHANGED
@@ -55,5 +55,13 @@ module Shipit
|
|
55
55
|
@hook.stack_id = 42
|
56
56
|
assert @hook.scoped?
|
57
57
|
end
|
58
|
+
|
59
|
+
test "#purge_old_deliveries!" do
|
60
|
+
Hook.deliver(:deploy, @stack, 'foo' => 42)
|
61
|
+
|
62
|
+
assert_difference -> { Delivery.count }, -1 do
|
63
|
+
@hook.purge_old_deliveries!(keep: 1)
|
64
|
+
end
|
65
|
+
end
|
58
66
|
end
|
59
67
|
end
|
@@ -3,6 +3,7 @@ require 'test_helper'
|
|
3
3
|
module Shipit
|
4
4
|
class RollbackTest < ActiveSupport::TestCase
|
5
5
|
setup do
|
6
|
+
@stack = shipit_stacks(:shipit)
|
6
7
|
@rollback = Rollback.new
|
7
8
|
end
|
8
9
|
|
@@ -17,5 +18,38 @@ module Shipit
|
|
17
18
|
test "#supports_rollback? returns false" do
|
18
19
|
refute @rollback.supports_rollback?
|
19
20
|
end
|
21
|
+
|
22
|
+
test "when a rollback succeed reverted commits are locked" do
|
23
|
+
@stack.tasks.where.not(id: shipit_tasks(:shipit_complete).id).delete_all
|
24
|
+
|
25
|
+
deploy = @stack.deploys.success.last
|
26
|
+
reverted_commit = deploy.until_commit
|
27
|
+
|
28
|
+
@stack.commits.create!(
|
29
|
+
sha: '50ce7d4440fcd8c734f8b7b76c86f8db46706e4f',
|
30
|
+
message: %(Revert "#{reverted_commit.message_header}"),
|
31
|
+
author: reverted_commit.author,
|
32
|
+
committer: reverted_commit.committer,
|
33
|
+
authored_at: Time.zone.now,
|
34
|
+
committed_at: Time.zone.now,
|
35
|
+
)
|
36
|
+
|
37
|
+
expected = [
|
38
|
+
['Revert "Merge pull request #7 from shipit-engine/yoloshipit"', false],
|
39
|
+
['fix all the things', false],
|
40
|
+
]
|
41
|
+
assert_equal expected, @stack.undeployed_commits.map { |c| [c.title, c.locked?] }
|
42
|
+
|
43
|
+
rollback = deploy.trigger_revert
|
44
|
+
rollback.run!
|
45
|
+
rollback.complete!
|
46
|
+
|
47
|
+
expected = [
|
48
|
+
['Revert "Merge pull request #7 from shipit-engine/yoloshipit"', false],
|
49
|
+
['fix all the things', true],
|
50
|
+
['yoloshipit!', true],
|
51
|
+
]
|
52
|
+
assert_equal expected, @stack.undeployed_commits.map { |c| [c.title, c.locked?] }
|
53
|
+
end
|
20
54
|
end
|
21
55
|
end
|
data/test/models/stacks_test.rb
CHANGED
@@ -123,7 +123,7 @@ module Shipit
|
|
123
123
|
assert_equal @stack.commits.first.id, deploy.since_commit_id
|
124
124
|
end
|
125
125
|
|
126
|
-
test "#trigger_deploy
|
126
|
+
test "#trigger_deploy enqueues a deploy job" do
|
127
127
|
@stack.deploys.destroy_all
|
128
128
|
Deploy.any_instance.expects(:enqueue).once
|
129
129
|
|
@@ -132,6 +132,22 @@ module Shipit
|
|
132
132
|
assert_instance_of Deploy, deploy
|
133
133
|
end
|
134
134
|
|
135
|
+
test "#trigger_deploy marks the deploy as `ignored_safeties` if the commit wasn't deployable" do
|
136
|
+
last_commit = shipit_commits(:fifth)
|
137
|
+
refute_predicate last_commit, :deployable?
|
138
|
+
|
139
|
+
deploy = @stack.trigger_deploy(last_commit, AnonymousUser.new)
|
140
|
+
assert_predicate deploy, :ignored_safeties?
|
141
|
+
end
|
142
|
+
|
143
|
+
test "#trigger_deploy doesn't mark the deploy as `ignored_safeties` if the commit was deployable" do
|
144
|
+
last_commit = shipit_commits(:third)
|
145
|
+
assert_predicate last_commit, :deployable?
|
146
|
+
|
147
|
+
deploy = @stack.trigger_deploy(last_commit, AnonymousUser.new)
|
148
|
+
refute_predicate deploy, :ignored_safeties?
|
149
|
+
end
|
150
|
+
|
135
151
|
test "#update_deployed_revision bail out if there is an active deploy" do
|
136
152
|
@stack.deploys_and_rollbacks.last.update_columns(status: 'running')
|
137
153
|
assert_no_difference 'Deploy.count' do
|
@@ -428,6 +444,13 @@ module Shipit
|
|
428
444
|
assert_equal 'backlogged', @stack.merge_status
|
429
445
|
end
|
430
446
|
|
447
|
+
test "#merge_status returns success with a higher leniency factor" do
|
448
|
+
@stack.deploys_and_rollbacks.destroy_all
|
449
|
+
@stack.update_undeployed_commits_count
|
450
|
+
@stack.reload
|
451
|
+
assert_equal 'success', @stack.merge_status(backlog_leniency_factor: 2.0)
|
452
|
+
end
|
453
|
+
|
431
454
|
test "#handle_github_redirections update the stack if the repository was renamed" do
|
432
455
|
repo_permalink = 'https://api.github.com/repositories/42'
|
433
456
|
|
@@ -188,6 +188,12 @@ module Shipit
|
|
188
188
|
assert_equal 'BAR', command.env['FOO']
|
189
189
|
end
|
190
190
|
|
191
|
+
test "IGNORED_SAFETIES is exposed" do
|
192
|
+
assert_equal '0', @commands.env['IGNORED_SAFETIES']
|
193
|
+
@deploy.ignored_safeties = true
|
194
|
+
assert_equal '1', @commands.env['IGNORED_SAFETIES']
|
195
|
+
end
|
196
|
+
|
191
197
|
test "#clear_working_directory rm -rf the working directory" do
|
192
198
|
FileUtils.expects(:rm_rf).with(@deploy.working_directory)
|
193
199
|
@commands.clear_working_directory
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shipit-engine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: 0.5.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: 0.5.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: active_model_serializers
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -530,6 +530,7 @@ files:
|
|
530
530
|
- app/jobs/shipit/merge_pull_requests_job.rb
|
531
531
|
- app/jobs/shipit/perform_commit_checks_job.rb
|
532
532
|
- app/jobs/shipit/perform_task_job.rb
|
533
|
+
- app/jobs/shipit/purge_old_deliveries_job.rb
|
533
534
|
- app/jobs/shipit/refresh_github_user_job.rb
|
534
535
|
- app/jobs/shipit/refresh_pull_request_job.rb
|
535
536
|
- app/jobs/shipit/refresh_statuses_job.rb
|
@@ -675,6 +676,7 @@ files:
|
|
675
676
|
- db/migrate/20170524084548_index_pull_requests_on_merge_status.rb
|
676
677
|
- db/migrate/20170524104615_index_commits_on_stack_id_and_sha.rb
|
677
678
|
- db/migrate/20170524125249_fix_tasks_index_by_status.rb
|
679
|
+
- db/migrate/20170629141736_add_ignored_safeties_on_tasks.rb
|
678
680
|
- lib/shipit-engine.rb
|
679
681
|
- lib/shipit.rb
|
680
682
|
- lib/shipit/command.rb
|
@@ -780,6 +782,7 @@ files:
|
|
780
782
|
- test/dummy/db/schema.rb
|
781
783
|
- test/dummy/db/seeds.rb
|
782
784
|
- test/dummy/db/test.sqlite3
|
785
|
+
- test/dummy/db/test.sqlite3-journal
|
783
786
|
- test/dummy/public/404.html
|
784
787
|
- test/dummy/public/422.html
|
785
788
|
- test/dummy/public/500.html
|
@@ -820,6 +823,7 @@ files:
|
|
820
823
|
- test/jobs/github_sync_job_test.rb
|
821
824
|
- test/jobs/merge_pull_requests_job_test.rb
|
822
825
|
- test/jobs/perform_task_job_test.rb
|
826
|
+
- test/jobs/purge_old_deliveries_job_test.rb
|
823
827
|
- test/jobs/refresh_github_user_job_test.rb
|
824
828
|
- test/jobs/refresh_status_job_test.rb
|
825
829
|
- test/jobs/unique_job_test.rb
|
@@ -959,6 +963,7 @@ test_files:
|
|
959
963
|
- test/dummy/db/schema.rb
|
960
964
|
- test/dummy/db/seeds.rb
|
961
965
|
- test/dummy/db/test.sqlite3
|
966
|
+
- test/dummy/db/test.sqlite3-journal
|
962
967
|
- test/dummy/public/404.html
|
963
968
|
- test/dummy/public/422.html
|
964
969
|
- test/dummy/public/500.html
|
@@ -1000,6 +1005,7 @@ test_files:
|
|
1000
1005
|
- test/jobs/github_sync_job_test.rb
|
1001
1006
|
- test/jobs/merge_pull_requests_job_test.rb
|
1002
1007
|
- test/jobs/perform_task_job_test.rb
|
1008
|
+
- test/jobs/purge_old_deliveries_job_test.rb
|
1003
1009
|
- test/jobs/refresh_github_user_job_test.rb
|
1004
1010
|
- test/jobs/refresh_status_job_test.rb
|
1005
1011
|
- test/jobs/unique_job_test.rb
|