shipit-engine 0.33.0 → 0.34.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 +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,
|