shipit-engine 0.35.1 → 0.36.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/README.md +7 -7
- data/app/controllers/concerns/shipit/authentication.rb +5 -1
- data/app/controllers/shipit/api/base_controller.rb +13 -1
- data/app/controllers/shipit/api/rollbacks_controller.rb +1 -1
- data/app/controllers/shipit/api/stacks_controller.rb +8 -2
- data/app/controllers/shipit/api/tasks_controller.rb +19 -2
- data/app/helpers/shipit/stacks_helper.rb +11 -0
- data/app/models/concerns/shipit/deferred_touch.rb +3 -3
- data/app/models/shipit/anonymous_user.rb +4 -0
- data/app/models/shipit/commit_checks.rb +3 -3
- data/app/models/shipit/task.rb +3 -3
- data/app/models/shipit/user.rb +23 -9
- data/app/serializers/shipit/stack_serializer.rb +1 -1
- data/app/views/shipit/deploys/_deploy.html.erb +1 -5
- data/app/views/shipit/stacks/_banners.html.erb +1 -1
- data/app/views/shipit/stacks/_settings_form.erb +55 -0
- data/app/views/shipit/stacks/settings.html.erb +1 -55
- data/app/views/shipit/stacks/show.html.erb +1 -1
- data/config/locales/en.yml +1 -1
- data/config/routes.rb +4 -0
- data/db/migrate/20211103154121_increase_github_team_slug_size.rb +5 -0
- data/lib/shipit/engine.rb +13 -5
- data/lib/shipit/stack_commands.rb +1 -1
- data/lib/shipit/version.rb +1 -1
- data/lib/shipit.rb +5 -2
- data/test/controllers/api/hooks_controller_test.rb +1 -1
- data/test/controllers/api/rollback_controller_test.rb +1 -0
- data/test/controllers/api/stacks_controller_test.rb +25 -0
- data/test/controllers/api/tasks_controller_test.rb +56 -0
- data/test/controllers/stacks_controller_test.rb +11 -0
- data/test/dummy/config/application.rb +1 -2
- data/test/dummy/db/schema.rb +2 -2
- data/test/fixtures/shipit/check_runs.yml +3 -3
- data/test/fixtures/shipit/commits.yml +101 -101
- data/test/fixtures/shipit/deliveries.yml +1 -1
- data/test/fixtures/shipit/merge_requests.yml +19 -19
- data/test/fixtures/shipit/stacks.yml +28 -28
- data/test/fixtures/shipit/statuses.yml +16 -16
- data/test/fixtures/shipit/tasks.yml +65 -65
- data/test/fixtures/shipit/users.yml +2 -5
- data/test/models/commits_test.rb +6 -6
- data/test/models/tasks_test.rb +2 -2
- data/test/models/team_test.rb +21 -2
- data/test/models/users_test.rb +29 -9
- data/test/unit/deploy_commands_test.rb +1 -1
- metadata +175 -173
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3336765264c2c554f5dd879ac8ed409b08e4f5b281bbd9127132b688d23184ee
|
4
|
+
data.tar.gz: ac55d9a82c007326c9a231b784d887be1a826ba11cc71c581888a0018ffaed7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a770a63ffadea62d25d8244265d5ea9552930fee64951d6c4b1e5be4a518271d54d34161b83a8760c9331c6f2758995e61114000bfcf5675b0353a955cc41bad
|
7
|
+
data.tar.gz: 7e7d3629476bab8aa1ab7655e099e6218b511fe728ef9161a2591835ae2c369cd22724e7c193243fd29779574ea1148b2adb97119ce8a04def1a46df0168d62c
|
data/README.md
CHANGED
@@ -390,7 +390,7 @@ machine:
|
|
390
390
|
|
391
391
|
<h3 id="ci">CI</h3>
|
392
392
|
|
393
|
-
**<code>ci.require</code>** contains an array of the [statuses context](https://
|
393
|
+
**<code>ci.require</code>** contains an array of the [statuses context](https://docs.github.com/en/rest/reference/commits#commit-statuses) you want Shipit to disallow deploys if any of them is missing on the commit being deployed.
|
394
394
|
|
395
395
|
For example:
|
396
396
|
```yml
|
@@ -399,7 +399,7 @@ ci:
|
|
399
399
|
- ci/circleci
|
400
400
|
```
|
401
401
|
|
402
|
-
**<code>ci.hide</code>** contains an array of the [statuses context](https://
|
402
|
+
**<code>ci.hide</code>** contains an array of the [statuses context](https://docs.github.com/en/rest/reference/commits#commit-statuses) you want Shipit to ignore.
|
403
403
|
|
404
404
|
For example:
|
405
405
|
```yml
|
@@ -408,7 +408,7 @@ ci:
|
|
408
408
|
- ci/circleci
|
409
409
|
```
|
410
410
|
|
411
|
-
**<code>ci.allow_failures</code>** contains an array of the [statuses context](https://
|
411
|
+
**<code>ci.allow_failures</code>** contains an array of the [statuses context](https://docs.github.com/en/rest/reference/commits#commit-statuses) you want to be visible but not to required for deploy.
|
412
412
|
|
413
413
|
For example:
|
414
414
|
```yml
|
@@ -417,7 +417,7 @@ ci:
|
|
417
417
|
- ci/circleci
|
418
418
|
```
|
419
419
|
|
420
|
-
**<code>ci.blocking</code>** contains an array of the [statuses context](https://
|
420
|
+
**<code>ci.blocking</code>** contains an array of the [statuses context](https://docs.github.com/en/rest/reference/commits#commit-statuses) you want to disallow deploys if any of them is missing or failing on any of the commits being deployed.
|
421
421
|
|
422
422
|
For example:
|
423
423
|
```yml
|
@@ -440,7 +440,7 @@ merge:
|
|
440
440
|
revalidate_after: 12m30s
|
441
441
|
```
|
442
442
|
|
443
|
-
**<code>merge.require</code>** contains an array of the [statuses context](https://
|
443
|
+
**<code>merge.require</code>** contains an array of the [statuses context](https://docs.github.com/en/rest/reference/commits#commit-statuses) that you want Shipit to consider as failing if they aren't present on the pull request. Defaults to `ci.require` if present, or empty otherwise.
|
444
444
|
|
445
445
|
For example:
|
446
446
|
```yml
|
@@ -449,7 +449,7 @@ merge:
|
|
449
449
|
- continuous-integration/travis-ci/push
|
450
450
|
```
|
451
451
|
|
452
|
-
**<code>merge.ignore</code>** contains an array of the [statuses context](https://
|
452
|
+
**<code>merge.ignore</code>** contains an array of the [statuses context](https://docs.github.com/en/rest/reference/commits#commit-statuses) that you want Shipit not to consider when merging pull requests. Defaults to the union of `ci.allow_failures` and `ci.hide` if any is present or empty otherwise.
|
453
453
|
|
454
454
|
For example:
|
455
455
|
```yml
|
@@ -458,7 +458,7 @@ merge:
|
|
458
458
|
- codeclimate
|
459
459
|
```
|
460
460
|
|
461
|
-
**<code>merge.method</code>** the [merge method](https://
|
461
|
+
**<code>merge.method</code>** the [merge method](https://docs.github.com/en/rest/reference/pulls#merge-a-pull-request--parameters) to use for this stack. If it's not set the default merge method will be used. Can be either `merge`, `squash` or `rebase`.
|
462
462
|
|
463
463
|
For example:
|
464
464
|
```yml
|
@@ -17,7 +17,11 @@ module Shipit
|
|
17
17
|
private
|
18
18
|
|
19
19
|
def force_github_authentication
|
20
|
-
if
|
20
|
+
if current_user.logged_in? && current_user.requires_fresh_login?
|
21
|
+
Rails.logger.warn("User #{current_user.id} requires a fresh login, logging out...")
|
22
|
+
reset_session
|
23
|
+
redirect_to(Shipit::Engine.routes.url_helpers.github_authentication_path(origin: request.original_url))
|
24
|
+
elsif Shipit.authentication_disabled? || current_user.logged_in?
|
21
25
|
unless current_user.authorized?
|
22
26
|
team_handles = Shipit.github_teams.map(&:handle)
|
23
27
|
team_list = team_handles.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')
|
@@ -28,6 +28,18 @@ module Shipit
|
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
+
module BasicAuth
|
32
|
+
# Workaround for https://github.com/rails/rails/pull/44610
|
33
|
+
extend ActionController::HttpAuthentication::Basic
|
34
|
+
extend self
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def has_basic_credentials?(request)
|
39
|
+
request.authorization.present? && (auth_scheme(request).downcase == "basic")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
31
43
|
def namespace_for_serializer
|
32
44
|
nil
|
33
45
|
end
|
@@ -36,7 +48,7 @@ module Shipit
|
|
36
48
|
@current_api_client = if Shipit.disable_api_authentication
|
37
49
|
UnlimitedApiClient.new
|
38
50
|
else
|
39
|
-
|
51
|
+
BasicAuth.authenticate(request) do |*parts|
|
40
52
|
token = parts.select(&:present?).join('--')
|
41
53
|
ApiClient.authenticate(token)
|
42
54
|
end
|
@@ -21,7 +21,7 @@ module Shipit
|
|
21
21
|
param_error!(:force, "Can't rollback, deploy in progress")
|
22
22
|
elsif stack.active_task?
|
23
23
|
active_task = stack.active_task
|
24
|
-
active_task.abort!(aborted_by: current_user, rollback_once_aborted_to: deploy)
|
24
|
+
active_task.abort!(aborted_by: current_user, rollback_once_aborted_to: deploy, rollback_once_aborted: true)
|
25
25
|
response = active_task
|
26
26
|
else
|
27
27
|
response = deploy.trigger_rollback(current_user, env: deploy_env, force: params.force, lock: params.lock)
|
@@ -27,7 +27,7 @@ module Shipit
|
|
27
27
|
requires :repo_name, String
|
28
28
|
accepts :environment, String
|
29
29
|
accepts :branch, String
|
30
|
-
accepts :deploy_url, String
|
30
|
+
accepts :deploy_url, String, allow_nil: true
|
31
31
|
accepts :ignore_ci, Boolean
|
32
32
|
accepts :merge_queue_enabled, Boolean
|
33
33
|
accepts :continuous_deployment, Boolean
|
@@ -40,8 +40,9 @@ module Shipit
|
|
40
40
|
end
|
41
41
|
|
42
42
|
params do
|
43
|
+
accepts :environment, String
|
43
44
|
accepts :branch, String
|
44
|
-
accepts :deploy_url, String
|
45
|
+
accepts :deploy_url, String, allow_nil: true
|
45
46
|
accepts :ignore_ci, Boolean
|
46
47
|
accepts :merge_queue_enabled, Boolean
|
47
48
|
accepts :continuous_deployment, Boolean
|
@@ -60,6 +61,11 @@ module Shipit
|
|
60
61
|
head(:accepted)
|
61
62
|
end
|
62
63
|
|
64
|
+
def refresh
|
65
|
+
GithubSyncJob.perform_later(id: stack.id)
|
66
|
+
render_resource(stack, status: :accepted)
|
67
|
+
end
|
68
|
+
|
63
69
|
private
|
64
70
|
|
65
71
|
def create_params
|
@@ -3,14 +3,14 @@ module Shipit
|
|
3
3
|
module Api
|
4
4
|
class TasksController < BaseController
|
5
5
|
require_permission :read, :stack
|
6
|
-
require_permission :deploy, :stack, only:
|
6
|
+
require_permission :deploy, :stack, only: %i(trigger abort)
|
7
7
|
|
8
8
|
def index
|
9
9
|
render_resources(stack.tasks)
|
10
10
|
end
|
11
11
|
|
12
12
|
def show
|
13
|
-
render_resource(
|
13
|
+
render_resource(task)
|
14
14
|
end
|
15
15
|
|
16
16
|
params do
|
@@ -23,6 +23,23 @@ module Shipit
|
|
23
23
|
message: 'A task is already running.',
|
24
24
|
})
|
25
25
|
end
|
26
|
+
|
27
|
+
def abort
|
28
|
+
if task.active?
|
29
|
+
task.abort!(aborted_by: current_user)
|
30
|
+
head(:accepted)
|
31
|
+
else
|
32
|
+
render(status: :method_not_allowed, json: {
|
33
|
+
message: "This task is not currently running.",
|
34
|
+
})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def task
|
41
|
+
stack.tasks.find(params[:id])
|
42
|
+
end
|
26
43
|
end
|
27
44
|
end
|
28
45
|
end
|
@@ -36,6 +36,17 @@ module Shipit
|
|
36
36
|
link_to(t("deploy_button.caption.#{deploy_state}"), url, class: classes, data: data)
|
37
37
|
end
|
38
38
|
|
39
|
+
def rollback_button(deploy)
|
40
|
+
if deploy.stack.active_task?
|
41
|
+
link_to('Deploy in progress...', '#', class: 'btn disabled deploy-action')
|
42
|
+
else
|
43
|
+
url = rollback_stack_deploy_path(deploy.stack, deploy)
|
44
|
+
classes = %w(btn btn--delete deploy-action rollback-action)
|
45
|
+
|
46
|
+
link_to('Rollback to this deploy...', url, class: classes)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
39
50
|
def github_change_url(commit)
|
40
51
|
if commit.pull_request?
|
41
52
|
github_pull_request_url(commit)
|
@@ -49,9 +49,9 @@ module Shipit
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def fetch_members
|
52
|
-
Shipit.redis.multi do
|
53
|
-
|
54
|
-
|
52
|
+
Shipit.redis.multi do |transaction|
|
53
|
+
transaction.sunionstore(TMP_KEY, SET_KEY)
|
54
|
+
transaction.del(SET_KEY)
|
55
55
|
end
|
56
56
|
|
57
57
|
yield Shipit.redis.smembers(TMP_KEY).map { |r| r.split('|') }
|
@@ -44,9 +44,9 @@ module Shipit
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def write(output)
|
47
|
-
Shipit.redis.pipelined do
|
48
|
-
|
49
|
-
|
47
|
+
Shipit.redis.pipelined do |pipeline|
|
48
|
+
pipeline.append(key('output'), output)
|
49
|
+
pipeline.expire(key('output'), OUTPUT_TTL)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
data/app/models/shipit/task.rb
CHANGED
@@ -313,9 +313,9 @@ module Shipit
|
|
313
313
|
end
|
314
314
|
|
315
315
|
def request_abort
|
316
|
-
Shipit.redis.pipelined do
|
317
|
-
|
318
|
-
|
316
|
+
Shipit.redis.pipelined do |pipeline|
|
317
|
+
pipeline.incr(abort_key)
|
318
|
+
pipeline.expire(abort_key, 1.month.to_i)
|
319
319
|
end
|
320
320
|
end
|
321
321
|
|
data/app/models/shipit/user.rb
CHANGED
@@ -3,6 +3,8 @@ module Shipit
|
|
3
3
|
class User < Record
|
4
4
|
DEFAULT_AVATAR = URI.parse('https://avatars.githubusercontent.com/u/583231?')
|
5
5
|
|
6
|
+
self.ignored_columns = %w(encrypted_github_access_token_iv)
|
7
|
+
|
6
8
|
has_many :memberships
|
7
9
|
has_many :teams, through: :memberships
|
8
10
|
has_many :authored_commits, class_name: :Commit, foreign_key: :author_id, inverse_of: :author
|
@@ -11,7 +13,10 @@ module Shipit
|
|
11
13
|
|
12
14
|
validates :name, presence: true
|
13
15
|
|
14
|
-
|
16
|
+
encrypts :encrypted_github_access_token
|
17
|
+
alias_attribute :github_access_token, :encrypted_github_access_token
|
18
|
+
|
19
|
+
after_find :discard_outdated_credentials!
|
15
20
|
|
16
21
|
def self.find_or_create_by_login!(login)
|
17
22
|
find_or_create_by!(login: login) do |user|
|
@@ -56,14 +61,6 @@ module Shipit
|
|
56
61
|
end
|
57
62
|
end
|
58
63
|
|
59
|
-
alias_method :original_github_access_token, :github_access_token
|
60
|
-
def github_access_token
|
61
|
-
original_github_access_token
|
62
|
-
rescue OpenSSL::Cipher::CipherError
|
63
|
-
update_columns(encrypted_github_access_token: nil, encrypted_github_access_token_iv: nil)
|
64
|
-
nil
|
65
|
-
end
|
66
|
-
|
67
64
|
def github_api
|
68
65
|
return Shipit.github.api unless github_access_token
|
69
66
|
|
@@ -123,8 +120,25 @@ module Shipit
|
|
123
120
|
DEFAULT_AVATAR.dup
|
124
121
|
end
|
125
122
|
|
123
|
+
# https://github.blog/2021-04-05-behind-githubs-new-authentication-token-formats
|
124
|
+
GITHUB_TOKEN_FORMAT = /^gh[a-z]_/
|
125
|
+
|
126
|
+
def requires_fresh_login?
|
127
|
+
github_access_token.present? && !github_access_token.match(GITHUB_TOKEN_FORMAT)
|
128
|
+
end
|
129
|
+
|
126
130
|
private
|
127
131
|
|
132
|
+
def discard_outdated_credentials!
|
133
|
+
if encrypted_github_access_token_before_type_cast.present?
|
134
|
+
begin
|
135
|
+
encrypted_github_access_token
|
136
|
+
rescue ActiveRecord::Encryption::Errors::Decryption
|
137
|
+
update_column(:encrypted_github_access_token, nil)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
128
142
|
def identify_renamed_user!
|
129
143
|
last_commit = commits.last
|
130
144
|
return unless last_commit
|
@@ -8,7 +8,7 @@ module Shipit
|
|
8
8
|
attributes :id, :repo_owner, :repo_name, :environment, :html_url, :url, :tasks_url, :deploy_url,
|
9
9
|
:merge_requests_url, :deploy_spec, :undeployed_commits_count, :is_locked, :lock_reason, :continuous_deployment,
|
10
10
|
:created_at, :updated_at, :locked_since, :last_deployed_at, :branch, :merge_queue_enabled, :is_archived,
|
11
|
-
:archived_since
|
11
|
+
:archived_since, :ignore_ci
|
12
12
|
|
13
13
|
def url
|
14
14
|
api_stack_url(object)
|
@@ -55,11 +55,7 @@
|
|
55
55
|
<% unless read_only %>
|
56
56
|
<div class="deploy-actions">
|
57
57
|
<% if deploy.rollbackable? %>
|
58
|
-
|
59
|
-
<%= link_to 'Deploy in progress...', '#', class: 'btn disabled deploy-action' %>
|
60
|
-
<% else %>
|
61
|
-
<%= link_to 'Rollback to this deploy...', rollback_stack_deploy_path(@stack, deploy), class: 'btn btn--delete deploy-action rollback-action' %>
|
62
|
-
<% end %>
|
58
|
+
<%= rollback_button(deploy) %>
|
63
59
|
<% elsif deploy.currently_deployed? && !deploy.stack.active_task? %>
|
64
60
|
<%= redeploy_button(deploy.until_commit) %>
|
65
61
|
<% end %>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
<%= link_to stack.github_repo_name, github_repo_url(stack.repo_owner, stack.repo_name) %>
|
24
24
|
has been inaccessible for <%= time_ago_in_words(stack.inaccessible_since) %>.
|
25
25
|
|
26
|
-
This could be a permission issue, or the
|
26
|
+
This could be a permission issue, or the repo could have changed on GitHub.
|
27
27
|
</p>
|
28
28
|
</div>
|
29
29
|
</div>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<div class="setting-section">
|
2
|
+
<%= form_with scope: :stack, url: stack_path(stack), method: :patch do |f| %>
|
3
|
+
<div class="field-wrapper">
|
4
|
+
<%= f.label :environment %>
|
5
|
+
<%= f.text_field :environment, placeholder: 'production' %>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<div class="field-wrapper">
|
9
|
+
<span>Branch: <%= stack.branch %></span>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<div class="field-wrapper">
|
13
|
+
<%= f.label :deploy_url, 'Deploy URL (Where is this stack deployed to?)' %>
|
14
|
+
<%= f.text_field :deploy_url, placeholder: 'https://' %>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div class="field-wrapper">
|
18
|
+
<%= f.check_box :continuous_deployment %>
|
19
|
+
<%= f.label :continuous_deployment, 'Enable continuous deployment' %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="field-wrapper">
|
23
|
+
<%= f.check_box :merge_queue_enabled %>
|
24
|
+
<%= f.label :merge_queue_enabled, 'Enable merge queue' %>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div class="field-wrapper">
|
28
|
+
<%= f.check_box :ignore_ci %>
|
29
|
+
<%= f.label :ignore_ci, "Don't require CI to deploy" %>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<%= f.submit class: "btn", value: "Save" %>
|
33
|
+
<% end %>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div class="setting-section">
|
37
|
+
<h5>Lock deploys</h5>
|
38
|
+
<%= form_with scope: :stack, url: stack_path(@stack), method: :patch do |f| %>
|
39
|
+
<div class="field-wrapper">
|
40
|
+
<%= f.label :lock_reason, 'Reason for lock' %>
|
41
|
+
<%= f.text_area :lock_reason %>
|
42
|
+
</div>
|
43
|
+
<% if @stack.locked? %>
|
44
|
+
<%= f.submit class: "btn", value: "Update Reason" %>
|
45
|
+
<% else %>
|
46
|
+
<%= f.submit class: "btn", value: "Lock" %>
|
47
|
+
<% end %>
|
48
|
+
<% end %>
|
49
|
+
<% if @stack.locked? %>
|
50
|
+
<%= form_with scope: :stack, url: stack_path(@stack), method: :patch do |f| %>
|
51
|
+
<%= f.hidden_field :lock_reason, value: nil %>
|
52
|
+
<%= f.submit class: "btn btn--primary", value: "Unlock" %>
|
53
|
+
<%- end -%>
|
54
|
+
<% end %>
|
55
|
+
</div>
|
@@ -6,61 +6,7 @@
|
|
6
6
|
<h2>Settings (Stack #<%= @stack.id %>)</h2>
|
7
7
|
</header>
|
8
8
|
|
9
|
-
|
10
|
-
<%= form_with scope: :stack, url: stack_path(@stack), method: :patch do |f| %>
|
11
|
-
<div class="field-wrapper">
|
12
|
-
<%= f.label :environment %>
|
13
|
-
<%= f.text_field :environment, placeholder: 'production' %>
|
14
|
-
</div>
|
15
|
-
|
16
|
-
<div class="field-wrapper">
|
17
|
-
<span>Branch: <%= @stack.branch %></span>
|
18
|
-
</div>
|
19
|
-
|
20
|
-
<div class="field-wrapper">
|
21
|
-
<%= f.label :deploy_url, 'Deploy URL (Where is this stack deployed to?)' %>
|
22
|
-
<%= f.text_field :deploy_url, placeholder: 'https://' %>
|
23
|
-
</div>
|
24
|
-
|
25
|
-
<div class="field-wrapper">
|
26
|
-
<%= f.check_box :continuous_deployment %>
|
27
|
-
<%= f.label :continuous_deployment, 'Enable continuous deployment' %>
|
28
|
-
</div>
|
29
|
-
|
30
|
-
<div class="field-wrapper">
|
31
|
-
<%= f.check_box :merge_queue_enabled %>
|
32
|
-
<%= f.label :merge_queue_enabled, 'Enable merge queue' %>
|
33
|
-
</div>
|
34
|
-
|
35
|
-
<div class="field-wrapper">
|
36
|
-
<%= f.check_box :ignore_ci %>
|
37
|
-
<%= f.label :ignore_ci, "Don't require CI to deploy" %>
|
38
|
-
</div>
|
39
|
-
|
40
|
-
<%= f.submit class: "btn", value: "Save" %>
|
41
|
-
<% end %>
|
42
|
-
</div>
|
43
|
-
|
44
|
-
<div class="setting-section">
|
45
|
-
<h5>Lock deploys</h5>
|
46
|
-
<%= form_with scope: :stack, url: stack_path(@stack), method: :patch do |f| %>
|
47
|
-
<div class="field-wrapper">
|
48
|
-
<%= f.label :lock_reason, 'Reason for lock' %>
|
49
|
-
<%= f.text_area :lock_reason %>
|
50
|
-
</div>
|
51
|
-
<% if @stack.locked? %>
|
52
|
-
<%= f.submit class: "btn", value: "Update Reason" %>
|
53
|
-
<% else %>
|
54
|
-
<%= f.submit class: "btn", value: "Lock" %>
|
55
|
-
<% end %>
|
56
|
-
<% end %>
|
57
|
-
<% if @stack.locked? %>
|
58
|
-
<%= form_with scope: :stack, url: stack_path(@stack), method: :patch do |f| %>
|
59
|
-
<%= f.hidden_field :lock_reason, value: nil %>
|
60
|
-
<%= f.submit class: "btn btn--primary", value: "Unlock" %>
|
61
|
-
<%- end -%>
|
62
|
-
<% end %>
|
63
|
-
</div>
|
9
|
+
<%= render partial: 'shipit/stacks/settings_form', locals: { stack: @stack } %>
|
64
10
|
|
65
11
|
<div class="setting-section">
|
66
12
|
<h5>Resynchronize this stack</h5>
|
data/config/locales/en.yml
CHANGED
@@ -41,7 +41,7 @@ en:
|
|
41
41
|
reject: Mark the release as faulty
|
42
42
|
deploy_button:
|
43
43
|
hint:
|
44
|
-
max_commits:
|
44
|
+
max_commits: Use caution when deploying more than %{maximum} commits at once.
|
45
45
|
blocked: This commit range includes a commit that can't be deployed.
|
46
46
|
caption:
|
47
47
|
pending: Pending CI
|
data/config/routes.rb
CHANGED
@@ -20,6 +20,7 @@ Shipit::Engine.routes.draw do
|
|
20
20
|
get '/' => 'stacks#show'
|
21
21
|
delete '/' => 'stacks#destroy'
|
22
22
|
patch '/' => 'stacks#update'
|
23
|
+
post '/refresh' => 'stacks#refresh'
|
23
24
|
end
|
24
25
|
|
25
26
|
scope '/stacks/*stack_id', stack_id: stack_id_format, as: :stack do
|
@@ -27,6 +28,9 @@ Shipit::Engine.routes.draw do
|
|
27
28
|
resource :lock, only: %i(create update destroy)
|
28
29
|
resources :tasks, only: %i(index show) do
|
29
30
|
resource :output, only: :show
|
31
|
+
member do
|
32
|
+
put :abort
|
33
|
+
end
|
30
34
|
end
|
31
35
|
resources :deploys, only: %i(index create) do
|
32
36
|
resources :release_statuses, only: %i(create)
|
data/lib/shipit/engine.rb
CHANGED
@@ -5,7 +5,7 @@ module Shipit
|
|
5
5
|
|
6
6
|
paths['app/models'] << 'app/serializers' << 'app/serializers/concerns'
|
7
7
|
|
8
|
-
initializer 'shipit.config' do |app|
|
8
|
+
initializer 'shipit.config', before: 'active_record_encryption.configuration' do |app|
|
9
9
|
Rails.application.routes.default_url_options[:host] = Shipit.host
|
10
10
|
Shipit::Engine.routes.default_url_options[:host] = Shipit.host
|
11
11
|
Pubsubstub.redis_url = Shipit.redis_url.to_s
|
@@ -28,8 +28,6 @@ module Shipit
|
|
28
28
|
path.end_with?('.svg') || (path.start_with?('emoji/') && path.end_with?('.png'))
|
29
29
|
end
|
30
30
|
|
31
|
-
ActionDispatch::ExceptionWrapper.rescue_responses[Shipit::TaskDefinition::NotFound.name] = :not_found
|
32
|
-
|
33
31
|
ActiveModel::Serializer._root = false
|
34
32
|
ActiveModel::ArraySerializer._root = false
|
35
33
|
ActiveModel::Serializer.include(Engine.routes.url_helpers)
|
@@ -45,9 +43,19 @@ module Shipit
|
|
45
43
|
app.config.middleware.insert_after(::Rack::Runtime, Shipit::SameSiteCookieMiddleware)
|
46
44
|
end
|
47
45
|
|
48
|
-
app.
|
49
|
-
|
46
|
+
if app.credentials.active_record_encryption.blank? && Shipit.user_access_tokens_key.present?
|
47
|
+
# For ease of upgrade, we derive an Active Record encryption config automatically.
|
48
|
+
# But if AR Encryption is already configured, we just use that
|
49
|
+
app.credentials[:active_record_encryption] = {
|
50
|
+
primary_key: Shipit.user_access_tokens_key,
|
51
|
+
key_derivation_salt: Digest::SHA256.digest("salt:".b + Shipit.user_access_tokens_key),
|
52
|
+
}
|
50
53
|
end
|
51
54
|
end
|
55
|
+
|
56
|
+
config.after_initialize do
|
57
|
+
ActionDispatch::ExceptionWrapper.rescue_responses[Shipit::TaskDefinition::NotFound.name] = :not_found
|
58
|
+
ActionController::Base.include(Shipit::ActiveModelSerializersPatch)
|
59
|
+
end
|
52
60
|
end
|
53
61
|
end
|
@@ -16,7 +16,7 @@ module Shipit
|
|
16
16
|
def fetch
|
17
17
|
create_directories
|
18
18
|
if valid_git_repository?(@stack.git_path)
|
19
|
-
git('fetch', 'origin', '--tags', @stack.branch, env: env, chdir: @stack.git_path)
|
19
|
+
git('fetch', 'origin', '--quiet', '--tags', @stack.branch, env: env, chdir: @stack.git_path)
|
20
20
|
else
|
21
21
|
@stack.clear_git_cache!
|
22
22
|
git_clone(@stack.repo_git_url, @stack.git_path, branch: @stack.branch, env: env, chdir: @stack.deploys_path)
|
data/lib/shipit/version.rb
CHANGED
data/lib/shipit.rb
CHANGED
@@ -5,7 +5,6 @@ require 'state_machines-activerecord'
|
|
5
5
|
require 'validate_url'
|
6
6
|
require 'responders'
|
7
7
|
require 'explicit-parameters'
|
8
|
-
require 'attr_encrypted'
|
9
8
|
|
10
9
|
require 'sass-rails'
|
11
10
|
require 'coffee-rails'
|
@@ -153,7 +152,11 @@ module Shipit
|
|
153
152
|
end
|
154
153
|
|
155
154
|
def user_access_tokens_key
|
156
|
-
|
155
|
+
if secrets.user_access_tokens_key.present?
|
156
|
+
secrets.user_access_tokens_key
|
157
|
+
elsif secrets.secret_key_base
|
158
|
+
Digest::SHA256.digest("user_access_tokens_key" + secrets.secret_key_base)
|
159
|
+
end
|
157
160
|
end
|
158
161
|
|
159
162
|
def host
|