shipit-engine 0.24.0 → 0.25.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/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
|