pact_broker 2.82.0 → 2.83.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|