shipit-engine 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|