shipit-engine 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -1
- data/app/assets/javascripts/shipit/page_updater.js.coffee +63 -0
- data/app/assets/javascripts/shipit/stacks.js.coffee +9 -21
- data/app/assets/stylesheets/_base/_base.scss +2 -2
- data/app/assets/stylesheets/_base/_colors.scss +0 -1
- data/app/assets/stylesheets/_base/_forms.scss +14 -0
- data/app/assets/stylesheets/_pages/_commits.scss +16 -6
- data/app/assets/stylesheets/_pages/_settings.scss +8 -0
- data/app/assets/stylesheets/_pages/_stacks.scss +1 -1
- data/app/controllers/shipit/api/base_controller.rb +7 -3
- data/app/controllers/shipit/api/ccmenu_controller.rb +33 -0
- data/app/controllers/shipit/api/pull_requests_controller.rb +36 -0
- data/app/controllers/shipit/api/stacks_controller.rb +1 -0
- data/app/controllers/shipit/ccmenu_url_controller.rb +22 -0
- data/app/controllers/shipit/pull_requests_controller.rb +30 -0
- data/app/controllers/shipit/stacks_controller.rb +7 -2
- data/app/controllers/shipit/webhooks_controller.rb +1 -2
- data/app/helpers/shipit/github_url_helper.rb +8 -2
- data/app/helpers/shipit/shipit_helper.rb +9 -0
- data/app/helpers/shipit/stacks_helper.rb +22 -7
- data/app/jobs/shipit/background_job/unique.rb +19 -1
- data/app/jobs/shipit/cache_deploy_spec_job.rb +1 -1
- data/app/jobs/shipit/merge_pull_requests_job.rb +26 -0
- data/app/jobs/shipit/perform_task_job.rb +1 -1
- data/app/jobs/shipit/refresh_pull_request_job.rb +8 -0
- data/app/models/concerns/shipit/deferred_touch.rb +6 -1
- data/app/models/shipit/anonymous_user.rb +4 -0
- data/app/models/shipit/application_record.rb +5 -0
- data/app/models/shipit/commit.rb +51 -49
- data/app/models/shipit/commit_message.rb +32 -0
- data/app/models/shipit/deploy.rb +5 -0
- data/app/models/shipit/deploy_spec.rb +26 -1
- data/app/models/shipit/deploy_spec/file_system.rb +6 -1
- data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +10 -13
- data/app/models/shipit/deploy_spec/npm_discovery.rb +2 -1
- data/app/models/shipit/duration.rb +3 -1
- data/app/models/shipit/hook.rb +1 -0
- data/app/models/shipit/pull_request.rb +252 -0
- data/app/models/shipit/stack.rb +33 -17
- data/app/models/shipit/status.rb +1 -16
- data/app/models/shipit/status/common.rb +45 -0
- data/app/models/shipit/status/group.rb +82 -0
- data/app/models/shipit/status/missing.rb +30 -0
- data/app/models/shipit/status/unknown.rb +33 -0
- data/app/models/shipit/unlimited_api_client.rb +10 -0
- data/app/serializers/shipit/commit_serializer.rb +1 -1
- data/app/serializers/shipit/pull_request_serializer.rb +20 -0
- data/app/serializers/shipit/stack_serializer.rb +6 -2
- data/app/views/layouts/shipit.html.erb +41 -39
- data/app/views/shipit/ccmenu/project.xml.builder +13 -0
- data/app/views/shipit/commits/_commit.html.erb +1 -1
- data/app/views/shipit/deploys/_deploy.html.erb +1 -1
- data/app/views/shipit/pull_requests/_pull_request.html.erb +29 -0
- data/app/views/shipit/pull_requests/index.html.erb +20 -0
- data/app/views/shipit/shared/_author.html.erb +7 -0
- data/app/views/shipit/stacks/_header.html.erb +5 -0
- data/app/views/shipit/stacks/settings.html.erb +13 -0
- data/app/views/shipit/stacks/show.html.erb +3 -2
- data/app/views/shipit/statuses/_group.html.erb +1 -1
- data/app/views/shipit/tasks/_task.html.erb +1 -1
- data/config/initializers/inflections.rb +3 -0
- data/config/locales/en.yml +1 -3
- data/config/routes.rb +8 -0
- data/db/migrate/20170130113633_create_shipit_pull_requests.rb +25 -0
- data/db/migrate/20170208143657_add_pull_request_number_and_title_to_commits.rb +7 -0
- data/db/migrate/20170208154609_backfill_merge_commits.rb +13 -0
- data/db/migrate/20170209160355_add_branch_to_pull_requests.rb +5 -0
- data/db/migrate/20170215123538_add_merge_queue_enabled_to_stacks.rb +5 -0
- data/db/migrate/20170220152410_improve_users_indexing.rb +6 -0
- data/db/migrate/20170221102128_improve_tasks_indexing.rb +8 -0
- data/db/migrate/20170221130336_add_last_revalidated_at_on_pull_requests.rb +10 -0
- data/lib/shipit.rb +2 -0
- data/lib/shipit/version.rb +1 -1
- data/lib/tasks/cron.rake +1 -0
- data/test/controllers/api/ccmenu_controller_test.rb +57 -0
- data/test/controllers/api/commits_controller_test.rb +1 -1
- data/test/controllers/api/pull_requests_controller_test.rb +59 -0
- data/test/controllers/ccmenu_controller_test.rb +33 -0
- data/test/controllers/pull_requests_controller_test.rb +31 -0
- data/test/controllers/webhooks_controller_test.rb +3 -4
- data/test/dummy/config/environments/development.rb +3 -1
- data/test/dummy/data/stacks/shopify/junk/production/git/README.md +8 -0
- data/test/dummy/data/stacks/shopify/junk/production/git/circle.yml +4 -0
- data/test/dummy/data/stacks/shopify/junk/production/git/shipit.yml +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +45 -11
- data/test/dummy/db/seeds.rb +33 -10
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/fixtures/shipit/commits.yml +14 -0
- data/test/fixtures/shipit/pull_requests.yml +56 -0
- data/test/fixtures/shipit/stacks.yml +5 -1
- data/test/fixtures/shipit/statuses.yml +8 -0
- data/test/helpers/json_helper.rb +16 -14
- data/test/jobs/merge_pull_requests_job_test.rb +59 -0
- data/test/models/commits_test.rb +104 -49
- data/test/{unit → models}/deploy_spec_test.rb +138 -12
- data/test/models/deploys_test.rb +10 -4
- data/test/models/pull_request_test.rb +197 -0
- data/test/models/stacks_test.rb +46 -53
- data/test/models/status/group_test.rb +44 -0
- data/test/models/status/missing_test.rb +23 -0
- data/test/models/status_test.rb +3 -6
- data/test/unit/csv_serializer_test.rb +10 -2
- metadata +57 -12
- data/app/models/shipit/missing_status.rb +0 -21
- data/app/models/shipit/status_group.rb +0 -35
- data/app/models/shipit/unknown_status.rb +0 -48
- data/app/views/shipit/commits/_commit_author.html.erb +0 -7
- data/test/models/missing_status_test.rb +0 -23
- data/test/models/status_group_test.rb +0 -26
@@ -27,8 +27,7 @@ module Shipit
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
def state
|
30
|
-
if
|
31
|
-
commit = stack.commits.find_by_sha!(params.sha)
|
30
|
+
if commit = stack.commits.find_by_sha(params.sha)
|
32
31
|
commit.create_status_from_github!(params)
|
33
32
|
end
|
34
33
|
head :ok
|
@@ -40,8 +40,14 @@ module Shipit
|
|
40
40
|
github_repo_url(commit.stack.repo_owner, commit.stack.repo_name, 'commit', commit.sha)
|
41
41
|
end
|
42
42
|
|
43
|
-
def github_pull_request_url(
|
44
|
-
|
43
|
+
def github_pull_request_url(pull_request_or_commit)
|
44
|
+
stack = pull_request_or_commit.stack
|
45
|
+
number = if pull_request_or_commit.respond_to?(:pull_request_number)
|
46
|
+
pull_request_or_commit.pull_request_number
|
47
|
+
else
|
48
|
+
pull_request_or_commit.number
|
49
|
+
end
|
50
|
+
github_repo_url(stack.repo_owner, stack.repo_name, 'pull', number)
|
45
51
|
end
|
46
52
|
|
47
53
|
def link_to_github_deploy(deploy)
|
@@ -1,5 +1,14 @@
|
|
1
1
|
module Shipit
|
2
2
|
module ShipitHelper
|
3
|
+
def subscribe(url, *selectors)
|
4
|
+
content_for(:update_subscription) do
|
5
|
+
[
|
6
|
+
tag('meta', name: 'subscription-channel', content: url),
|
7
|
+
*selectors.map { |s| tag('meta', name: 'subscription-selector', content: s) },
|
8
|
+
].join("\n").html_safe
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
3
12
|
def emojify(content)
|
4
13
|
h(content).to_str.gsub(/:([\w+-]+):/) do |match|
|
5
14
|
if emoji = Emoji.find_by_alias($1)
|
@@ -33,16 +33,26 @@ module Shipit
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def github_change_url(commit)
|
36
|
-
commit.
|
36
|
+
if commit.pull_request?
|
37
|
+
github_pull_request_url(commit)
|
38
|
+
else
|
39
|
+
github_commit_url(commit)
|
40
|
+
end
|
37
41
|
end
|
38
42
|
|
39
|
-
def render_commit_message(
|
40
|
-
message =
|
41
|
-
content_tag(:span, emojify(message
|
43
|
+
def render_commit_message(pull_request_or_commit)
|
44
|
+
message = pull_request_or_commit.title.to_s.truncate(COMMIT_TITLE_LENGTH)
|
45
|
+
content_tag(:span, emojify(message), class: 'event-message')
|
46
|
+
end
|
47
|
+
|
48
|
+
def render_pull_request_title_with_link(pull_request)
|
49
|
+
message = render_commit_message(pull_request)
|
50
|
+
link_to(message, github_pull_request_url(pull_request), target: '_blank')
|
42
51
|
end
|
43
52
|
|
44
53
|
def render_commit_message_with_link(commit)
|
45
|
-
|
54
|
+
message = render_commit_message(commit)
|
55
|
+
link_to(message, github_change_url(commit), target: '_blank')
|
46
56
|
end
|
47
57
|
|
48
58
|
def render_commit_id_link(commit)
|
@@ -53,8 +63,13 @@ module Shipit
|
|
53
63
|
end
|
54
64
|
end
|
55
65
|
|
56
|
-
def pull_request_link(
|
57
|
-
|
66
|
+
def pull_request_link(pull_request_or_commit)
|
67
|
+
number = if pull_request_or_commit.respond_to?(:pull_request_number)
|
68
|
+
pull_request_or_commit.pull_request_number
|
69
|
+
else
|
70
|
+
pull_request_or_commit.number
|
71
|
+
end
|
72
|
+
link_to("##{number}", github_pull_request_url(pull_request_or_commit), target: '_blank', class: 'number')
|
58
73
|
end
|
59
74
|
|
60
75
|
def render_raw_commit_id_link(commit)
|
@@ -2,12 +2,12 @@ module Shipit
|
|
2
2
|
class BackgroundJob
|
3
3
|
module Unique
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
|
6
5
|
DEFAULT_TIMEOUT = 10
|
7
6
|
|
8
7
|
included do
|
9
8
|
around_perform { |job, block| job.acquire_lock(&block) }
|
10
9
|
cattr_accessor :lock_timeout
|
10
|
+
on_duplicate :retry
|
11
11
|
end
|
12
12
|
|
13
13
|
def acquire_lock(&block)
|
@@ -18,11 +18,29 @@ module Shipit
|
|
18
18
|
timeout: self.class.lock_timeout || 0,
|
19
19
|
)
|
20
20
|
mutex.lock(&block)
|
21
|
+
rescue Redis::Lock::LockTimeout
|
22
|
+
raise unless self.class.drop_duplicate_jobs?
|
21
23
|
end
|
22
24
|
|
23
25
|
def lock_key(*args)
|
24
26
|
ActiveJob::Arguments.serialize([self.class.name] + args).join('-')
|
25
27
|
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
ACTIONS = %i(retry drop).freeze
|
31
|
+
ACTIONS_LIST = ACTIONS.map(&:inspect).join(', ').freeze
|
32
|
+
def on_duplicate(action)
|
33
|
+
unless ACTIONS.include?(action)
|
34
|
+
raise ArgumentsError, "invalid action: #{action.inspect}, should be one of #{ACTIONS_LIST}"
|
35
|
+
end
|
36
|
+
|
37
|
+
@on_duplicate = action
|
38
|
+
end
|
39
|
+
|
40
|
+
def drop_duplicate_jobs?
|
41
|
+
@on_duplicate == :drop
|
42
|
+
end
|
43
|
+
end
|
26
44
|
end
|
27
45
|
end
|
28
46
|
end
|
@@ -6,7 +6,7 @@ module Shipit
|
|
6
6
|
return if stack.inaccessible?
|
7
7
|
|
8
8
|
commands = Commands.for(stack)
|
9
|
-
commands.with_temporary_working_directory(commit: stack.commits.last) do |path|
|
9
|
+
commands.with_temporary_working_directory(commit: stack.commits.reachable.last) do |path|
|
10
10
|
stack.update!(cached_deploy_spec: DeploySpec::FileSystem.new(path, stack.environment))
|
11
11
|
end
|
12
12
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Shipit
|
2
|
+
class MergePullRequestsJob < BackgroundJob
|
3
|
+
include BackgroundJob::Unique
|
4
|
+
on_duplicate :drop
|
5
|
+
|
6
|
+
def perform(stack)
|
7
|
+
pull_requests = stack.pull_requests.to_be_merged.to_a
|
8
|
+
pull_requests.each do |pull_request|
|
9
|
+
pull_request.refresh!
|
10
|
+
pull_request.reject_unless_mergeable!
|
11
|
+
end
|
12
|
+
|
13
|
+
return false unless stack.allows_merges?
|
14
|
+
|
15
|
+
pull_requests.select(&:pending?).each do |pull_request|
|
16
|
+
pull_request.refresh!
|
17
|
+
begin
|
18
|
+
pull_request.merge!
|
19
|
+
rescue PullRequest::NotReady
|
20
|
+
MergePullRequestsJob.set(wait: 10.seconds).perform_later(stack)
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -77,7 +77,12 @@ module Shipit
|
|
77
77
|
|
78
78
|
def schedule_touches
|
79
79
|
return unless self.class.deferred_touches
|
80
|
-
|
80
|
+
deferred_touches = self.class.deferred_touches.reject do |m, _fk, _a|
|
81
|
+
ActiveRecord::NoTouching.applied_to?(m.constantize)
|
82
|
+
end
|
83
|
+
return if deferred_touches.empty?
|
84
|
+
|
85
|
+
touches = deferred_touches.map { |m, fk, a| [m, self[fk], a].join('|') }
|
81
86
|
Shipit.redis.sadd(SET_KEY, touches)
|
82
87
|
if DeferredTouch.enabled
|
83
88
|
Rails.cache.fetch(CACHE_KEY, expires_in: THROTTLE_TTL) do
|
data/app/models/shipit/commit.rb
CHANGED
@@ -8,9 +8,11 @@ module Shipit
|
|
8
8
|
has_many :deploys
|
9
9
|
has_many :statuses, -> { order(created_at: :desc) }, dependent: :destroy
|
10
10
|
has_many :commit_deployments, dependent: :destroy
|
11
|
+
belongs_to :pull_request, inverse_of: :merge_commit
|
11
12
|
|
12
13
|
deferred_touch stack: :updated_at
|
13
14
|
|
15
|
+
before_create :identify_pull_request
|
14
16
|
after_commit { broadcast_update }
|
15
17
|
after_create { stack.update_undeployed_commits_count }
|
16
18
|
|
@@ -21,7 +23,8 @@ module Shipit
|
|
21
23
|
|
22
24
|
scope :reachable, -> { where(detached: false) }
|
23
25
|
|
24
|
-
delegate :broadcast_update, :github_repo_name,
|
26
|
+
delegate :broadcast_update, :github_repo_name, :hidden_statuses, :required_statuses,
|
27
|
+
:soft_failing_statuses, to: :stack
|
25
28
|
|
26
29
|
def self.newer_than(commit)
|
27
30
|
return all unless commit
|
@@ -69,12 +72,14 @@ module Shipit
|
|
69
72
|
end
|
70
73
|
|
71
74
|
def reload(*)
|
72
|
-
@
|
75
|
+
@status = nil
|
73
76
|
super
|
74
77
|
end
|
75
78
|
|
76
|
-
def self.create_from_github!(commit)
|
77
|
-
from_github(commit)
|
79
|
+
def self.create_from_github!(commit, extra_attributes = {})
|
80
|
+
record = from_github(commit)
|
81
|
+
record.update!(extra_attributes)
|
82
|
+
record
|
78
83
|
end
|
79
84
|
|
80
85
|
def schedule_refresh_statuses!
|
@@ -112,30 +117,26 @@ module Shipit
|
|
112
117
|
children.detach!
|
113
118
|
end
|
114
119
|
|
115
|
-
def
|
116
|
-
|
120
|
+
def pull_request?
|
121
|
+
pull_request_number.present?
|
117
122
|
end
|
118
123
|
|
119
|
-
def pull_request_number
|
120
|
-
|
124
|
+
def pull_request_number # TODO: remove in a few versions when it is assumed the commits table was backfilled
|
125
|
+
super || message_parser.pull_request_number
|
121
126
|
end
|
122
127
|
|
123
|
-
def
|
124
|
-
|
128
|
+
def title
|
129
|
+
pull_request_title || message
|
125
130
|
end
|
126
131
|
|
127
|
-
def
|
128
|
-
|
132
|
+
def pull_request_title # TODO: remove in a few versions when it is assumed the commits table was backfilled
|
133
|
+
super || message_parser.pull_request_title
|
129
134
|
end
|
130
135
|
|
131
136
|
def short_sha
|
132
137
|
sha[0..9]
|
133
138
|
end
|
134
139
|
|
135
|
-
def parsed
|
136
|
-
@parsed ||= message.match(/\AMerge pull request #(?<pr_id>\d+) from [\w\-.\/]+\n\n(?<pr_title>.*)/)
|
137
|
-
end
|
138
|
-
|
139
140
|
def schedule_continuous_delivery
|
140
141
|
return unless deployable? && stack.continuous_deployment? && stack.deployable?
|
141
142
|
ContinuousDeliveryJob.perform_later(stack)
|
@@ -156,30 +157,8 @@ module Shipit
|
|
156
157
|
)
|
157
158
|
end
|
158
159
|
|
159
|
-
def visible_statuses
|
160
|
-
stack.filter_visible_statuses(last_statuses).presence || [UnknownStatus.new(self)]
|
161
|
-
end
|
162
|
-
|
163
|
-
def meaningful_statuses
|
164
|
-
stack.filter_meaningful_statuses(last_statuses).presence || [UnknownStatus.new(self)]
|
165
|
-
end
|
166
|
-
|
167
|
-
def last_statuses
|
168
|
-
@last_statuses ||= statuses.to_a.uniq(&:context).sort_by(&:context).presence || [UnknownStatus.new(self)]
|
169
|
-
end
|
170
|
-
|
171
160
|
def status
|
172
|
-
|
173
|
-
status = visibles.size > 1 ? StatusGroup.new(significant_status, visibles) : visibles.first
|
174
|
-
missing_statuses.empty? ? status : MissingStatus.new(status, missing_statuses)
|
175
|
-
end
|
176
|
-
|
177
|
-
def significant_status
|
178
|
-
statuses = meaningful_statuses
|
179
|
-
return UnknownStatus.new(self) if statuses.empty?
|
180
|
-
return statuses.first if statuses.all?(&:success?)
|
181
|
-
non_success_statuses = statuses.reject(&:success?)
|
182
|
-
non_success_statuses.reject(&:pending?).first || non_success_statuses.first || UnknownStatus.new(self)
|
161
|
+
@status ||= Status::Group.compact(self, statuses)
|
183
162
|
end
|
184
163
|
|
185
164
|
def deployed?
|
@@ -190,24 +169,47 @@ module Shipit
|
|
190
169
|
stack.deploys.unsuccessful.where(until_commit_id: id).any?
|
191
170
|
end
|
192
171
|
|
172
|
+
def identify_pull_request
|
173
|
+
return unless message_parser.pull_request?
|
174
|
+
if pull_request = stack.pull_requests.find_by_number(message_parser.pull_request_number)
|
175
|
+
self.pull_request = pull_request
|
176
|
+
self.pull_request_number = pull_request.number
|
177
|
+
self.pull_request_title = pull_request.title
|
178
|
+
self.author = pull_request.merge_requested_by if pull_request.merge_requested_by
|
179
|
+
end
|
180
|
+
|
181
|
+
self.pull_request_number = message_parser.pull_request_number unless self[:pull_request_number]
|
182
|
+
self.pull_request_title = message_parser.pull_request_title unless self[:pull_request_title]
|
183
|
+
end
|
184
|
+
|
193
185
|
private
|
194
186
|
|
187
|
+
def message_parser
|
188
|
+
@message_parser ||= CommitMessage.new(message)
|
189
|
+
end
|
190
|
+
|
195
191
|
def add_status
|
196
|
-
|
192
|
+
already_deployed = deployed?
|
193
|
+
|
194
|
+
previous_status = status
|
197
195
|
yield
|
198
196
|
reload # to get the statuses into the right order (since sorted :desc)
|
199
|
-
new_status =
|
197
|
+
new_status = status
|
200
198
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
Hook.emit(:deployable_status, stack, payload.merge(deployable_status: new_status))
|
199
|
+
unless already_deployed
|
200
|
+
payload = {commit: self, stack: stack, status: new_status.state}
|
201
|
+
Hook.emit(:commit_status, stack, payload.merge(commit_status: new_status)) if previous_status != new_status
|
205
202
|
end
|
206
|
-
new_status
|
207
|
-
end
|
208
203
|
|
209
|
-
|
210
|
-
|
204
|
+
if previous_status.simple_state != new_status.simple_state
|
205
|
+
if !already_deployed && (!new_status.pending? || previous_status.unknown?)
|
206
|
+
Hook.emit(:deployable_status, stack, payload.merge(deployable_status: new_status))
|
207
|
+
end
|
208
|
+
if new_status.pending? || new_status.success?
|
209
|
+
stack.schedule_merges
|
210
|
+
end
|
211
|
+
end
|
212
|
+
new_status
|
211
213
|
end
|
212
214
|
end
|
213
215
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Shipit
|
2
|
+
class CommitMessage
|
3
|
+
GITHUB_MERGE_COMMIT_PATTERN = %r{\AMerge pull request #(?<pr_id>\d+) from [\w\-./]+\n\n(?<pr_title>.*)}
|
4
|
+
|
5
|
+
def initialize(text)
|
6
|
+
@text = text
|
7
|
+
end
|
8
|
+
|
9
|
+
def pull_request?
|
10
|
+
!!parsed
|
11
|
+
end
|
12
|
+
|
13
|
+
def pull_request_number
|
14
|
+
parsed && parsed['pr_id'].to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
def pull_request_title
|
18
|
+
parsed && parsed['pr_title']
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
@text
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parsed
|
28
|
+
return @parsed if defined?(@parsed)
|
29
|
+
@parsed = to_s.match(GITHUB_MERGE_COMMIT_PATTERN)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/app/models/shipit/deploy.rb
CHANGED
@@ -6,6 +6,7 @@ module Shipit
|
|
6
6
|
|
7
7
|
state_machine :status do
|
8
8
|
after_transition to: :success, do: :schedule_continuous_delivery
|
9
|
+
after_transition to: :success, do: :schedule_merges
|
9
10
|
after_transition to: :success, do: :update_undeployed_commits_count
|
10
11
|
after_transition to: :aborted, do: :trigger_revert_if_required
|
11
12
|
after_transition any => any, do: :update_commit_deployments
|
@@ -163,6 +164,10 @@ module Shipit
|
|
163
164
|
self.deletions = commits.map(&:deletions).compact.sum
|
164
165
|
end
|
165
166
|
|
167
|
+
def schedule_merges
|
168
|
+
stack.schedule_merges
|
169
|
+
end
|
170
|
+
|
166
171
|
def schedule_continuous_delivery
|
167
172
|
return unless stack.continuous_deployment?
|
168
173
|
ContinuousDeliveryJob.perform_later(stack)
|
@@ -64,7 +64,7 @@ module Shipit
|
|
64
64
|
alias_method :dependencies_steps!, :dependencies_steps
|
65
65
|
|
66
66
|
def maximum_commits_per_deploy
|
67
|
-
config('deploy', 'max_commits')
|
67
|
+
config('deploy', 'max_commits') { 8 }
|
68
68
|
end
|
69
69
|
|
70
70
|
def pause_between_deploys
|
@@ -143,6 +143,31 @@ module Shipit
|
|
143
143
|
Array.wrap(config('ci', 'allow_failures'))
|
144
144
|
end
|
145
145
|
|
146
|
+
def pull_request_required_statuses
|
147
|
+
if config('merge', 'require') || config('merge', 'ignore')
|
148
|
+
Array.wrap(config('merge', 'require'))
|
149
|
+
else
|
150
|
+
required_statuses
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def pull_request_ignored_statuses
|
155
|
+
if config('merge', 'require') || config('merge', 'ignore')
|
156
|
+
Array.wrap(config('merge', 'ignore'))
|
157
|
+
else
|
158
|
+
soft_failing_statuses | hidden_statuses
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def revalidate_pull_requests_after
|
163
|
+
if timeout = config('merge', 'revalidate_after')
|
164
|
+
begin
|
165
|
+
Duration.parse(timeout)
|
166
|
+
rescue Duration::ParseError
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
146
171
|
def review_checks
|
147
172
|
config('review', 'checks') || []
|
148
173
|
end
|