shipit-engine 0.22.0 → 0.23.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 +22 -2
- data/app/assets/javascripts/merge_status.coffee +83 -0
- data/app/assets/stylesheets/merge_status.scss +3 -0
- data/app/controllers/shipit/merge_status_controller.rb +131 -0
- data/app/helpers/shipit/merge_status_helper.rb +7 -0
- data/app/jobs/shipit/perform_task_job.rb +1 -3
- data/app/models/shipit/deploy.rb +4 -0
- data/app/models/shipit/deploy_spec.rb +5 -0
- data/app/models/shipit/deploy_spec/file_system.rb +1 -0
- data/app/models/shipit/hook.rb +1 -1
- data/app/models/shipit/pull_request.rb +1 -1
- data/app/models/shipit/stack.rb +4 -0
- data/app/models/shipit/task.rb +4 -0
- data/app/models/shipit/task_definition.rb +10 -0
- data/app/models/shipit/user.rb +1 -5
- data/app/serializers/shipit/task_serializer.rb +1 -0
- data/app/views/layouts/merge_status.html.erb +11 -0
- data/app/views/shipit/merge_status/_anchor.html.erb +6 -0
- data/app/views/shipit/merge_status/_commit_count_warning.html.erb +8 -0
- data/app/views/shipit/merge_status/_merge_queue_button.html.erb +16 -0
- data/app/views/shipit/merge_status/_warning_icon.html.erb +4 -0
- data/app/views/shipit/merge_status/backlogged.html.erb +21 -0
- data/app/views/shipit/merge_status/failure.html.erb +21 -0
- data/app/views/shipit/merge_status/locked.html.erb +21 -0
- data/app/views/shipit/merge_status/logged_out.erb +11 -0
- data/app/views/shipit/merge_status/success.html.erb +24 -0
- data/app/views/shipit/tasks/_task.html.erb +1 -1
- data/app/views/shipit/tasks/_task_output.html.erb +1 -1
- data/config/routes.rb +5 -0
- data/lib/shipit.rb +5 -3
- data/lib/shipit/engine.rb +2 -0
- data/lib/shipit/github_app.rb +8 -11
- data/lib/shipit/stack_commands.rb +0 -9
- data/lib/shipit/version.rb +1 -1
- data/lib/snippets/misconfigured-npm-publish-config +4 -4
- data/test/controllers/merge_status_controller_test.rb +37 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/fixtures/shipit/tasks.yml +27 -0
- data/test/jobs/perform_task_job_test.rb +0 -1
- data/test/models/deploy_spec_test.rb +24 -0
- data/test/models/task_definitions_test.rb +2 -0
- data/test/models/tasks_test.rb +16 -0
- metadata +24 -7
- data/lib/shipit/octokit_bot_users_patch.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc62ac846a6e7816e9de50d219459166c6941f0b230174309ad76bd695ab338e
|
4
|
+
data.tar.gz: 9879387bc8a1a0a89e334bea062ae56bfd060881da2f4e2779bbfddcae3b1f0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee9308a0a602a3aed84a3d7e8a2b9d0d0acf9a8eabebc57a245139c78a0404782bd58f6bbd3bd16661fdef199861833d74ae841cbdb3a439f6567351b7f80ed7
|
7
|
+
data.tar.gz: 4ecf8b958d7080b98babff0249bd8db5cdabcfe7c5b920c822a6db52148db5c953e3f7260ec60bf1eeba604d8403f4f8260806a15a3698eb29bf315ca0b84717
|
data/README.md
CHANGED
@@ -31,7 +31,6 @@ This guide aims to help you [set up](#installation-and-setup), [use](#using-ship
|
|
31
31
|
**III. REFERENCE**
|
32
32
|
|
33
33
|
* [Format and content of shipit.yml](#configuring-shipit)
|
34
|
-
* [Format and content of secrets.yml](#configuring-secrets)
|
35
34
|
* [Script parameters](#script-parameters)
|
36
35
|
* [Configuring providers](#configuring-providers)
|
37
36
|
* [Free samples](/examples/shipit.yml)
|
@@ -406,7 +405,7 @@ ci:
|
|
406
405
|
|
407
406
|
<h3 id="merge-queue">Merge Queue</h3>
|
408
407
|
|
409
|
-
The merge queue
|
408
|
+
The merge queue allows developers to register pull requests which will be merged by Shipit once the stack is clear (no lock, no failing CI, no backlog). It can be enabled on a per stack basis via the settings page.
|
410
409
|
|
411
410
|
It can be customized via several `shipit.yml` properties:
|
412
411
|
|
@@ -436,6 +435,14 @@ merge:
|
|
436
435
|
- codeclimate
|
437
436
|
```
|
438
437
|
|
438
|
+
**<code>merge.method</code>** the [merge method](https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button) to use for this stack. If it's not set the default merge method will be used. Can be either `merge`, `squash` or `rebase`.
|
439
|
+
|
440
|
+
For example:
|
441
|
+
```yml
|
442
|
+
merge:
|
443
|
+
method: squash
|
444
|
+
```
|
445
|
+
|
439
446
|
**<code>merge.max_divergence.commits</code>** the maximum number of commits a pull request can be behind its merge base, after which pull requests are rejected from the merge queue.
|
440
447
|
|
441
448
|
For example:
|
@@ -496,6 +503,19 @@ tasks:
|
|
496
503
|
default: 0
|
497
504
|
```
|
498
505
|
|
506
|
+
You can also make these variables appear in the task title:
|
507
|
+
|
508
|
+
```yml
|
509
|
+
tasks:
|
510
|
+
failover:
|
511
|
+
action: "Failover a pod"
|
512
|
+
title: "Failover Pod %{POD_ID}"
|
513
|
+
steps:
|
514
|
+
- script/failover $POD_ID
|
515
|
+
variables:
|
516
|
+
- name: POD_ID
|
517
|
+
```
|
518
|
+
|
499
519
|
<h3 id="review-process">Review process</h3>
|
500
520
|
|
501
521
|
You can display review elements, such as monitoring data or a pre-deployment checklist, on the deployment page in Shipit:
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class MergeStatusPoller
|
2
|
+
POLL_INTERVAL = 3000
|
3
|
+
|
4
|
+
constructor: ->
|
5
|
+
@request = {abort: ->}
|
6
|
+
@previousLastModified = null
|
7
|
+
@timeoutId = null
|
8
|
+
|
9
|
+
start: ->
|
10
|
+
@timeoutId = setTimeout(@refreshPage, POLL_INTERVAL)
|
11
|
+
@
|
12
|
+
|
13
|
+
stop: ->
|
14
|
+
@request.abort()
|
15
|
+
clearTimeout(@timeoutId)
|
16
|
+
@
|
17
|
+
|
18
|
+
onPageChange: =>
|
19
|
+
window.parent.postMessage({event: 'hctw:height:change', height: document.body.clientHeight, service: 'shipit'}, '*')
|
20
|
+
window.parent.postMessage({event: 'hctw:stack:info', queue_enabled: @isMergeQueueEnabled(), status: @mergeStatus(), service: 'shipit'}, '*')
|
21
|
+
|
22
|
+
fetchPage: (url, callback) ->
|
23
|
+
request = @request = new XMLHttpRequest()
|
24
|
+
request.onreadystatechange = ->
|
25
|
+
if request.readyState == XMLHttpRequest.DONE
|
26
|
+
callback(request.status == 200 && request.responseText, request)
|
27
|
+
request.open('GET', url, true)
|
28
|
+
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
|
29
|
+
request.send()
|
30
|
+
|
31
|
+
previousLastModified = null
|
32
|
+
refreshPage: =>
|
33
|
+
@fetchPage window.location.toString(), (html, response) =>
|
34
|
+
@updateDocument(html, response)
|
35
|
+
setTimeout(@refreshPage, POLL_INTERVAL)
|
36
|
+
|
37
|
+
updateDocument: (html, response) =>
|
38
|
+
lastModified = response.getResponseHeader('last-modified')
|
39
|
+
if !lastModified || lastModified != @previousLastModified
|
40
|
+
@previousLastModified = lastModified
|
41
|
+
if html && container = document.querySelector('[data-layout-content]')
|
42
|
+
container.innerHTML = html
|
43
|
+
@onPageChange()
|
44
|
+
|
45
|
+
isMergeQueueEnabled: =>
|
46
|
+
document.querySelector('.merge-status-container .js-details-container').hasAttribute('data-queue-enabled')
|
47
|
+
|
48
|
+
mergeStatus: =>
|
49
|
+
document.querySelector('.merge-status-container .js-details-container').getAttribute('data-merge-status') || 'unknown'
|
50
|
+
|
51
|
+
class AjaxAction
|
52
|
+
constructor: (@poller) ->
|
53
|
+
document.addEventListener('submit', @submit, false)
|
54
|
+
|
55
|
+
submit: (event) =>
|
56
|
+
return unless event.target.getAttribute('data-remote') == 'true'
|
57
|
+
|
58
|
+
event.preventDefault()
|
59
|
+
|
60
|
+
@poller.stop()
|
61
|
+
@disableButtons(event.target)
|
62
|
+
@submitFormAsynchronously event.target, (html, request) =>
|
63
|
+
@poller.updateDocument(html, request)
|
64
|
+
@poller.start()
|
65
|
+
|
66
|
+
submitFormAsynchronously: (form, callback) ->
|
67
|
+
request = new XMLHttpRequest()
|
68
|
+
request.onreadystatechange = ->
|
69
|
+
if request.readyState == XMLHttpRequest.DONE
|
70
|
+
callback(request.status == 200 && request.responseText, request)
|
71
|
+
request.open(form.method.toLocaleUpperCase(), form.action, true)
|
72
|
+
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
|
73
|
+
request.send(new FormData(form))
|
74
|
+
|
75
|
+
disableButtons: (form) ->
|
76
|
+
for button in form.querySelectorAll('[data-disable-with]')
|
77
|
+
button.disabled = true
|
78
|
+
button.textContent = button.getAttribute('data-disable-with')
|
79
|
+
|
80
|
+
poller = new MergeStatusPoller
|
81
|
+
poller.onPageChange()
|
82
|
+
poller.start()
|
83
|
+
new AjaxAction(poller)
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Shipit
|
2
|
+
class MergeStatusController < ShipitController
|
3
|
+
skip_authentication only: %i(check show)
|
4
|
+
|
5
|
+
etag { cache_seed }
|
6
|
+
layout 'merge_status'
|
7
|
+
|
8
|
+
def show
|
9
|
+
response.headers['X-Frame-Options'] = 'ALLOWALL'
|
10
|
+
response.headers['Vary'] = 'X-Requested-With'
|
11
|
+
|
12
|
+
if stack
|
13
|
+
return render('logged_out') unless current_user.logged_in?
|
14
|
+
if stale?(last_modified: [stack.updated_at, pull_request.updated_at].max, template: false)
|
15
|
+
render stack_status, layout: !request.xhr?
|
16
|
+
end
|
17
|
+
else
|
18
|
+
render html: ''
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def enqueue
|
23
|
+
PullRequest.request_merge!(stack, params[:number], current_user)
|
24
|
+
render stack_status, layout: !request.xhr?
|
25
|
+
end
|
26
|
+
|
27
|
+
def dequeue
|
28
|
+
if pull_request = stack.pull_requests.find_by_number(params[:number])
|
29
|
+
pull_request.cancel! if pull_request.waiting?
|
30
|
+
end
|
31
|
+
render stack_status, layout: !request.xhr?
|
32
|
+
end
|
33
|
+
|
34
|
+
def check
|
35
|
+
respond_to do |format|
|
36
|
+
format.html do
|
37
|
+
if stack_status == 'success'
|
38
|
+
render plain: 'ok'
|
39
|
+
else
|
40
|
+
render plain: stack_status, status: 503
|
41
|
+
end
|
42
|
+
end
|
43
|
+
format.json { render json: {stack_status: stack_status} }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def cache_seed
|
50
|
+
"#{request.xhr? ? 'partial' : 'full'}-#{Shipit.revision}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def stack_status
|
54
|
+
@stack_status ||= stack.merge_status(backlog_leniency_factor: 1.0)
|
55
|
+
end
|
56
|
+
|
57
|
+
def stack
|
58
|
+
@stack ||= if params[:stack_id]
|
59
|
+
Stack.from_param!(params[:stack_id])
|
60
|
+
else
|
61
|
+
scope = Stack.order(id: :asc).where(
|
62
|
+
repo_owner: referrer_parser.repo_owner,
|
63
|
+
repo_name: referrer_parser.repo_name,
|
64
|
+
)
|
65
|
+
scope = if params[:branch]
|
66
|
+
scope.where(branch: params[:branch])
|
67
|
+
else
|
68
|
+
scope.where(environment: 'production')
|
69
|
+
end
|
70
|
+
scope.first
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def referrer_parser
|
75
|
+
@referrer_parser ||= ReferrerParser.new(params[:referrer])
|
76
|
+
end
|
77
|
+
|
78
|
+
def pull_request
|
79
|
+
return @pull_request if defined?(@pull_request)
|
80
|
+
@pull_request = pull_request_number && stack.pull_requests.find_by_number(pull_request_number)
|
81
|
+
@pull_request ||= UnknownPullRequest.new
|
82
|
+
end
|
83
|
+
|
84
|
+
def pull_request_number
|
85
|
+
return @pull_request_number if defined?(@pull_request_number)
|
86
|
+
@pull_request_number = referrer_parser.pull_request_number
|
87
|
+
end
|
88
|
+
|
89
|
+
def queue_enabled?
|
90
|
+
stack.merge_queue_enabled? && pull_request_number
|
91
|
+
end
|
92
|
+
|
93
|
+
helper_method :pull_request_number
|
94
|
+
helper_method :pull_request
|
95
|
+
helper_method :queue_enabled?
|
96
|
+
helper_method :stack
|
97
|
+
helper_method :stack_status
|
98
|
+
|
99
|
+
# FIXME: for some reason if invoked in the view, those path helpers will link to /events?...
|
100
|
+
helper_method :enqueue_pull_request_path
|
101
|
+
helper_method :dequeue_pull_request_path
|
102
|
+
|
103
|
+
class ReferrerParser
|
104
|
+
URL_PATTERN = %r{\Ahttps://github\.com/([^/]+)/([^/]+)/pull/(\d+)}
|
105
|
+
|
106
|
+
attr_reader :repo_owner, :repo_name, :pull_request_number
|
107
|
+
|
108
|
+
def initialize(referrer)
|
109
|
+
if URL_PATTERN =~ referrer.to_s
|
110
|
+
@repo_owner = $1.downcase
|
111
|
+
@repo_name = $2.downcase
|
112
|
+
@pull_request_number = $3.to_i
|
113
|
+
else
|
114
|
+
raise ArgumentError, "Invalid referrer: #{referrer.inspect}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class UnknownPullRequest
|
120
|
+
attr_reader :updated_at
|
121
|
+
|
122
|
+
def initialize
|
123
|
+
@updated_at = Time.at(0).utc
|
124
|
+
end
|
125
|
+
|
126
|
+
def waiting?
|
127
|
+
false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -63,9 +63,7 @@ module Shipit
|
|
63
63
|
|
64
64
|
def checkout_repository
|
65
65
|
@task.acquire_git_cache_lock do
|
66
|
-
|
67
|
-
capture! @commands.fetch
|
68
|
-
end
|
66
|
+
capture! @commands.fetch
|
69
67
|
end
|
70
68
|
capture! @commands.clone
|
71
69
|
capture! @commands.checkout(@task.until_commit)
|
data/app/models/shipit/deploy.rb
CHANGED
@@ -146,6 +146,11 @@ module Shipit
|
|
146
146
|
Array.wrap(config('ci', 'blocking'))
|
147
147
|
end
|
148
148
|
|
149
|
+
def pull_request_merge_method
|
150
|
+
method = config('merge', 'method')
|
151
|
+
method if %w(merge rebase squash).include?(method)
|
152
|
+
end
|
153
|
+
|
149
154
|
def pull_request_required_statuses
|
150
155
|
if config('merge', 'require') || config('merge', 'ignore')
|
151
156
|
Array.wrap(config('merge', 'require'))
|
@@ -34,6 +34,7 @@ module Shipit
|
|
34
34
|
'require' => pull_request_required_statuses,
|
35
35
|
'ignore' => pull_request_ignored_statuses,
|
36
36
|
'revalidate_after' => revalidate_pull_requests_after&.to_i,
|
37
|
+
'method' => pull_request_merge_method,
|
37
38
|
'max_divergence' => {
|
38
39
|
'commits' => max_divergence_commits&.to_i,
|
39
40
|
'age' => max_divergence_age&.to_i,
|
data/app/models/shipit/hook.rb
CHANGED
@@ -80,7 +80,7 @@ module Shipit
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def purge_old_deliveries!(keep: DELIVERIES_LOG_SIZE)
|
83
|
-
delivery_ids = deliveries.sent.order(id: :desc).offset(keep).pluck(:id)
|
83
|
+
delivery_ids = deliveries.sent.order(id: :desc).offset(keep).limit(50).pluck(:id)
|
84
84
|
deliveries.where(id: delivery_ids).delete_all
|
85
85
|
end
|
86
86
|
|
@@ -163,7 +163,7 @@ module Shipit
|
|
163
163
|
merge_message,
|
164
164
|
sha: head.sha,
|
165
165
|
commit_message: 'Merged by Shipit',
|
166
|
-
merge_method:
|
166
|
+
merge_method: stack.merge_method,
|
167
167
|
)
|
168
168
|
begin
|
169
169
|
if Shipit.github.api.pull_requests(stack.github_repo_name, base: branch).empty?
|
data/app/models/shipit/stack.rb
CHANGED
@@ -275,6 +275,10 @@ module Shipit
|
|
275
275
|
merge_queue_enabled? && !locked? && merge_status == 'success'
|
276
276
|
end
|
277
277
|
|
278
|
+
def merge_method
|
279
|
+
cached_deploy_spec&.pull_request_merge_method || Shipit.default_merge_method
|
280
|
+
end
|
281
|
+
|
278
282
|
def repo_name=(name)
|
279
283
|
super(name&.downcase)
|
280
284
|
end
|
data/app/models/shipit/task.rb
CHANGED
@@ -26,6 +26,15 @@ module Shipit
|
|
26
26
|
@variables = task_variables(config['variables'] || [])
|
27
27
|
@checklist = config['checklist'] || []
|
28
28
|
@allow_concurrency = config['allow_concurrency'] || false
|
29
|
+
@title = config['title']
|
30
|
+
end
|
31
|
+
|
32
|
+
def render_title(env)
|
33
|
+
if @title
|
34
|
+
@title % env.symbolize_keys
|
35
|
+
else
|
36
|
+
action
|
37
|
+
end
|
29
38
|
end
|
30
39
|
|
31
40
|
def allow_concurrency?
|
@@ -36,6 +45,7 @@ module Shipit
|
|
36
45
|
{
|
37
46
|
id: id,
|
38
47
|
action: action,
|
48
|
+
title: @title,
|
39
49
|
description: description,
|
40
50
|
steps: steps,
|
41
51
|
variables: variables.map(&:to_h),
|
data/app/models/shipit/user.rb
CHANGED
@@ -46,11 +46,7 @@ module Shipit
|
|
46
46
|
def github_api
|
47
47
|
return Shipit.github.api unless github_access_token
|
48
48
|
|
49
|
-
@github_api ||=
|
50
|
-
client = Octokit::Client.new(access_token: github_access_token)
|
51
|
-
client.middleware = Shipit.new_faraday_stack
|
52
|
-
client
|
53
|
-
end
|
49
|
+
@github_api ||= Shipit.github.new_client(access_token: github_access_token)
|
54
50
|
end
|
55
51
|
|
56
52
|
def identifiers_for_ping
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<%= stylesheet_link_tag *(params[:stylesheets] || []).select { |url| url.start_with?('https://assets-cdn.github.com/') } %>
|
5
|
+
<%= stylesheet_link_tag 'merge_status' %>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<div class="merge-status-container" data-layout-content><%= yield %></div>
|
9
|
+
<%= javascript_include_tag 'merge_status' %>
|
10
|
+
</body>
|
11
|
+
</html>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<svg style="fill: <%= color %>; stroke: <%= color %>;" viewBox="-584 580 33 40" enable-background="new -583 582.2 31.3 36.8">
|
2
|
+
<path d="M-553.7,605.9l-5.4-1.2l-0.9,3.8l3.2,0.7c-2.2,3.7-6.2,6-10.6,5.9l3.5-19.2c3.5-0.4,6.2-3.3,6.2-6.9
|
3
|
+
c0-3.8-3.1-6.9-6.9-6.9c-3.8,0-6.9,3.1-6.9,6.9c0,2.7,1.6,5,3.8,6.2l-3.5,19.2c-4.3-1.5-7.3-5.4-7.8-9.8l3.8,0.8l0.8-3.8l-5.1-1
|
4
|
+
l-3.1-0.6c-1.8,8.6,3.7,17,12.3,18.7c1.1,0.2,2.2,0.3,3.3,0.3c3.1,0,6-0.9,8.7-2.6c3.5-2.3,6-5.9,6.8-10L-553.7,605.9z M-564.6,586
|
5
|
+
c1.7,0,3,1.4,3,3c0,1.7-1.4,3-3,3c-1.7,0-3-1.4-3-3C-567.7,587.4-566.3,586-564.6,586z"/>
|
6
|
+
</svg>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<p class="status-heading text-red">
|
2
|
+
<%= render 'warning_icon' %>
|
3
|
+
Consider rebasing into a smaller number of commits containing atomic changes. Find out
|
4
|
+
<%= link_to 'why', 'https://docs.google.com/document/d/1lZlNo7ekugQDxug6Nc6pdY87VNobl3g2IQjY7R0YIIc',
|
5
|
+
target: '_blank',
|
6
|
+
rel: 'noopener'
|
7
|
+
%>.
|
8
|
+
</p>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% classes = 'branch-action-btn float-right js-immediate-updates js-handle-pull-merging-errors' %>
|
2
|
+
<% if pull_request.try!(&:waiting?) %>
|
3
|
+
<%= form_tag dequeue_pull_request_path(stack, pull_request_number), method: 'delete', class: classes, data: {remote: true} do %>
|
4
|
+
<%= hidden_field_tag 'referrer', params[:referrer] %>
|
5
|
+
<button type="submit" data-disable-with="Removing from merge queue…" class="btn">
|
6
|
+
Remove from merge queue
|
7
|
+
</button>
|
8
|
+
<% end %>
|
9
|
+
<% else %>
|
10
|
+
<%= form_tag enqueue_pull_request_path(stack, pull_request_number), method: 'put', class: classes, data: {remote: true} do %>
|
11
|
+
<%= hidden_field_tag 'referrer', params[:referrer] %>
|
12
|
+
<button type="submit" data-disable-with="Adding to merge queue…" class="btn btn-primary">
|
13
|
+
Add to merge queue
|
14
|
+
</button>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14">
|
2
|
+
<path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7
|
3
|
+
5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z" />
|
4
|
+
</svg>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="branch-action-item js-details-container" <% if queue_enabled? %>data-queue-enabled<% end %> data-merge-status="<%= stack_status %>">
|
2
|
+
<%= render 'merge_queue_button' if queue_enabled? %>
|
3
|
+
<div class="branch-action-item-icon completeness-indicator">
|
4
|
+
<%= render 'anchor', color: '#cea61b' %>
|
5
|
+
</div>
|
6
|
+
<h4 class="status-heading text-pending">
|
7
|
+
<% if pull_request.waiting? %>
|
8
|
+
Will be merged shortly after the backlog is shipped!
|
9
|
+
<% else %>
|
10
|
+
Please hold off merging!
|
11
|
+
<% if queue_enabled? %>
|
12
|
+
Add it to the merge queue instead.
|
13
|
+
<% end %>
|
14
|
+
<% end %>
|
15
|
+
</h4>
|
16
|
+
<span class="status-meta">
|
17
|
+
<%= link_to @stack.to_param, stack_url(@stack), target: '_blank', rel: 'noopener' %>
|
18
|
+
is <strong>backlogged</strong>
|
19
|
+
</span>
|
20
|
+
<%= render 'commit_count_warning' if too_many_commits?(params[:commits].to_i) %>
|
21
|
+
</div>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="branch-action-item js-details-container" <% if queue_enabled? %>data-queue-enabled<% end %> data-merge-status="<%= stack_status %>">
|
2
|
+
<%= render 'merge_queue_button' if queue_enabled? %>
|
3
|
+
<div class="branch-action-item-icon completeness-indicator">
|
4
|
+
<%= render 'anchor', color: '#d73a49' %>
|
5
|
+
</div>
|
6
|
+
<h4 class="status-heading text-red">
|
7
|
+
<% if pull_request.waiting? %>
|
8
|
+
Will be merged shortly after the CI is fixed!
|
9
|
+
<% else %>
|
10
|
+
Please hold off merging!
|
11
|
+
<% if queue_enabled? %>
|
12
|
+
Add it to the merge queue instead.
|
13
|
+
<% end %>
|
14
|
+
<% end %>
|
15
|
+
</h4>
|
16
|
+
<span class="status-meta">
|
17
|
+
<%= link_to @stack.to_param, stack_url(@stack), target: '_blank', rel: 'noopener' %>
|
18
|
+
<strong>master branch is failing!</strong>
|
19
|
+
</span>
|
20
|
+
<%= render 'commit_count_warning' if too_many_commits?(params[:commits].to_i) %>
|
21
|
+
</div>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="branch-action-item js-details-container" <% if queue_enabled? %>data-queue-enabled<% end %> data-merge-status="<%= stack_status %>">
|
2
|
+
<%= render 'merge_queue_button' if queue_enabled? %>
|
3
|
+
<div class="branch-action-item-icon completeness-indicator">
|
4
|
+
<%= render 'anchor', color: '#bd2c00' %>
|
5
|
+
</div>
|
6
|
+
<h4 class="status-heading text-red">
|
7
|
+
<% if pull_request.waiting? %>
|
8
|
+
Will be merged shortly after the lock is removed!
|
9
|
+
<% else %>
|
10
|
+
Please hold off merging!
|
11
|
+
<% if queue_enabled? %>
|
12
|
+
Add it to the merge queue instead.
|
13
|
+
<% end %>
|
14
|
+
<% end %>
|
15
|
+
</h4>
|
16
|
+
<span class="status-meta">
|
17
|
+
<%= link_to @stack.to_param, stack_url(@stack), target: '_blank', rel: 'noopener' %>
|
18
|
+
is <strong>locked</strong> because: <strong><%= auto_link(emojify(@stack.lock_reason), html: { target: '_blank' }) %></strong>
|
19
|
+
</span>
|
20
|
+
<%= render 'commit_count_warning' if too_many_commits?(params[:commits].to_i) %>
|
21
|
+
</div>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<div class="branch-action-item">
|
2
|
+
<div class="branch-action-item-icon completeness-indicator">
|
3
|
+
<%= render 'anchor', color: '#bd2c00' %>
|
4
|
+
</div>
|
5
|
+
<h4 class="status-heading text-red">
|
6
|
+
Please log in to <%= link_to 'Shipit', '/', target: '_blank', rel: 'noopener' %>
|
7
|
+
</h4>
|
8
|
+
<span class="status-meta">
|
9
|
+
Here Comes The Walrus is unable to check merge status.
|
10
|
+
</span>
|
11
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<div class="branch-action-item js-details-container" <% if queue_enabled? %>data-queue-enabled<% end %> data-merge-status="<%= stack_status %>">
|
2
|
+
<%= render 'merge_queue_button' if queue_enabled? %>
|
3
|
+
<div class="branch-action-item-icon completeness-indicator">
|
4
|
+
<%= render 'anchor', color: '#2cbe4e' %>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<h4 class="status-heading">
|
8
|
+
<% if pull_request.waiting? %>
|
9
|
+
<% if pull_request.all_status_checks_passed? %>
|
10
|
+
Will be merged shortly!
|
11
|
+
<% else %>
|
12
|
+
Will be merged when required checks are passing.
|
13
|
+
<% end %>
|
14
|
+
<% else %>
|
15
|
+
Ready to ship!
|
16
|
+
<% end %>
|
17
|
+
</h4>
|
18
|
+
|
19
|
+
<span class="status-meta">
|
20
|
+
<%= link_to @stack.to_param, stack_url(@stack), target: '_blank', rel: 'noopener' %> is clear.
|
21
|
+
</span>
|
22
|
+
|
23
|
+
<%= render 'commit_count_warning' if too_many_commits?(params[:commits].to_i) %>
|
24
|
+
</div>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<div class="sidebar-plugins"></div>
|
9
9
|
</div>
|
10
10
|
|
11
|
-
<div class="deploy-main" data-task="<%= {repo: @stack.github_repo_name, description:
|
11
|
+
<div class="deploy-main" data-task="<%= {repo: @stack.github_repo_name, description: task.title}.to_json %>">
|
12
12
|
<span class="deploy-tasks"></span>
|
13
13
|
<div class="deploy-banner" data-status="<%= task.status %>">
|
14
14
|
<div class="deploy-banner-status"></div>
|
data/config/routes.rb
CHANGED
@@ -38,6 +38,11 @@ Shipit::Engine.routes.draw do
|
|
38
38
|
get '/' => 'ccmenu_url#fetch'
|
39
39
|
end
|
40
40
|
|
41
|
+
# Browser extension
|
42
|
+
get '/merge_status', action: :show, controller: :merge_status, as: :merge_status
|
43
|
+
put '/merge_status/*stack_id/pull/:number', action: :enqueue, controller: :merge_status, id: stack_id_format, as: :enqueue_pull_request
|
44
|
+
delete '/merge_status/*stack_id/pull/:number', action: :dequeue, controller: :merge_status, id: stack_id_format, as: :dequeue_pull_request
|
45
|
+
|
41
46
|
# Humans
|
42
47
|
resources :stacks, only: %i(new create index)
|
43
48
|
|
data/lib/shipit.rb
CHANGED
@@ -26,8 +26,6 @@ require 'redis-objects'
|
|
26
26
|
require 'redis-namespace'
|
27
27
|
|
28
28
|
require 'octokit'
|
29
|
-
require 'shipit/octokit_bot_users_patch'
|
30
|
-
|
31
29
|
require 'faraday-http-cache'
|
32
30
|
|
33
31
|
require 'shipit/version'
|
@@ -81,7 +79,7 @@ module Shipit
|
|
81
79
|
|
82
80
|
def legacy_github_api
|
83
81
|
if secrets&.github_api.present?
|
84
|
-
@legacy_github_api ||=
|
82
|
+
@legacy_github_api ||= github.new_client(access_token: secrets.github_api['access_token'])
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
@@ -121,6 +119,10 @@ module Shipit
|
|
121
119
|
secrets.host.presence
|
122
120
|
end
|
123
121
|
|
122
|
+
def default_merge_method
|
123
|
+
secrets.default_merge_method || 'merge'
|
124
|
+
end
|
125
|
+
|
124
126
|
def enforce_publish_config
|
125
127
|
secrets.enforce_publish_config.presence
|
126
128
|
end
|
data/lib/shipit/engine.rb
CHANGED
data/lib/shipit/github_app.rb
CHANGED
@@ -22,7 +22,7 @@ module Shipit
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def api
|
25
|
-
@client = new_client if !defined?(@client) || @client.access_token != token
|
25
|
+
@client = new_client(access_token: token) if !defined?(@client) || @client.access_token != token
|
26
26
|
@client
|
27
27
|
end
|
28
28
|
|
@@ -40,7 +40,7 @@ module Shipit
|
|
40
40
|
return unless private_key && app_id && installation_id
|
41
41
|
|
42
42
|
Rails.cache.fetch('github:integration:token', expires_in: 50.minutes, race_condition_ttl: 10.minutes) do
|
43
|
-
token =
|
43
|
+
token = new_client(bearer_token: authentication_payload).create_app_installation_access_token(
|
44
44
|
installation_id,
|
45
45
|
accept: 'application/vnd.github.machine-man-preview+json',
|
46
46
|
).token
|
@@ -84,6 +84,12 @@ module Shipit
|
|
84
84
|
domain != DOMAIN
|
85
85
|
end
|
86
86
|
|
87
|
+
def new_client(options = {})
|
88
|
+
client = Octokit::Client.new(options.reverse_merge(api_endpoint: api_endpoint))
|
89
|
+
client.middleware = Shipit.new_faraday_stack
|
90
|
+
client
|
91
|
+
end
|
92
|
+
|
87
93
|
private
|
88
94
|
|
89
95
|
attr_reader :webhook_secret, :oauth_id, :oauth_secret
|
@@ -100,15 +106,6 @@ module Shipit
|
|
100
106
|
@private_key ||= @config.fetch(:private_key)
|
101
107
|
end
|
102
108
|
|
103
|
-
def new_client
|
104
|
-
client = Octokit::Client.new(
|
105
|
-
access_token: token,
|
106
|
-
api_endpoint: api_endpoint,
|
107
|
-
)
|
108
|
-
client.middleware = Shipit.new_faraday_stack
|
109
|
-
client
|
110
|
-
end
|
111
|
-
|
112
109
|
def authentication_payload
|
113
110
|
payload = {
|
114
111
|
iat: Time.now.to_i,
|
@@ -16,15 +16,6 @@ module Shipit
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def fetched?(commit)
|
20
|
-
git_dir = File.join(@stack.git_path, '.git')
|
21
|
-
if Dir.exist?(git_dir)
|
22
|
-
git('rev-parse', '--quiet', '--verify', "#{commit.sha}^{commit}", env: env, chdir: @stack.git_path)
|
23
|
-
else
|
24
|
-
Command.new('test', '-d', git_dir, env: env, chdir: @stack.deploys_path)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
19
|
def fetch_deployed_revision
|
29
20
|
with_temporary_working_directory(commit: @stack.commits.last) do |dir|
|
30
21
|
spec = DeploySpec::FileSystem.new(dir, @stack.environment)
|
data/lib/shipit/version.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
2
|
|
3
|
-
echo -e "\033[1;31m
|
3
|
+
echo -e "\033[1;31m Issue(s) found in package.json. Ensure the following conditions are met and try again.\n \033[0m"
|
4
4
|
|
5
|
-
echo -e "\033[1;31m *
|
6
|
-
echo -e "\n\033[1;31m\t\"publishConfig
|
7
|
-
echo -e "\n\033[1;31m * If
|
5
|
+
echo -e "\033[1;31m * Set the appropriate access in publishConfig:\033[0m"
|
6
|
+
echo -e "\n\033[1;31m\t\"publishConfig\": {\n\t \"access\": \"<public|restricted>\" \n\t}\033[0m"
|
7
|
+
echo -e "\n\033[1;31m * If the package is private, its name must be scoped (@organization-scope/package)\033[0m"
|
8
8
|
exit 1
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Shipit
|
4
|
+
class MergeStatusControllerTest < ActionController::TestCase
|
5
|
+
setup do
|
6
|
+
request.env['HTTPS'] = 'on'
|
7
|
+
@request.host = URI(Shipit.host).host
|
8
|
+
session[:user_id] = shipit_users(:walrus).id
|
9
|
+
end
|
10
|
+
|
11
|
+
test "GET show" do
|
12
|
+
get :show, params: {referrer: 'https://github.com/Shopify/shipit-engine/pull/42', branch: 'master'}
|
13
|
+
assert_response :ok
|
14
|
+
assert_includes response.body, 'Ready to ship!'
|
15
|
+
end
|
16
|
+
|
17
|
+
test "GET show when there is no matching stacks" do
|
18
|
+
get :show, params: {referrer: 'https://github.com/Shopify/unknown-repo/pull/42', branch: 'master'}
|
19
|
+
assert_response :ok
|
20
|
+
assert_predicate response.body, :blank?
|
21
|
+
end
|
22
|
+
|
23
|
+
test "GET anonymous show returns a login message" do
|
24
|
+
session.delete(:user_id)
|
25
|
+
get :show, params: {referrer: 'https://github.com/Shopify/shipit-engine/pull/42', branch: 'master'}
|
26
|
+
assert_response :ok
|
27
|
+
assert_includes response.body.downcase, 'please log in'
|
28
|
+
end
|
29
|
+
|
30
|
+
test "GET anonymous show when there is no matching stack is blank" do
|
31
|
+
session.delete(:user_id)
|
32
|
+
get :show, params: {referrer: 'https://github.com/Shopify/unknown-repo/pull/42', branch: 'master'}
|
33
|
+
assert_response :ok
|
34
|
+
assert_predicate response.body, :blank?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/test/dummy/db/test.sqlite3
CHANGED
Binary file
|
@@ -134,3 +134,30 @@ soc_deploy:
|
|
134
134
|
created_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
|
135
135
|
started_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
|
136
136
|
ended_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
|
137
|
+
|
138
|
+
shipit_rendered_failover:
|
139
|
+
id: 10
|
140
|
+
user: walrus
|
141
|
+
since_commit_id: 2 # second
|
142
|
+
until_commit_id: 2 # second
|
143
|
+
type: Shipit::Task
|
144
|
+
stack: shipit
|
145
|
+
status: success
|
146
|
+
definition: >
|
147
|
+
{
|
148
|
+
"id": "failover",
|
149
|
+
"action": "Failover a pod",
|
150
|
+
"title": "Failover pod %{POD_ID}",
|
151
|
+
"description": "Restart app and job servers",
|
152
|
+
"variables": [
|
153
|
+
{"name": "POD_ID", "title": "Id of the pod to failover"}
|
154
|
+
],
|
155
|
+
"steps": [
|
156
|
+
"cap $ENVIRONMENT pod:failover"
|
157
|
+
]
|
158
|
+
}
|
159
|
+
env:
|
160
|
+
POD_ID: "12"
|
161
|
+
created_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
|
162
|
+
started_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
|
163
|
+
ended_at: <%= (60 - 4).minutes.ago.to_s(:db) %>
|
@@ -14,7 +14,6 @@ module Shipit
|
|
14
14
|
@commands = stub(:commands)
|
15
15
|
Commands.expects(:for).with(@deploy).returns(@commands)
|
16
16
|
|
17
|
-
@commands.expects(:fetched?).once.returns(false)
|
18
17
|
@commands.expects(:fetch).once
|
19
18
|
@commands.expects(:clone).once
|
20
19
|
@commands.expects(:checkout).with(@deploy.until_commit).once
|
@@ -295,6 +295,7 @@ module Shipit
|
|
295
295
|
'require' => [],
|
296
296
|
'ignore' => [],
|
297
297
|
'revalidate_after' => nil,
|
298
|
+
'method' => nil,
|
298
299
|
'max_divergence' => {
|
299
300
|
'commits' => nil,
|
300
301
|
'age' => nil,
|
@@ -442,6 +443,29 @@ module Shipit
|
|
442
443
|
assert_equal %w(ci/circleci soc/compliance), @spec.required_statuses
|
443
444
|
end
|
444
445
|
|
446
|
+
test "pull_request_merge_method defaults to `nil`" do
|
447
|
+
@spec.expects(:load_config).returns({})
|
448
|
+
assert_nil @spec.pull_request_merge_method
|
449
|
+
end
|
450
|
+
|
451
|
+
test "pull_request_merge_method returns `merge.method`" do
|
452
|
+
@spec.expects(:load_config).returns(
|
453
|
+
'merge' => {
|
454
|
+
'method' => 'squash',
|
455
|
+
},
|
456
|
+
)
|
457
|
+
assert_equal 'squash', @spec.pull_request_merge_method
|
458
|
+
end
|
459
|
+
|
460
|
+
test "pull_request_merge_method returns `nil` if `merge.method` is invalid" do
|
461
|
+
@spec.expects(:load_config).returns(
|
462
|
+
'merge' => {
|
463
|
+
'method' => 'squashing',
|
464
|
+
},
|
465
|
+
)
|
466
|
+
assert_nil @spec.pull_request_merge_method
|
467
|
+
end
|
468
|
+
|
445
469
|
test "pull_request_ignored_statuses defaults to the union of ci.hide and ci.allow_failures" do
|
446
470
|
@spec.expects(:load_config).returns(
|
447
471
|
'ci' => {
|
@@ -6,6 +6,7 @@ module Shipit
|
|
6
6
|
@definition = TaskDefinition.new(
|
7
7
|
'restart',
|
8
8
|
'action' => 'Restart application',
|
9
|
+
'title' => 'Restart application %{FOO}',
|
9
10
|
'description' => 'Restart app and job servers',
|
10
11
|
'steps' => ['touch tmp/restart'],
|
11
12
|
'allow_concurrency' => true,
|
@@ -36,6 +37,7 @@ module Shipit
|
|
36
37
|
as_json = {
|
37
38
|
id: 'restart',
|
38
39
|
action: 'Restart application',
|
40
|
+
title: "Restart application %{FOO}",
|
39
41
|
description: 'Restart app and job servers',
|
40
42
|
steps: ['touch tmp/restart'],
|
41
43
|
checklist: [],
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Shipit
|
4
|
+
class TasksTest < ActiveSupport::TestCase
|
5
|
+
test "#title interpolates env" do
|
6
|
+
task = shipit_tasks(:shipit_rendered_failover)
|
7
|
+
assert_equal({'POD_ID' => '12'}, task.env)
|
8
|
+
assert_equal 'Failover pod 12', task.title
|
9
|
+
end
|
10
|
+
|
11
|
+
test "#title returns the task action if title is not defined" do
|
12
|
+
task = shipit_tasks(:shipit_restart)
|
13
|
+
assert_equal 'Restart application', task.title
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
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.23.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: 2018-
|
11
|
+
date: 2018-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_model_serializers
|
@@ -170,28 +170,28 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: 4.
|
173
|
+
version: 4.9.0
|
174
174
|
type: :runtime
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: 4.
|
180
|
+
version: 4.9.0
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: omniauth-github
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
185
|
- - "~>"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version: 1.
|
187
|
+
version: 1.3.0
|
188
188
|
type: :runtime
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version: 1.
|
194
|
+
version: 1.3.0
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
196
|
name: pubsubstub
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -428,6 +428,7 @@ files:
|
|
428
428
|
- app/assets/images/validation/invalid.png
|
429
429
|
- app/assets/images/validation/required.png
|
430
430
|
- app/assets/images/validation/valid.png
|
431
|
+
- app/assets/javascripts/merge_status.coffee
|
431
432
|
- app/assets/javascripts/shipit.js.coffee
|
432
433
|
- app/assets/javascripts/shipit/checklist.js.coffee
|
433
434
|
- app/assets/javascripts/shipit/deploy.js.coffee
|
@@ -460,6 +461,7 @@ files:
|
|
460
461
|
- app/assets/stylesheets/_structure/_layout.scss
|
461
462
|
- app/assets/stylesheets/_structure/_main.scss
|
462
463
|
- app/assets/stylesheets/_structure/_navigation.scss
|
464
|
+
- app/assets/stylesheets/merge_status.scss
|
463
465
|
- app/assets/stylesheets/shipit.scss
|
464
466
|
- app/assets/webfonts/CheckoutSymbols-Regular.eot
|
465
467
|
- app/assets/webfonts/CheckoutSymbols-Regular.svg
|
@@ -485,6 +487,7 @@ files:
|
|
485
487
|
- app/controllers/shipit/commits_controller.rb
|
486
488
|
- app/controllers/shipit/deploys_controller.rb
|
487
489
|
- app/controllers/shipit/github_authentication_controller.rb
|
490
|
+
- app/controllers/shipit/merge_status_controller.rb
|
488
491
|
- app/controllers/shipit/pull_requests_controller.rb
|
489
492
|
- app/controllers/shipit/rollbacks_controller.rb
|
490
493
|
- app/controllers/shipit/shipit_controller.rb
|
@@ -495,6 +498,7 @@ files:
|
|
495
498
|
- app/helpers/shipit/chunks_helper.rb
|
496
499
|
- app/helpers/shipit/deploys_helper.rb
|
497
500
|
- app/helpers/shipit/github_url_helper.rb
|
501
|
+
- app/helpers/shipit/merge_status_helper.rb
|
498
502
|
- app/helpers/shipit/shipit_helper.rb
|
499
503
|
- app/helpers/shipit/stacks_helper.rb
|
500
504
|
- app/helpers/shipit/tasks_helper.rb
|
@@ -578,6 +582,7 @@ files:
|
|
578
582
|
- app/serializers/shipit/user_serializer.rb
|
579
583
|
- app/validators/ascii_only_validator.rb
|
580
584
|
- app/validators/subset_validator.rb
|
585
|
+
- app/views/layouts/merge_status.html.erb
|
581
586
|
- app/views/layouts/shipit.html.erb
|
582
587
|
- app/views/shipit/_variables.html.erb
|
583
588
|
- app/views/shipit/ccmenu/project.xml.builder
|
@@ -593,6 +598,15 @@ files:
|
|
593
598
|
- app/views/shipit/deploys/rollback.html.erb
|
594
599
|
- app/views/shipit/deploys/show.html.erb
|
595
600
|
- app/views/shipit/github_authentication/failed.html.erb
|
601
|
+
- app/views/shipit/merge_status/_anchor.html.erb
|
602
|
+
- app/views/shipit/merge_status/_commit_count_warning.html.erb
|
603
|
+
- app/views/shipit/merge_status/_merge_queue_button.html.erb
|
604
|
+
- app/views/shipit/merge_status/_warning_icon.html.erb
|
605
|
+
- app/views/shipit/merge_status/backlogged.html.erb
|
606
|
+
- app/views/shipit/merge_status/failure.html.erb
|
607
|
+
- app/views/shipit/merge_status/locked.html.erb
|
608
|
+
- app/views/shipit/merge_status/logged_out.erb
|
609
|
+
- app/views/shipit/merge_status/success.html.erb
|
596
610
|
- app/views/shipit/missing_settings.html.erb
|
597
611
|
- app/views/shipit/pull_requests/_pull_request.html.erb
|
598
612
|
- app/views/shipit/pull_requests/index.html.erb
|
@@ -676,7 +690,6 @@ files:
|
|
676
690
|
- lib/shipit/first_parent_commits_iterator.rb
|
677
691
|
- lib/shipit/github_app.rb
|
678
692
|
- lib/shipit/null_serializer.rb
|
679
|
-
- lib/shipit/octokit_bot_users_patch.rb
|
680
693
|
- lib/shipit/octokit_iterator.rb
|
681
694
|
- lib/shipit/paginator.rb
|
682
695
|
- lib/shipit/rollback_commands.rb
|
@@ -717,6 +730,7 @@ files:
|
|
717
730
|
- test/controllers/commits_controller_test.rb
|
718
731
|
- test/controllers/deploys_controller_test.rb
|
719
732
|
- test/controllers/github_authentication_controller_test.rb
|
733
|
+
- test/controllers/merge_status_controller_test.rb
|
720
734
|
- test/controllers/pull_requests_controller_test.rb
|
721
735
|
- test/controllers/rollbacks_controller_test.rb
|
722
736
|
- test/controllers/stacks_controller_test.rb
|
@@ -839,6 +853,7 @@ files:
|
|
839
853
|
- test/models/status/missing_test.rb
|
840
854
|
- test/models/status_test.rb
|
841
855
|
- test/models/task_definitions_test.rb
|
856
|
+
- test/models/tasks_test.rb
|
842
857
|
- test/models/team_test.rb
|
843
858
|
- test/models/undeployed_commits_test.rb
|
844
859
|
- test/models/users_test.rb
|
@@ -960,6 +975,7 @@ test_files:
|
|
960
975
|
- test/models/delivery_test.rb
|
961
976
|
- test/models/commit_deployment_status_test.rb
|
962
977
|
- test/models/api_client_test.rb
|
978
|
+
- test/models/tasks_test.rb
|
963
979
|
- test/models/hook_test.rb
|
964
980
|
- test/models/task_definitions_test.rb
|
965
981
|
- test/models/status/group_test.rb
|
@@ -1012,6 +1028,7 @@ test_files:
|
|
1012
1028
|
- test/controllers/stacks_controller_test.rb
|
1013
1029
|
- test/controllers/commits_controller_test.rb
|
1014
1030
|
- test/controllers/github_authentication_controller_test.rb
|
1031
|
+
- test/controllers/merge_status_controller_test.rb
|
1015
1032
|
- test/controllers/ccmenu_controller_test.rb
|
1016
1033
|
- test/controllers/commit_checks_controller_test.rb
|
1017
1034
|
- test/controllers/pull_requests_controller_test.rb
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'octokit'
|
2
|
-
|
3
|
-
# https://github.com/octokit/octokit.rb/pull/1006
|
4
|
-
if Octokit::VERSION >= '5'
|
5
|
-
raise 'This patch should be removed'
|
6
|
-
else
|
7
|
-
module Octokit
|
8
|
-
module Connection
|
9
|
-
protected
|
10
|
-
|
11
|
-
def request(method, path, data, options = {})
|
12
|
-
if data.is_a?(Hash)
|
13
|
-
options[:query] = data.delete(:query) || {}
|
14
|
-
options[:headers] = data.delete(:headers) || {}
|
15
|
-
if accept = data.delete(:accept)
|
16
|
-
options[:headers][:accept] = accept
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
@last_response = response = agent.call(method, Addressable::URI.parse(path.to_s).normalize.to_s, data, options)
|
21
|
-
response.data
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|