pact_broker 2.81.0 → 2.82.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +30 -0
- data/DEVELOPER_SETUP.md +1 -1
- data/README.md +7 -5
- data/config.ru +3 -28
- data/db/migrations/20210722_add_index_to_triggered_webhooks_webhook_uuid.rb +7 -0
- data/db/migrations/20210810_set_allow_contract_modification.rb +17 -0
- data/docs/CONFIGURATION.md +398 -0
- data/docs/configuration.yml +320 -0
- data/example/Gemfile +4 -4
- data/example/README.md +15 -22
- data/example/config.ru +1 -24
- data/example/config/pact_broker.yml +9 -0
- data/example/config/puma.rb +3 -0
- data/lib/db.rb +1 -1
- data/lib/pact_broker/api/authorization/resource_access_policy.rb +68 -0
- data/lib/pact_broker/api/authorization/resource_access_rules.rb +40 -0
- data/lib/pact_broker/api/decorators/deployed_version_decorator.rb +2 -0
- data/lib/pact_broker/api/decorators/released_version_decorator.rb +2 -0
- data/lib/pact_broker/api/middleware/basic_auth.rb +63 -0
- data/lib/pact_broker/api/resources/pact.rb +15 -6
- data/lib/pact_broker/api/resources/tag.rb +1 -14
- data/lib/pact_broker/app.rb +52 -30
- data/lib/pact_broker/config/basic_auth_configuration.rb +38 -0
- data/lib/pact_broker/config/load.rb +21 -10
- data/lib/pact_broker/config/runtime_configuration.rb +188 -0
- data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +41 -0
- data/lib/pact_broker/config/runtime_configuration_database_methods.rb +119 -0
- data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +61 -0
- data/lib/pact_broker/configuration.rb +67 -131
- data/lib/pact_broker/contracts/notice.rb +4 -0
- data/lib/pact_broker/contracts/service.rb +4 -4
- data/lib/pact_broker/db/models.rb +3 -0
- data/lib/pact_broker/db/validate_encoding.rb +0 -4
- data/lib/pact_broker/deployments/deployed_version.rb +8 -2
- data/lib/pact_broker/deployments/deployed_version_service.rb +13 -6
- data/lib/pact_broker/deployments/environment.rb +1 -1
- data/lib/pact_broker/deployments/released_version.rb +8 -0
- data/lib/pact_broker/deployments/released_version_service.rb +12 -0
- data/lib/pact_broker/doc/views/provider-pacts-for-verification.markdown +4 -0
- data/lib/pact_broker/domain/pacticipant.rb +17 -13
- data/lib/pact_broker/domain/verification.rb +4 -22
- data/lib/pact_broker/domain/version.rb +9 -5
- data/lib/pact_broker/domain/webhook.rb +4 -0
- data/lib/pact_broker/error.rb +1 -0
- data/lib/pact_broker/errors.rb +1 -1
- data/lib/pact_broker/feature_toggle.rb +3 -5
- data/lib/pact_broker/hash_refinements.rb +0 -1
- data/lib/pact_broker/index/service.rb +4 -6
- data/lib/pact_broker/initializers/database_connection.rb +80 -0
- data/lib/pact_broker/integrations/integration.rb +5 -0
- data/lib/pact_broker/integrations/service.rb +4 -2
- data/lib/pact_broker/locale/en.yml +1 -0
- data/lib/pact_broker/logging.rb +2 -1
- data/lib/pact_broker/matrix/integration.rb +1 -1
- data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +2 -2
- data/lib/pact_broker/matrix/quick_row.rb +10 -0
- data/lib/pact_broker/matrix/repository.rb +64 -3
- data/lib/pact_broker/metrics/service.rb +16 -13
- data/lib/pact_broker/pacticipants/repository.rb +4 -0
- data/lib/pact_broker/pacticipants/service.rb +9 -1
- data/lib/pact_broker/pacts/pact_publication.rb +10 -13
- data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +6 -1
- data/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +1 -2
- data/lib/pact_broker/pacts/pact_version.rb +25 -11
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +54 -77
- data/lib/pact_broker/pacts/selected_pact.rb +1 -1
- data/lib/pact_broker/pacts/selector.rb +15 -2
- data/lib/pact_broker/pacts/selectors.rb +4 -0
- data/lib/pact_broker/pacts/service.rb +4 -0
- data/lib/pact_broker/repositories/scopes.rb +12 -1
- data/lib/pact_broker/string_refinements.rb +6 -0
- data/lib/pact_broker/tags/service.rb +8 -1
- data/lib/pact_broker/test/http_test_data_builder.rb +11 -5
- data/lib/pact_broker/ui/views/index/_css_and_js.haml +11 -9
- data/lib/pact_broker/ui/views/index/_pagination.haml +3 -1
- data/lib/pact_broker/ui/views/layouts/main.haml +5 -3
- data/lib/pact_broker/ui/views/matrix/show.haml +10 -8
- data/lib/pact_broker/verifications/required_verification.rb +28 -0
- data/lib/pact_broker/verifications/service.rb +49 -1
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/repository.rb +15 -0
- data/lib/pact_broker/versions/service.rb +32 -2
- data/lib/pact_broker/webhooks/event_listener.rb +3 -0
- data/lib/pact_broker/webhooks/trigger_service.rb +30 -14
- data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -0
- data/lib/pact_broker/webhooks/webhook.rb +2 -2
- data/lib/pact_broker/webhooks/webhook_event.rb +6 -1
- data/lib/semantic_logger/formatters/short.rb +29 -0
- data/pact_broker.gemspec +1 -0
- data/script/data/auto-create-things-for-tags.rb +19 -0
- data/script/data/contract-published-requiring-verification.rb +27 -0
- data/script/{reproduce-issue-expand-currently-deployed.rb → data/expand-currently-deployed.rb} +0 -0
- data/script/docs/generate-configuration-docs.rb +86 -0
- data/spec/features/get_latest_pact_badge_spec.rb +1 -0
- data/spec/features/get_matrix_badge_spec.rb +1 -0
- data/spec/features/publish_pact_spec.rb +21 -7
- data/spec/features/wip_pacts_spec.rb +1 -1
- data/spec/fixtures/approvals/matrix_integration_environment_spec.approved.json +62 -0
- data/spec/fixtures/approvals/matrix_integration_ignore_spec.approved.json +124 -0
- data/spec/fixtures/approvals/matrix_integration_spec.approved.json +173 -0
- data/spec/fixtures/approvals/publish_contract_no_branch.approved.json +9 -9
- data/spec/fixtures/approvals/publish_contract_nothing_exists.approved.json +7 -7
- data/spec/fixtures/approvals/publish_contract_nothing_exists_with_webhook.approved.json +5 -5
- data/spec/fixtures/approvals/publish_contract_verification_already_exists.approved.json +5 -5
- data/spec/lib/pact_broker/api/middleware/basic_auth_spec.rb +312 -0
- data/spec/lib/pact_broker/api/resources/tag_spec.rb +14 -39
- data/spec/lib/pact_broker/app_basic_auth_spec.rb +122 -0
- data/spec/lib/pact_broker/config/load_spec.rb +33 -6
- data/spec/lib/pact_broker/config/runtime_configuration_logging_methods_spec.rb +22 -0
- data/spec/lib/pact_broker/config/runtime_configuration_spec.rb +71 -0
- data/spec/lib/pact_broker/configuration_spec.rb +51 -25
- data/spec/lib/pact_broker/errors/error_logger_spec.rb +3 -0
- data/spec/lib/pact_broker/feature_toggle_spec.rb +18 -19
- data/spec/lib/pact_broker/matrix/integration_environment_spec.rb +12 -0
- data/spec/lib/pact_broker/matrix/integration_ignore_spec.rb +15 -3
- data/spec/lib/pact_broker/matrix/integration_spec.rb +47 -6
- data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +16 -1
- data/spec/lib/pact_broker/matrix/repository_dependency_spec.rb +0 -2
- data/spec/lib/pact_broker/matrix/repository_spec.rb +0 -2
- data/spec/lib/pact_broker/metrics/service_spec.rb +44 -0
- data/spec/lib/pact_broker/pacticipants/service_spec.rb +28 -5
- data/spec/lib/pact_broker/pacts/pact_publication_selector_dataset_module_spec.rb +25 -0
- data/spec/lib/pact_broker/pacts/pact_version_spec.rb +30 -1
- data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +107 -20
- data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +1 -1
- data/spec/lib/pact_broker/tags/service_spec.rb +24 -8
- data/spec/lib/pact_broker/verifications/service_spec.rb +146 -0
- data/spec/lib/pact_broker/versions/repository_spec.rb +38 -2
- data/spec/lib/pact_broker/versions/service_spec.rb +93 -2
- data/spec/lib/pact_broker/webhooks/trigger_service_spec.rb +54 -2
- data/spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb +3 -3
- data/spec/spec_helper.rb +2 -1
- data/spec/support/approvals.rb +29 -0
- metadata +52 -13
- data/example/basic_auth/Gemfile +0 -5
- data/example/basic_auth/Procfile +0 -1
- data/example/basic_auth/README.md +0 -43
- data/example/basic_auth/config.ru +0 -19
- data/example/example_data.sql +0 -19
- data/spec/lib/pact_broker/config/save_and_load_spec.rb +0 -25
- data/spec/lib/pact_broker/pacts/service_find_for_verification_spec.rb +0 -50
@@ -13,7 +13,7 @@ module PactBroker
|
|
13
13
|
|
14
14
|
def self.merge(selected_pacts)
|
15
15
|
latest_selected_pact = selected_pacts.sort_by(&:consumer_version_order).last
|
16
|
-
selectors = selected_pacts.collect(&:selectors).reduce(&:+)
|
16
|
+
selectors = selected_pacts.collect(&:selectors).reduce(&:+).sort
|
17
17
|
SelectedPact.new(latest_selected_pact.pact, selectors)
|
18
18
|
end
|
19
19
|
|
@@ -101,7 +101,7 @@ module PactBroker
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def currently_deployed?
|
104
|
-
currently_deployed
|
104
|
+
!!currently_deployed
|
105
105
|
end
|
106
106
|
|
107
107
|
def currently_supported= currently_supported
|
@@ -113,7 +113,7 @@ module PactBroker
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def currently_supported?
|
116
|
-
currently_supported
|
116
|
+
!!currently_supported
|
117
117
|
end
|
118
118
|
|
119
119
|
def environment_name= environment_name
|
@@ -204,6 +204,10 @@ module PactBroker
|
|
204
204
|
Selector.new(hash)
|
205
205
|
end
|
206
206
|
|
207
|
+
def for_consumer(consumer)
|
208
|
+
Selector.new(to_h.merge(consumer: consumer))
|
209
|
+
end
|
210
|
+
|
207
211
|
def latest_for_main_branch?
|
208
212
|
!!main_branch
|
209
213
|
end
|
@@ -334,6 +338,15 @@ module PactBroker
|
|
334
338
|
def == other
|
335
339
|
super && consumer_version == other.consumer_version
|
336
340
|
end
|
341
|
+
|
342
|
+
def <=> other
|
343
|
+
comparison = super
|
344
|
+
if comparison == 0
|
345
|
+
consumer_version.order <=> other.consumer_version.order
|
346
|
+
else
|
347
|
+
comparison
|
348
|
+
end
|
349
|
+
end
|
337
350
|
end
|
338
351
|
end
|
339
352
|
end
|
@@ -156,6 +156,10 @@ module PactBroker
|
|
156
156
|
updated_pact
|
157
157
|
end
|
158
158
|
|
159
|
+
def disallowed_modification?(existing_pact, new_json_content)
|
160
|
+
!PactBroker.configuration.allow_dangerous_contract_modification && existing_pact && existing_pact.pact_version_sha != generate_sha(new_json_content)
|
161
|
+
end
|
162
|
+
|
159
163
|
private :update_pact
|
160
164
|
|
161
165
|
# When no publication for the given consumer/provider/consumer version number exists
|
@@ -1,8 +1,19 @@
|
|
1
1
|
module PactBroker
|
2
2
|
module Repositories
|
3
3
|
module Scopes
|
4
|
+
def with_no_scope
|
5
|
+
@unscoped = true
|
6
|
+
yield self
|
7
|
+
ensure
|
8
|
+
@unscoped = false
|
9
|
+
end
|
10
|
+
|
4
11
|
def scope_for(scope)
|
5
|
-
|
12
|
+
if @unscoped == true
|
13
|
+
scope
|
14
|
+
else
|
15
|
+
PactBroker.policy_scope!(scope)
|
16
|
+
end
|
6
17
|
end
|
7
18
|
|
8
19
|
# For the times when it doesn't make sense to use the scoped class, this is a way to
|
@@ -1,15 +1,22 @@
|
|
1
1
|
require "pact_broker/repositories"
|
2
|
+
require "pact_broker/configuration"
|
3
|
+
require "pact_broker/logging"
|
2
4
|
|
3
5
|
module PactBroker
|
4
6
|
module Tags
|
5
7
|
module Service
|
6
8
|
extend self
|
7
9
|
extend PactBroker::Repositories
|
10
|
+
extend PactBroker::Services
|
11
|
+
include PactBroker::Logging
|
8
12
|
|
9
13
|
def create args
|
14
|
+
tag_name = args.fetch(:tag_name)
|
10
15
|
pacticipant = pacticipant_repository.find_by_name_or_create args.fetch(:pacticipant_name)
|
11
16
|
version = version_repository.find_by_pacticipant_id_and_number_or_create pacticipant.id, args.fetch(:pacticipant_version_number)
|
12
|
-
|
17
|
+
version_service.maybe_set_version_branch_from_tag(version, tag_name)
|
18
|
+
pacticipant_service.maybe_set_main_branch(version.pacticipant, tag_name)
|
19
|
+
tag_repository.create(version: version, name: tag_name)
|
13
20
|
end
|
14
21
|
|
15
22
|
def find args
|
@@ -180,17 +180,19 @@ module PactBroker
|
|
180
180
|
self
|
181
181
|
end
|
182
182
|
|
183
|
-
def
|
183
|
+
def create_global_webhook_for_event(uuid: nil, url: "https://postman-echo.com/post", body: nil, event_name: )
|
184
184
|
puts "Creating global webhook for contract changed event with uuid #{uuid}"
|
185
185
|
uuid ||= SecureRandom.uuid
|
186
186
|
default_body = {
|
187
|
-
"
|
187
|
+
"providerVersionNumber" => "${pactbroker.providerVersionNumber}",
|
188
|
+
"providerVersionBranch" => "${pactbroker.providerVersionBranch}",
|
189
|
+
"consumerVersionNumber" => "${pactbroker.consumerVersionNumber}",
|
188
190
|
"consumerVersionBranch" => "${pactbroker.consumerVersionBranch}"
|
189
191
|
}
|
190
192
|
request_body = {
|
191
193
|
"description" => "A webhook for all consumers and providers",
|
192
194
|
"events" => [{
|
193
|
-
"name" =>
|
195
|
+
"name" => event_name
|
194
196
|
}],
|
195
197
|
"request" => {
|
196
198
|
"method" => "POST",
|
@@ -204,6 +206,10 @@ module PactBroker
|
|
204
206
|
self
|
205
207
|
end
|
206
208
|
|
209
|
+
def create_global_webhook_for_contract_changed(uuid: nil, url: "https://postman-echo.com/post", body: nil)
|
210
|
+
create_global_webhook_for_event(uuid: uuid, url: url, body: body, event_name: "contract_content_changed")
|
211
|
+
end
|
212
|
+
|
207
213
|
def create_global_webhook_for_anything_published(uuid: nil, url: "https://postman-echo.com/post")
|
208
214
|
puts "Creating global webhook for contract changed event with uuid #{uuid}"
|
209
215
|
uuid ||= SecureRandom.uuid
|
@@ -248,8 +254,8 @@ module PactBroker
|
|
248
254
|
self
|
249
255
|
end
|
250
256
|
|
251
|
-
def can_i_deploy(pacticipant:, version:, to:)
|
252
|
-
can_i_deploy_response = client.get("can-i-deploy", { pacticipant: pacticipant, version: version, to: to} ).tap { |response| check_for_error(response) }
|
257
|
+
def can_i_deploy(pacticipant:, version:, to: nil, to_environment: nil)
|
258
|
+
can_i_deploy_response = client.get("can-i-deploy", { pacticipant: pacticipant, version: version, to: to, environment: to_environment}.compact ).tap { |response| check_for_error(response) }
|
253
259
|
can = !!(can_i_deploy_response.body["summary"] || {})["deployable"]
|
254
260
|
puts "can-i-deploy #{pacticipant} version #{version} to #{to}: #{can ? 'yes' : 'no'}"
|
255
261
|
summary = can_i_deploy_response.body["summary"]
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/
|
4
|
-
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/
|
5
|
-
%
|
6
|
-
%
|
7
|
-
%script{type: 'text/javascript', src:"#{base_url}/javascripts/
|
8
|
-
%script{type: 'text/javascript', src:"#{base_url}/javascripts/
|
9
|
-
%script{type: 'text/javascript', src:"#{base_url}/javascripts/
|
1
|
+
- require "pact_broker/version"
|
2
|
+
|
3
|
+
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/index.css?v=#{PactBroker::VERSION}"}
|
4
|
+
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/material-menu.css?v=#{PactBroker::VERSION}"}
|
5
|
+
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/material-icon.css?v=#{PactBroker::VERSION}"}
|
6
|
+
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/jquery-confirm.min.css?v=#{PactBroker::VERSION}"}
|
7
|
+
%script{type: 'text/javascript', src:"#{base_url}/javascripts/jquery.tablesorter.min.js?v=#{PactBroker::VERSION}"}
|
8
|
+
%script{type: 'text/javascript', src:"#{base_url}/javascripts/material-menu.js?v=#{PactBroker::VERSION}"}
|
9
|
+
%script{type: 'text/javascript', src:"#{base_url}/javascripts/index.js?v=#{PactBroker::VERSION}"}
|
10
|
+
%script{type: 'text/javascript', src:"#{base_url}/javascripts/clipboard.js?v=#{PactBroker::VERSION}"}
|
11
|
+
%script{type: 'text/javascript', src:"#{base_url}/javascripts/jquery-confirm.min.js?v=#{PactBroker::VERSION}"}
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
- require "pact_broker/version"
|
2
|
+
|
3
|
+
%script{type: 'text/javascript', src:"#{base_url}/javascripts/pagination.js?v=#{PactBroker::VERSION}"}
|
2
4
|
|
3
5
|
:javascript
|
4
6
|
const PAGE_NUMBER = #{page_number};
|
@@ -1,9 +1,11 @@
|
|
1
|
+
- require "pact_broker/version"
|
2
|
+
|
1
3
|
<!DOCTYPE html>
|
2
4
|
%html
|
3
5
|
%head
|
4
6
|
%title= defined?(title) ? title : ""
|
5
7
|
%link{rel: 'shortcut icon', href: "#{base_url}/images/favicon.ico", type:'image/x-icon'}
|
6
|
-
%link{rel: 'stylesheet', href: "#{base_url}/css/bootstrap.min.css"}
|
7
|
-
%script{type: 'text/javascript', src:"#{base_url}/javascripts/jquery-3.5.1.min.js"}
|
8
|
-
%script{type: 'text/javascript', src:"#{base_url}/js/bootstrap.bundle.min.js"}
|
8
|
+
%link{rel: 'stylesheet', href: "#{base_url}/css/bootstrap.min.css?v=#{PactBroker::VERSION}"}
|
9
|
+
%script{type: 'text/javascript', src:"#{base_url}/javascripts/jquery-3.5.1.min.js?v=#{PactBroker::VERSION}"}
|
10
|
+
%script{type: 'text/javascript', src:"#{base_url}/js/bootstrap.bundle.min.js?v=#{PactBroker::VERSION}"}
|
9
11
|
!= yield
|
@@ -1,12 +1,14 @@
|
|
1
|
+
- require "pact_broker/version"
|
2
|
+
|
1
3
|
%body
|
2
|
-
%link{rel: 'stylesheet', href: "#{base_url}/css/bootstrap.min.css"}
|
3
|
-
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/index.css"}
|
4
|
-
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/matrix.css"}
|
5
|
-
%script{type: 'text/javascript', src: "#{base_url}/javascripts/jquery-3.5.1.min.js"}
|
6
|
-
%script{type: 'text/javascript', src: "#{base_url}/javascripts/jquery.tablesorter.min.js"}
|
7
|
-
%script{type: 'text/javascript', src: "#{base_url}/javascripts/matrix.js"}
|
8
|
-
%script{type: 'text/javascript', src: "#{base_url}/javascripts/clipboard.js"}
|
9
|
-
%script{type: 'text/javascript', src: "#{base_url}/js/bootstrap.bundle.min.js"}
|
4
|
+
%link{rel: 'stylesheet', href: "#{base_url}/css/bootstrap.min.css?v=#{PactBroker::VERSION}"}
|
5
|
+
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/index.css?v=#{PactBroker::VERSION}"}
|
6
|
+
%link{rel: 'stylesheet', href: "#{base_url}/stylesheets/matrix.css?v=#{PactBroker::VERSION}"}
|
7
|
+
%script{type: 'text/javascript', src: "#{base_url}/javascripts/jquery-3.5.1.min.js?v=#{PactBroker::VERSION}"}
|
8
|
+
%script{type: 'text/javascript', src: "#{base_url}/javascripts/jquery.tablesorter.min.js?v=#{PactBroker::VERSION}"}
|
9
|
+
%script{type: 'text/javascript', src: "#{base_url}/javascripts/matrix.js?v=#{PactBroker::VERSION}"}
|
10
|
+
%script{type: 'text/javascript', src: "#{base_url}/javascripts/clipboard.js?v=#{PactBroker::VERSION}"}
|
11
|
+
%script{type: 'text/javascript', src: "#{base_url}/js/bootstrap.bundle.min.js?v=#{PactBroker::VERSION}"}
|
10
12
|
|
11
13
|
.container
|
12
14
|
.navbar-right
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module PactBroker
|
2
|
+
module Verifications
|
3
|
+
class RequiredVerification
|
4
|
+
attr_reader :provider_version, :provider_version_descriptions
|
5
|
+
|
6
|
+
def initialize(attributes = {})
|
7
|
+
attributes.each do | (name, value) |
|
8
|
+
instance_variable_set("@#{name}", value) if respond_to?(name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def == other
|
13
|
+
provider_version == other.provider_version && provider_version_descriptions == other.provider_version_descriptions
|
14
|
+
end
|
15
|
+
|
16
|
+
def + other
|
17
|
+
if provider_version != other.provider_version
|
18
|
+
raise PactBroker::Error.new("Can't + RequiredVerifications with different provider versions (#{provider_version.number}/#{other.provider_version.number})")
|
19
|
+
end
|
20
|
+
|
21
|
+
RequiredVerification.new(
|
22
|
+
provider_version: provider_version,
|
23
|
+
provider_version_descriptions: (provider_version_descriptions + other.provider_version_descriptions).uniq
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -5,6 +5,7 @@ require "pact_broker/verifications/summary_for_consumer_version"
|
|
5
5
|
require "pact_broker/logging"
|
6
6
|
require "pact_broker/hash_refinements"
|
7
7
|
require "pact_broker/events/publisher"
|
8
|
+
require "pact_broker/verifications/required_verification"
|
8
9
|
|
9
10
|
module PactBroker
|
10
11
|
module Verifications
|
@@ -89,7 +90,16 @@ module PactBroker
|
|
89
90
|
verification_repository.delete_all_verifications_between(consumer_name, options)
|
90
91
|
end
|
91
92
|
|
92
|
-
|
93
|
+
def calculate_required_verifications_for_pact(pact)
|
94
|
+
pact_version = PactBroker::Pacts::PactVersion.for_pact_domain(pact)
|
95
|
+
required_verifications = required_verifications_for_main_branch(pact_version) +
|
96
|
+
required_verifications_for_deployed_versions(pact_version) +
|
97
|
+
required_verifications_for_released_versions(pact_version)
|
98
|
+
required_verifications
|
99
|
+
.group_by(&:provider_version)
|
100
|
+
.values
|
101
|
+
.flat_map { | required_verifications_for_provider_version | required_verifications_for_provider_version.reduce(&:+) }
|
102
|
+
end
|
93
103
|
|
94
104
|
def broadcast_events(verification, pact, event_context)
|
95
105
|
event_params = {
|
@@ -105,6 +115,44 @@ module PactBroker
|
|
105
115
|
broadcast(:provider_verification_failed, event_params)
|
106
116
|
end
|
107
117
|
end
|
118
|
+
private :broadcast_events
|
119
|
+
|
120
|
+
def identify_required_verification(pact_version, provider_version, description)
|
121
|
+
any_verifications = PactBroker::Domain::Verification.where(pact_version_id: pact_version.id, provider_version_id: provider_version.id).any?
|
122
|
+
if !any_verifications
|
123
|
+
RequiredVerification.new(provider_version: provider_version, provider_version_descriptions: [description])
|
124
|
+
end
|
125
|
+
end
|
126
|
+
private :identify_required_verification
|
127
|
+
|
128
|
+
def required_verifications_for_main_branch(pact_version)
|
129
|
+
latest_version_from_main_branch = [version_service.find_latest_version_from_main_branch(pact_version.provider)].compact
|
130
|
+
|
131
|
+
latest_version_from_main_branch.collect do | main_branch_version |
|
132
|
+
identify_required_verification(pact_version, main_branch_version, "latest version from main branch")
|
133
|
+
end.compact
|
134
|
+
end
|
135
|
+
private :required_verifications_for_main_branch
|
136
|
+
|
137
|
+
def required_verifications_for_deployed_versions(pact_version)
|
138
|
+
deployed_versions = deployed_version_service.with_no_scope do | unscoped_service |
|
139
|
+
unscoped_service.find_currently_deployed_versions_for_pacticipant(pact_version.provider)
|
140
|
+
end
|
141
|
+
deployed_versions.collect do | deployed_version |
|
142
|
+
identify_required_verification(pact_version, deployed_version.version, "currently deployed version (#{deployed_version.environment_name})")
|
143
|
+
end.compact
|
144
|
+
end
|
145
|
+
private :required_verifications_for_deployed_versions
|
146
|
+
|
147
|
+
def required_verifications_for_released_versions(pact_version)
|
148
|
+
released_versions = released_version_service.with_no_scope do | unscoped_service |
|
149
|
+
unscoped_service.find_currently_supported_versions_for_pacticipant(pact_version.provider)
|
150
|
+
end
|
151
|
+
released_versions.collect do | released_version |
|
152
|
+
identify_required_verification(pact_version, released_version.version, "currently released version (#{released_version.environment_name})")
|
153
|
+
end.compact
|
154
|
+
end
|
155
|
+
private :required_verifications_for_released_versions
|
108
156
|
end
|
109
157
|
end
|
110
158
|
end
|
data/lib/pact_broker/version.rb
CHANGED
@@ -128,6 +128,21 @@ module PactBroker
|
|
128
128
|
def find_versions_for_selector(selector)
|
129
129
|
PactBroker::Domain::Version.select_all_qualified.for_selector(selector).all
|
130
130
|
end
|
131
|
+
|
132
|
+
def set_branch_if_unset(version, branch)
|
133
|
+
version.update(branch: branch) if version.branch.nil?
|
134
|
+
version
|
135
|
+
end
|
136
|
+
|
137
|
+
def find_latest_version_from_main_branch(pacticipant)
|
138
|
+
if pacticipant.main_branch
|
139
|
+
latest_from_main_branch = PactBroker::Domain::Version
|
140
|
+
.latest_versions_for_pacticipant_branches(pacticipant.id, pacticipant.main_branch)
|
141
|
+
.single_record
|
142
|
+
|
143
|
+
latest_from_main_branch || find_by_pacticipant_name_and_latest_tag(pacticipant.name, pacticipant.main_branch)
|
144
|
+
end
|
145
|
+
end
|
131
146
|
end
|
132
147
|
end
|
133
148
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "pact_broker/logging"
|
1
2
|
require "pact_broker/repositories"
|
2
3
|
require "pact_broker/messages"
|
3
4
|
|
@@ -6,6 +7,8 @@ module PactBroker
|
|
6
7
|
class Service
|
7
8
|
extend PactBroker::Messages
|
8
9
|
extend PactBroker::Repositories
|
10
|
+
extend PactBroker::Services
|
11
|
+
include PactBroker::Logging
|
9
12
|
|
10
13
|
def self.conflict_errors(_existing_version, _open_struct_version, _version_url)
|
11
14
|
# This validation is causing problems in the PF build when branches are merged
|
@@ -38,12 +41,20 @@ module PactBroker
|
|
38
41
|
|
39
42
|
def self.create_or_overwrite(pacticipant_name, version_number, version)
|
40
43
|
pacticipant = pacticipant_repository.find_by_name_or_create(pacticipant_name)
|
41
|
-
version_repository.create_or_overwrite(pacticipant, version_number, version)
|
44
|
+
version = version_repository.create_or_overwrite(pacticipant, version_number, version)
|
45
|
+
pacticipant_service.maybe_set_main_branch(pacticipant, version.branch)
|
46
|
+
version
|
42
47
|
end
|
43
48
|
|
44
49
|
def self.create_or_update(pacticipant_name, version_number, version)
|
45
50
|
pacticipant = pacticipant_repository.find_by_name_or_create(pacticipant_name)
|
46
|
-
version_repository.create_or_update(pacticipant, version_number, version)
|
51
|
+
version = version_repository.create_or_update(pacticipant, version_number, version)
|
52
|
+
pacticipant_service.maybe_set_main_branch(pacticipant, version.branch)
|
53
|
+
version
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.find_latest_version_from_main_branch(pacticipant)
|
57
|
+
version_repository.find_latest_version_from_main_branch(pacticipant)
|
47
58
|
end
|
48
59
|
|
49
60
|
def self.delete version
|
@@ -53,6 +64,25 @@ module PactBroker
|
|
53
64
|
verification_repository.delete_by_provider_version_id version.id
|
54
65
|
version_repository.delete_by_id version.id
|
55
66
|
end
|
67
|
+
|
68
|
+
def self.maybe_set_version_branch_from_tag(version, tag_name)
|
69
|
+
if use_tag_as_branch?(version) && !version.branch
|
70
|
+
logger.info "Setting #{version.pacticipant.name} version #{version.number} branch to '#{tag_name}' from first tag (because use_first_tag_as_branch=true)"
|
71
|
+
version_repository.set_branch_if_unset(version, tag_name)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.use_tag_as_branch?(version)
|
76
|
+
version.tags.count == 0 &&
|
77
|
+
PactBroker.configuration.use_first_tag_as_branch &&
|
78
|
+
((now - version.created_at.to_datetime) * 24 * 60 * 60) <= PactBroker.configuration.use_first_tag_as_branch_time_limit
|
79
|
+
end
|
80
|
+
private_class_method :use_tag_as_branch?
|
81
|
+
|
82
|
+
def self.now
|
83
|
+
Time.now.utc.to_datetime
|
84
|
+
end
|
85
|
+
private_class_method :now
|
56
86
|
end
|
57
87
|
end
|
58
88
|
end
|