shipit-engine 0.16.0 → 0.17.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 +1 -0
- data/app/assets/images/caret-down.svg +1 -0
- data/app/assets/javascripts/shipit/stacks.js.coffee +10 -0
- data/app/assets/stylesheets/_base/_banner.scss +7 -3
- data/app/assets/stylesheets/_base/_base.scss +0 -74
- data/app/assets/stylesheets/_base/_buttons.scss +7 -3
- data/app/assets/stylesheets/_base/_colors.scss +2 -0
- data/app/assets/stylesheets/_base/_icons.scss +8 -0
- data/app/assets/stylesheets/_base/_spacing.scss +21 -0
- data/app/assets/stylesheets/_pages/_commits.scss +41 -3
- data/app/assets/stylesheets/_structure/_layout.scss +8 -35
- data/app/assets/stylesheets/_structure/_main.scss +2 -2
- data/app/assets/stylesheets/_structure/_navigation.scss +89 -0
- data/app/assets/stylesheets/shipit.scss +3 -0
- data/app/controllers/concerns/shipit/api/rendering.rb +3 -6
- data/app/controllers/shipit/api/ccmenu_controller.rb +4 -0
- data/app/controllers/shipit/commits_controller.rb +18 -0
- data/app/jobs/shipit/destroy_stack_job.rb +25 -0
- data/app/jobs/shipit/github_sync_job.rb +12 -1
- data/app/jobs/shipit/merge_pull_requests_job.rb +3 -0
- data/app/models/shipit/commit.rb +14 -2
- data/app/models/shipit/deploy.rb +5 -0
- data/app/models/shipit/deploy_spec.rb +9 -6
- data/app/models/shipit/deploy_spec/kubernetes_discovery.rb +24 -2
- data/app/models/shipit/pull_request.rb +16 -1
- data/app/models/shipit/stack.rb +11 -4
- data/app/models/shipit/task_definition.rb +4 -0
- data/app/models/shipit/team.rb +1 -1
- data/app/models/shipit/undeployed_commit.rb +1 -2
- data/app/models/shipit/user.rb +1 -1
- data/app/models/shipit/variable_definition.rb +5 -0
- data/app/serializers/shipit/stack_serializer.rb +1 -1
- data/app/views/layouts/shipit.html.erb +2 -1
- data/app/views/shipit/commits/_commit.html.erb +9 -1
- data/app/views/shipit/deploys/rollback.html.erb +1 -1
- data/app/views/shipit/stacks/_header.html.erb +15 -3
- data/app/views/shipit/stacks/settings.html.erb +1 -1
- data/config/locales/en.yml +9 -5
- data/config/routes.rb +1 -0
- data/db/migrate/20170310164315_add_merged_at_on_pull_requests.rb +9 -0
- data/db/migrate/20170314145604_add_last_deployed_at_to_stack.rb +9 -0
- data/db/migrate/20170320124156_add_locked_to_commits.rb +5 -0
- data/lib/shipit/task_commands.rb +1 -0
- data/lib/shipit/version.rb +1 -1
- data/test/controllers/api/ccmenu_controller_test.rb +6 -0
- data/test/controllers/api/stacks_controller_test.rb +6 -0
- data/test/controllers/api/tasks_controller_test.rb +31 -0
- data/test/controllers/commits_controller_test.rb +18 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +4 -1
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3-journal +0 -0
- data/test/fixtures/shipit/commits.yml +1 -1
- data/test/fixtures/shipit/pull_requests.yml +33 -0
- data/test/fixtures/shipit/stacks.yml +4 -1
- data/test/jobs/github_sync_job_test.rb +49 -0
- data/test/jobs/merge_pull_requests_job_test.rb +18 -0
- data/test/models/commits_test.rb +71 -0
- data/test/models/deploy_spec_test.rb +15 -0
- data/test/models/deploys_test.rb +7 -0
- data/test/models/pull_request_test.rb +19 -1
- data/test/models/task_definitions_test.rb +9 -0
- data/test/models/undeployed_commits_test.rb +2 -7
- data/test/unit/deploy_commands_test.rb +7 -0
- data/test/unit/variable_definition_test.rb +10 -0
- metadata +15 -7
- data/app/assets/images/github.svg +0 -9
- data/app/assets/images/refresh.svg +0 -8
- data/app/assets/images/settings.svg +0 -33
- data/lib/snippets/deploy-to-gke +0 -161
@@ -1,4 +1,4 @@
|
|
1
|
-
<li class="commit" id="commit-<%= commit.id %>">
|
1
|
+
<li class="commit <%= 'locked' if commit.locked? %>" id="commit-<%= commit.id %>">
|
2
2
|
<%= render 'shipit/shared/author', author: commit.author %>
|
3
3
|
<%= render commit.status %>
|
4
4
|
<div class="commit-details">
|
@@ -14,6 +14,14 @@
|
|
14
14
|
<%= timeago_tag(commit.committed_at, force: true) %>
|
15
15
|
</p>
|
16
16
|
</div>
|
17
|
+
<div class="commit-lock" >
|
18
|
+
<%= link_to stack_commit_path(commit.stack, commit), class: 'action-lock-commit', data: {tooltip: t('commit.lock')} do %>
|
19
|
+
<i class="icon icon--lock"></i>
|
20
|
+
<% end %>
|
21
|
+
<%= link_to stack_commit_path(commit.stack, commit), class: 'action-unlock-commit', data: {tooltip: t('commit.unlock'), confirm: t('commit.confirm_unlock')} do %>
|
22
|
+
<i class="icon icon--lock"></i>
|
23
|
+
<% end %>
|
24
|
+
</div>
|
17
25
|
<div class="commit-actions">
|
18
26
|
<%= deploy_button(commit) %>
|
19
27
|
</div>
|
@@ -6,9 +6,6 @@
|
|
6
6
|
|
7
7
|
<% content_for :primary_navigation do %>
|
8
8
|
<%= link_to 'Refresh statuses & commits', stack_refresh_path(stack), method: 'post', class: "header__btn btn" %>
|
9
|
-
<% stack.task_definitions.each do |definition| %>
|
10
|
-
<%= link_to "#{definition.action}…", new_stack_tasks_path(stack, definition_id: definition.id), class: %w(header__btn stack-action btn trigger-deploy) %>
|
11
|
-
<% end %>
|
12
9
|
<% end %>
|
13
10
|
|
14
11
|
<% content_for :secondary_navigation do %>
|
@@ -27,7 +24,22 @@
|
|
27
24
|
<%= link_to "Pull Requests (#{stack.pull_requests.queued.count})", stack_pull_requests_path(stack) %>
|
28
25
|
</li>
|
29
26
|
<% end %>
|
27
|
+
|
28
|
+
<% if stack.task_definitions.present? %>
|
29
|
+
<li class="nav__list__item nav__list__item--has-children">
|
30
|
+
Tasks
|
31
|
+
|
32
|
+
<ul class="nav__sub__list">
|
33
|
+
<% stack.task_definitions.each do |definition| %>
|
34
|
+
<li class="nav__list__sub__item">
|
35
|
+
<%= link_to "#{definition.action}…", new_stack_tasks_path(stack, definition_id: definition.id), class: "trigger-deploy" %>
|
36
|
+
</li>
|
37
|
+
<% end %>
|
38
|
+
</ul>
|
39
|
+
</li>
|
40
|
+
<% end %>
|
30
41
|
</ul>
|
42
|
+
|
31
43
|
<ul class="nav__list nav__list--secondary">
|
32
44
|
<% if stack.links.present? %>
|
33
45
|
<% stack.links.each do |name, url| %>
|
@@ -74,7 +74,7 @@
|
|
74
74
|
<div class="setting-section setting-ccmenu">
|
75
75
|
<h5>Miscellaneous</h5>
|
76
76
|
<div class="field-wrapper">
|
77
|
-
<label>CCMenu URL</label>
|
77
|
+
<label>CCMenu URL (choose “Use URL as entered above” during CCMenu setup)</label>
|
78
78
|
<input id="ccmenu-url" class="hidden" type="text" disabled />
|
79
79
|
</div>
|
80
80
|
<%= button_to "Fetch URL", "", class: 'btn', data: {remote: ccmenu_url_url(stack_id: @stack.to_param)} %>
|
data/config/locales/en.yml
CHANGED
@@ -20,21 +20,25 @@
|
|
20
20
|
# available at http://guides.rubyonrails.org/i18n.html.
|
21
21
|
|
22
22
|
en:
|
23
|
+
commit:
|
24
|
+
lock: This commit is safe to deploy. Click to mark it as unsafe.
|
25
|
+
unlock: This commit is unsafe to deploy. Click to mark it as safe.
|
26
|
+
confirm_unlock: Mark this commit as safe to deploy?
|
23
27
|
deploy_button:
|
24
28
|
hint:
|
25
29
|
max_commits: It is recommended not to deploy more than %{maximum} commits at once.
|
26
30
|
caption:
|
27
|
-
pending: CI
|
28
|
-
failure: CI
|
29
|
-
error: CI
|
31
|
+
pending: Pending CI
|
32
|
+
failure: Failing CI
|
33
|
+
error: Failing CI
|
30
34
|
unknown: Not Run
|
31
35
|
locked: Locked
|
32
|
-
deploying: A Deploy is in Progress
|
36
|
+
deploying: A Deploy is in Progress
|
33
37
|
allowed: Deploy
|
34
38
|
missing: Missing CI
|
35
39
|
redeploy_button:
|
36
40
|
caption:
|
37
|
-
deploying: A Deploy is in Progress
|
41
|
+
deploying: A Deploy is in Progress
|
38
42
|
allowed: Redeploy
|
39
43
|
locked: Locked
|
40
44
|
deploy_spec:
|
data/config/routes.rb
CHANGED
@@ -73,6 +73,7 @@ Shipit::Engine.routes.draw do
|
|
73
73
|
get '/commit/:sha/checks/tail' => 'commit_checks#tail', as: :tail_commit_checks, defaults: {format: :json}
|
74
74
|
|
75
75
|
resources :rollbacks, only: %i(create)
|
76
|
+
resources :commits, only: %i(update)
|
76
77
|
resources :tasks, only: %i(show) do
|
77
78
|
collection do
|
78
79
|
get '' => 'tasks#index', as: :index
|
data/lib/shipit/task_commands.rb
CHANGED
data/lib/shipit/version.rb
CHANGED
@@ -42,6 +42,12 @@ module Shipit
|
|
42
42
|
assert_payload 'lastBuildStatus', 'Failure'
|
43
43
|
end
|
44
44
|
|
45
|
+
test "stacks with no deploys render correctly" do
|
46
|
+
stack = Stack.create!(repo_owner: 'foo', repo_name: 'bar')
|
47
|
+
get :show, params: {stack_id: stack.to_param}
|
48
|
+
assert_payload 'lastBuildStatus', 'Success'
|
49
|
+
end
|
50
|
+
|
45
51
|
private
|
46
52
|
|
47
53
|
def get_project_from_xml(xml)
|
@@ -101,6 +101,12 @@ module Shipit
|
|
101
101
|
assert_response :ok
|
102
102
|
assert_json 'id', @stack.id
|
103
103
|
end
|
104
|
+
|
105
|
+
test "#show returns last_deployed_at column for stack" do
|
106
|
+
get :show, params: {id: @stack.to_param}
|
107
|
+
assert_response :ok
|
108
|
+
assert_json 'last_deployed_at', @stack.last_deployed_at
|
109
|
+
end
|
104
110
|
end
|
105
111
|
end
|
106
112
|
end
|
@@ -24,11 +24,22 @@ module Shipit
|
|
24
24
|
assert_json 'id', task.id
|
25
25
|
end
|
26
26
|
|
27
|
+
test "#trigger returns 404 with unknown task" do
|
28
|
+
post :trigger, params: {stack_id: @stack.to_param, task_name: 'shave_the_yak'}
|
29
|
+
assert_response :not_found
|
30
|
+
end
|
31
|
+
|
27
32
|
test "#trigger triggers a custom task" do
|
28
33
|
post :trigger, params: {stack_id: @stack.to_param, task_name: 'restart'}
|
29
34
|
assert_response :accepted
|
30
35
|
assert_json 'type', 'task'
|
31
36
|
assert_json 'status', 'pending'
|
37
|
+
|
38
|
+
expected_env = {
|
39
|
+
"FOO" => "1",
|
40
|
+
"BAR" => "0",
|
41
|
+
}
|
42
|
+
assert_equal expected_env, Shipit::Task.last.env
|
32
43
|
end
|
33
44
|
|
34
45
|
test "#trigger refuses to trigger a task with tasks not whitelisted" do
|
@@ -44,6 +55,26 @@ module Shipit
|
|
44
55
|
assert_response :accepted
|
45
56
|
assert_json 'type', 'task'
|
46
57
|
assert_json 'status', 'pending'
|
58
|
+
|
59
|
+
expected_env = {
|
60
|
+
"FOO" => "bar",
|
61
|
+
"BAR" => "0",
|
62
|
+
}
|
63
|
+
assert_equal expected_env, Shipit::Task.last.env
|
64
|
+
end
|
65
|
+
|
66
|
+
test "#trigger triggers a task with explicitly passed and default variables" do
|
67
|
+
env = {'WALRUS' => 'overridden value'}
|
68
|
+
post :trigger, params: {stack_id: @stack.to_param, task_name: 'restart', env: env}
|
69
|
+
assert_response :accepted
|
70
|
+
|
71
|
+
# FOO and BAR are variables with a default value
|
72
|
+
expected_env = {
|
73
|
+
"FOO" => "1",
|
74
|
+
"BAR" => "0",
|
75
|
+
"WALRUS" => "overridden value",
|
76
|
+
}
|
77
|
+
assert_equal expected_env, Shipit::Task.last.env
|
47
78
|
end
|
48
79
|
|
49
80
|
test "#trigger returns a 404 when the task doesn't exist" do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Shipit
|
4
|
+
class CommitsControllerTest < ActionController::TestCase
|
5
|
+
setup do
|
6
|
+
@stack = shipit_stacks(:shipit)
|
7
|
+
@commit = shipit_commits(:first)
|
8
|
+
session[:user_id] = shipit_users(:walrus).id
|
9
|
+
end
|
10
|
+
|
11
|
+
test "#update allows to lock a commit" do
|
12
|
+
refute_predicate @commit, :locked?
|
13
|
+
patch :update, params: {stack_id: @stack.to_param, id: @commit.id, commit: {locked: true}}
|
14
|
+
assert_response :ok
|
15
|
+
assert_predicate @commit.reload, :locked?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
Binary file
|
data/test/dummy/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 20170320124156) do
|
14
14
|
|
15
15
|
create_table "api_clients", force: :cascade do |t|
|
16
16
|
t.text "permissions", limit: 65535
|
@@ -59,6 +59,7 @@ ActiveRecord::Schema.define(version: 20170221130336) do
|
|
59
59
|
t.integer "pull_request_number"
|
60
60
|
t.string "pull_request_title", limit: 1024
|
61
61
|
t.integer "pull_request_id"
|
62
|
+
t.boolean "locked", default: false, null: false
|
62
63
|
t.index ["author_id"], name: "index_commits_on_author_id"
|
63
64
|
t.index ["committer_id"], name: "index_commits_on_committer_id"
|
64
65
|
t.index ["created_at"], name: "index_commits_on_created_at"
|
@@ -145,6 +146,7 @@ ActiveRecord::Schema.define(version: 20170221130336) do
|
|
145
146
|
t.datetime "updated_at", null: false
|
146
147
|
t.string "branch"
|
147
148
|
t.datetime "revalidated_at"
|
149
|
+
t.datetime "merged_at"
|
148
150
|
t.index ["head_id"], name: "index_pull_requests_on_head_id"
|
149
151
|
t.index ["merge_requested_by_id"], name: "index_pull_requests_on_merge_requested_by_id"
|
150
152
|
t.index ["stack_id", "github_id"], name: "index_pull_requests_on_stack_id_and_github_id", unique: true
|
@@ -173,6 +175,7 @@ ActiveRecord::Schema.define(version: 20170221130336) do
|
|
173
175
|
t.datetime "continuous_delivery_delayed_since"
|
174
176
|
t.datetime "locked_since"
|
175
177
|
t.boolean "merge_queue_enabled", default: false, null: false
|
178
|
+
t.datetime "last_deployed_at"
|
176
179
|
t.index ["repo_owner", "repo_name", "environment"], name: "stack_unicity", unique: true
|
177
180
|
end
|
178
181
|
|
data/test/dummy/db/test.sqlite3
CHANGED
Binary file
|
Binary file
|
@@ -54,3 +54,36 @@ shipit_pending_not_mergeable_yet:
|
|
54
54
|
mergeable: null
|
55
55
|
additions: 23
|
56
56
|
deletions: 43
|
57
|
+
|
58
|
+
shipit_pending_closed:
|
59
|
+
stack: shipit
|
60
|
+
number: 65
|
61
|
+
merge_status: pending
|
62
|
+
merge_requested_by: walrus
|
63
|
+
merge_requested_at: <%= 3.minute.ago.to_s(:db) %>
|
64
|
+
revalidated_at: <%= 3.minute.ago.to_s(:db) %>
|
65
|
+
github_id: 43243243243243
|
66
|
+
api_url: https://api.github.com/repos/shopify/shipit-engine/pulls/65
|
67
|
+
state: closed
|
68
|
+
branch: feature-64
|
69
|
+
head_id: 8
|
70
|
+
mergeable: null
|
71
|
+
additions: 23
|
72
|
+
deletions: 43
|
73
|
+
|
74
|
+
shipit_pending_merged:
|
75
|
+
stack: shipit
|
76
|
+
number: 66
|
77
|
+
merge_status: pending
|
78
|
+
merge_requested_by: walrus
|
79
|
+
merge_requested_at: <%= 3.minute.ago.to_s(:db) %>
|
80
|
+
merged_at: <%= 2.minute.ago.to_s(:db) %>
|
81
|
+
revalidated_at: <%= 3.minute.ago.to_s(:db) %>
|
82
|
+
github_id: 43243243243232
|
83
|
+
api_url: https://api.github.com/repos/shopify/shipit-engine/pulls/66
|
84
|
+
state: closed
|
85
|
+
branch: feature-64
|
86
|
+
head_id: 8
|
87
|
+
mergeable: null
|
88
|
+
additions: 23
|
89
|
+
deletions: 43
|
@@ -26,7 +26,8 @@ shipit:
|
|
26
26
|
"description": "Restart app and job servers",
|
27
27
|
"variables": [
|
28
28
|
{"name": "FOO", "title": "Set to 0 to foo", "default": 1},
|
29
|
-
{"name": "BAR", "title": "Set to 1 to bar", "default": 0}
|
29
|
+
{"name": "BAR", "title": "Set to 1 to bar", "default": 0},
|
30
|
+
{"name": "WALRUS", "title": "Walrus without a default value"}
|
30
31
|
],
|
31
32
|
"steps": [
|
32
33
|
"cap $ENVIRONMENT deploy:restart"
|
@@ -49,6 +50,7 @@ shipit:
|
|
49
50
|
"allow_failures": ["ci/ok_to_fail"]
|
50
51
|
}
|
51
52
|
}
|
53
|
+
last_deployed_at: <%= 8.days.ago.to_s(:db) %>
|
52
54
|
updated_at: <%= 8.days.ago.to_s(:db) %>
|
53
55
|
|
54
56
|
cyclimse:
|
@@ -82,6 +84,7 @@ cyclimse:
|
|
82
84
|
}
|
83
85
|
}
|
84
86
|
}
|
87
|
+
last_deployed_at: <%= 8.days.ago.to_s(:db) %>
|
85
88
|
updated_at: <%= 8.days.ago.to_s(:db) %>
|
86
89
|
|
87
90
|
undeployed_stack:
|
@@ -36,6 +36,55 @@ module Shipit
|
|
36
36
|
assert shipit_commits(:fifth).reload.detached?
|
37
37
|
end
|
38
38
|
|
39
|
+
test "#perform locks all commits leading to a revert" do
|
40
|
+
@stack.deploys_and_rollbacks.destroy_all
|
41
|
+
|
42
|
+
initial_queue = [
|
43
|
+
["fix all the things", false],
|
44
|
+
["yoloshipit!", false],
|
45
|
+
["fix it!", false],
|
46
|
+
["sheep it!", false],
|
47
|
+
["lets go", false],
|
48
|
+
]
|
49
|
+
assert_equal initial_queue, @stack.undeployed_commits.map { |c| [c.title, c.locked?] }
|
50
|
+
|
51
|
+
author = stub(
|
52
|
+
id: 1234,
|
53
|
+
login: 'bob',
|
54
|
+
name: 'Bob the Builder',
|
55
|
+
email: 'bob@bob.com',
|
56
|
+
date: '2011-04-14T16:00:49Z',
|
57
|
+
)
|
58
|
+
@job.expects(:fetch_missing_commits).returns([
|
59
|
+
[
|
60
|
+
stub(
|
61
|
+
sha: '36514755579bfb5bc313f403b216f4347a027990',
|
62
|
+
author: author,
|
63
|
+
committer: author,
|
64
|
+
stats: nil,
|
65
|
+
commit: stub(
|
66
|
+
sha: '36514755579bfb5bc313f403b216f4347a027990',
|
67
|
+
message: 'Revert "fix it!"',
|
68
|
+
author: author,
|
69
|
+
committer: author,
|
70
|
+
),
|
71
|
+
),
|
72
|
+
],
|
73
|
+
shipit_commits(:fifth),
|
74
|
+
])
|
75
|
+
@job.perform(stack_id: @stack.id)
|
76
|
+
|
77
|
+
final_queue = [
|
78
|
+
['Revert "fix it!"', false],
|
79
|
+
["fix all the things", true],
|
80
|
+
["yoloshipit!", true],
|
81
|
+
["fix it!", true],
|
82
|
+
["sheep it!", false],
|
83
|
+
["lets go", false],
|
84
|
+
]
|
85
|
+
assert_equal final_queue, @stack.reload.undeployed_commits.map { |c| [c.title, c.locked?] }
|
86
|
+
end
|
87
|
+
|
39
88
|
test "#fetch_missing_commits returns the commits in the reverse order if it doesn't know the parent" do
|
40
89
|
last = stub(sha: 123)
|
41
90
|
first = stub(sha: 345)
|
@@ -9,6 +9,8 @@ module Shipit
|
|
9
9
|
@pending_pr = shipit_pull_requests(:shipit_pending)
|
10
10
|
@unmergeable_pr = shipit_pull_requests(:shipit_pending_unmergeable)
|
11
11
|
@not_ready_pr = shipit_pull_requests(:shipit_pending_not_mergeable_yet)
|
12
|
+
@closed_pr = shipit_pull_requests(:shipit_pending_closed)
|
13
|
+
@merged_pr = shipit_pull_requests(:shipit_pending_merged)
|
12
14
|
end
|
13
15
|
|
14
16
|
test "#perform rejects unmergeable PRs and merge the others" do
|
@@ -20,6 +22,8 @@ module Shipit
|
|
20
22
|
}.to_json)
|
21
23
|
branch_url = "https://api.github.com/repos/shopify/shipit-engine/git/refs/heads/feature-62"
|
22
24
|
FakeWeb.register_uri(:delete, branch_url, status: %w(204 No content))
|
25
|
+
pulls_url = "https://api.github.com/repos/shopify/shipit-engine/pulls?base=feature-62"
|
26
|
+
FakeWeb.register_uri(:get, pulls_url, status: %w(200 OK), body: '[]')
|
23
27
|
|
24
28
|
@job.perform(@stack)
|
25
29
|
|
@@ -55,5 +59,19 @@ module Shipit
|
|
55
59
|
end
|
56
60
|
assert_predicate @pending_pr.reload, :pending?
|
57
61
|
end
|
62
|
+
|
63
|
+
test "#perform cancels merge requests for closed PRs" do
|
64
|
+
@pending_pr.cancel!
|
65
|
+
PullRequest.any_instance.stubs(:refresh!)
|
66
|
+
@job.perform(@stack)
|
67
|
+
assert_predicate @closed_pr.reload, :canceled?
|
68
|
+
end
|
69
|
+
|
70
|
+
test "#perform completes merge requests for already merged PRs" do
|
71
|
+
@pending_pr.cancel!
|
72
|
+
PullRequest.any_instance.stubs(:refresh!)
|
73
|
+
@job.perform(@stack)
|
74
|
+
assert_predicate @merged_pr.reload, :merged?
|
75
|
+
end
|
58
76
|
end
|
59
77
|
end
|