pact_broker 2.82.0 → 2.83.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/.gitignore +1 -0
- data/CHANGELOG.md +16 -0
- data/db/migrations/20210815_add_provider_version_id_index_to_verifications.rb +7 -0
- data/db/migrations/20210818_add_consumer_version_selectors_to_verification.rb +8 -0
- data/lib/pact_broker/api/resources/verifications.rb +2 -1
- data/lib/pact_broker/db/clean/selector.rb +54 -0
- data/lib/pact_broker/db/clean.rb +7 -1
- data/lib/pact_broker/db/clean_incremental.rb +13 -5
- data/lib/pact_broker/diagnostic/resources/base_resource.rb +4 -0
- data/lib/pact_broker/diagnostic/resources/dependencies.rb +1 -1
- data/lib/pact_broker/diagnostic/resources/heartbeat.rb +2 -3
- data/lib/pact_broker/domain/verification.rb +4 -1
- data/lib/pact_broker/domain/version.rb +32 -3
- data/lib/pact_broker/locale/en.yml +1 -0
- data/lib/pact_broker/matrix/service.rb +4 -0
- data/lib/pact_broker/matrix/unresolved_selector.rb +3 -2
- data/lib/pact_broker/pacts/metadata.rb +3 -0
- data/lib/pact_broker/pacts/pact_version.rb +2 -1
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +1 -7
- data/lib/pact_broker/pacts/repository.rb +4 -0
- data/lib/pact_broker/pacts/selected_pact.rb +20 -0
- data/lib/pact_broker/pacts/service.rb +21 -0
- data/lib/pact_broker/test/http_test_data_builder.rb +4 -3
- data/lib/pact_broker/test/test_data_builder.rb +2 -1
- data/lib/pact_broker/verifications/repository.rb +6 -11
- data/lib/pact_broker/verifications/service.rb +10 -5
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +9 -1
- data/spec/lib/pact_broker/api/resources/verifications_spec.rb +4 -1
- data/spec/lib/pact_broker/db/clean_spec.rb +2 -2
- data/spec/lib/pact_broker/diagnostic/resources/dependencies_spec.rb +4 -4
- data/spec/lib/pact_broker/diagnostic/resources/heartbeat_spec.rb +3 -4
- data/spec/lib/pact_broker/domain/version_spec.rb +126 -1
- data/spec/lib/pact_broker/matrix/service_spec.rb +10 -1
- data/spec/lib/pact_broker/pacts/metadata_spec.rb +0 -1
- data/spec/lib/pact_broker/pacts/service_spec.rb +61 -0
- data/spec/lib/pact_broker/verifications/repository_spec.rb +39 -30
- data/spec/lib/pact_broker/verifications/service_spec.rb +5 -3
- data/spec/service_consumers/pact_helper.rb +2 -0
- data/spec/spec_helper.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36d8ba30424126875c015264b7ba7e8fd7feb281a019f3436b5c714c7c5ddd0a
|
|
4
|
+
data.tar.gz: 4858eeee386bb44f6d9880b79a92b71d3760b8307fb5faebe07efa8f773fb2ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 23a3f387f860177de7cfdc7152127fd295aa124b415e0d1b7b66c657947c0b89ea06decff7bf2b840d75b690b844bd0fb2999ddb14deb4b269d21e9e5cc7d736
|
|
7
|
+
data.tar.gz: 98c2642b548b2b08ac71fe55a66c18981392ea575bc6c2ca389c19c1f283b134c814cf2479e03d7899bb70a8d244c1987fca10556833df5c3c506e45dfd5ee07
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
<a name="v2.83.0"></a>
|
|
2
|
+
### v2.83.0 (2021-08-19)
|
|
3
|
+
|
|
4
|
+
#### Features
|
|
5
|
+
|
|
6
|
+
* **clean**
|
|
7
|
+
* update default selectors for clean task to include deployed, released and branch head versions ([aaffe71f](/../../commit/aaffe71f))
|
|
8
|
+
* support keeping currently deployed and released versions, and the latest version for each branch ([e4fbd766](/../../commit/e4fbd766))
|
|
9
|
+
|
|
10
|
+
* add index to verifications table to improve performance of 'latest verification' query ([02eeb424](/../../commit/02eeb424))
|
|
11
|
+
|
|
12
|
+
#### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* use provider_version_number from webhook context ([3cf421ac](/../../commit/3cf421ac))
|
|
15
|
+
* validate matrix query limit ([ac5e0890](/../../commit/ac5e0890))
|
|
16
|
+
|
|
1
17
|
<a name="v2.82.0"></a>
|
|
2
18
|
### v2.82.0 (2021-08-14)
|
|
3
19
|
|
|
@@ -51,7 +51,8 @@ module PactBroker
|
|
|
51
51
|
|
|
52
52
|
def from_json
|
|
53
53
|
handle_webhook_events do
|
|
54
|
-
|
|
54
|
+
verified_pacts = pact_service.find_for_verification_publication(pact_params, event_context[:consumer_version_selectors])
|
|
55
|
+
verification = verification_service.create(next_verification_number, verification_params, verified_pacts, event_context)
|
|
55
56
|
response.body = decorator_for(verification).to_json(decorator_options)
|
|
56
57
|
end
|
|
57
58
|
true
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require "pact_broker/hash_refinements"
|
|
2
|
+
|
|
3
|
+
module PactBroker
|
|
4
|
+
module DB
|
|
5
|
+
class Clean
|
|
6
|
+
class Selector
|
|
7
|
+
using PactBroker::HashRefinements
|
|
8
|
+
|
|
9
|
+
ATTRIBUTES = [:pacticipant_name, :latest, :tag, :branch, :environment_name, :max_age, :deployed, :released, :main_branch]
|
|
10
|
+
|
|
11
|
+
attr_accessor(*ATTRIBUTES)
|
|
12
|
+
|
|
13
|
+
def initialize(attributes = {})
|
|
14
|
+
attributes.each do | (name, value) |
|
|
15
|
+
instance_variable_set("@#{name}", value) if respond_to?(name)
|
|
16
|
+
end
|
|
17
|
+
@source_hash = attributes[:source_hash]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.from_hash(hash)
|
|
21
|
+
standard_hash = hash.symbolize_keys.snakecase_keys
|
|
22
|
+
new_hash = standard_hash.slice(*ATTRIBUTES)
|
|
23
|
+
new_hash[:pacticipant_name] ||= standard_hash[:pacticipant] if standard_hash[:pacticipant]
|
|
24
|
+
new_hash[:environment_name] ||= standard_hash[:environment] if standard_hash[:environment]
|
|
25
|
+
new_hash[:source_hash] = hash
|
|
26
|
+
new(new_hash.compact)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_hash
|
|
30
|
+
ATTRIBUTES.each_with_object({}) do | key, hash |
|
|
31
|
+
hash[key] = send(key)
|
|
32
|
+
end.compact
|
|
33
|
+
end
|
|
34
|
+
alias_method :to_h, :to_hash
|
|
35
|
+
|
|
36
|
+
def to_json
|
|
37
|
+
(@source_hash || to_hash).to_json
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def currently_deployed?
|
|
41
|
+
!!deployed
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def currently_supported?
|
|
45
|
+
!!released
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def latest?
|
|
49
|
+
!!latest
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/pact_broker/db/clean.rb
CHANGED
|
@@ -2,6 +2,7 @@ require "sequel"
|
|
|
2
2
|
require "pact_broker/project_root"
|
|
3
3
|
require "pact_broker/pacts/latest_tagged_pact_publications"
|
|
4
4
|
require "pact_broker/logging"
|
|
5
|
+
require "pact_broker/db/clean/selector"
|
|
5
6
|
|
|
6
7
|
module PactBroker
|
|
7
8
|
module DB
|
|
@@ -24,7 +25,12 @@ module PactBroker
|
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def keep
|
|
27
|
-
|
|
28
|
+
@keep ||= if options[:keep]
|
|
29
|
+
# Could be a Matrix::UnresolvedSelector from the docker image, convert it
|
|
30
|
+
options[:keep].collect { | unknown_thing | Selector.from_hash(unknown_thing.to_hash) }
|
|
31
|
+
else
|
|
32
|
+
[Selector.new(tag: true, latest: true), Selector.new(branch: true, latest: true), Selector.new(latest: true), Selector.new(deployed: true), Selector.new(released: true)]
|
|
33
|
+
end
|
|
28
34
|
end
|
|
29
35
|
|
|
30
36
|
def resolve_ids(query, column_name = :id)
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
require "pact_broker/logging"
|
|
2
2
|
require "pact_broker/matrix/unresolved_selector"
|
|
3
3
|
require "pact_broker/date_helper"
|
|
4
|
-
|
|
4
|
+
require "pact_broker/db/clean/selector"
|
|
5
5
|
|
|
6
6
|
module PactBroker
|
|
7
7
|
module DB
|
|
8
8
|
class CleanIncremental
|
|
9
9
|
DEFAULT_KEEP_SELECTORS = [
|
|
10
|
-
PactBroker::
|
|
11
|
-
PactBroker::
|
|
12
|
-
PactBroker::
|
|
10
|
+
PactBroker::DB::Clean::Selector.new(tag: true, latest: true),
|
|
11
|
+
PactBroker::DB::Clean::Selector.new(branch: true, latest: true),
|
|
12
|
+
PactBroker::DB::Clean::Selector.new(latest: true),
|
|
13
|
+
PactBroker::DB::Clean::Selector.new(deployed: true),
|
|
14
|
+
PactBroker::DB::Clean::Selector.new(released: true),
|
|
15
|
+
PactBroker::DB::Clean::Selector.new(max_age: 90)
|
|
13
16
|
]
|
|
14
17
|
TABLES = [:versions, :pact_publications, :pact_versions, :verifications, :triggered_webhooks, :webhook_executions]
|
|
15
18
|
|
|
@@ -27,7 +30,12 @@ module PactBroker
|
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
def keep
|
|
30
|
-
options[:keep]
|
|
33
|
+
@keep ||= if options[:keep]
|
|
34
|
+
# Could be a Matrix::UnresolvedSelector from the docker image, convert it
|
|
35
|
+
options[:keep].collect { | unknown_thing | PactBroker::DB::Clean::Selector.from_hash(unknown_thing.to_hash) }
|
|
36
|
+
else
|
|
37
|
+
DEFAULT_KEEP_SELECTORS
|
|
38
|
+
end
|
|
31
39
|
end
|
|
32
40
|
|
|
33
41
|
def limit
|
|
@@ -16,6 +16,10 @@ module PactBroker
|
|
|
16
16
|
return false if PactBroker.configuration.authorize.nil?
|
|
17
17
|
!PactBroker.configuration.authorize.call(self, {})
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
def base_url
|
|
21
|
+
request.env["pactbroker.base_url"] || request.base_uri.to_s.chomp("/")
|
|
22
|
+
end
|
|
19
23
|
end
|
|
20
24
|
end
|
|
21
25
|
end
|
|
@@ -4,7 +4,6 @@ module PactBroker
|
|
|
4
4
|
module Diagnostic
|
|
5
5
|
module Resources
|
|
6
6
|
class Heartbeat < BaseResource
|
|
7
|
-
|
|
8
7
|
def allowed_methods
|
|
9
8
|
["GET"]
|
|
10
9
|
end
|
|
@@ -14,11 +13,11 @@ module PactBroker
|
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
def to_json
|
|
17
|
-
|
|
16
|
+
{
|
|
18
17
|
"ok" => true,
|
|
19
18
|
"_links" => {
|
|
20
19
|
"self" => {
|
|
21
|
-
"href" =>
|
|
20
|
+
"href" => base_url + "/diagnostic/status/heartbeat"
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
}.to_json
|
|
@@ -9,6 +9,8 @@ module PactBroker
|
|
|
9
9
|
module Domain
|
|
10
10
|
class Verification < Sequel::Model
|
|
11
11
|
using Sequel::SymbolAref
|
|
12
|
+
TO_JSON = lambda { | thing | Sequel.object_to_json(thing) }
|
|
13
|
+
FROM_JSON_WITH_SYMBOL_KEYS = lambda { | json | JSON.parse(json, symbolize_names: true) }
|
|
12
14
|
|
|
13
15
|
set_primary_key :id
|
|
14
16
|
associate(:many_to_one, :pact_version, class: "PactBroker::Pacts::PactVersion", key: :pact_version_id, primary_key: :id)
|
|
@@ -16,7 +18,8 @@ module PactBroker
|
|
|
16
18
|
associate(:many_to_one, :provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
|
|
17
19
|
associate(:many_to_one, :consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
|
|
18
20
|
associate(:one_to_many, :provider_version_tags, :class => "PactBroker::Domain::Tag", primary_key: :provider_version_id, key: :version_id)
|
|
19
|
-
plugin :serialization, :json, :test_results
|
|
21
|
+
plugin :serialization, :json, :test_results, :tag_names
|
|
22
|
+
serialize_attributes [TO_JSON, FROM_JSON_WITH_SYMBOL_KEYS], :consumer_version_selector_hashes
|
|
20
23
|
|
|
21
24
|
def before_create
|
|
22
25
|
super
|
|
@@ -115,6 +115,16 @@ module PactBroker
|
|
|
115
115
|
where(id: supported_version_query.select(:version_id))
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
+
def currently_deployed
|
|
119
|
+
deployed_version_query = PactBroker::Deployments::DeployedVersion.currently_deployed
|
|
120
|
+
where(id: deployed_version_query.select(:version_id))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def currently_supported
|
|
124
|
+
supported_version_query = PactBroker::Deployments::ReleasedVersion.currently_supported
|
|
125
|
+
where(id: supported_version_query.select(:version_id))
|
|
126
|
+
end
|
|
127
|
+
|
|
118
128
|
def where_tag(tag)
|
|
119
129
|
if tag == true
|
|
120
130
|
join(:tags, Sequel[:tags][:version_id] => Sequel[first_source_alias][:id])
|
|
@@ -129,7 +139,19 @@ module PactBroker
|
|
|
129
139
|
end
|
|
130
140
|
|
|
131
141
|
def where_branch(branch)
|
|
132
|
-
|
|
142
|
+
if branch == true
|
|
143
|
+
exclude(branch: nil)
|
|
144
|
+
else
|
|
145
|
+
where(branch: branch)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def for_main_branches
|
|
150
|
+
pacticipants_join = {
|
|
151
|
+
Sequel[:versions][:pacticipant_id] => Sequel[:pacticipants][:id],
|
|
152
|
+
Sequel[:pacticipants][:main_branch] => Sequel[:versions][:branch]
|
|
153
|
+
}
|
|
154
|
+
where(id: select(Sequel[:versions][:id]).join(:pacticipants, pacticipants_join))
|
|
133
155
|
end
|
|
134
156
|
|
|
135
157
|
def where_number(number)
|
|
@@ -161,10 +183,13 @@ module PactBroker
|
|
|
161
183
|
query = self
|
|
162
184
|
query = query.where_pacticipant_name(selector.pacticipant_name) if selector.pacticipant_name
|
|
163
185
|
query = query.currently_in_environment(selector.environment_name, selector.pacticipant_name) if selector.environment_name
|
|
186
|
+
query = query.currently_deployed if selector.respond_to?(:currently_deployed?) && selector.currently_deployed?
|
|
187
|
+
query = query.currently_supported if selector.respond_to?(:currently_supported?) && selector.currently_supported?
|
|
164
188
|
query = query.where_tag(selector.tag) if selector.tag
|
|
165
189
|
query = query.where_branch(selector.branch) if selector.branch
|
|
166
|
-
query = query.
|
|
167
|
-
query = query.
|
|
190
|
+
query = query.for_main_branches if selector.respond_to?(:main_branch) && selector.main_branch
|
|
191
|
+
query = query.where_number(selector.pacticipant_version_number) if selector.respond_to?(:pacticipant_version_number) && selector.pacticipant_version_number
|
|
192
|
+
query = query.where_age_less_than(selector.max_age) if selector.respond_to?(:max_age) && selector.max_age
|
|
168
193
|
|
|
169
194
|
if selector.latest
|
|
170
195
|
calculate_max_version_order_and_join_back_to_versions(query, selector)
|
|
@@ -232,6 +257,10 @@ module PactBroker
|
|
|
232
257
|
def latest_for_pacticipant?
|
|
233
258
|
latest_version_for_pacticipant == self
|
|
234
259
|
end
|
|
260
|
+
|
|
261
|
+
def tag_names
|
|
262
|
+
tags.collect(&:name)
|
|
263
|
+
end
|
|
235
264
|
end
|
|
236
265
|
end
|
|
237
266
|
end
|
|
@@ -87,6 +87,7 @@ en:
|
|
|
87
87
|
invalid_content_for_content_type: "The content could not be parsed as %{content_type}"
|
|
88
88
|
cannot_set_currently_deployed_true: The currentlyDeployed property cannot be set back to true. Please record a new deployment.
|
|
89
89
|
cannot_set_currently_supported_true: The currentlySupported property cannot be set back to true. Please record a new deployment.
|
|
90
|
+
invalid_limit: The limit must be 1 or greater.
|
|
90
91
|
duplicate_pacticipant: |
|
|
91
92
|
This is the first time a pact has been published for "%{new_name}".
|
|
92
93
|
The name "%{new_name}" is very similar to the following existing consumers/providers:
|
|
@@ -100,6 +100,10 @@ module PactBroker
|
|
|
100
100
|
error_messages << message("errors.validation.environment_with_name_not_found", name: options[:environment_name])
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
+
if options[:limit] && options[:limit].to_i < 1
|
|
104
|
+
error_messages << message("errors.validation.invalid_limit")
|
|
105
|
+
end
|
|
106
|
+
|
|
103
107
|
error_messages
|
|
104
108
|
end
|
|
105
109
|
# rubocop: enable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
@@ -10,7 +10,7 @@ module PactBroker
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def self.from_hash(hash)
|
|
13
|
-
new(hash.symbolize_keys.snakecase_keys.slice(:pacticipant_name, :pacticipant_version_number, :latest, :tag, :branch, :environment_name
|
|
13
|
+
new(hash.symbolize_keys.snakecase_keys.slice(:pacticipant_name, :pacticipant_version_number, :latest, :tag, :branch, :environment_name))
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def pacticipant_name
|
|
@@ -26,7 +26,7 @@ module PactBroker
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def overall_latest?
|
|
29
|
-
latest? && !tag && !
|
|
29
|
+
latest? && !tag && !branch
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def latest
|
|
@@ -69,6 +69,7 @@ module PactBroker
|
|
|
69
69
|
self[:pacticipant_version_number] = pacticipant_version_number
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
# TODO delete this once docker image uses new selector class for clean
|
|
72
73
|
def max_age= max_age
|
|
73
74
|
self[:max_age] = max_age
|
|
74
75
|
end
|
|
@@ -10,6 +10,7 @@ module PactBroker
|
|
|
10
10
|
[:wip, "w"],
|
|
11
11
|
[:consumer_version_selectors, "s"],
|
|
12
12
|
[:tag, "t"],
|
|
13
|
+
[:branch, "b"],
|
|
13
14
|
[:latest, "l"]
|
|
14
15
|
]
|
|
15
16
|
|
|
@@ -52,9 +53,11 @@ module PactBroker
|
|
|
52
53
|
"w" => true
|
|
53
54
|
}
|
|
54
55
|
else
|
|
56
|
+
# TODO support deployed and released
|
|
55
57
|
{
|
|
56
58
|
"s" => verifiable_pact.selectors.collect do | selector |
|
|
57
59
|
{
|
|
60
|
+
"b" => selector.branch,
|
|
58
61
|
"t" => selector.tag,
|
|
59
62
|
"l" => selector.latest,
|
|
60
63
|
"cv" => selector.consumer_version.id
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require "sequel"
|
|
2
2
|
require "pact_broker/repositories/helpers"
|
|
3
3
|
require "pact_broker/verifications/latest_verification_for_pact_version"
|
|
4
|
+
require "pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version"
|
|
4
5
|
|
|
5
6
|
module PactBroker
|
|
6
7
|
module Pacts
|
|
@@ -17,7 +18,7 @@ module PactBroker
|
|
|
17
18
|
one_to_one(:latest_verification,
|
|
18
19
|
class: "PactBroker::Domain::Verification",
|
|
19
20
|
read_only: true,
|
|
20
|
-
dataset: lambda { PactBroker::Domain::Verification.where(id: PactBroker::
|
|
21
|
+
dataset: lambda { PactBroker::Domain::Verification.where(id: PactBroker::Verifications::LatestVerificationIdForPactVersionAndProviderVersion.select(Sequel.function(:max, :verification_id)).where(pact_version_id: id)) },
|
|
21
22
|
key: :pact_version_id, primary_key: :id,
|
|
22
23
|
eager_block: lambda { | ds | ds.latest_by_pact_version }
|
|
23
24
|
)
|
|
@@ -183,13 +183,7 @@ module PactBroker
|
|
|
183
183
|
end
|
|
184
184
|
|
|
185
185
|
def merge_selected_pacts(selected_pacts)
|
|
186
|
-
selected_pacts
|
|
187
|
-
.group_by{ |p| [p.consumer_name, p.pact_version_sha] }
|
|
188
|
-
.values
|
|
189
|
-
.collect do | selected_pacts_for_pact_version_id |
|
|
190
|
-
SelectedPact.merge(selected_pacts_for_pact_version_id)
|
|
191
|
-
end
|
|
192
|
-
.sort
|
|
186
|
+
SelectedPact.merge_by_pact_version_sha(selected_pacts)
|
|
193
187
|
end
|
|
194
188
|
|
|
195
189
|
# TODO ? find the WIP pacts by consumer branch
|
|
@@ -321,6 +321,10 @@ module PactBroker
|
|
|
321
321
|
end
|
|
322
322
|
end
|
|
323
323
|
|
|
324
|
+
def find_pact_version(consumer, provider, pact_version_sha)
|
|
325
|
+
PactBroker::Pacts::PactVersion.where(consumer_id: consumer.id, provider_id: provider.id, sha: pact_version_sha).single_record
|
|
326
|
+
end
|
|
327
|
+
|
|
324
328
|
private
|
|
325
329
|
|
|
326
330
|
def find_previous_distinct_pact_by_sha pact
|
|
@@ -11,6 +11,26 @@ module PactBroker
|
|
|
11
11
|
@selectors = selectors
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
def self.merge_by_pact_version_sha(selected_pacts)
|
|
15
|
+
selected_pacts
|
|
16
|
+
.group_by{ |p| [p.consumer_name, p.pact_version_sha] }
|
|
17
|
+
.values
|
|
18
|
+
.collect do | selected_pacts_for_pact_version_id |
|
|
19
|
+
SelectedPact.merge(selected_pacts_for_pact_version_id)
|
|
20
|
+
end
|
|
21
|
+
.sort
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.merge_by_consumer_version_number(selected_pacts)
|
|
25
|
+
selected_pacts
|
|
26
|
+
.group_by{ |p| [p.consumer_name, p.consumer_version_number] }
|
|
27
|
+
.values
|
|
28
|
+
.collect do | selected_pacts_for_consumer_version_number |
|
|
29
|
+
SelectedPact.merge(selected_pacts_for_consumer_version_number)
|
|
30
|
+
end
|
|
31
|
+
.sort
|
|
32
|
+
end
|
|
33
|
+
|
|
14
34
|
def self.merge(selected_pacts)
|
|
15
35
|
latest_selected_pact = selected_pacts.sort_by(&:consumer_version_order).last
|
|
16
36
|
selectors = selected_pacts.collect(&:selectors).reduce(&:+).sort
|
|
@@ -6,10 +6,12 @@ require "pact_broker/pacts/verifiable_pact"
|
|
|
6
6
|
require "pact_broker/pacts/squash_pacts_for_verification"
|
|
7
7
|
require "pact_broker/events/publisher"
|
|
8
8
|
require "pact_broker/messages"
|
|
9
|
+
require "pact_broker/hash_refinements"
|
|
9
10
|
|
|
10
11
|
module PactBroker
|
|
11
12
|
module Pacts
|
|
12
13
|
module Service
|
|
14
|
+
using PactBroker::HashRefinements
|
|
13
15
|
|
|
14
16
|
extend self
|
|
15
17
|
extend PactBroker::Events::Publisher
|
|
@@ -133,6 +135,25 @@ module PactBroker
|
|
|
133
135
|
explicitly_specified_verifiable_pacts + verifiable_wip_pacts
|
|
134
136
|
end
|
|
135
137
|
|
|
138
|
+
def find_for_verification_publication(pact_params, consumer_version_selector_hashes)
|
|
139
|
+
if consumer_version_selector_hashes&.any?
|
|
140
|
+
selected_pacts = consumer_version_selector_hashes.collect do | consumer_version_selector_hash |
|
|
141
|
+
find_pact_params = {
|
|
142
|
+
consumer_name: pact_params.consumer_name,
|
|
143
|
+
provider_name: pact_params.provider_name,
|
|
144
|
+
pact_version_sha: pact_params.pact_version_sha,
|
|
145
|
+
consumer_version_number: consumer_version_selector_hash[:consumer_version_number]
|
|
146
|
+
}
|
|
147
|
+
pact = find_pact(find_pact_params)
|
|
148
|
+
resolved_selector = Selector.new(consumer_version_selector_hash.without(:consumer_version_number)).resolve(pact.consumer_version)
|
|
149
|
+
SelectedPact.new(pact, Selectors.new(resolved_selector))
|
|
150
|
+
end
|
|
151
|
+
SelectedPact.merge_by_consumer_version_number(selected_pacts)
|
|
152
|
+
else
|
|
153
|
+
[SelectedPact.new(find_pact(pact_params), Selectors.new)]
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
136
157
|
# Overwriting an existing pact with the same consumer/provider/consumer version number
|
|
137
158
|
def update_pact params, existing_pact
|
|
138
159
|
logger.info "Updating existing pact publication with params #{params.reject{ |k, _v| k == :json_content}}"
|
|
@@ -120,7 +120,7 @@ module PactBroker
|
|
|
120
120
|
self
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
-
def get_pacts_for_verification(provider: last_provider_name, provider_version_tag: nil, provider_version_branch: nil, consumer_version_selectors
|
|
123
|
+
def get_pacts_for_verification(provider: last_provider_name, provider_version_tag: nil, provider_version_branch: nil, consumer_version_selectors: [], enable_pending: false, include_wip_pacts_since: nil)
|
|
124
124
|
@last_provider_name = provider
|
|
125
125
|
@last_provider_version_tag = provider_version_tag
|
|
126
126
|
@last_provder_version_branch = provider_version_branch
|
|
@@ -149,7 +149,8 @@ module PactBroker
|
|
|
149
149
|
puts({
|
|
150
150
|
"url" => pact["_links"]["self"]["href"],
|
|
151
151
|
"wip" => pact["verificationProperties"]["wip"],
|
|
152
|
-
"pending" => pact["verificationProperties"]["pending"]
|
|
152
|
+
"pending" => pact["verificationProperties"]["pending"],
|
|
153
|
+
"why" => pact["verificationProperties"]["notices"].select { | n | n["when"] == "before_verification" }.collect{ | n | n["text"] }
|
|
153
154
|
}.to_yaml)
|
|
154
155
|
end
|
|
155
156
|
end
|
|
@@ -166,7 +167,7 @@ module PactBroker
|
|
|
166
167
|
self
|
|
167
168
|
end
|
|
168
169
|
|
|
169
|
-
def verify_pact(index: 0, success
|
|
170
|
+
def verify_pact(index: 0, success: true, provider: last_provider_name, provider_version_tag: last_provider_version_tag, provider_version_branch: last_provider_version_branch, provider_version: )
|
|
170
171
|
@last_provider_name = provider
|
|
171
172
|
@last_provider_version_tag = provider_version_tag
|
|
172
173
|
@last_provider_version_branch = provider_version_branch
|
|
@@ -373,7 +373,8 @@ module PactBroker
|
|
|
373
373
|
parameters = default_parameters.merge(parameters)
|
|
374
374
|
parameters.delete(:provider_version)
|
|
375
375
|
verification = PactBroker::Domain::Verification.new(parameters)
|
|
376
|
-
|
|
376
|
+
pact_version = PactBroker::Pacts::Repository.new.find_pact_version(@consumer, @provider, pact.pact_version_sha)
|
|
377
|
+
@verification = PactBroker::Verifications::Repository.new.create(verification, provider_version_number, pact_version)
|
|
377
378
|
@provider_version = PactBroker::Domain::Version.where(pacticipant_id: @provider.id, number: provider_version_number).single_record
|
|
378
379
|
@provider_version.update(branch: branch) if branch
|
|
379
380
|
|
|
@@ -19,14 +19,13 @@ module PactBroker
|
|
|
19
19
|
Sequence.next_val
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def create verification, provider_version_number,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
version = version_repository.find_by_pacticipant_id_and_number_or_create(provider.id, provider_version_number)
|
|
26
|
-
verification.pact_version_id = pact_version_id_for(pact)
|
|
22
|
+
def create verification, provider_version_number, pact_version
|
|
23
|
+
version = version_repository.find_by_pacticipant_id_and_number_or_create(pact_version.provider_id, provider_version_number)
|
|
24
|
+
verification.pact_version_id = pact_version.id
|
|
27
25
|
verification.provider_version = version
|
|
28
|
-
verification.provider_id =
|
|
29
|
-
verification.consumer_id =
|
|
26
|
+
verification.provider_id = pact_version.provider_id
|
|
27
|
+
verification.consumer_id = pact_version.consumer_id
|
|
28
|
+
verification.tag_names = version.tag_names # TODO pass this in from contracts service
|
|
30
29
|
verification.save
|
|
31
30
|
update_latest_verification_id(verification)
|
|
32
31
|
verification
|
|
@@ -150,10 +149,6 @@ module PactBroker
|
|
|
150
149
|
provider = pacticipant_repository.find_by_name!(options.fetch(:and))
|
|
151
150
|
PactBroker::Domain::Verification.where(provider: provider, consumer: consumer).delete
|
|
152
151
|
end
|
|
153
|
-
|
|
154
|
-
def pact_version_id_for pact
|
|
155
|
-
PactBroker::Pacts::PactPublication.select(:pact_version_id).where(id: pact.id)
|
|
156
|
-
end
|
|
157
152
|
end
|
|
158
153
|
end
|
|
159
154
|
end
|
|
@@ -27,16 +27,21 @@ module PactBroker
|
|
|
27
27
|
verification_repository.next_number
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
# verified_pacts is an array of SelectedPact objects
|
|
31
|
+
def create next_verification_number, params, verified_pacts, event_context
|
|
32
|
+
first_verified_pact = verified_pacts.first
|
|
33
|
+
logger.info "Creating verification #{next_verification_number} for pact_version_sha=#{first_verified_pact.pact_version_sha}", payload: params.reject{ |k,_| k == "testResults"}
|
|
32
34
|
verification = PactBroker::Domain::Verification.new
|
|
33
35
|
provider_version_number = params.fetch("providerApplicationVersion")
|
|
34
36
|
PactBroker::Api::Decorators::VerificationDecorator.new(verification).from_hash(params)
|
|
35
37
|
verification.wip = params.fetch("wip")
|
|
36
38
|
verification.number = next_verification_number
|
|
37
|
-
verification =
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
verification.consumer_version_selector_hashes = event_context[:consumer_version_selectors]
|
|
40
|
+
pact_version = pact_repository.find_pact_version(first_verified_pact.consumer, first_verified_pact.provider, first_verified_pact.pact_version_sha)
|
|
41
|
+
verification = verification_repository.create(verification, provider_version_number, pact_version)
|
|
42
|
+
# TODO set the latest_verification_id on each PactPublication
|
|
43
|
+
# TODO broadcast the verified_pacts for the webhooks
|
|
44
|
+
broadcast_events(verification, first_verified_pact.pact, event_context)
|
|
40
45
|
|
|
41
46
|
verification
|
|
42
47
|
end
|
data/lib/pact_broker/version.rb
CHANGED
|
@@ -52,7 +52,7 @@ module PactBroker
|
|
|
52
52
|
PACT_URL => pact ? PactBroker::Api::PactBrokerUrls.pact_version_url_with_webhook_metadata(pact, base_url) : "",
|
|
53
53
|
VERIFICATION_RESULT_URL => verification_url,
|
|
54
54
|
CONSUMER_VERSION_NUMBER => consumer_version_number,
|
|
55
|
-
PROVIDER_VERSION_NUMBER =>
|
|
55
|
+
PROVIDER_VERSION_NUMBER => provider_version_number,
|
|
56
56
|
PROVIDER_VERSION_TAGS => provider_version_tags,
|
|
57
57
|
PROVIDER_VERSION_BRANCH => provider_version_branch,
|
|
58
58
|
CONSUMER_VERSION_TAGS => consumer_version_tags,
|
|
@@ -146,6 +146,14 @@ module PactBroker
|
|
|
146
146
|
end
|
|
147
147
|
end
|
|
148
148
|
|
|
149
|
+
def provider_version_number
|
|
150
|
+
if webhook_context[:provider_version_number]
|
|
151
|
+
webhook_context[:provider_version_number]
|
|
152
|
+
else
|
|
153
|
+
verification ? verification.provider_version_number : ""
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
149
157
|
def provider_version_branch
|
|
150
158
|
if webhook_context[:provider_version_branch]
|
|
151
159
|
webhook_context[:provider_version_branch]
|
|
@@ -62,11 +62,14 @@ module PactBroker
|
|
|
62
62
|
|
|
63
63
|
before do
|
|
64
64
|
allow(Pacts::Service).to receive(:find_pact).and_return(pact)
|
|
65
|
+
allow(Pacts::Service).to receive(:find_for_verification_publication).and_return(verified_pacts)
|
|
65
66
|
allow(PactBroker::Verifications::Service).to receive(:next_number).and_return(next_verification_number)
|
|
66
67
|
allow(PactBroker::Api::Decorators::VerificationDecorator).to receive(:new).and_return(decorator)
|
|
67
68
|
allow(PactBroker.configuration).to receive(:show_webhook_response?).and_return("some-boolean")
|
|
68
69
|
end
|
|
69
70
|
|
|
71
|
+
let(:verified_pacts) { double("verified pacts") }
|
|
72
|
+
|
|
70
73
|
it "parses the webhook metadata" do
|
|
71
74
|
expect(PactBrokerUrls).to receive(:decode_pact_metadata).with("abcd")
|
|
72
75
|
subject
|
|
@@ -84,7 +87,7 @@ module PactBroker
|
|
|
84
87
|
expect(PactBroker::Verifications::Service).to receive(:create).with(
|
|
85
88
|
next_verification_number,
|
|
86
89
|
hash_including("some" => "params", "wip" => false),
|
|
87
|
-
|
|
90
|
+
verified_pacts,
|
|
88
91
|
parsed_metadata
|
|
89
92
|
)
|
|
90
93
|
subject
|
|
@@ -14,8 +14,8 @@ module PactBroker
|
|
|
14
14
|
let(:db) { PactBroker::DB.connection }
|
|
15
15
|
|
|
16
16
|
subject { Clean.call(PactBroker::DB.connection, options) }
|
|
17
|
-
let(:latest_dev_selector) {
|
|
18
|
-
let(:all_prod_selector) {
|
|
17
|
+
let(:latest_dev_selector) { { tag: "dev", latest: true } }
|
|
18
|
+
let(:all_prod_selector) { { tag: "prod" } }
|
|
19
19
|
|
|
20
20
|
describe ".call"do
|
|
21
21
|
context "when there are specified versions to keep" do
|
|
@@ -5,22 +5,22 @@ module PactBroker
|
|
|
5
5
|
module Diagnostic
|
|
6
6
|
module Resources
|
|
7
7
|
describe Dependencies do
|
|
8
|
-
|
|
9
8
|
describe "GET /diagnostic/status/dependencies" do
|
|
10
|
-
|
|
11
9
|
include Rack::Test::Methods
|
|
12
10
|
|
|
11
|
+
let(:rack_env) { { "pactbroker.base_url" => "http://pact-broker"} }
|
|
13
12
|
let(:app) { PactBroker::Diagnostic::App.new }
|
|
14
13
|
let(:parsed_response_body) { JSON.parse(subject.body) }
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
|
|
16
|
+
subject { get("/diagnostic/status/dependencies", nil, rack_env) }
|
|
17
17
|
|
|
18
18
|
it "returns application/hal+json" do
|
|
19
19
|
expect(subject.headers["Content-Type"]).to eq "application/hal+json"
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "returns a link to itself" do
|
|
23
|
-
expect(parsed_response_body["_links"]["self"]["href"]).to eq "http://
|
|
23
|
+
expect(parsed_response_body["_links"]["self"]["href"]).to eq "http://pact-broker/diagnostic/status/dependencies"
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
context "when we can connect to the database" do
|
|
@@ -6,16 +6,15 @@ module PactBroker
|
|
|
6
6
|
module Diagnostic
|
|
7
7
|
module Resources
|
|
8
8
|
describe Heartbeat do
|
|
9
|
-
|
|
10
9
|
include Rack::Test::Methods
|
|
11
10
|
|
|
12
11
|
let(:app) { PactBroker::Diagnostic::App.new }
|
|
13
12
|
|
|
14
13
|
describe "GET /diagnostic/status/heartbeat" do
|
|
15
|
-
|
|
14
|
+
let(:rack_env) { { "pactbroker.base_url" => "http://pact-broker"} }
|
|
16
15
|
let(:parsed_response_body) { JSON.parse(subject.body) }
|
|
17
16
|
|
|
18
|
-
subject { get
|
|
17
|
+
subject { get("/diagnostic/status/heartbeat", nil, rack_env) }
|
|
19
18
|
|
|
20
19
|
it "returns a 200" do
|
|
21
20
|
expect(subject.status).to eq 200
|
|
@@ -26,7 +25,7 @@ module PactBroker
|
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
it "returns a link to itself" do
|
|
29
|
-
expect(parsed_response_body["_links"]["self"]["href"]).to eq "http://
|
|
28
|
+
expect(parsed_response_body["_links"]["self"]["href"]).to eq "http://pact-broker/diagnostic/status/heartbeat"
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "pact_broker/domain/version"
|
|
2
|
+
require "pact_broker/db/clean/selector"
|
|
2
3
|
|
|
3
4
|
module PactBroker
|
|
4
5
|
module Domain
|
|
@@ -131,7 +132,7 @@ module PactBroker
|
|
|
131
132
|
.create_consumer_version("3", tag_names: %w{master})
|
|
132
133
|
end
|
|
133
134
|
|
|
134
|
-
let(:selector) { PactBroker::
|
|
135
|
+
let(:selector) { PactBroker::DB::Clean::Selector.new(tag: "master", max_age: max_age) }
|
|
135
136
|
|
|
136
137
|
let(:max_age) { 3 }
|
|
137
138
|
let(:four_days_ago) { Date.today - 4 }
|
|
@@ -141,6 +142,76 @@ module PactBroker
|
|
|
141
142
|
end
|
|
142
143
|
end
|
|
143
144
|
|
|
145
|
+
context "when selecting the latest version for each branch" do
|
|
146
|
+
before do
|
|
147
|
+
td.create_consumer("Foo")
|
|
148
|
+
.create_consumer_version("1", branch: "main")
|
|
149
|
+
.create_consumer_version("2", branch: "main")
|
|
150
|
+
.create_consumer("Bar")
|
|
151
|
+
.create_consumer_version("3", branch: "main")
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
let(:selector) { PactBroker::DB::Clean::Selector.new(branch: true, latest: true) }
|
|
155
|
+
|
|
156
|
+
it "selects the consumer versions that are the latest for their branches" do
|
|
157
|
+
expect(version_numbers).to eq %w{2 3}
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context "when selecting all versions with a branch" do
|
|
162
|
+
before do
|
|
163
|
+
td.create_consumer("Foo")
|
|
164
|
+
.create_consumer_version("1", branch: "main")
|
|
165
|
+
.create_consumer_version("2")
|
|
166
|
+
.create_consumer("Bar")
|
|
167
|
+
.create_consumer_version("3", branch: "main")
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
let(:selector) { PactBroker::DB::Clean::Selector.new(branch: true, latest: true) }
|
|
171
|
+
|
|
172
|
+
it "selects the consumer versions that are the latest for their branches" do
|
|
173
|
+
expect(version_numbers).to eq %w{1 3}
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
context "when selecting the latest versions from the main branches" do
|
|
178
|
+
before do
|
|
179
|
+
td.create_consumer("Foo", main_branch: "main")
|
|
180
|
+
.create_consumer_version("1", branch: "main")
|
|
181
|
+
.create_consumer_version("2", branch: "main")
|
|
182
|
+
.create_consumer_version("3", branch: "not-main")
|
|
183
|
+
.create_consumer("Bar", main_branch: "develop")
|
|
184
|
+
.create_consumer_version("4", branch: "develop")
|
|
185
|
+
.create_consumer_version("5", branch: "develop")
|
|
186
|
+
.create_consumer_version("6", branch: "main")
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
let(:selector) { PactBroker::DB::Clean::Selector.new(main_branch: true, latest: true) }
|
|
190
|
+
|
|
191
|
+
it "selects the consumer versions that are the latest for their branches" do
|
|
192
|
+
expect(version_numbers).to eq %w{2 5}
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
context "when selecting all versions from the main branches" do
|
|
197
|
+
before do
|
|
198
|
+
td.create_consumer("Foo", main_branch: "main")
|
|
199
|
+
.create_consumer_version("1", branch: "main")
|
|
200
|
+
.create_consumer_version("2", branch: "main")
|
|
201
|
+
.create_consumer_version("3", branch: "not-main")
|
|
202
|
+
.create_consumer("Bar", main_branch: "develop")
|
|
203
|
+
.create_consumer_version("4", branch: "develop")
|
|
204
|
+
.create_consumer_version("5", branch: "develop")
|
|
205
|
+
.create_consumer_version("6", branch: "main")
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
let(:selector) { PactBroker::DB::Clean::Selector.new(main_branch: true) }
|
|
209
|
+
|
|
210
|
+
it "selects the consumer versions that are the latest for their branches" do
|
|
211
|
+
expect(version_numbers).to eq %w{1 2 4 5}
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
144
215
|
context "when selecting all versions of a pacticipant currently deployed to an environment" do
|
|
145
216
|
let(:selector) { PactBroker::Matrix::UnresolvedSelector.new(environment_name: "prod", pacticipant_name: "Foo") }
|
|
146
217
|
|
|
@@ -194,6 +265,60 @@ module PactBroker
|
|
|
194
265
|
end
|
|
195
266
|
end
|
|
196
267
|
|
|
268
|
+
context "when selecting all currently deployed versions" do
|
|
269
|
+
let(:selector) { PactBroker::DB::Clean::Selector.new(deployed: true) }
|
|
270
|
+
|
|
271
|
+
before do
|
|
272
|
+
td.create_environment("test")
|
|
273
|
+
.create_consumer("Foo")
|
|
274
|
+
.create_consumer_version("1")
|
|
275
|
+
.create_deployed_version_for_consumer_version(target: "1")
|
|
276
|
+
.create_consumer_version("2")
|
|
277
|
+
.create_environment("prod")
|
|
278
|
+
.create_deployed_version_for_consumer_version(target: "2")
|
|
279
|
+
.create_consumer_version("3")
|
|
280
|
+
.create_consumer_version("5")
|
|
281
|
+
.create_consumer("Bar")
|
|
282
|
+
.create_consumer_version("10")
|
|
283
|
+
.create_deployed_version_for_consumer_version(target: "3")
|
|
284
|
+
.create_consumer_version("11")
|
|
285
|
+
.create_deployed_version_for_consumer_version(currently_deployed: false)
|
|
286
|
+
.create_consumer_version("12")
|
|
287
|
+
.create_released_version_for_consumer_version
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it "returns the versions that are currently deployed" do
|
|
291
|
+
expect(version_numbers).to eq %w{1 2 10}
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
context "when selecting all currently released+supported versions" do
|
|
296
|
+
let(:selector) { PactBroker::DB::Clean::Selector.new(released: true) }
|
|
297
|
+
|
|
298
|
+
before do
|
|
299
|
+
td.create_environment("test")
|
|
300
|
+
.create_consumer("Foo")
|
|
301
|
+
.create_consumer_version("1")
|
|
302
|
+
.create_released_version_for_consumer_version
|
|
303
|
+
.create_consumer_version("2")
|
|
304
|
+
.create_environment("prod")
|
|
305
|
+
.create_released_version_for_consumer_version
|
|
306
|
+
.create_consumer_version("3")
|
|
307
|
+
.create_consumer_version("5")
|
|
308
|
+
.create_consumer("Bar")
|
|
309
|
+
.create_consumer_version("10")
|
|
310
|
+
.create_released_version_for_consumer_version
|
|
311
|
+
.create_consumer_version("11")
|
|
312
|
+
.create_released_version_for_consumer_version(currently_supported: false)
|
|
313
|
+
.create_consumer_version("12")
|
|
314
|
+
.create_deployed_version_for_consumer_version
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it "returns the versions that are currently released+supported" do
|
|
318
|
+
expect(version_numbers).to eq %w{1 2 10}
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
197
322
|
context "selecting versions for a branch" do
|
|
198
323
|
before do
|
|
199
324
|
td.create_consumer("Foo")
|
|
@@ -12,7 +12,7 @@ module PactBroker
|
|
|
12
12
|
|
|
13
13
|
subject { Service.validate_selectors(selectors, options) }
|
|
14
14
|
|
|
15
|
-
let(:options) { {} }
|
|
15
|
+
let(:options) { { limit: "1" } }
|
|
16
16
|
|
|
17
17
|
context "when there are no selectors" do
|
|
18
18
|
let(:selectors) { [] }
|
|
@@ -145,6 +145,15 @@ module PactBroker
|
|
|
145
145
|
expect(subject.last).to include "Please specify the pacticipant name to ignore"
|
|
146
146
|
end
|
|
147
147
|
end
|
|
148
|
+
|
|
149
|
+
context "with an invalid limit" do
|
|
150
|
+
let(:options) { { limit: "limit" } }
|
|
151
|
+
let(:selectors) { [] }
|
|
152
|
+
|
|
153
|
+
it "returns an error message" do
|
|
154
|
+
expect(subject.last).to include "The limit"
|
|
155
|
+
end
|
|
156
|
+
end
|
|
148
157
|
end
|
|
149
158
|
|
|
150
159
|
describe "find_for_consumer_and_provider_with_tags integration test" do
|
|
@@ -289,6 +289,67 @@ module PactBroker
|
|
|
289
289
|
end
|
|
290
290
|
end
|
|
291
291
|
end
|
|
292
|
+
|
|
293
|
+
describe "find_for_verification_publication integration test" do
|
|
294
|
+
before do
|
|
295
|
+
json_content = { interactions: [] }.to_json
|
|
296
|
+
td.create_pact_with_hierarchy("Foo", "1", "Bar", json_content)
|
|
297
|
+
.create_pact_with_hierarchy("Foo", "2", "Bar", json_content)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
let(:consumer_version_selector_hashes) do
|
|
301
|
+
[
|
|
302
|
+
{ tag: "foo", latest: true, consumer_version_number: "1"},
|
|
303
|
+
{ tag: "bar", latest: true, consumer_version_number: "1"},
|
|
304
|
+
{ branch: "beep", latest: true, consumer_version_number: "2"}
|
|
305
|
+
]
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
let(:pact_params) do
|
|
309
|
+
PactParams.new(
|
|
310
|
+
consumer_name: "Foo",
|
|
311
|
+
provider_name: "Bar",
|
|
312
|
+
pact_version_sha: td.and_return(:pact).pact_version_sha
|
|
313
|
+
)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
subject { Service.find_for_verification_publication(pact_params, consumer_version_selector_hashes) }
|
|
317
|
+
|
|
318
|
+
it "deduplicates the pacts by consumer version number" do
|
|
319
|
+
expect(subject.size).to eq 2
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "sets the selectors" do
|
|
323
|
+
expect(subject.first.selectors.size).to eq 2
|
|
324
|
+
expect(subject.first.selectors.first).to have_attributes(latest: true, tag: "bar")
|
|
325
|
+
expect(subject.first.selectors.first.consumer_version).to have_attributes(number: "1")
|
|
326
|
+
|
|
327
|
+
expect(subject.first.selectors.last).to have_attributes(latest: true, tag: "foo")
|
|
328
|
+
expect(subject.first.selectors.last.consumer_version).to have_attributes(number: "1")
|
|
329
|
+
|
|
330
|
+
expect(subject.last.selectors.size).to eq 1
|
|
331
|
+
expect(subject.last.selectors.first).to have_attributes(latest: true, branch: "beep")
|
|
332
|
+
expect(subject.last.selectors.last.consumer_version).to have_attributes(number: "2")
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
context "when there are no consumer version selectors" do
|
|
336
|
+
let(:consumer_version_selector_hashes) { nil }
|
|
337
|
+
|
|
338
|
+
it "returns the latest pact for the sha" do
|
|
339
|
+
expect(subject.size).to eq 1
|
|
340
|
+
expect(subject.first.consumer_version_number).to eq "2"
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
context "when the consumer version selectors is empty" do
|
|
345
|
+
let(:consumer_version_selector_hashes) { [] }
|
|
346
|
+
|
|
347
|
+
it "returns the latest pact for the sha" do
|
|
348
|
+
expect(subject.size).to eq 1
|
|
349
|
+
expect(subject.first.consumer_version_number).to eq "2"
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
end
|
|
292
353
|
end
|
|
293
354
|
end
|
|
294
355
|
end
|
|
@@ -4,16 +4,23 @@ module PactBroker
|
|
|
4
4
|
module Verifications
|
|
5
5
|
describe Repository do
|
|
6
6
|
describe "#create" do
|
|
7
|
+
before do
|
|
8
|
+
td.create_pact_with_hierarchy("Foo", "1", "Bar").and_return(:pact)
|
|
9
|
+
end
|
|
10
|
+
|
|
7
11
|
let(:verification) do
|
|
8
|
-
PactBroker::Domain::Verification.new(
|
|
12
|
+
PactBroker::Domain::Verification.new(
|
|
13
|
+
success: true,
|
|
14
|
+
consumer_version_selector_hashes: [{ foo: "bar" }]
|
|
15
|
+
)
|
|
9
16
|
end
|
|
10
17
|
|
|
11
18
|
let(:provider_version_number) { "2" }
|
|
12
|
-
let(:
|
|
13
|
-
|
|
19
|
+
let(:pact_version) do
|
|
20
|
+
PactBroker::Pacts::PactVersion.first
|
|
14
21
|
end
|
|
15
22
|
|
|
16
|
-
subject { Repository.new.create
|
|
23
|
+
subject { Repository.new.create(verification, provider_version_number, pact_version) }
|
|
17
24
|
|
|
18
25
|
it "creates a LatestVerificationIdForPactVersionAndProviderVersion" do
|
|
19
26
|
expect { subject }.to change { LatestVerificationIdForPactVersionAndProviderVersion.count }.by(1)
|
|
@@ -22,27 +29,39 @@ module PactBroker
|
|
|
22
29
|
it "sets the created_at of the LatestVerificationIdForPactVersionAndProviderVersion to the same as the verification" do
|
|
23
30
|
expect(subject.created_at).to eq LatestVerificationIdForPactVersionAndProviderVersion.first.created_at
|
|
24
31
|
end
|
|
32
|
+
|
|
33
|
+
context "when the provider version already exists" do
|
|
34
|
+
before do
|
|
35
|
+
td.create_provider_version(provider_version_number, tag_names: ["foo", "bar"], branch: "main")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "sets the tag names" do
|
|
39
|
+
expect(subject.reload.tag_names).to eq ["foo", "bar"]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "saves the consumer_version_selector_hashes" do
|
|
43
|
+
expect(subject.reload.consumer_version_selector_hashes).to eq [{ foo: "bar" }]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
25
46
|
end
|
|
26
47
|
|
|
27
48
|
describe "#find" do
|
|
28
49
|
let!(:pact) do
|
|
29
|
-
|
|
30
|
-
pact =
|
|
50
|
+
|
|
51
|
+
pact = td
|
|
31
52
|
.create_provider("Provider1")
|
|
32
53
|
.create_consumer("Consumer1")
|
|
33
54
|
.create_consumer_version("1.0.0")
|
|
34
55
|
.create_pact
|
|
35
56
|
.and_return(:pact)
|
|
36
57
|
|
|
37
|
-
|
|
38
|
-
.create_verification(number: 1)
|
|
58
|
+
td.create_verification(number: 1)
|
|
39
59
|
.create_verification(number: 2, provider_version: "3.7.4")
|
|
40
60
|
.create_consumer_version("1.2.3")
|
|
41
61
|
.create_pact
|
|
42
62
|
.create_verification(number: 1)
|
|
43
63
|
|
|
44
|
-
|
|
45
|
-
.create_provider("Provider3")
|
|
64
|
+
td.create_provider("Provider3")
|
|
46
65
|
.create_consumer("Consumer2")
|
|
47
66
|
.create_consumer_version("1.2.3")
|
|
48
67
|
.create_pact
|
|
@@ -62,8 +81,7 @@ module PactBroker
|
|
|
62
81
|
|
|
63
82
|
describe "#find_latest_verifications_for_consumer_version" do
|
|
64
83
|
before do
|
|
65
|
-
|
|
66
|
-
.create_provider("Provider1")
|
|
84
|
+
td.create_provider("Provider1")
|
|
67
85
|
.create_consumer("Consumer1")
|
|
68
86
|
.create_consumer_version("1.0.0")
|
|
69
87
|
.create_pact
|
|
@@ -76,8 +94,7 @@ module PactBroker
|
|
|
76
94
|
.create_pact
|
|
77
95
|
.create_verification(number: 1, provider_version: "6.5.4")
|
|
78
96
|
|
|
79
|
-
|
|
80
|
-
.create_provider("Provider3")
|
|
97
|
+
td.create_provider("Provider3")
|
|
81
98
|
.create_consumer("Consumer2")
|
|
82
99
|
.create_consumer_version("1.2.3")
|
|
83
100
|
.create_pact
|
|
@@ -94,8 +111,7 @@ module PactBroker
|
|
|
94
111
|
|
|
95
112
|
describe "#search_for_latest" do
|
|
96
113
|
before do
|
|
97
|
-
|
|
98
|
-
.create_pact_with_hierarchy("Foo", "1", "Bar")
|
|
114
|
+
td.create_pact_with_hierarchy("Foo", "1", "Bar")
|
|
99
115
|
.create_verification(provider_version: "2")
|
|
100
116
|
.create_verification(provider_version: "3", number: 2)
|
|
101
117
|
.create_provider("Wiffle")
|
|
@@ -131,8 +147,7 @@ module PactBroker
|
|
|
131
147
|
describe "#find_latest_verification_for" do
|
|
132
148
|
context "when there is a revision" do
|
|
133
149
|
before do
|
|
134
|
-
|
|
135
|
-
.create_provider("Provider1")
|
|
150
|
+
td.create_provider("Provider1")
|
|
136
151
|
.create_consumer("Consumer1")
|
|
137
152
|
.create_consumer_version("1.2.3")
|
|
138
153
|
.create_pact
|
|
@@ -151,8 +166,7 @@ module PactBroker
|
|
|
151
166
|
context "when no tag is specified" do
|
|
152
167
|
before do
|
|
153
168
|
PactBroker.configuration.order_versions_by_date = false
|
|
154
|
-
|
|
155
|
-
.create_provider("Provider1")
|
|
169
|
+
td.create_provider("Provider1")
|
|
156
170
|
.create_consumer("Consumer1")
|
|
157
171
|
.create_consumer_version("1.2.3")
|
|
158
172
|
.create_pact
|
|
@@ -177,8 +191,7 @@ module PactBroker
|
|
|
177
191
|
|
|
178
192
|
context "when a tag is specified" do
|
|
179
193
|
before do
|
|
180
|
-
|
|
181
|
-
.create_provider("Provider1")
|
|
194
|
+
td.create_provider("Provider1")
|
|
182
195
|
.create_consumer("Consumer1")
|
|
183
196
|
.create_consumer_version("1.0.0")
|
|
184
197
|
.create_consumer_version_tag("prod")
|
|
@@ -216,8 +229,7 @@ module PactBroker
|
|
|
216
229
|
|
|
217
230
|
context "when the latest untagged verification is required" do
|
|
218
231
|
before do
|
|
219
|
-
|
|
220
|
-
.create_provider("Provider1")
|
|
232
|
+
td.create_provider("Provider1")
|
|
221
233
|
.create_consumer("Consumer1")
|
|
222
234
|
.create_consumer_version("1.0.0")
|
|
223
235
|
.create_pact
|
|
@@ -249,8 +261,7 @@ module PactBroker
|
|
|
249
261
|
describe "find_latest_verification_for_tags" do
|
|
250
262
|
context "with no revisions" do
|
|
251
263
|
before do
|
|
252
|
-
|
|
253
|
-
.create_pact_with_hierarchy("Foo", "1", "Bar")
|
|
264
|
+
td.create_pact_with_hierarchy("Foo", "1", "Bar")
|
|
254
265
|
.create_consumer_version_tag("feat-x")
|
|
255
266
|
.create_verification(provider_version: "5")
|
|
256
267
|
.use_provider_version("5")
|
|
@@ -276,8 +287,7 @@ module PactBroker
|
|
|
276
287
|
let(:content_2) { { content: 2 }.to_json }
|
|
277
288
|
|
|
278
289
|
before do
|
|
279
|
-
|
|
280
|
-
.create_pact_with_hierarchy("Foo", "1", "Bar", content_1)
|
|
290
|
+
td.create_pact_with_hierarchy("Foo", "1", "Bar", content_1)
|
|
281
291
|
.create_consumer_version_tag("develop")
|
|
282
292
|
.create_verification(provider_version: "5", number: 1, tag_name: "develop", comment: "not this because pact revised")
|
|
283
293
|
.create_verification(provider_version: "6", number: 2, tag_name: "develop", comment: "not this because pact revised")
|
|
@@ -319,8 +329,7 @@ module PactBroker
|
|
|
319
329
|
|
|
320
330
|
describe "delete_by_provider_version_id" do
|
|
321
331
|
let!(:provider_version) do
|
|
322
|
-
|
|
323
|
-
.create_consumer
|
|
332
|
+
td.create_consumer
|
|
324
333
|
.create_provider
|
|
325
334
|
.create_consumer_version
|
|
326
335
|
.create_pact
|
|
@@ -4,7 +4,6 @@ require "pact_broker/webhooks/execution_configuration"
|
|
|
4
4
|
require "pact_broker/webhooks/trigger_service"
|
|
5
5
|
|
|
6
6
|
module PactBroker
|
|
7
|
-
|
|
8
7
|
module Verifications
|
|
9
8
|
describe Service do
|
|
10
9
|
before do
|
|
@@ -20,7 +19,7 @@ module PactBroker
|
|
|
20
19
|
allow(Service).to receive(:broadcast)
|
|
21
20
|
end
|
|
22
21
|
|
|
23
|
-
let(:event_context) { { some: "data" } }
|
|
22
|
+
let(:event_context) { { some: "data", consumer_version_selectors: [{ foo: "bar" }] } }
|
|
24
23
|
let(:expected_event_context) { { some: "data", provider_version_tags: ["dev"] } }
|
|
25
24
|
let(:params) { { "success" => success, "providerApplicationVersion" => "4.5.6", "wip" => true, "testResults" => { "some" => "results" }} }
|
|
26
25
|
let(:success) { true }
|
|
@@ -30,7 +29,8 @@ module PactBroker
|
|
|
30
29
|
.create_provider_version_tag("dev")
|
|
31
30
|
.and_return(:pact)
|
|
32
31
|
end
|
|
33
|
-
let(:
|
|
32
|
+
let(:selected_pacts) { [PactBroker::Pacts::SelectedPact.new(pact, PactBroker::Pacts::Selectors.new)]}
|
|
33
|
+
let(:create_verification) { subject.create 3, params, selected_pacts, event_context }
|
|
34
34
|
|
|
35
35
|
it "logs the creation" do
|
|
36
36
|
expect(logger).to receive(:info).with(/.*verification.*3/, payload: {"providerApplicationVersion"=>"4.5.6", "success"=>true, "wip"=>true})
|
|
@@ -43,6 +43,8 @@ module PactBroker
|
|
|
43
43
|
expect(verification.success).to be true
|
|
44
44
|
expect(verification.number).to eq 3
|
|
45
45
|
expect(verification.test_results).to eq "some" => "results"
|
|
46
|
+
expect(verification.consumer_version_selector_hashes).to eq [{ foo: "bar" }]
|
|
47
|
+
expect(verification.tag_names).to eq ["dev"]
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
it "sets the pact content for the verification" do
|
|
@@ -17,6 +17,8 @@ Dir.glob(File.join(File.dirname(__FILE__), "provider_states_for*.rb")).each do |
|
|
|
17
17
|
require path
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
PactBroker.configuration.base_urls = ["http://example.org"]
|
|
21
|
+
|
|
20
22
|
pact_broker = PactBroker::App.new { |c| c.database_connection = DB::PACT_BROKER_DB }
|
|
21
23
|
app_to_verify = HalRelationProxyApp.new(pact_broker)
|
|
22
24
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -5,7 +5,7 @@ return if ENV["REGRESSION"] == "true"
|
|
|
5
5
|
$: << File.expand_path("../../", __FILE__)
|
|
6
6
|
|
|
7
7
|
RACK_ENV = ENV["RACK_ENV"] = "test"
|
|
8
|
-
ENV["PACT_BROKER_LOG_LEVEL"] ||= "
|
|
8
|
+
ENV["PACT_BROKER_LOG_LEVEL"] ||= "fatal"
|
|
9
9
|
require "spec/support/simplecov"
|
|
10
10
|
|
|
11
11
|
require "support/logging"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pact_broker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.83.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bethany Skurrie
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2021-08-
|
|
13
|
+
date: 2021-08-29 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: httparty
|
|
@@ -577,6 +577,8 @@ files:
|
|
|
577
577
|
- db/migrations/20210712_add_interaction_count_to_pact_versions.rb
|
|
578
578
|
- db/migrations/20210722_add_index_to_triggered_webhooks_webhook_uuid.rb
|
|
579
579
|
- db/migrations/20210810_set_allow_contract_modification.rb
|
|
580
|
+
- db/migrations/20210815_add_provider_version_id_index_to_verifications.rb
|
|
581
|
+
- db/migrations/20210818_add_consumer_version_selectors_to_verification.rb
|
|
580
582
|
- db/migrations/migration_helper.rb
|
|
581
583
|
- db/test/backwards_compatibility/.rspec
|
|
582
584
|
- db/test/backwards_compatibility/Appraisals
|
|
@@ -815,6 +817,7 @@ files:
|
|
|
815
817
|
- lib/pact_broker/date_helper.rb
|
|
816
818
|
- lib/pact_broker/db.rb
|
|
817
819
|
- lib/pact_broker/db/clean.rb
|
|
820
|
+
- lib/pact_broker/db/clean/selector.rb
|
|
818
821
|
- lib/pact_broker/db/clean_incremental.rb
|
|
819
822
|
- lib/pact_broker/db/data_migrations/delete_deprecated_webhook_executions.rb
|
|
820
823
|
- lib/pact_broker/db/data_migrations/helpers.rb
|
|
@@ -1711,7 +1714,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
1711
1714
|
- !ruby/object:Gem::Version
|
|
1712
1715
|
version: '0'
|
|
1713
1716
|
requirements: []
|
|
1714
|
-
rubygems_version: 3.2.
|
|
1717
|
+
rubygems_version: 3.2.26
|
|
1715
1718
|
signing_key:
|
|
1716
1719
|
specification_version: 4
|
|
1717
1720
|
summary: See description
|