shipit-engine 0.35.1 → 0.36.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 +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
|