pact_broker 2.114.0 → 2.116.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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/Gemfile +4 -2
  4. data/lib/pact/doc/interaction_view_model.rb +25 -5
  5. data/lib/pact/doc/markdown/interaction_async.erb +10 -0
  6. data/lib/pact/doc/markdown/interaction_renderer.rb +5 -1
  7. data/lib/pact_broker/api/decorators/integration_decorator.rb +7 -0
  8. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +11 -0
  9. data/lib/pact_broker/api/decorators/provider_states_decorator.rb +21 -4
  10. data/lib/pact_broker/api/decorators/version_decorator.rb +14 -0
  11. data/lib/pact_broker/api/pact_broker_urls.rb +4 -0
  12. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +55 -1
  13. data/lib/pact_broker/api/resources/branch_versions.rb +5 -1
  14. data/lib/pact_broker/api/resources/pacticipant.rb +6 -1
  15. data/lib/pact_broker/api/resources/tag_versions.rb +58 -0
  16. data/lib/pact_broker/api/resources/version.rb +5 -1
  17. data/lib/pact_broker/api/resources/versions.rb +5 -1
  18. data/lib/pact_broker/api.rb +2 -0
  19. data/lib/pact_broker/deployments/deployed_version_service.rb +21 -0
  20. data/lib/pact_broker/doc/views/integrations.markdown +8 -2
  21. data/lib/pact_broker/integrations/integration.rb +3 -3
  22. data/lib/pact_broker/integrations/repository.rb +1 -0
  23. data/lib/pact_broker/json.rb +4 -1
  24. data/lib/pact_broker/labels/repository.rb +1 -1
  25. data/lib/pact_broker/pacts/provider_state_service.rb +1 -1
  26. data/lib/pact_broker/tags/repository.rb +11 -0
  27. data/lib/pact_broker/tags/service.rb +4 -0
  28. data/lib/pact_broker/test/test_data_builder.rb +3 -2
  29. data/lib/pact_broker/version.rb +1 -1
  30. data/lib/pact_broker/versions/repository.rb +9 -0
  31. data/lib/pact_broker/versions/service.rb +5 -0
  32. data/pact_broker.gemspec +5 -3
  33. metadata +9 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 159a993d4863a7a528c058763f2c5a5b6a3104710757d51110fc3d08b9f6c38b
4
- data.tar.gz: 1832a40fbf58b8d54e375d460d50b5db331167d09dc695252cbf91e57878c8e7
3
+ metadata.gz: 1b6fe2169fc6d5b3554dc0da5de9e5e73fddbb186fb56a0bede25809d7ef3254
4
+ data.tar.gz: 5c0e050b04a5d478b46b016a8bda1eae907457c4d7dac7985ca6c8c1c4b25226
5
5
  SHA512:
6
- metadata.gz: 55a9a315ba42be7d8533af1e3fb895e5fcc6f24e49a199ae1f42150e6119b7c2cc80aec2e9b7ac4e56d2fc291ab665e44948f191912c9fe355aca74fc4abf1f9
7
- data.tar.gz: fe719a11a09ca94776bebe02e51d66da51809080b7c009dfbd8a2ec208802e66863713e3ee698145accb800fed5d7dde8d0d184aa331917f840017b3dafee88d
6
+ metadata.gz: 3fa91a39b55d0d3783e9ac6ce873bc1c2b88434409d6b64e49aff53747b1d776806fedf1342285741883bcf6aebe11e7bdca79fe91fc2ac1ec5fbe29d3fb4d31
7
+ data.tar.gz: 6fc4a2ff15cfb1a0cda2b83d73317c0ff28b835c1bc1205c68ebfcea52428c619c5439c96ad35d2dcdfd06aeda670c2ebc4c8ad6bc4f7f68dd3d9e720712b67b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,35 @@
1
+ <a name="v2.116.0"></a>
2
+ ### v2.116.0 (2025-07-04)
3
+
4
+ #### Features
5
+
6
+ * render sync messages ([c0ad9f5b](/../../commit/c0ad9f5b))
7
+ * render async messages mixed v4 and v3 ([d727d950](/../../commit/d727d950))
8
+ * add deployed-environments to pacticipant response and tag versions (#804) ([d8c7ee65](/../../commit/d8c7ee65))
9
+ * show deployed-environments in branch versions response (#803) ([cc346010](/../../commit/cc346010))
10
+ * add tag_versions endpoint ([42bf5203](/../../commit/42bf5203))
11
+ * added deployed-environments to `/parcticipants/$name/versions` abd (#801) ([af66f6a3](/../../commit/af66f6a3))
12
+
13
+ #### Bug Fixes
14
+
15
+ * rubocop errors ([e311422c](/../../commit/e311422c))
16
+ * refactored long consumer_contract method ([7d8af4d5](/../../commit/7d8af4d5))
17
+ * remove unsupported Pact::Term from test example ([1a4056bd](/../../commit/1a4056bd))
18
+ * rename interaction_async.erb filename ([77ddcb59](/../../commit/77ddcb59))
19
+ * refactored the query to filter out duplicate integration rows (#806) ([7bff0f0d](/../../commit/7bff0f0d))
20
+
21
+ <a name="v2.115.0"></a>
22
+ ### v2.115.0 (2025-03-17)
23
+
24
+ #### Features
25
+
26
+ * group provider states by consumers ([e39860a9](/../../commit/e39860a9))
27
+
28
+ #### Bug Fixes
29
+
30
+ * dedupe non unique provider states #789 ([3cf22169](/../../commit/3cf22169))
31
+ * explicitly order labels by name ([d25746c1](/../../commit/d25746c1))
32
+
1
33
  <a name="v2.114.0"></a>
2
34
  ### v2.114.0 (2025-03-06)
3
35
 
data/Gemfile CHANGED
@@ -3,12 +3,14 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
 
6
- gem "rake", "~>13.0"
6
+ gem "rake", "~> 13.3"
7
7
  gem "sqlite3", ">=2.0.0"
8
8
  gem "conventional-changelog", "~>1.3"
9
9
  gem "bump", "~> 0.5"
10
10
  gem "padrino-core", ">= 0.16.0.pre3", require: false
11
11
  gem "rackup", "~> 2.2"
12
+ # TODO: using release-candidate of pact-support is release remove this and restore to gemspec.
13
+ gem "pact-support", github: "pact-foundation/pact-support", branch: "release-1.21.3.rc1"
12
14
 
13
15
  group :development do
14
16
  gem "pry-byebug"
@@ -33,7 +35,7 @@ group :test do
33
35
  gem "approvals", ">=0.0.24", "<1.0.0"
34
36
  gem "tzinfo", "~>2.0"
35
37
  gem "faraday-retry", "~>2.0"
36
- gem "openapi_first", ">= 2.3", "< 3"
38
+ gem "openapi_first", "2.9.2" # pinned to specific version due to changelog volatility
37
39
  end
38
40
 
39
41
  group :pg, optional: true do
@@ -70,7 +70,12 @@ module Pact
70
70
  end
71
71
 
72
72
  def request
73
- fix_json_formatting JSON.pretty_generate(clean_request)
73
+ the_clean_request = clean_request
74
+ if the_clean_request == "ASYNC_REQUEST"
75
+ "ASYNC_REQUEST"
76
+ else
77
+ fix_json_formatting JSON.pretty_generate(clean_request)
78
+ end
74
79
  end
75
80
 
76
81
  def response
@@ -82,14 +87,29 @@ module Pact
82
87
  attr_reader :interaction, :consumer_contract
83
88
 
84
89
  def clean_request
85
- reified_request = Reification.from_term(interaction.request)
86
- ordered_clean_hash(reified_request).tap do | hash |
87
- hash[:body] = reified_request[:body] if reified_request[:body]
90
+ reified = Reification.from_term(interaction.request)
91
+ return "ASYNC_REQUEST" if reified[:method] == "FAKE_ASYNC_METHOD"
92
+
93
+ ordered = ordered_clean_hash(reified).tap do |h|
94
+ h[:body] = reified[:body] if reified[:body]
88
95
  end
96
+
97
+ return ordered[:body].to_h.slice("contents", "metadata") if ordered[:method] == "FAKE_SYNC_METHOD"
98
+
99
+ ordered
89
100
  end
90
101
 
91
102
  def clean_response
92
- ordered_clean_hash Reification.from_term(interaction.response)
103
+ raw = Reification.from_term(interaction.response)
104
+
105
+ case raw[:status]
106
+ when "FAKE_ASYNC_METHOD"
107
+ raw[:body] || {}
108
+ when "FAKE_SYNC_METHOD"
109
+ Array(raw.dig(:body, "contents")).map { |item| item.slice("contents", "metadata") }
110
+ else
111
+ ordered_clean_hash(raw)
112
+ end
93
113
  end
94
114
 
95
115
  # Remove empty body and headers hashes from response, and empty headers from request,
@@ -0,0 +1,10 @@
1
+ <a name="<%= interaction.id %>"></a><% formatted_provider_states = h(interaction.formatted_provider_states mark_bold: true) %>
2
+ <%= if !formatted_provider_states.empty?
3
+ "Given #{formatted_provider_states}"
4
+ end
5
+ %>
6
+
7
+ <%= h(interaction.provider_name) %> will **asyncronously** send **<%= h(interaction.description) %>**:
8
+ ```json
9
+ <%= interaction.response %>
10
+ ```
@@ -19,7 +19,11 @@ module Pact
19
19
  end
20
20
 
21
21
  def render_full_interaction
22
- render("/interaction.erb")
22
+ if interaction.request == "ASYNC_REQUEST"
23
+ render("/interaction_async.erb")
24
+ else
25
+ render("/interaction.erb")
26
+ end
23
27
  end
24
28
 
25
29
  def render template_file
@@ -36,6 +36,13 @@ module PactBroker
36
36
  href: group_url(represented.consumer.name, options.fetch(:base_url))
37
37
  }
38
38
  end
39
+
40
+ link "pb:delete_integration" do | options |
41
+ {
42
+ title: "Delete the integration between #{represented.consumer.name} and #{represented.provider.name}",
43
+ href: integration_url(represented.consumer.name, represented.provider.name, options.fetch(:base_url))
44
+ }
45
+ end
39
46
  end
40
47
  end
41
48
  end
@@ -43,6 +43,17 @@ module PactBroker
43
43
  pacticipant_branches_url(represented, options[:base_url])
44
44
  end
45
45
 
46
+ links :'pb:deployed-environments' do | context |
47
+ context[:deployed_versions]&.collect do | deployed_version |
48
+ {
49
+ title: "Version deployed to #{deployed_version.environment.display_name}",
50
+ name: deployed_version.environment.display_name,
51
+ href: deployed_version_url(deployed_version, context.fetch(:base_url)),
52
+ currently_deployed: deployed_version.currently_deployed
53
+ }
54
+ end
55
+ end
56
+
46
57
  link :'pb:version' do | options |
47
58
  {
48
59
  title: "Get, create or delete a pacticipant version",
@@ -6,13 +6,30 @@ module PactBroker
6
6
  class ProviderStateDecorator < BaseDecorator
7
7
  camelize_property_names
8
8
 
9
- property :name
10
- property :params
11
-
9
+ property :name, getter: -> (context) { context[:represented][:name] }
10
+ property :params, getter: -> (context) { context[:represented][:params] }
11
+ property :consumers, getter: -> (context) { context[:represented][:consumers] }
12
12
  end
13
13
 
14
14
  class ProviderStatesDecorator < BaseDecorator
15
- collection :providerStates, getter: -> (context) { context[:represented].sort_by(&:name) }, :extend => PactBroker::Api::Decorators::ProviderStateDecorator
15
+ collection :providerStates, getter: -> (context) {
16
+ consumers_map = {}
17
+
18
+ context[:represented].each do |item|
19
+ item["providerStates"].each do |provider_state|
20
+ provider_state = provider_state.to_h
21
+ provider_state[:consumers] ||= []
22
+ provider_state[:consumers] << item["consumer"]
23
+ consumers_map[[provider_state[:name], provider_state[:params]]] ||= []
24
+ consumers_map[[provider_state[:name], provider_state[:params]]] += provider_state[:consumers]
25
+ end
26
+ end
27
+
28
+ consumers_map.map do |(name, params), consumers|
29
+ { name: name, params: params, consumers: consumers.uniq }.transform_keys(&:to_sym)
30
+ end
31
+ .sort_by { |provider_state| provider_state[:name] }
32
+ }, :extend => PactBroker::Api::Decorators::ProviderStateDecorator
16
33
  end
17
34
  end
18
35
  end
@@ -73,6 +73,20 @@ module PactBroker
73
73
  end
74
74
  end
75
75
 
76
+ links :'pb:deployed-environments' do | context |
77
+ # I couldn't another way to check if call is from a collection or a single item 🤷‍♂️
78
+ # Also not sure why the heck .to_a?(Hash) doesn't work, I mean what...
79
+ deployed_versions = context[:deployed_versions].class.to_s == "Hash" ? context[:deployed_versions][represented.id] : context[:deployed_versions]
80
+ deployed_versions&.collect do | deployed_version |
81
+ {
82
+ title: "Version deployed to #{deployed_version.environment.display_name}",
83
+ name: deployed_version.environment.display_name,
84
+ href: deployed_version_url(deployed_version, context.fetch(:base_url)),
85
+ currently_deployed: deployed_version.currently_deployed
86
+ }
87
+ end
88
+ end
89
+
76
90
  links :'pb:record-deployment' do | context |
77
91
  context[:environments]&.collect do | environment |
78
92
  {
@@ -414,6 +414,10 @@ module PactBroker
414
414
  end
415
415
  end
416
416
 
417
+ def tag_versions_url(tag, base_url = "")
418
+ "#{pacticipant_url(base_url, tag.pacticipant)}/tags/#{tag.name}/versions"
419
+ end
420
+
417
421
  private
418
422
 
419
423
  def representable_pact pact
@@ -195,12 +195,66 @@ module PactBroker
195
195
  end
196
196
 
197
197
  def consumer_contract
198
- Pact::ConsumerContract.from_json(@json_content)
198
+ pact_object = JSON.parse(@json_content, quirks_mode: true)
199
+ convert_v3_messages_to_interactions(pact_object)
200
+
201
+ pact_object["interactions"]&.each do |interaction|
202
+ add_dummy_html_request_response_to_asynchronous_message(interaction)
203
+ add_dummy_html_request_response_to_synchronous_message(interaction)
204
+ end
205
+
206
+ new_json_content = pact_object.to_json
207
+
208
+ Pact::ConsumerContract.from_json(new_json_content)
199
209
  rescue => e
200
210
  logger.info "Could not parse the following content to a Pact due to #{e.class} #{e.message}, showing raw content instead: #{@json_content}"
201
211
  raise NotAPactError
202
212
  end
203
213
 
214
+ def convert_v3_messages_to_interactions(pact_object)
215
+ return unless pact_object.key?("messages")
216
+
217
+ logger.warn "Detected a v3 Pact, converting 'messages' to 'interactions'."
218
+ pact_object["interactions"] = pact_object.delete("messages")
219
+ end
220
+
221
+ def add_dummy_html_request_response_to_asynchronous_message(interaction)
222
+ if !interaction["request"] || !interaction["response"]
223
+ logger.warn "Interaction '#{interaction['description']}' does not have a request or response, adding dummy request and response so that they can be parsed and appear on the UI."
224
+ end
225
+
226
+ interaction["request"] ||= {
227
+ method: "FAKE_ASYNC_METHOD",
228
+ path: interaction["description"]
229
+ }
230
+
231
+ unless interaction.key?("response")
232
+ interaction["response"] = {
233
+ status: "FAKE_ASYNC_METHOD",
234
+ body: {
235
+ contents: interaction.delete("contents"),
236
+ metadata: interaction.delete("metadata")
237
+ }
238
+ }
239
+ end
240
+ end
241
+
242
+ def add_dummy_html_request_response_to_synchronous_message(interaction)
243
+ if interaction["type"] == "Synchronous/Messages"
244
+ interaction["request"] = {
245
+ method: "FAKE_SYNC_METHOD",
246
+ path: interaction["description"],
247
+ body: interaction.delete("request"),
248
+ }
249
+ interaction["response"] = {
250
+ status: "FAKE_SYNC_METHOD",
251
+ body: {
252
+ contents: interaction.delete("response"),
253
+ }
254
+ }
255
+ end
256
+ end
257
+
204
258
  def h string
205
259
  Rack::Utils.escape_html(string)
206
260
  end
@@ -27,13 +27,17 @@ module PactBroker
27
27
  end
28
28
 
29
29
  def to_json
30
- decorator_class(:versions_decorator).new(versions).to_json(**decorator_options(identifier_from_path.merge(resource_title: resource_title)))
30
+ decorator_class(:versions_decorator).new(versions).to_json(**decorator_options(identifier_from_path.merge(resource_title: resource_title, deployed_versions: deployed_versions)))
31
31
  end
32
32
 
33
33
  def versions
34
34
  @versions ||= version_service.find_pacticipant_versions_in_reverse_order(pacticipant_name, { branch_name: identifier_from_path[:branch_name] }, pagination_options, decorator_class(:versions_decorator).eager_load_associations)
35
35
  end
36
36
 
37
+ def deployed_versions
38
+ @deployed_versions ||= deployed_version_service.find_deployed_versions_for_versions(versions)
39
+ end
40
+
37
41
  def policy_name
38
42
  :'versions::versions'
39
43
  end
@@ -71,7 +71,12 @@ module PactBroker
71
71
  end
72
72
 
73
73
  def to_json
74
- decorator_class(:pacticipant_decorator).new(pacticipant).to_json(**decorator_options)
74
+ decorator_class(:pacticipant_decorator).new(pacticipant)
75
+ .to_json(**decorator_options(deployed_versions: deployed_versions))
76
+ end
77
+
78
+ def deployed_versions
79
+ @deployed_versions ||= deployed_version_service.find_all_deployed_versions_for_pacticipant(pacticipant)
75
80
  end
76
81
 
77
82
  def parsed_pacticipant(pacticipant)
@@ -0,0 +1,58 @@
1
+ require "pact_broker/api/resources/base_resource"
2
+ require "pact_broker/api/decorators/versions_decorator"
3
+ require "pact_broker/api/resources/pagination_methods"
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Resources
8
+ class TagVersions < BaseResource
9
+ include PactBroker::Api::Resources::PaginationMethods
10
+
11
+ def allowed_methods
12
+ ["GET", "OPTIONS"]
13
+ end
14
+
15
+ def malformed_request?
16
+ super || request.get? && validation_errors_for_schema?(schema, request.query)
17
+ end
18
+
19
+ def content_types_provided
20
+ [["application/hal+json", :to_json]]
21
+ end
22
+
23
+ def policy_name
24
+ :'versions::versions'
25
+ end
26
+
27
+ def resource_exists?
28
+ !tags.empty?
29
+ end
30
+
31
+ def to_json
32
+ decorator_class(:versions_decorator).new(tag_versions)
33
+ .to_json(**decorator_options(deployed_versions: deployed_versions))
34
+ end
35
+
36
+ private
37
+
38
+ def deployed_versions
39
+ @deployed_versions ||= deployed_version_service.find_deployed_versions_for_versions(tag_versions)
40
+ end
41
+
42
+ def tag_versions
43
+ @versions ||= version_service.find_by_ids_in_reverse_order(@tags.select_map(:version_id), pagination_options, decorator_class(:versions_decorator).eager_load_associations)
44
+ end
45
+
46
+ def tags
47
+ @tags ||= tag_service.find_all_by_pacticipant_name_and_tag(**identifier_from_path.slice(:pacticipant_name, :tag_name))
48
+ end
49
+
50
+ def schema
51
+ if request.get?
52
+ PactBroker::Api::Contracts::PaginationQueryParamsSchema
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -54,7 +54,7 @@ module PactBroker
54
54
  end
55
55
 
56
56
  def to_json
57
- decorator_class(:version_decorator).new(version).to_json(**decorator_options(environments: environments))
57
+ decorator_class(:version_decorator).new(version).to_json(**decorator_options(environments: environments, deployed_versions: deployed_versions))
58
58
  end
59
59
 
60
60
  def delete_resource
@@ -83,6 +83,10 @@ module PactBroker
83
83
  @environments ||= environment_service.find_for_pacticipant(version.pacticipant)
84
84
  end
85
85
 
86
+ def deployed_versions
87
+ @deployed_versions ||= deployed_version_service.find_deployed_versions_for_version(version)
88
+ end
89
+
86
90
  def version
87
91
  @version ||= version_service.find_by_pacticipant_name_and_number(identifier_from_path)
88
92
  end
@@ -27,13 +27,17 @@ module PactBroker
27
27
  end
28
28
 
29
29
  def to_json
30
- decorator_class(:versions_decorator).new(versions).to_json(**decorator_options(identifier_from_path))
30
+ decorator_class(:versions_decorator).new(versions).to_json(**decorator_options(identifier_from_path.merge(deployed_versions: deployed_versions)))
31
31
  end
32
32
 
33
33
  def versions
34
34
  @versions ||= version_service.find_pacticipant_versions_in_reverse_order(pacticipant_name, {}, pagination_options, decorator_class(:versions_decorator).eager_load_associations)
35
35
  end
36
36
 
37
+ def deployed_versions
38
+ @deployed_versions ||= deployed_version_service.find_deployed_versions_for_versions(versions)
39
+ end
40
+
37
41
  def policy_name
38
42
  :'versions::versions'
39
43
  end
@@ -152,6 +152,8 @@ module PactBroker
152
152
  add ["integrations", "provider", :provider_name, "consumer", :consumer_name], Api::Resources::Integration, {resource_name: "integration"}
153
153
  add ["metrics"], Api::Resources::Metrics, {resource_name: "metrics"}
154
154
  add [], Api::Resources::Index, {resource_name: "index"}
155
+
156
+ add ["pacticipants", :pacticipant_name, "tags", :tag_name, "versions"], Api::Resources::TagVersions, {resource_name: "pacticipant_tag_versions"}
155
157
  end
156
158
  end
157
159
  end
@@ -44,6 +44,20 @@ module PactBroker
44
44
  .all
45
45
  end
46
46
 
47
+ def self.find_deployed_versions_for_version(version)
48
+ scope_for(DeployedVersion)
49
+ .where(version_id: version.id)
50
+ .eager(:environment)
51
+ .all
52
+ end
53
+
54
+ def self.find_deployed_versions_for_versions(versions_array)
55
+ scope_for(DeployedVersion)
56
+ .where(version_id: versions_array.map(&:id))
57
+ .eager(:environment)
58
+ .to_hash_groups(:version_id)
59
+ end
60
+
47
61
  # Policy applied at resource level to Version
48
62
  def self.find_currently_deployed_version_for_version_and_environment_and_target(version, environment, target)
49
63
  DeployedVersion
@@ -52,6 +66,13 @@ module PactBroker
52
66
  .single_record
53
67
  end
54
68
 
69
+ def self.find_all_deployed_versions_for_pacticipant(pacticipant)
70
+ scope_for(DeployedVersion)
71
+ .where(pacticipant_id: pacticipant.id)
72
+ .eager(:environment)
73
+ .all
74
+ end
75
+
55
76
  def self.find_currently_deployed_versions_for_environment(environment, pacticipant_name: nil, target: :unspecified)
56
77
  query = scope_for(DeployedVersion)
57
78
  .currently_deployed
@@ -1,11 +1,17 @@
1
1
  # Integrations
2
2
 
3
- Allowed methods: `GET`, `DELETE`
4
-
5
3
  Path: `/integrations`
6
4
 
5
+ Allowed methods: `GET`, `DELETE`
6
+
7
7
  Content types: `text/vnd.graphviz`, `application/hal+json`
8
8
 
9
9
  A list of all the integrations (consumer/provider pairs) stored in the Pact Broker.
10
10
 
11
11
  Sending a `DELETE` request to this endpoint will remove all data irretrievably from the Pact Broker.
12
+
13
+ Path: `/integrations/provider/{providerName}/consumer/{consumerName}`
14
+
15
+ Allowed methods: `DELETE`
16
+
17
+ Sending a `DELETE` request to this endpoint will remove all data irretrievably from the Pact Broker for the specified integration.
@@ -89,9 +89,9 @@ module PactBroker
89
89
  include PactBroker::Dataset
90
90
 
91
91
  def filter_by_pacticipant(query_string)
92
- matching_pacticipants = PactBroker::Domain::Pacticipant.filter(:name, query_string)
93
- pacticipants_join = Sequel.|({ Sequel[:integrations][:consumer_id] => Sequel[:p][:id] }, { Sequel[:integrations][:provider_id] => Sequel[:p][:id] })
94
- join(matching_pacticipants, pacticipants_join, table_alias: :p)
92
+ matching_pacticipant_ids = PactBroker::Domain::Pacticipant.filter(:name, query_string).select(:id).all.collect(&:id)
93
+ return nil if matching_pacticipant_ids.empty?
94
+ including_pacticipant_id(matching_pacticipant_ids)
95
95
  end
96
96
 
97
97
  def including_pacticipant_id(pacticipant_id)
@@ -10,6 +10,7 @@ module PactBroker
10
10
  def find(filter_options = {}, pagination_options = {}, eager_load_associations = [])
11
11
  query = scope_for(PactBroker::Integrations::Integration).select_all_qualified
12
12
  query = query.filter_by_pacticipant(filter_options[:query_string]) if filter_options[:query_string]
13
+ return [] if query.nil?
13
14
  query
14
15
  .eager(*eager_load_associations)
15
16
  .order(Sequel.desc(:contract_data_updated_at, nulls: :last))
@@ -1,4 +1,7 @@
1
1
 
2
2
  module PactBroker
3
- PACT_PARSING_OPTIONS = { max_nesting: 50 }
3
+ PACT_PARSING_OPTIONS = {
4
+ max_nesting: 50,
5
+ create_additions: false
6
+ }
4
7
  end
@@ -5,7 +5,7 @@ module PactBroker
5
5
  class Repository
6
6
 
7
7
  def get_all_unique_labels pagination_options = {}
8
- PactBroker::Domain::Label.distinct.select(:name).all_with_pagination_options(pagination_options)
8
+ PactBroker::Domain::Label.distinct.select(:name).order(:name).all_with_pagination_options(pagination_options)
9
9
  end
10
10
 
11
11
  def create args
@@ -14,7 +14,7 @@ module PactBroker
14
14
  def self.list_provider_states(provider)
15
15
  query = scope_for(PactPublication).eager_for_domain_with_content.for_provider_and_consumer_version_selector(provider, PactBroker::Pacts::Selector.latest_for_main_branch)
16
16
  query.all.flat_map do | pact_publication |
17
- pact_publication.to_domain.content_object.provider_states
17
+ { "providerStates" => pact_publication.to_domain.content_object.provider_states, "consumer" => pact_publication.to_domain.consumer.name }
18
18
  end
19
19
  end
20
20
  end
@@ -1,8 +1,11 @@
1
1
  require "pact_broker/domain/tag"
2
+ require "pact_broker/repositories"
2
3
 
3
4
  module PactBroker
4
5
  module Tags
5
6
  class Repository
7
+ include PactBroker::Repositories
8
+
6
9
  def create args
7
10
  params = {
8
11
  name: args.fetch(:name),
@@ -37,6 +40,14 @@ module PactBroker
37
40
  .distinct
38
41
  .collect{ |tag| tag[:name] }.sort
39
42
  end
43
+
44
+ def find_all_by_pacticipant_name_and_tag(pacticipant_name, tag_name)
45
+ pacticipant = pacticipant_repository.find_by_name(pacticipant_name)
46
+ return PactBroker::Domain::Tag.where(pacticipant_id: pacticipant.id, name: tag_name) if pacticipant
47
+
48
+ []
49
+ end
50
+
40
51
  end
41
52
  end
42
53
  end
@@ -32,6 +32,10 @@ module PactBroker
32
32
  def find_all_tag_names_for_pacticipant pacticipant_name
33
33
  tag_repository.find_all_tag_names_for_pacticipant pacticipant_name
34
34
  end
35
+
36
+ def find_all_by_pacticipant_name_and_tag pacticipant_name:, tag_name:
37
+ tag_repository.find_all_by_pacticipant_name_and_tag pacticipant_name, tag_name
38
+ end
35
39
  end
36
40
  end
37
41
  end
@@ -670,15 +670,16 @@ module PactBroker
670
670
  version
671
671
  end
672
672
 
673
- private
674
-
675
673
  def create_deployed_version(uuid: , currently_deployed: , version:, environment_name: , target: nil, created_at: nil)
676
674
  env = find_environment(environment_name)
677
675
  @deployed_version = PactBroker::Deployments::DeployedVersionService.find_or_create(uuid, version, env, target)
678
676
  PactBroker::Deployments::DeployedVersionService.record_version_undeployed(deployed_version) unless currently_deployed
679
677
  set_created_at_if_set(created_at, :deployed_versions, id: deployed_version.id)
678
+ self
680
679
  end
681
680
 
681
+ private
682
+
682
683
  def create_released_version(uuid: , currently_supported: true, version:, environment_name: , created_at: nil)
683
684
  env = find_environment(environment_name)
684
685
  @released_version = PactBroker::Deployments::ReleasedVersionService.create_or_update(uuid, version, env)
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = "2.114.0"
2
+ VERSION = "2.116.0"
3
3
  end
@@ -174,6 +174,15 @@ module PactBroker
174
174
  latest_from_main_branch || find_by_pacticipant_name_and_latest_tag(pacticipant.name, pacticipant.main_branch)
175
175
  end
176
176
  end
177
+
178
+ def find_by_ids_in_reverse_order version_ids, pagination_options = {}, eager_load_associations =[]
179
+ query = PactBroker::Domain::Version
180
+ .where(id: version_ids)
181
+ .eager(*eager_load_associations)
182
+ .reverse_order(:order)
183
+
184
+ query.all_with_pagination_options(pagination_options)
185
+ end
177
186
  end
178
187
  end
179
188
  end
@@ -66,6 +66,11 @@ module PactBroker
66
66
  PactBroker.configuration.use_first_tag_as_branch &&
67
67
  ((now - version.created_at.to_datetime) * 24 * 60 * 60) <= PactBroker.configuration.use_first_tag_as_branch_time_limit
68
68
  end
69
+
70
+ def self.find_by_ids_in_reverse_order version_ids, pagination_options = {}, eager_load_associations = []
71
+ version_repository.find_by_ids_in_reverse_order version_ids, pagination_options, eager_load_associations
72
+ end
73
+
69
74
  private_class_method :use_tag_as_branch?
70
75
 
71
76
  def self.now
data/pact_broker.gemspec CHANGED
@@ -54,12 +54,14 @@ Gem::Specification.new do |gem|
54
54
  gem.add_runtime_dependency "roar", "~> 1.1"
55
55
  gem.add_runtime_dependency "dry-validation", "~> 1.8"
56
56
  gem.add_runtime_dependency "reform", "~> 2.6"
57
- gem.add_runtime_dependency "sequel", "~> 5.28"
57
+ gem.add_runtime_dependency "sequel", "~> 5.90"
58
58
  gem.add_runtime_dependency "webmachine", ">= 2.0.0.beta", "< 3.0"
59
59
  gem.add_runtime_dependency "semver2", "~> 3.4.2"
60
- gem.add_runtime_dependency "rack", "~> 3.1", ">= 3.1.11"
60
+ gem.add_runtime_dependency "rack", "~> 3.1", ">= 3.1.16"
61
61
  gem.add_runtime_dependency "redcarpet", ">= 3.5.1", "~>3.5"
62
- gem.add_runtime_dependency "pact-support" , ">= 1.21.2", "~> 1.21"
62
+ # TODO: restore this with when latest master is released as 1.21.3
63
+ # remove the Gemfile entry pointing to master
64
+ # gem.add_runtime_dependency "pact-support" , ">= 1.21.3", "~> 1.21"
63
65
  gem.add_runtime_dependency "haml", "~>5.0"
64
66
  gem.add_runtime_dependency "sucker_punch", "~>3.0"
65
67
  gem.add_runtime_dependency "rack-protection", "~> 4.1"
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.114.0
4
+ version: 2.116.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bethany Skurrie
@@ -9,7 +9,7 @@ authors:
9
9
  - Warner Godfrey
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-03-06 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -87,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '5.28'
90
+ version: '5.90'
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: '5.28'
97
+ version: '5.90'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: webmachine
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -138,7 +138,7 @@ dependencies:
138
138
  version: '3.1'
139
139
  - - ">="
140
140
  - !ruby/object:Gem::Version
141
- version: 3.1.11
141
+ version: 3.1.16
142
142
  type: :runtime
143
143
  prerelease: false
144
144
  version_requirements: !ruby/object:Gem::Requirement
@@ -148,7 +148,7 @@ dependencies:
148
148
  version: '3.1'
149
149
  - - ">="
150
150
  - !ruby/object:Gem::Version
151
- version: 3.1.11
151
+ version: 3.1.16
152
152
  - !ruby/object:Gem::Dependency
153
153
  name: redcarpet
154
154
  requirement: !ruby/object:Gem::Requirement
@@ -169,26 +169,6 @@ dependencies:
169
169
  - - "~>"
170
170
  - !ruby/object:Gem::Version
171
171
  version: '3.5'
172
- - !ruby/object:Gem::Dependency
173
- name: pact-support
174
- requirement: !ruby/object:Gem::Requirement
175
- requirements:
176
- - - ">="
177
- - !ruby/object:Gem::Version
178
- version: 1.21.2
179
- - - "~>"
180
- - !ruby/object:Gem::Version
181
- version: '1.21'
182
- type: :runtime
183
- prerelease: false
184
- version_requirements: !ruby/object:Gem::Requirement
185
- requirements:
186
- - - ">="
187
- - !ruby/object:Gem::Version
188
- version: 1.21.2
189
- - - "~>"
190
- - !ruby/object:Gem::Version
191
- version: '1.21'
192
172
  - !ruby/object:Gem::Dependency
193
173
  name: haml
194
174
  requirement: !ruby/object:Gem::Requirement
@@ -546,6 +526,7 @@ files:
546
526
  - lib/pact/doc/markdown/generator.rb
547
527
  - lib/pact/doc/markdown/index_renderer.rb
548
528
  - lib/pact/doc/markdown/interaction.erb
529
+ - lib/pact/doc/markdown/interaction_async.erb
549
530
  - lib/pact/doc/markdown/interaction_renderer.rb
550
531
  - lib/pact/doc/sort_interactions.rb
551
532
  - lib/pact_broker.rb
@@ -734,6 +715,7 @@ files:
734
715
  - lib/pact_broker/api/resources/released_version.rb
735
716
  - lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb
736
717
  - lib/pact_broker/api/resources/tag.rb
718
+ - lib/pact_broker/api/resources/tag_versions.rb
737
719
  - lib/pact_broker/api/resources/tagged_pact_versions.rb
738
720
  - lib/pact_broker/api/resources/triggered_webhook_logs.rb
739
721
  - lib/pact_broker/api/resources/verification.rb
@@ -1227,7 +1209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1227
1209
  - !ruby/object:Gem::Version
1228
1210
  version: '0'
1229
1211
  requirements: []
1230
- rubygems_version: 3.6.5
1212
+ rubygems_version: 3.6.9
1231
1213
  specification_version: 4
1232
1214
  summary: See description
1233
1215
  test_files: []