shipit-engine 0.24.0 → 0.25.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/javascripts/shipit/stacks.js.coffee +15 -1
- data/app/assets/stylesheets/_base/_icons.scss +18 -0
- data/app/assets/stylesheets/_base/_status-items.scss +28 -0
- data/app/assets/stylesheets/_pages/_commits.scss +1 -5
- data/app/assets/stylesheets/_pages/_deploy.scss +60 -3
- data/app/controllers/concerns/shipit/authentication.rb +1 -1
- data/app/controllers/shipit/merge_status_controller.rb +2 -0
- data/app/controllers/shipit/release_statuses_controller.rb +36 -0
- data/app/jobs/shipit/append_delayed_release_status_job.rb +17 -0
- data/app/jobs/shipit/cache_deploy_spec_job.rb +2 -0
- data/app/jobs/shipit/clear_git_cache_job.rb +1 -1
- data/app/jobs/shipit/create_release_statuses_job.rb +11 -0
- data/app/jobs/shipit/deferred_touch_job.rb +2 -0
- data/app/jobs/shipit/deliver_hook_job.rb +1 -0
- data/app/jobs/shipit/merge_pull_requests_job.rb +2 -0
- data/app/jobs/shipit/perform_commit_checks_job.rb +2 -0
- data/app/jobs/shipit/perform_task_job.rb +2 -4
- data/app/jobs/shipit/refresh_pull_request_job.rb +2 -0
- data/app/models/shipit/anonymous_user.rb +1 -1
- data/app/models/shipit/commit.rb +36 -3
- data/app/models/shipit/deploy.rb +43 -0
- data/app/models/shipit/deploy_spec.rb +16 -2
- data/app/models/shipit/deploy_spec/bundler_discovery.rb +5 -1
- data/app/models/shipit/deploy_spec/file_system.rb +4 -0
- data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +1 -1
- data/app/models/shipit/ephemeral_commit_checks.rb +2 -4
- data/app/models/shipit/hook.rb +36 -3
- data/app/models/shipit/pull_request.rb +4 -2
- data/app/models/shipit/release_status.rb +41 -0
- data/app/models/shipit/rollback.rb +9 -0
- data/app/models/shipit/stack.rb +4 -9
- data/app/models/shipit/status/common.rb +4 -0
- data/app/models/shipit/status/group.rb +2 -1
- data/app/models/shipit/status/missing.rb +4 -0
- data/app/models/shipit/status/unknown.rb +15 -0
- data/app/models/shipit/task.rb +4 -0
- data/app/models/shipit/user.rb +16 -3
- data/app/serializers/shipit/stack_serializer.rb +1 -1
- data/app/views/shipit/deploys/_deploy.html.erb +18 -2
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20180802172632_allow_commit_without_author.rb +6 -0
- data/db/migrate/20180906083930_create_release_statuses.rb +21 -0
- data/lib/shipit.rb +5 -0
- data/lib/shipit/command.rb +14 -18
- data/lib/shipit/deploy_commands.rb +0 -4
- data/lib/shipit/engine.rb +1 -1
- data/lib/shipit/first_parent_commits_iterator.rb +1 -1
- data/lib/shipit/flock.rb +43 -0
- data/lib/shipit/github_app.rb +5 -3
- data/lib/shipit/rollback_commands.rb +6 -0
- data/lib/shipit/task_commands.rb +1 -5
- data/lib/shipit/version.rb +1 -1
- data/test/controllers/release_statuses_controller_test.rb +23 -0
- data/test/dummy/db/schema.rb +18 -3
- data/test/dummy/db/seeds.rb +4 -0
- data/test/fixtures/shipit/commits.yml +13 -0
- data/test/fixtures/shipit/release_statuses.yml +16 -0
- data/test/fixtures/shipit/stacks.yml +4 -0
- data/test/jobs/append_delayed_release_status_job_test.rb +25 -0
- data/test/jobs/cache_deploy_spec_job_test.rb +1 -2
- data/test/jobs/emit_event_job_test.rb +1 -1
- data/test/jobs/github_sync_job_test.rb +1 -0
- data/test/models/commits_test.rb +54 -1
- data/test/models/deploy_spec_test.rb +83 -11
- data/test/models/deploys_test.rb +52 -0
- data/test/models/hook_test.rb +1 -28
- data/test/models/pull_request_test.rb +19 -0
- data/test/models/release_statuses_test.rb +28 -0
- data/test/models/rollbacks_test.rb +2 -0
- data/test/models/stacks_test.rb +1 -1
- data/test/test_helper.rb +5 -0
- data/test/unit/rollback_commands_test.rb +35 -0
- metadata +121 -104
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71f403cb4167fb521f7a2c190e2d31504dc0dea8
|
4
|
+
data.tar.gz: e1b1a94eefcc449a882ced01fa8036cd9df8e072
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a04e776ddb132ab89a89b80ba5f5a78dfb69a53e73e7300b495e38deaa947cf6c69a6fd3b14dd9ca769ed5aa5d18c47d41a6e3a79de6f02ce2655f3cf305293
|
7
|
+
data.tar.gz: 5e71eaea76929fb232b98197018bc029e32d1f8b4d7743b775c72a6c549082fc0bdc7d212f930d66d657322f7fc15a2b0d736ee519bab026ecc18c16f0ae756a
|
@@ -1,4 +1,6 @@
|
|
1
|
-
$
|
1
|
+
$document = $(document)
|
2
|
+
|
3
|
+
$document.on 'click', '.commit-lock a', (event) ->
|
2
4
|
event.preventDefault()
|
3
5
|
$commit = $(event.target).closest('.commit')
|
4
6
|
$link = $(event.target).closest('a')
|
@@ -8,6 +10,18 @@ $(document).on 'click', '.commit-lock a', (event) ->
|
|
8
10
|
|
9
11
|
$.ajax($link.attr('href'), method: 'PATCH', data: {commit: {locked: !locked}})
|
10
12
|
|
13
|
+
$document.on 'click', '.action-set-release-status', (event) ->
|
14
|
+
event.preventDefault()
|
15
|
+
$link = $(event.target).closest('a')
|
16
|
+
$deploy = $link.closest('.deploy')
|
17
|
+
newStatus = $link.data('status')
|
18
|
+
|
19
|
+
return if $deploy.attr('data-release-status') == newStatus
|
20
|
+
|
21
|
+
$.ajax($link.attr('href'), method: 'POST', data: {status: newStatus}).success((last_status) ->
|
22
|
+
$deploy.attr('data-release-status', last_status.state)
|
23
|
+
)
|
24
|
+
|
11
25
|
jQuery ($) ->
|
12
26
|
displayIgnoreCiMessage = ->
|
13
27
|
ignoreCiMessage = $(".ignoring-ci")
|
@@ -6,3 +6,21 @@
|
|
6
6
|
height: 15px;
|
7
7
|
width: 12px;
|
8
8
|
}
|
9
|
+
|
10
|
+
.icon--validate {
|
11
|
+
display: inline-block;
|
12
|
+
background-color: #000;
|
13
|
+
mask: asset-data-url("success-small.svg") no-repeat 50% 50%;
|
14
|
+
// background: asset-data-url("lock.svg") center center no-repeat;
|
15
|
+
height: 15px;
|
16
|
+
width: 12px;
|
17
|
+
}
|
18
|
+
|
19
|
+
.icon--reject {
|
20
|
+
display: inline-block;
|
21
|
+
background-color: #000;
|
22
|
+
mask: asset-data-url("error-small.svg") no-repeat 50% 50%;
|
23
|
+
// background: asset-data-url("lock.svg") center center no-repeat;
|
24
|
+
height: 15px;
|
25
|
+
width: 12px;
|
26
|
+
}
|
@@ -136,3 +136,31 @@
|
|
136
136
|
background-image: asset-data-url('failure-small.svg');
|
137
137
|
}
|
138
138
|
}
|
139
|
+
|
140
|
+
// DEPLOY STATUS ICON
|
141
|
+
// -----------------------------------------------------------------------------
|
142
|
+
|
143
|
+
.deploy-status__icon {
|
144
|
+
width: 12px;
|
145
|
+
height: 12px;
|
146
|
+
display: inline-block;
|
147
|
+
background: transparent no-repeat center center;
|
148
|
+
vertical-align: -2px;
|
149
|
+
|
150
|
+
.deploy[data-release-status=success] & {
|
151
|
+
background-image: asset-data-url('success-small.svg');
|
152
|
+
}
|
153
|
+
|
154
|
+
.deploy[data-release-status=pending] &,
|
155
|
+
.deploy[data-release-status=unknown] & {
|
156
|
+
background-image: asset-data-url('pending-small.svg');
|
157
|
+
}
|
158
|
+
|
159
|
+
.deploy[data-release-status=error] & {
|
160
|
+
background-image: asset-data-url('error-small.svg');
|
161
|
+
}
|
162
|
+
|
163
|
+
.deploy[data-release-status=failure] & {
|
164
|
+
background-image: asset-data-url('failure-small.svg');
|
165
|
+
}
|
166
|
+
}
|
@@ -136,10 +136,6 @@
|
|
136
136
|
color: $grey;
|
137
137
|
margin: 0;
|
138
138
|
|
139
|
-
@include media(desktop) {
|
140
|
-
@include truncate;
|
141
|
-
}
|
142
|
-
|
143
139
|
.warning {
|
144
140
|
color: $orange;
|
145
141
|
}
|
@@ -166,7 +162,7 @@
|
|
166
162
|
|
167
163
|
@include media(desktop) {
|
168
164
|
margin-left: 1rem;
|
169
|
-
min-width:
|
165
|
+
min-width: 12rem;
|
170
166
|
|
171
167
|
.btn {
|
172
168
|
float: right;
|
@@ -35,7 +35,11 @@
|
|
35
35
|
margin: 0 0.5rem;
|
36
36
|
|
37
37
|
display: none;
|
38
|
-
&[data-status="running"],
|
38
|
+
&[data-status="running"],
|
39
|
+
&[data-status="aborting"],
|
40
|
+
&[data-status="pending"] {
|
41
|
+
display: inline-block;
|
42
|
+
}
|
39
43
|
|
40
44
|
.caption--pending {
|
41
45
|
display: none;
|
@@ -114,6 +118,7 @@
|
|
114
118
|
width: 100%;
|
115
119
|
}
|
116
120
|
|
121
|
+
&[data-status="pending"] .deploy-banner-status,
|
117
122
|
&[data-status="running"] .deploy-banner-status {
|
118
123
|
background-color: $blue;
|
119
124
|
width: 0%;
|
@@ -202,7 +207,7 @@
|
|
202
207
|
border-color: $bright-red;
|
203
208
|
}
|
204
209
|
|
205
|
-
&[data-status="
|
210
|
+
&[data-status="pending"],
|
206
211
|
&[data-status="running"] {
|
207
212
|
border-color: $dark-yellow;
|
208
213
|
}
|
@@ -217,4 +222,56 @@
|
|
217
222
|
|
218
223
|
.ignored-safeties {
|
219
224
|
color: $orange;
|
220
|
-
}
|
225
|
+
}
|
226
|
+
|
227
|
+
.deploy-actions {
|
228
|
+
flex-shrink: 0;
|
229
|
+
|
230
|
+
@include media(desktop) {
|
231
|
+
margin-left: 1rem;
|
232
|
+
min-width: 12rem;
|
233
|
+
|
234
|
+
.btn {
|
235
|
+
float: right;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
.release-validation {
|
241
|
+
display: inline-block;
|
242
|
+
.icon {
|
243
|
+
background-color: #ddd;
|
244
|
+
}
|
245
|
+
|
246
|
+
&:hover .icon {
|
247
|
+
background-color: darken(#ddd, 20%);
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
.deploy[data-release-status="success"] .release-validation .action-validate-release,
|
252
|
+
.deploy[data-release-status="failure"] .release-validation .action-reject-release {
|
253
|
+
&:before, &:after {
|
254
|
+
display: none; // Hide tooltips
|
255
|
+
}
|
256
|
+
.icon {
|
257
|
+
background-color: #ddd;
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
.deploy .commit-lock {
|
262
|
+
.icon {
|
263
|
+
background-color: $bright-red;
|
264
|
+
}
|
265
|
+
|
266
|
+
&:hover .icon {
|
267
|
+
background-color: darken($bright-red, 20%);
|
268
|
+
}
|
269
|
+
|
270
|
+
.action-lock-commit {
|
271
|
+
display: none;
|
272
|
+
}
|
273
|
+
|
274
|
+
.action-unlock-commit {
|
275
|
+
display: inline-block;
|
276
|
+
}
|
277
|
+
}
|
@@ -16,7 +16,7 @@ module Shipit
|
|
16
16
|
private
|
17
17
|
|
18
18
|
def force_github_authentication
|
19
|
-
if current_user.logged_in?
|
19
|
+
if Shipit.authentication_disabled? || current_user.logged_in?
|
20
20
|
unless current_user.authorized?
|
21
21
|
team_handles = Shipit.github_teams.map(&:handle)
|
22
22
|
team_list = team_handles.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Shipit
|
2
|
+
class ReleaseStatusesController < ShipitController
|
3
|
+
before_action :load_stack
|
4
|
+
before_action :load_deploy
|
5
|
+
|
6
|
+
def create
|
7
|
+
case params[:status]
|
8
|
+
when 'success'
|
9
|
+
@deploy.append_release_status(
|
10
|
+
'success',
|
11
|
+
"@#{current_user.login} signaled this release as healthy.",
|
12
|
+
user: current_user,
|
13
|
+
)
|
14
|
+
when 'failure'
|
15
|
+
@deploy.append_release_status(
|
16
|
+
'failure',
|
17
|
+
"@#{current_user.login} signaled this release as faulty.",
|
18
|
+
user: current_user,
|
19
|
+
)
|
20
|
+
else
|
21
|
+
render status: :unprocessable_entity, json: {message: "Invalid `status` parameter"}
|
22
|
+
end
|
23
|
+
render status: :created, json: @deploy.last_release_status
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def load_deploy
|
29
|
+
@deploy = @stack.deploys_and_rollbacks.find(params[:deploy_id])
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_stack
|
33
|
+
@stack ||= Stack.from_param!(params[:stack_id])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Shipit
|
2
|
+
class AppendDelayedReleaseStatusJob < BackgroundJob
|
3
|
+
include BackgroundJob::Unique
|
4
|
+
|
5
|
+
queue_as :default
|
6
|
+
|
7
|
+
def lock_key(deploy, *)
|
8
|
+
super(deploy)
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform(deploy, cursor:, status:, description:)
|
12
|
+
return unless cursor == deploy.until_commit.release_statuses.last
|
13
|
+
|
14
|
+
deploy.append_release_status(status, description)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -55,10 +55,8 @@ module Shipit
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def perform_task
|
58
|
-
|
59
|
-
|
60
|
-
capture_all! @commands.perform
|
61
|
-
end
|
58
|
+
capture_all! @commands.install_dependencies
|
59
|
+
capture_all! @commands.perform
|
62
60
|
end
|
63
61
|
|
64
62
|
def checkout_repository
|
data/app/models/shipit/commit.rb
CHANGED
@@ -8,6 +8,7 @@ module Shipit
|
|
8
8
|
has_many :deploys
|
9
9
|
has_many :statuses, -> { order(created_at: :desc) }, dependent: :destroy, inverse_of: :commit
|
10
10
|
has_many :commit_deployments, dependent: :destroy
|
11
|
+
has_many :release_statuses, dependent: :destroy
|
11
12
|
belongs_to :pull_request, inverse_of: :merge_commit, optional: true
|
12
13
|
|
13
14
|
deferred_touch stack: :updated_at
|
@@ -21,6 +22,14 @@ module Shipit
|
|
21
22
|
belongs_to :author, class_name: 'User', inverse_of: :authored_commits
|
22
23
|
belongs_to :committer, class_name: 'User', inverse_of: :commits
|
23
24
|
|
25
|
+
def author
|
26
|
+
super || AnonymousUser.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def committer
|
30
|
+
super || AnonymousUser.new
|
31
|
+
end
|
32
|
+
|
24
33
|
scope :reachable, -> { where(detached: false) }
|
25
34
|
|
26
35
|
delegate :broadcast_update, :github_repo_name, :hidden_statuses, :required_statuses, :blocking_statuses,
|
@@ -64,11 +73,16 @@ module Shipit
|
|
64
73
|
end
|
65
74
|
|
66
75
|
def self.from_github(commit)
|
76
|
+
author = User.find_or_create_author_from_github_commit(commit)
|
77
|
+
author ||= Anonymous.new
|
78
|
+
committer = User.find_or_create_committer_from_github_commit(commit)
|
79
|
+
committer ||= Anonymous.new
|
80
|
+
|
67
81
|
new(
|
68
82
|
sha: commit.sha,
|
69
83
|
message: commit.commit.message,
|
70
|
-
author:
|
71
|
-
committer:
|
84
|
+
author: author,
|
85
|
+
committer: committer,
|
72
86
|
committed_at: commit.commit.committer.date,
|
73
87
|
authored_at: commit.commit.author.date,
|
74
88
|
additions: commit.stats&.additions,
|
@@ -104,6 +118,23 @@ module Shipit
|
|
104
118
|
end
|
105
119
|
end
|
106
120
|
|
121
|
+
def last_release_status
|
122
|
+
@last_release_status ||= release_statuses.last || Status::Unknown.new(self)
|
123
|
+
end
|
124
|
+
|
125
|
+
def create_release_status!(state, user: nil, target_url: nil, description: nil)
|
126
|
+
return unless stack.release_status?
|
127
|
+
|
128
|
+
@last_release_status = nil
|
129
|
+
release_statuses.create!(
|
130
|
+
stack: stack,
|
131
|
+
user: user,
|
132
|
+
state: state,
|
133
|
+
target_url: target_url,
|
134
|
+
description: description,
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
107
138
|
def checks
|
108
139
|
@checks ||= CommitChecks.new(self)
|
109
140
|
end
|
@@ -233,7 +264,9 @@ module Shipit
|
|
233
264
|
|
234
265
|
unless already_deployed
|
235
266
|
payload = {commit: self, stack: stack, status: new_status.state}
|
236
|
-
|
267
|
+
if previous_status != new_status
|
268
|
+
Hook.emit(:commit_status, stack, payload.merge(commit_status: new_status))
|
269
|
+
end
|
237
270
|
end
|
238
271
|
|
239
272
|
if previous_status.simple_state != new_status.simple_state
|