shipit-engine 0.29.0 → 0.30.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 +37 -2
- data/app/assets/images/archive-solid.svg +1 -0
- data/app/assets/stylesheets/_pages/_stacks.scss +76 -0
- data/app/controllers/shipit/api/stacks_controller.rb +20 -1
- data/app/controllers/shipit/api_clients_controller.rb +49 -0
- data/app/controllers/shipit/merge_status_controller.rb +8 -4
- data/app/controllers/shipit/stacks_controller.rb +58 -9
- data/app/controllers/shipit/webhooks_controller.rb +2 -130
- data/app/helpers/shipit/stacks_helper.rb +4 -0
- data/app/jobs/shipit/background_job/unique.rb +3 -1
- data/app/jobs/shipit/continuous_delivery_job.rb +1 -0
- data/app/jobs/shipit/destroy_stack_job.rb +2 -2
- data/app/models/shipit/commit.rb +21 -9
- data/app/models/shipit/commit_deployment.rb +15 -11
- data/app/models/shipit/commit_deployment_status.rb +6 -2
- data/app/models/shipit/deploy.rb +48 -7
- data/app/models/shipit/deploy_stats.rb +57 -0
- data/app/models/shipit/repository.rb +38 -0
- data/app/models/shipit/stack.rb +41 -34
- data/app/models/shipit/task.rb +26 -4
- data/app/models/shipit/webhooks.rb +32 -0
- data/app/models/shipit/webhooks/handlers/check_suite_handler.rb +19 -0
- data/app/models/shipit/webhooks/handlers/handler.rb +40 -0
- data/app/models/shipit/webhooks/handlers/membership_handler.rb +45 -0
- data/app/models/shipit/webhooks/handlers/push_handler.rb +20 -0
- data/app/models/shipit/webhooks/handlers/status_handler.rb +26 -0
- data/app/serializers/shipit/stack_serializer.rb +6 -1
- data/app/validators/ascii_only_validator.rb +3 -3
- data/app/views/layouts/_head.html.erb +0 -0
- data/app/views/layouts/shipit.html.erb +4 -2
- data/app/views/shipit/api_clients/index.html.erb +36 -0
- data/app/views/shipit/api_clients/new.html.erb +33 -0
- data/app/views/shipit/api_clients/show.html.erb +35 -0
- data/app/views/shipit/merge_status/logged_out.erb +1 -1
- data/app/views/shipit/stacks/_header.html.erb +12 -7
- data/app/views/shipit/stacks/_links.html.erb +1 -0
- data/app/views/shipit/stacks/index.html.erb +7 -2
- data/app/views/shipit/stacks/settings.html.erb +19 -0
- data/app/views/shipit/stacks/statistics.html.erb +82 -0
- data/config/locales/en.yml +14 -2
- data/config/routes.rb +4 -0
- data/db/migrate/20191209231045_create_shipit_repositories.rb +12 -0
- data/db/migrate/20191209231307_add_repository_reference_to_stacks.rb +15 -0
- data/db/migrate/20191216162728_backfill_repository_data.rb +22 -0
- data/db/migrate/20191216163010_remove_repository_information_from_stacks.rb +20 -0
- data/db/migrate/20191219205202_add_archived_since_to_stacks.rb +6 -0
- data/db/migrate/20200102175621_optional_task_commits.rb +6 -0
- data/db/migrate/20200109132519_add_sha_to_commit_deployments.rb +5 -0
- data/lib/shipit/github_app.rb +32 -3
- data/lib/shipit/task_commands.rb +10 -2
- data/lib/shipit/version.rb +1 -1
- data/test/controllers/api/ccmenu_controller_test.rb +1 -1
- data/test/controllers/api/stacks_controller_test.rb +14 -6
- data/test/controllers/api_clients_controller_test.rb +103 -0
- data/test/controllers/merge_status_controller_test.rb +21 -4
- data/test/controllers/stacks_controller_test.rb +35 -0
- data/test/controllers/webhooks_controller_test.rb +26 -0
- data/test/dummy/config/environments/development.rb +22 -4
- data/test/dummy/db/schema.rb +17 -6
- data/test/dummy/db/seeds.rb +20 -6
- data/test/fixtures/shipit/commit_deployment_statuses.yml +4 -4
- data/test/fixtures/shipit/commit_deployments.yml +8 -8
- data/test/fixtures/shipit/commits.yml +23 -0
- data/test/fixtures/shipit/repositories.yml +23 -0
- data/test/fixtures/shipit/stacks.yml +100 -16
- data/test/fixtures/shipit/tasks.yml +66 -3
- data/test/jobs/destroy_stack_job_test.rb +9 -0
- data/test/models/commit_deployment_status_test.rb +33 -4
- data/test/models/commit_deployment_test.rb +8 -11
- data/test/models/commits_test.rb +22 -2
- data/test/models/deploy_stats_test.rb +112 -0
- data/test/models/deploys_test.rb +55 -17
- data/test/models/pull_request_test.rb +1 -1
- data/test/models/shipit/repository_test.rb +76 -0
- data/test/models/shipit/wehbooks/handlers_test.rb +26 -0
- data/test/models/stacks_test.rb +44 -51
- data/test/models/undeployed_commits_test.rb +13 -0
- data/test/test_helper.rb +3 -1
- data/test/unit/deploy_commands_test.rb +9 -0
- data/test/unit/github_app_test.rb +136 -0
- metadata +161 -128
@@ -0,0 +1 @@
|
|
1
|
+
<%# Placeholder to be used by the host application %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% content_for :page_title do %>
|
2
|
-
<h1
|
2
|
+
<h1><%= Shipit.app_name %></h1>
|
3
3
|
<% end %>
|
4
4
|
<% content_for :primary_navigation do %>
|
5
5
|
<%= link_to 'Add a stack', new_stack_path, class: 'btn secondary' %>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
</ul>
|
19
19
|
<ul class="stack-lst">
|
20
20
|
<% @stacks.each do |stack| %>
|
21
|
-
<li class="search-item <%= stack.undeployed_commits? ? 'undeployed' : '' %> <%= @user_stacks.include?(stack.id) ? 'contributor' : 'not-matching' %>" data-search="<%= stack.repo_name %> <%= stack.environment %> <%= stack.deploy_url %>" data-stack-id="<%= stack.id %>">
|
21
|
+
<li class="search-item <%= stack.archived? ? 'archived' : '' %> <%= stack.undeployed_commits? ? 'undeployed' : '' %> <%= @user_stacks.include?(stack.id) ? 'contributor' : 'not-matching' %>" data-search="<%= stack.repo_name %> <%= stack.environment %> <%= stack.deploy_url %>" data-stack-id="<%= stack.id %>">
|
22
22
|
<%= link_to stack_path(stack), class: 'commits-path' do %>
|
23
23
|
<span class="col"><%= stack.repo_name %></span>
|
24
24
|
<small class="col"><%= stack.environment.capitalize %></small>
|
@@ -30,6 +30,11 @@
|
|
30
30
|
</ul>
|
31
31
|
|
32
32
|
<%= link_to 'show all stacks', '#', class: 'btn secondary show-all-stacks' %></p>
|
33
|
+
<% if @show_archived %>
|
34
|
+
<%= link_to 'hide archived stacks', '?', class: 'btn secondary' %></p>
|
35
|
+
<% else %>
|
36
|
+
<%= link_to 'show archived stacks', '?show_archived=1', class: 'btn secondary' %></p>
|
37
|
+
<% end %>
|
33
38
|
</section>
|
34
39
|
|
35
40
|
</div>
|
@@ -61,6 +61,7 @@
|
|
61
61
|
<%- end -%>
|
62
62
|
<% end %>
|
63
63
|
</div>
|
64
|
+
|
64
65
|
<div class="setting-section">
|
65
66
|
<h5>Resynchronize this stack</h5>
|
66
67
|
<table>
|
@@ -80,6 +81,24 @@
|
|
80
81
|
<%= button_to "Fetch URL", "", class: 'btn', data: {remote: ccmenu_url_url(stack_id: @stack.to_param)} %>
|
81
82
|
</div>
|
82
83
|
|
84
|
+
<div class="setting-section">
|
85
|
+
<% if @stack.archived? %>
|
86
|
+
<h5>Restore Stack</h5>
|
87
|
+
<p>This action will de-archive the Stack, restoring it in the stack list and unlocking it.</p>
|
88
|
+
<%= form_for @stack do |f| %>
|
89
|
+
<%= f.hidden_field :archived, value: false %>
|
90
|
+
<%= f.submit class: "btn", value: "Restore" %>
|
91
|
+
<% end %>
|
92
|
+
<% else %>
|
93
|
+
<h5>Archive Stack</h5>
|
94
|
+
<p>This action will archive the Stack, hiding it from the stack list and locking it. It can still be found if you know the URL and de-archived.</p>
|
95
|
+
<%= form_for @stack do |f| %>
|
96
|
+
<%= f.hidden_field :archived, value: true %>
|
97
|
+
<%= f.submit class: "btn", value: "Archive" %>
|
98
|
+
<% end %>
|
99
|
+
<% end %>
|
100
|
+
</div>
|
101
|
+
|
83
102
|
<div class="setting-section">
|
84
103
|
<h5>Delete this stack</h5>
|
85
104
|
<p>This action will delete the stack from Ship it permanently. Be careful.</p>
|
@@ -0,0 +1,82 @@
|
|
1
|
+
<%= render partial: 'shipit/stacks/header', locals: {stack: @stack} %>
|
2
|
+
<%= render partial: 'shipit/stacks/banners', locals: {stack: @stack} %>
|
3
|
+
|
4
|
+
<div class="wrapper">
|
5
|
+
<section>
|
6
|
+
<header class="section-header">
|
7
|
+
<h2>Statistics – Past 7 Days</h2>
|
8
|
+
</header>
|
9
|
+
|
10
|
+
<div class="row">
|
11
|
+
<div class="box">
|
12
|
+
<div class="box__body">
|
13
|
+
<div class="stats">
|
14
|
+
<div class="stats__amount"><%= @deploy_stats.count %></div>
|
15
|
+
<div class="stats__caption">Deploys</div>
|
16
|
+
<div class="stats__change">
|
17
|
+
<div class="stats__value stats__value--<%=positive_negative_class(@diffs[:count])%>"><%= number_to_percentage(@diffs[:count], precision: 1) %></div>
|
18
|
+
<div class="stats__period">this week</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<div class="box">
|
25
|
+
<div class="box__body">
|
26
|
+
<div class="stats">
|
27
|
+
<div class="stats__amount"><%= number_to_percentage(@deploy_stats.success_rate, precision: 1) %></div>
|
28
|
+
<div class="stats__caption">Deploys success rate</div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<div class="box">
|
34
|
+
<div class="box__body">
|
35
|
+
<div class="stats">
|
36
|
+
<div class="stats__amount"><%= Shipit::Duration.new @deploy_stats.average_duration %></div>
|
37
|
+
<div class="stats__caption">Average deploy time</div>
|
38
|
+
<div class="stats__change">
|
39
|
+
<div class="stats__value stats__value--<%=positive_negative_class(@diffs[:average_duration])%>"><%= number_to_percentage(@diffs[:average_duration], precision: 1) %></div>
|
40
|
+
<div class="stats__period">this week</div>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<div class="row">
|
48
|
+
<div class="box">
|
49
|
+
<div class="box__body">
|
50
|
+
<div class="stats">
|
51
|
+
<div class="stats__amount"><%= Shipit::Duration.new @deploy_stats.min_duration %></div>
|
52
|
+
<div class="stats__caption">Min deploy time</div>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<div class="box">
|
58
|
+
<div class="box__body">
|
59
|
+
<div class="stats">
|
60
|
+
<div class="stats__amount"><%= Shipit::Duration.new @deploy_stats.median_duration %></div>
|
61
|
+
<div class="stats__caption">Median deploy time</div>
|
62
|
+
<div class="stats__change">
|
63
|
+
<div class="stats__value stats__value--<%=positive_negative_class(@diffs[:median_duration])%>"><%= number_to_percentage(@diffs[:median_duration], precision: 1) %></div>
|
64
|
+
<div class="stats__period">this week</div>
|
65
|
+
</div>
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
|
70
|
+
<div class="box">
|
71
|
+
<div class="box__body">
|
72
|
+
<div class="stats">
|
73
|
+
<div class="stats__amount"><%= Shipit::Duration.new @deploy_stats.max_duration %></div>
|
74
|
+
<div class="stats__caption">Max deploy time</div>
|
75
|
+
</div>
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
|
80
|
+
</section>
|
81
|
+
|
82
|
+
</div>
|
data/config/locales/en.yml
CHANGED
@@ -20,6 +20,16 @@
|
|
20
20
|
# available at http://guides.rubyonrails.org/i18n.html.
|
21
21
|
|
22
22
|
en:
|
23
|
+
stack:
|
24
|
+
nav:
|
25
|
+
refresh: Refresh statuses & commits
|
26
|
+
commits: Commits & Deploys
|
27
|
+
settings: Settings
|
28
|
+
timeline: Timeline
|
29
|
+
statistics: Stats
|
30
|
+
merge_queue: "Merge Queue (%{count})"
|
31
|
+
view_on_github: View on GitHub
|
32
|
+
deploy_link: View website
|
23
33
|
commit:
|
24
34
|
lock: This commit is safe to deploy. Click to mark it as unsafe.
|
25
35
|
unlock: This commit was marked as unsafe to deploy. Click to mark it as safe.
|
@@ -72,12 +82,14 @@ en:
|
|
72
82
|
ascii: "contains non-ASCII characters"
|
73
83
|
deployment_description:
|
74
84
|
deploy:
|
75
|
-
|
85
|
+
in_progress: "%{author} triggered the deploy of %{stack} to %{sha}"
|
86
|
+
pending: "%{author} created the deploy of %{stack} to %{sha}"
|
76
87
|
success: "%{author} deployed %{stack} to %{sha}"
|
77
88
|
failure: "Deploy of %{stack} to %{sha} by %{author} failed"
|
78
89
|
error: "Deploy of %{stack} to %{sha} by %{author} failed"
|
79
90
|
rollback:
|
80
|
-
|
91
|
+
in_progress: "%{author} triggered the deploy of %{stack} to %{sha}"
|
92
|
+
pending: "%{author} created the rollback of %{stack} to %{sha}"
|
81
93
|
success: "%{author} rolled back %{stack} to %{sha}"
|
82
94
|
failure: "Rollback of %{stack} to %{sha} by %{author} failed"
|
83
95
|
error: "Rollback of %{stack} to %{sha} by %{author} failed"
|
data/config/routes.rb
CHANGED
@@ -47,6 +47,7 @@ Shipit::Engine.routes.draw do
|
|
47
47
|
delete '/merge_status/*stack_id/pull/:number', action: :dequeue, controller: :merge_status, id: stack_id_format, as: :dequeue_pull_request
|
48
48
|
|
49
49
|
# Humans
|
50
|
+
resources :api_clients
|
50
51
|
resources :stacks, only: %i(new create index)
|
51
52
|
|
52
53
|
scope '/github/auth/github', as: :github_authentication, controller: :github_authentication do
|
@@ -61,6 +62,7 @@ Shipit::Engine.routes.draw do
|
|
61
62
|
patch '/' => 'stacks#update'
|
62
63
|
delete '/' => 'stacks#destroy'
|
63
64
|
get :settings, controller: :stacks
|
65
|
+
get :statistics, controller: :stacks
|
64
66
|
post :refresh, controller: :stacks
|
65
67
|
get :refresh, controller: :stacks # For easier design, sorry :/
|
66
68
|
post :clear_git_cache, controller: :stacks
|
@@ -74,6 +76,8 @@ Shipit::Engine.routes.draw do
|
|
74
76
|
get '/commit/:sha/checks' => 'commit_checks#show', as: :commit_checks
|
75
77
|
get '/commit/:sha/checks/tail' => 'commit_checks#tail', as: :tail_commit_checks, defaults: {format: :json}
|
76
78
|
|
79
|
+
get '/stats' => 'stats#show', as: :stats
|
80
|
+
|
77
81
|
resources :rollbacks, only: %i(create)
|
78
82
|
resources :commits, only: %i(update)
|
79
83
|
resources :tasks, only: %i(show) do
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateShipitRepositories < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :repositories do |t|
|
4
|
+
t.string :owner, limit: 39, null: false
|
5
|
+
t.string :name, limit: 100, null: false
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :repositories, ["owner", "name"], name: "repository_unicity", unique: true
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class AddRepositoryReferenceToStacks < ActiveRecord::Migration[6.0]
|
2
|
+
def up
|
3
|
+
change_table(:stacks) do |t|
|
4
|
+
t.references :repository
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def down
|
9
|
+
change_column :stacks, :repo_name, :string, null: false
|
10
|
+
change_column :stacks, :repo_owner, :string, null: false
|
11
|
+
change_table(:stacks) do |t|
|
12
|
+
t.remove_references :repository
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class BackfillRepositoryData < ActiveRecord::Migration[6.0]
|
2
|
+
def up
|
3
|
+
repositories = {}
|
4
|
+
Shipit::Stack.all.each do |stack|
|
5
|
+
repo_owner = stack[:repo_owner].downcase
|
6
|
+
repo_name = stack[:repo_name].downcase
|
7
|
+
|
8
|
+
repository = (repositories[[repo_owner, repo_name]] ||= Shipit::Repository.create_or_find_by!(
|
9
|
+
owner: repo_owner,
|
10
|
+
name: repo_name,
|
11
|
+
))
|
12
|
+
|
13
|
+
stack.update_column(:repository_id, repository.id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def down
|
18
|
+
Shipit::Repository.find_each do |repository|
|
19
|
+
repository.stacks.update_all(repo_owner: repository.owner, repo_name: repository.name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class RemoveRepositoryInformationFromStacks < ActiveRecord::Migration[6.0]
|
2
|
+
def up
|
3
|
+
change_column_null :stacks, :repository_id, false
|
4
|
+
change_table(:stacks) do |t|
|
5
|
+
t.remove_index ["repo_owner", "repo_name", "environment"]
|
6
|
+
t.remove :repo_owner
|
7
|
+
t.remove :repo_name
|
8
|
+
t.index ["repository_id", "environment"], name: "stack_unicity", unique: true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def down
|
13
|
+
change_table(:stacks) do |t|
|
14
|
+
t.column :repo_name, :string, limit: 100
|
15
|
+
t.column :repo_owner, :string, limit: 39
|
16
|
+
t.remove_index ["repository_id", "environment"]
|
17
|
+
t.index ["repo_owner", "repo_name", "environment"], name: "stack_unicity", unique: true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/shipit/github_app.rb
CHANGED
@@ -9,6 +9,8 @@ module Shipit
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
attr_reader :expires_at, :refresh_at
|
13
|
+
|
12
14
|
def to_s
|
13
15
|
@token
|
14
16
|
end
|
@@ -16,10 +18,16 @@ module Shipit
|
|
16
18
|
def initialize(token, expires_at)
|
17
19
|
@token = token
|
18
20
|
@expires_at = expires_at
|
21
|
+
|
22
|
+
# This needs to be lower than the token's lifetime, but higher than the cache expiry setting.
|
23
|
+
@refresh_at = expires_at - GITHUB_TOKEN_REFRESH_WINDOW
|
19
24
|
end
|
20
25
|
|
21
26
|
def blank?
|
22
|
-
@
|
27
|
+
# Old tokens missing @refresh_at may be used upon deploy, so we should auto-correct for now.
|
28
|
+
# TODO: Remove this assignment at a later date.
|
29
|
+
@refresh_at ||= @expires_at - GITHUB_TOKEN_REFRESH_WINDOW
|
30
|
+
@refresh_at.past?
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
@@ -27,6 +35,10 @@ module Shipit
|
|
27
35
|
AuthenticationFailed = Class.new(StandardError)
|
28
36
|
API_STATUS_ID = 'brv1bkgrwx7q'.freeze
|
29
37
|
|
38
|
+
GITHUB_EXPECTED_TOKEN_LIFETIME = 60.minutes
|
39
|
+
GITHUB_TOKEN_RAILS_CACHE_LIFETIME = 50.minutes
|
40
|
+
GITHUB_TOKEN_REFRESH_WINDOW = GITHUB_EXPECTED_TOKEN_LIFETIME - GITHUB_TOKEN_RAILS_CACHE_LIFETIME - 2.minutes
|
41
|
+
|
30
42
|
attr_reader :oauth_teams, :domain, :bot_login
|
31
43
|
|
32
44
|
def initialize(config)
|
@@ -79,13 +91,21 @@ module Shipit
|
|
79
91
|
end
|
80
92
|
|
81
93
|
def fetch_new_token
|
82
|
-
Rails
|
94
|
+
# Rails can add 5 minutes to the cache entry expiration time when any TTL is provided,
|
95
|
+
# so our TTL setting can be lower, and TTL + expires_in should be lower than the GitHub token expiration.
|
96
|
+
Rails.cache.fetch(
|
97
|
+
'github:integration:access-token',
|
98
|
+
expires_in: GITHUB_TOKEN_RAILS_CACHE_LIFETIME,
|
99
|
+
race_condition_ttl: 4.minutes,
|
100
|
+
) do
|
83
101
|
response = new_client(bearer_token: authentication_payload).create_app_installation_access_token(
|
84
102
|
installation_id,
|
85
103
|
accept: 'application/vnd.github.machine-man-preview+json',
|
86
104
|
)
|
87
105
|
token = Token.from_github(response)
|
88
106
|
raise AuthenticationFailed if token.blank?
|
107
|
+
Rails.logger.info("Created GitHub access token ending #{token.to_s[-5..-1]}, expires at #{token.expires_at}"\
|
108
|
+
" and will be refreshed at #{token&.refresh_at}")
|
89
109
|
token
|
90
110
|
end
|
91
111
|
end
|
@@ -120,12 +140,21 @@ module Shipit
|
|
120
140
|
url('/api/v3/') if enterprise?
|
121
141
|
end
|
122
142
|
|
143
|
+
def web_endpoint
|
144
|
+
url if enterprise?
|
145
|
+
end
|
146
|
+
|
123
147
|
def enterprise?
|
124
148
|
domain != DOMAIN
|
125
149
|
end
|
126
150
|
|
127
151
|
def new_client(options = {})
|
128
|
-
|
152
|
+
if enterprise?
|
153
|
+
options = options.reverse_merge(
|
154
|
+
api_endpoint: api_endpoint,
|
155
|
+
web_endpoint: web_endpoint,
|
156
|
+
)
|
157
|
+
end
|
129
158
|
client = Octokit::Client.new(options)
|
130
159
|
client.middleware = faraday_stack
|
131
160
|
client
|
data/lib/shipit/task_commands.rb
CHANGED
@@ -28,19 +28,21 @@ module Shipit
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def env
|
31
|
-
normalized_name = ActiveSupport::Inflector.transliterate(@task.author.name)
|
32
31
|
super.merge(
|
33
32
|
'ENVIRONMENT' => @stack.environment,
|
34
33
|
'BRANCH' => @stack.branch,
|
35
|
-
'SHIPIT_USER' => "#{@task.author.login} (#{
|
34
|
+
'SHIPIT_USER' => "#{@task.author.login} (#{normalized_author_name}) via Shipit",
|
36
35
|
'EMAIL' => @task.author.email,
|
37
36
|
'BUNDLE_PATH' => Rails.root.join('data', 'bundler').to_s,
|
38
37
|
'SHIPIT_LINK' => @task.permalink,
|
39
38
|
'LAST_DEPLOYED_SHA' => @stack.last_deployed_commit.sha,
|
40
39
|
'TASK_ID' => @task.id.to_s,
|
40
|
+
'DEPLOY_URL' => @stack.deploy_url,
|
41
41
|
'IGNORED_SAFETIES' => @task.ignored_safeties? ? '1' : '0',
|
42
42
|
'GIT_COMMITTER_NAME' => @task.user&.name || Shipit.committer_name,
|
43
43
|
'GIT_COMMITTER_EMAIL' => @task.user&.email || Shipit.committer_email,
|
44
|
+
'GITHUB_REPO_OWNER' => @stack.repository.owner,
|
45
|
+
'GITHUB_REPO_NAME' => @stack.repository.name,
|
44
46
|
).merge(deploy_spec.machine_env).merge(@task.env)
|
45
47
|
end
|
46
48
|
|
@@ -70,6 +72,12 @@ module Shipit
|
|
70
72
|
FileUtils.rm_rf(@task.working_directory) if deploy_spec.clear_working_directory?
|
71
73
|
end
|
72
74
|
|
75
|
+
private
|
76
|
+
|
77
|
+
def normalized_author_name
|
78
|
+
ActiveSupport::Inflector.transliterate(@task.author.name)
|
79
|
+
end
|
80
|
+
|
73
81
|
protected
|
74
82
|
|
75
83
|
def steps_directory
|
data/lib/shipit/version.rb
CHANGED
@@ -43,7 +43,7 @@ module Shipit
|
|
43
43
|
end
|
44
44
|
|
45
45
|
test "stacks with no deploys render correctly" do
|
46
|
-
stack = Stack.create!(
|
46
|
+
stack = Stack.create!(repository: Repository.new(owner: "foo", name: "bar"))
|
47
47
|
get :show, params: {stack_id: stack.to_param}
|
48
48
|
assert_payload 'lastBuildStatus', 'Success'
|
49
49
|
end
|
@@ -25,7 +25,7 @@ module Shipit
|
|
25
25
|
post :create, params: {repo_owner: 'some', repo_name: 'owner/path'}
|
26
26
|
end
|
27
27
|
assert_response :unprocessable_entity
|
28
|
-
assert_json 'errors', '
|
28
|
+
assert_json 'errors', 'repository' => ['is invalid']
|
29
29
|
end
|
30
30
|
|
31
31
|
test "#create creates a stack and renders it back" do
|
@@ -38,19 +38,27 @@ module Shipit
|
|
38
38
|
end
|
39
39
|
|
40
40
|
test "#create fails to create stack if it already exists" do
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
repository = shipit_repositories(:rails)
|
42
|
+
existing_stack = Stack.create!(
|
43
|
+
repository: repository,
|
44
44
|
environment: 'staging',
|
45
45
|
branch: 'staging',
|
46
46
|
)
|
47
47
|
|
48
48
|
assert_no_difference -> { Stack.count } do
|
49
|
-
post :create,
|
49
|
+
post :create,
|
50
|
+
params: {
|
51
|
+
repo_name: existing_stack.repo_name,
|
52
|
+
repo_owner: existing_stack.repo_owner,
|
53
|
+
environment: existing_stack.environment,
|
54
|
+
branch: existing_stack.branch,
|
55
|
+
}
|
50
56
|
end
|
51
57
|
|
52
58
|
assert_response :unprocessable_entity
|
53
|
-
assert_json 'errors', '
|
59
|
+
assert_json 'errors', 'repository' => [
|
60
|
+
'cannot be used more than once with this environment. Check archived stacks.',
|
61
|
+
]
|
54
62
|
end
|
55
63
|
|
56
64
|
test "#index returns a list of stacks" do
|