shipit-engine 0.33.0 → 0.34.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 +13 -2
- data/app/assets/stylesheets/_pages/_deploy.scss +0 -2
- data/app/controllers/shipit/api/ccmenu_controller.rb +1 -1
- data/app/controllers/shipit/api/deploys_controller.rb +2 -0
- data/app/controllers/shipit/api/rollbacks_controller.rb +2 -1
- data/app/controllers/shipit/api/stacks_controller.rb +1 -0
- data/app/controllers/shipit/deploys_controller.rb +1 -1
- data/app/controllers/shipit/stacks_controller.rb +2 -2
- data/app/controllers/shipit/tasks_controller.rb +2 -2
- data/app/controllers/shipit/webhooks_controller.rb +23 -4
- data/app/helpers/shipit/shipit_helper.rb +0 -1
- data/app/jobs/shipit/deliver_hook_job.rb +1 -1
- data/app/jobs/shipit/github_sync_job.rb +13 -9
- data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +1 -1
- data/app/models/shipit/anonymous_user.rb +6 -2
- data/app/models/shipit/check_run.rb +36 -0
- data/app/models/shipit/commit.rb +20 -9
- data/app/models/shipit/commit_checks.rb +13 -13
- data/app/models/shipit/commit_deployment.rb +3 -3
- data/app/models/shipit/commit_deployment_status.rb +3 -3
- data/app/models/shipit/deploy.rb +16 -11
- data/app/models/shipit/deploy_spec/lerna_discovery.rb +12 -4
- data/app/models/shipit/duration.rb +2 -0
- data/app/models/shipit/hook.rb +26 -2
- data/app/models/shipit/merge_request.rb +9 -7
- data/app/models/shipit/pull_request.rb +1 -1
- data/app/models/shipit/release_status.rb +1 -1
- data/app/models/shipit/repository.rb +9 -3
- data/app/models/shipit/review_stack.rb +16 -2
- data/app/models/shipit/stack.rb +59 -25
- data/app/models/shipit/status/group.rb +1 -1
- data/app/models/shipit/task.rb +6 -2
- data/app/models/shipit/task_execution_strategy/default.rb +4 -5
- data/app/models/shipit/team.rb +4 -2
- data/app/models/shipit/user.rb +4 -0
- data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +1 -1
- data/app/models/shipit/webhooks/handlers/push_handler.rb +4 -1
- data/app/serializers/shipit/merge_request_serializer.rb +1 -1
- data/app/validators/subset_validator.rb +1 -1
- data/app/views/layouts/merge_status.html.erb +1 -1
- data/app/views/shipit/stacks/_banners.html.erb +2 -1
- data/app/views/shipit/stacks/new.html.erb +1 -1
- data/config/secrets.development.example.yml +24 -0
- data/config/secrets.development.shopify.yml +20 -9
- data/db/migrate/20210325194053_remove_stacks_branch_default.rb +5 -0
- data/db/migrate/20210504200438_add_github_updated_at_to_check_runs.rb +5 -0
- data/lib/shipit.rb +39 -15
- data/lib/shipit/command.rb +7 -6
- data/lib/shipit/commands.rb +9 -2
- data/lib/shipit/engine.rb +2 -0
- data/lib/shipit/flock.rb +8 -1
- data/lib/shipit/github_app.rb +7 -5
- data/lib/shipit/octokit_iterator.rb +3 -3
- data/lib/shipit/simple_message_verifier.rb +2 -2
- data/lib/shipit/stack_commands.rb +28 -4
- data/lib/shipit/task_commands.rb +6 -0
- data/lib/shipit/version.rb +1 -1
- data/lib/snippets/publish-lerna-independent-packages +35 -34
- data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
- data/test/controllers/api/ccmenu_controller_test.rb +1 -1
- data/test/controllers/api/deploys_controller_test.rb +17 -0
- data/test/controllers/api/stacks_controller_test.rb +21 -7
- data/test/controllers/webhooks_controller_test.rb +26 -11
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/config/application.rb +1 -1
- data/test/dummy/config/database.yml +9 -0
- data/test/dummy/config/environments/development.rb +1 -1
- data/test/dummy/config/secrets_double_github_app.yml +79 -0
- data/test/dummy/db/schema.rb +5 -4
- data/test/dummy/db/seeds.rb +1 -0
- data/test/fixtures/payloads/check_suite_master.json +2 -30
- data/test/fixtures/payloads/push_master.json +1 -1
- data/test/fixtures/payloads/push_not_master.json +1 -1
- data/test/fixtures/shipit/commits.yml +2 -2
- data/test/fixtures/shipit/hooks.yml +1 -0
- data/test/fixtures/shipit/tasks.yml +1 -1
- data/test/helpers/json_helper.rb +5 -1
- data/test/jobs/github_sync_job_test.rb +2 -1
- data/test/models/commit_deployment_status_test.rb +3 -3
- data/test/models/commits_test.rb +2 -0
- data/test/models/deploy_spec_test.rb +7 -0
- data/test/models/deploys_test.rb +18 -0
- data/test/models/hook_test.rb +30 -1
- data/test/models/merge_request_test.rb +19 -4
- data/test/models/shipit/check_run_test.rb +124 -5
- data/test/models/shipit/review_stack_test.rb +38 -6
- data/test/models/shipit/stacks_test.rb +42 -4
- data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +24 -0
- data/test/models/tasks_test.rb +22 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/anonymous_user_serializer_test.rb +1 -1
- data/test/unit/command_test.rb +5 -0
- data/test/unit/commit_serializer_test.rb +1 -1
- data/test/unit/deploy_commands_test.rb +70 -14
- data/test/unit/deploy_serializer_test.rb +1 -1
- data/test/unit/github_app_test.rb +2 -3
- data/test/unit/github_apps_test.rb +416 -0
- data/test/unit/shipit_deployment_checks_test.rb +77 -0
- data/test/unit/shipit_test.rb +14 -0
- data/test/unit/user_serializer_test.rb +1 -1
- metadata +202 -191
data/lib/shipit/github_app.rb
CHANGED
@@ -42,8 +42,9 @@ module Shipit
|
|
42
42
|
|
43
43
|
attr_reader :oauth_teams, :domain, :bot_login
|
44
44
|
|
45
|
-
def initialize(config)
|
45
|
+
def initialize(organization, config)
|
46
46
|
super()
|
47
|
+
@organization = organization
|
47
48
|
@config = (config || {}).with_indifferent_access
|
48
49
|
@domain = @config[:domain] || DOMAIN
|
49
50
|
@webhook_secret = @config[:webhook_secret].presence
|
@@ -92,10 +93,11 @@ module Shipit
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def fetch_new_token
|
96
|
+
cache_key = @organization.nil? ? '' : "#{@organization.downcase}:"
|
95
97
|
# Rails can add 5 minutes to the cache entry expiration time when any TTL is provided,
|
96
98
|
# so our TTL setting can be lower, and TTL + expires_in should be lower than the GitHub token expiration.
|
97
99
|
Rails.cache.fetch(
|
98
|
-
|
100
|
+
"github:integration:#{cache_key}access-token",
|
99
101
|
expires_in: GITHUB_TOKEN_RAILS_CACHE_LIFETIME,
|
100
102
|
race_condition_ttl: 4.minutes,
|
101
103
|
) do
|
@@ -181,15 +183,15 @@ module Shipit
|
|
181
183
|
end
|
182
184
|
|
183
185
|
def app_id
|
184
|
-
@
|
186
|
+
@config.fetch(:app_id)
|
185
187
|
end
|
186
188
|
|
187
189
|
def installation_id
|
188
|
-
@
|
190
|
+
@config.fetch(:installation_id)
|
189
191
|
end
|
190
192
|
|
191
193
|
def private_key
|
192
|
-
@
|
194
|
+
@config.fetch(:private_key)
|
193
195
|
end
|
194
196
|
|
195
197
|
def authentication_payload
|
@@ -3,12 +3,12 @@ module Shipit
|
|
3
3
|
class OctokitIterator
|
4
4
|
include Enumerable
|
5
5
|
|
6
|
-
def initialize(relation = nil)
|
6
|
+
def initialize(relation = nil, github_api: nil)
|
7
7
|
if relation
|
8
8
|
@response = relation.get(per_page: 100)
|
9
9
|
else
|
10
|
-
data = yield
|
11
|
-
@response =
|
10
|
+
data = yield github_api
|
11
|
+
@response = github_api.last_response if data.present?
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Shipit
|
3
3
|
class SimpleMessageVerifier < ActiveSupport::MessageVerifier
|
4
|
-
def initialize(secret, options
|
4
|
+
def initialize(secret, **options)
|
5
5
|
options[:serializer] ||= ToS
|
6
|
-
super(secret, options)
|
6
|
+
super(secret, **options)
|
7
7
|
end
|
8
8
|
|
9
9
|
private
|
@@ -15,19 +15,25 @@ module Shipit
|
|
15
15
|
|
16
16
|
def fetch
|
17
17
|
create_directories
|
18
|
-
if
|
18
|
+
if valid_git_repository?(@stack.git_path)
|
19
19
|
git('fetch', 'origin', '--tags', @stack.branch, env: env, chdir: @stack.git_path)
|
20
20
|
else
|
21
|
+
@stack.clear_git_cache!
|
21
22
|
git_clone(@stack.repo_git_url, @stack.git_path, branch: @stack.branch, env: env, chdir: @stack.deploys_path)
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
26
|
def fetched?(commit)
|
26
|
-
|
27
|
-
if Dir.exist?(git_dir)
|
27
|
+
if valid_git_repository?(@stack.git_path)
|
28
28
|
git('rev-parse', '--quiet', '--verify', "#{commit.sha}^{commit}", env: env, chdir: @stack.git_path)
|
29
29
|
else
|
30
|
-
|
30
|
+
# When the stack's git cache is not valid, the commit is
|
31
|
+
# NOT fetched. To keep the interface of this method
|
32
|
+
# consistent, we must return a Shipit::Command whose #success?
|
33
|
+
# method returns false - has a non-zero exit status. We utilize
|
34
|
+
# the POSIX 'test' command with no arguments which should
|
35
|
+
# always have an exit status of 1.
|
36
|
+
Command.new('test', env: env, chdir: @stack.deploys_path)
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
@@ -71,6 +77,18 @@ module Shipit
|
|
71
77
|
end
|
72
78
|
end
|
73
79
|
|
80
|
+
def valid_git_repository?(path)
|
81
|
+
path.exist? &&
|
82
|
+
!path.empty? &&
|
83
|
+
git_cmd_succeeds?(path)
|
84
|
+
end
|
85
|
+
|
86
|
+
def git_cmd_succeeds?(path)
|
87
|
+
git("rev-parse", "--git-dir", chdir: path)
|
88
|
+
.tap(&:run)
|
89
|
+
.success?
|
90
|
+
end
|
91
|
+
|
74
92
|
def git_clone(url, path, branch: 'master', **kwargs)
|
75
93
|
git('clone', *modern_git_args, '--recursive', '--branch', branch, url, path, **kwargs)
|
76
94
|
end
|
@@ -83,5 +101,11 @@ module Shipit
|
|
83
101
|
def create_directories
|
84
102
|
FileUtils.mkdir_p(@stack.deploys_path)
|
85
103
|
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def github
|
108
|
+
Shipit.github(organization: @stack.repository.owner)
|
109
|
+
end
|
86
110
|
end
|
87
111
|
end
|
data/lib/shipit/task_commands.rb
CHANGED
data/lib/shipit/version.rb
CHANGED
@@ -1,39 +1,40 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
const {
|
3
|
-
const {execSync} = require('child_process')
|
4
|
-
const Repository = require(resolve('.', 'node_modules', 'lerna', 'lib', 'Repository'));
|
5
|
-
const PackageUtilities = require(resolve('.', 'node_modules', 'lerna', 'lib', 'PackageUtilities'));
|
6
|
-
|
7
|
-
function npmTag(version) {
|
8
|
-
const isNext = ['-beta', '-alpha', '-rc', '-next'].some(distributionType =>
|
9
|
-
version.includes(distributionType),
|
10
|
-
);
|
11
|
-
return isNext ? 'next' : 'latest';
|
12
|
-
}
|
2
|
+
const { execSync } = require("child_process");
|
13
3
|
|
14
|
-
const taggedPackages = execSync(
|
4
|
+
const taggedPackages = execSync("git tag --points-at HEAD")
|
15
5
|
.toString()
|
16
6
|
.trim()
|
17
|
-
.split(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
const
|
26
|
-
|
27
|
-
const packages = PackageUtilities.topologicallyBatchPackages(unsortedPackages, true)
|
28
|
-
.reduce((acc, packageGroup) => [...acc, ...packageGroup], [])
|
29
|
-
.filter(({name}) => taggedPackages.includes(name));
|
30
|
-
|
31
|
-
packages.forEach(({name, version}) => {
|
32
|
-
const command = `node_modules/.bin/lerna publish --yes --npm-client=npm --skip-npm=false --skip-git --force-publish=${name} --repo-version=${version} --scope=${name} --npm-tag=${npmTag(
|
33
|
-
version,
|
34
|
-
)}`;
|
35
|
-
|
36
|
-
// eslint-disable-next-line no-console
|
37
|
-
console.log(command);
|
38
|
-
require('child_process').execSync(command);
|
7
|
+
.split("\n");
|
8
|
+
|
9
|
+
// anything that matches `-` after MAJOR.MINOR.PATCH
|
10
|
+
const validPattern = new RegExp(/\d+\.\d+\.\d+-(\w+)/);
|
11
|
+
|
12
|
+
// Ensure that all releases use the same prerelease suffix.
|
13
|
+
// We want to only release all final versions, or all betas etc
|
14
|
+
const allPrereleaseSuffixes = taggedPackages.map((version) => {
|
15
|
+
const result = validPattern.exec(version);
|
16
|
+
return result ? result[1] : '';
|
39
17
|
});
|
18
|
+
if ((new Set(allPrereleaseSuffixes)).size > 1) {
|
19
|
+
throw Error("All packages must be of the same type of release. Versions cannot be mixed.");
|
20
|
+
}
|
21
|
+
|
22
|
+
// set this using machine.environment.SHIPIT_LERNA_PUBLISH_MECHANISM in your shipit.yml
|
23
|
+
const publishMechanism = process.env.SHIPIT_LERNA_PUBLISH_MECHANISM || 'from-git';
|
24
|
+
|
25
|
+
if (!['from-package', 'from-git'].includes(publishMechanism)) {
|
26
|
+
throw Error("SHIPIT_LERNA_PUBLISH_MECHANISM must be 'from-package' or 'from-git'.");
|
27
|
+
}
|
28
|
+
|
29
|
+
const command = [
|
30
|
+
"node_modules/.bin/lerna publish",
|
31
|
+
publishMechanism,
|
32
|
+
"--yes",
|
33
|
+
"--dist-tag latest",
|
34
|
+
"--pre-dist-tag next",
|
35
|
+
];
|
36
|
+
|
37
|
+
const commandString = command.join(" ");
|
38
|
+
|
39
|
+
console.log(`${commandString}`);
|
40
|
+
execSync(commandString);
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
const {resolve} = require('path');
|
3
|
+
const {execSync} = require('child_process')
|
4
|
+
const Repository = require(resolve('.', 'node_modules', 'lerna', 'lib', 'Repository'));
|
5
|
+
const PackageUtilities = require(resolve('.', 'node_modules', 'lerna', 'lib', 'PackageUtilities'));
|
6
|
+
|
7
|
+
function npmTag(version) {
|
8
|
+
const isNext = ['-beta', '-alpha', '-rc', '-next'].some(distributionType =>
|
9
|
+
version.includes(distributionType),
|
10
|
+
);
|
11
|
+
return isNext ? 'next' : 'latest';
|
12
|
+
}
|
13
|
+
|
14
|
+
const taggedPackages = execSync('git tag --points-at HEAD')
|
15
|
+
.toString()
|
16
|
+
.trim()
|
17
|
+
.split('\n')
|
18
|
+
.map(tag => {
|
19
|
+
if (tag.startsWith('@')) {
|
20
|
+
return `@${tag.split('@')[1]}`;
|
21
|
+
}
|
22
|
+
return tag.split('@')[0];
|
23
|
+
});
|
24
|
+
|
25
|
+
const repository = new Repository('.');
|
26
|
+
const unsortedPackages = PackageUtilities.getPackages({rootPath: '.', packageConfigs: repository.packageConfigs});
|
27
|
+
const packages = PackageUtilities.topologicallyBatchPackages(unsortedPackages, true)
|
28
|
+
.reduce((acc, packageGroup) => [...acc, ...packageGroup], [])
|
29
|
+
.filter(({name}) => taggedPackages.includes(name));
|
30
|
+
|
31
|
+
packages.forEach(({name, version}) => {
|
32
|
+
const command = `node_modules/.bin/lerna publish --yes --npm-client=npm --skip-npm=false --skip-git --force-publish=${name} --repo-version=${version} --scope=${name} --npm-tag=${npmTag(
|
33
|
+
version,
|
34
|
+
)}`;
|
35
|
+
|
36
|
+
// eslint-disable-next-line no-console
|
37
|
+
console.log(command);
|
38
|
+
require('child_process').execSync(command);
|
39
|
+
});
|
@@ -44,7 +44,7 @@ module Shipit
|
|
44
44
|
end
|
45
45
|
|
46
46
|
test "stacks with no deploys render correctly" do
|
47
|
-
stack = Stack.create!(repository: Repository.new(owner: "foo", name: "bar"))
|
47
|
+
stack = Stack.create!(repository: Repository.new(owner: "foo", name: "bar"), branch: 'main')
|
48
48
|
get :show, params: { stack_id: stack.to_param }
|
49
49
|
assert_payload 'lastBuildStatus', 'Success'
|
50
50
|
end
|
@@ -83,6 +83,23 @@ module Shipit
|
|
83
83
|
assert_response :conflict
|
84
84
|
end
|
85
85
|
|
86
|
+
test "#create refuses to deploy unsuccessful commits if the require_ci flag is passed" do
|
87
|
+
Commit.any_instance.expects(:deployable?).returns(false)
|
88
|
+
|
89
|
+
assert_no_difference -> { @stack.deploys.count } do
|
90
|
+
post :create, params: { stack_id: @stack.to_param, sha: @commit.sha, require_ci: true }
|
91
|
+
end
|
92
|
+
assert_response :unprocessable_entity
|
93
|
+
assert_json 'errors.require_ci', ["Commit is not deployable"]
|
94
|
+
end
|
95
|
+
|
96
|
+
test "#create deploys failing commits if the require_ci flag is not passed" do
|
97
|
+
Commit.any_instance.expects(:deployable?).returns(false)
|
98
|
+
|
99
|
+
post :create, params: { stack_id: @stack.to_param, sha: @commit.sha }
|
100
|
+
assert_response :accepted
|
101
|
+
end
|
102
|
+
|
86
103
|
test "#create refuses to deploy locked stacks" do
|
87
104
|
@stack.update!(lock_reason: 'Something broken')
|
88
105
|
|
@@ -23,7 +23,7 @@ module Shipit
|
|
23
23
|
|
24
24
|
test "#create fails with invalid stack" do
|
25
25
|
assert_no_difference "Stack.count" do
|
26
|
-
post :create, params: { repo_owner: 'some', repo_name: 'owner/path' }
|
26
|
+
post :create, params: { repo_owner: 'some', repo_name: 'owner/path', branch: 'main' }
|
27
27
|
end
|
28
28
|
assert_response :unprocessable_entity
|
29
29
|
assert_json 'errors', 'repository' => ['is invalid']
|
@@ -48,12 +48,12 @@ module Shipit
|
|
48
48
|
|
49
49
|
assert_no_difference -> { Stack.count } do
|
50
50
|
post :create,
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
params: {
|
52
|
+
repo_name: existing_stack.repo_name,
|
53
|
+
repo_owner: existing_stack.repo_owner,
|
54
|
+
environment: existing_stack.environment,
|
55
|
+
branch: existing_stack.branch,
|
56
|
+
}
|
57
57
|
end
|
58
58
|
|
59
59
|
assert_response :unprocessable_entity
|
@@ -82,6 +82,20 @@ module Shipit
|
|
82
82
|
assert_equal true, @stack.continuous_deployment
|
83
83
|
end
|
84
84
|
|
85
|
+
test "#update allows changing the branch name" do
|
86
|
+
assert_equal 'master', @stack.branch
|
87
|
+
|
88
|
+
patch :update, params: {
|
89
|
+
id: @stack.to_param,
|
90
|
+
branch: 'test',
|
91
|
+
}
|
92
|
+
|
93
|
+
assert_response :ok
|
94
|
+
@stack.reload
|
95
|
+
|
96
|
+
assert_equal 'test', @stack.branch
|
97
|
+
end
|
98
|
+
|
85
99
|
test "#index returns a list of stacks" do
|
86
100
|
stack = Stack.last
|
87
101
|
get :index
|
@@ -22,14 +22,15 @@ module Shipit
|
|
22
22
|
test ":push with the target branch queues a GithubSyncJob" do
|
23
23
|
request.headers['X-Github-Event'] = 'push'
|
24
24
|
|
25
|
+
body = JSON.parse(payload(:push_master)).to_json
|
25
26
|
assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
|
26
|
-
post :create, body:
|
27
|
+
post :create, body: body, as: :json
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
31
|
test ":push does not enqueue a job if not the target branch" do
|
31
32
|
request.headers['X-Github-Event'] = 'push'
|
32
|
-
params = payload(:push_not_master)
|
33
|
+
params = JSON.parse(payload(:push_not_master)).to_json
|
33
34
|
assert_no_enqueued_jobs do
|
34
35
|
post :create, body: params, as: :json
|
35
36
|
end
|
@@ -40,8 +41,9 @@ module Shipit
|
|
40
41
|
|
41
42
|
commit = shipit_commits(:first)
|
42
43
|
|
44
|
+
body = JSON.parse(payload(:status_master)).merge(repository_params).to_json
|
43
45
|
assert_difference 'commit.statuses.count', 1 do
|
44
|
-
post :create, body:
|
46
|
+
post :create, body: body, as: :json
|
45
47
|
end
|
46
48
|
|
47
49
|
status = commit.statuses.last
|
@@ -55,14 +57,14 @@ module Shipit
|
|
55
57
|
|
56
58
|
test ":state with a unexisting commit respond with 200 OK" do
|
57
59
|
request.headers['X-Github-Event'] = 'status'
|
58
|
-
params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [{ 'name' => 'master' }] }.to_json
|
60
|
+
params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [{ 'name' => 'master' }] }.merge(repository_params).to_json
|
59
61
|
post :create, body: params, as: :json
|
60
62
|
assert_response :ok
|
61
63
|
end
|
62
64
|
|
63
65
|
test ":state in an untracked branche bails out" do
|
64
66
|
request.headers['X-Github-Event'] = 'status'
|
65
|
-
params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [] }.to_json
|
67
|
+
params = { 'sha' => 'notarealcommit', 'state' => 'pending', 'branches' => [] }.merge(repository_params).to_json
|
66
68
|
post :create, body: params, as: :json
|
67
69
|
assert_response :ok
|
68
70
|
end
|
@@ -70,8 +72,9 @@ module Shipit
|
|
70
72
|
test ":check_suite with the target branch queues a RefreshCheckRunsJob" do
|
71
73
|
request.headers['X-Github-Event'] = 'check_suite'
|
72
74
|
|
75
|
+
body = JSON.parse(payload(:check_suite_master)).to_json
|
73
76
|
assert_enqueued_with(job: RefreshCheckRunsJob) do
|
74
|
-
post :create, body:
|
77
|
+
post :create, body: body, as: :json
|
75
78
|
assert_response :ok
|
76
79
|
end
|
77
80
|
end
|
@@ -88,13 +91,13 @@ module Shipit
|
|
88
91
|
test "verifies webhook signature" do
|
89
92
|
commit = shipit_commits(:first)
|
90
93
|
|
91
|
-
payload = { "sha" => commit.sha, "state" => "pending", "target_url" => "https://ci.example.com/1000/output" }.to_json
|
94
|
+
payload = { "sha" => commit.sha, "state" => "pending", "target_url" => "https://ci.example.com/1000/output" }.merge(repository_params).to_json
|
92
95
|
signature = 'sha1=4848deb1c9642cd938e8caa578d201ca359a8249'
|
93
96
|
|
94
97
|
@request.headers['X-Github-Event'] = 'push'
|
95
98
|
@request.headers['X-Hub-Signature'] = signature
|
96
99
|
|
97
|
-
Shipit.github.expects(:verify_webhook_signature).with(signature, payload).returns(false)
|
100
|
+
Shipit.github(organization: 'shopify').expects(:verify_webhook_signature).with(signature, payload).returns(false)
|
98
101
|
|
99
102
|
post :create, body: payload, as: :json
|
100
103
|
assert_response :unprocessable_entity
|
@@ -157,7 +160,7 @@ module Shipit
|
|
157
160
|
test "other events trigger custom handlers" do
|
158
161
|
event = 'pull_request'
|
159
162
|
mock_handler = mock
|
160
|
-
mock_handler.expects(:call).with(pull_request_params.
|
163
|
+
mock_handler.expects(:call).with(pull_request_params.deep_stringify_keys).once
|
161
164
|
Shipit::Webhooks.handlers["pull_request"] = [mock_handler]
|
162
165
|
|
163
166
|
@request.headers['X-Github-Event'] = event
|
@@ -165,20 +168,32 @@ module Shipit
|
|
165
168
|
assert_response :ok
|
166
169
|
end
|
167
170
|
|
171
|
+
test "events with no handler are dropped" do
|
172
|
+
event = 'not_a_real_event'
|
173
|
+
|
174
|
+
@request.headers['X-Github-Event'] = event
|
175
|
+
post :create, body: pull_request_params.to_json, as: :json
|
176
|
+
assert_response 204
|
177
|
+
end
|
178
|
+
|
168
179
|
private
|
169
180
|
|
170
181
|
def pull_request_params
|
171
|
-
{ action: 'opened', number: 2, pull_request: 'foobar' }
|
182
|
+
{ action: 'opened', number: 2, pull_request: 'foobar' }.merge(repository_params)
|
172
183
|
end
|
173
184
|
|
174
185
|
def membership_params
|
175
|
-
{ action: 'added', team: team_params, organization: { login: 'shopify' }, member: { login: 'walrus' } }
|
186
|
+
{ action: 'added', team: team_params, organization: { login: 'shopify' }, member: { login: 'walrus' } }.merge(repository_params)
|
176
187
|
end
|
177
188
|
|
178
189
|
def team_params
|
179
190
|
{ id: shipit_teams(:shopify_developers).id, slug: 'developers', name: 'Developers', url: 'http://example.com' }
|
180
191
|
end
|
181
192
|
|
193
|
+
def repository_params
|
194
|
+
{ repository: { owner: { login: 'shopify' } } }
|
195
|
+
end
|
196
|
+
|
182
197
|
def george
|
183
198
|
stub(
|
184
199
|
id: 42,
|