pact_broker 2.111.0 → 2.113.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/Gemfile +6 -5
  4. data/docs/CONFIGURATION.md +2 -2
  5. data/docs/developer/business_domain_models.md +9 -0
  6. data/lib/pact_broker/api/decorators/provider_states_decorator.rb +19 -0
  7. data/lib/pact_broker/api/decorators/triggered_webhook_logs_decorator.rb +38 -0
  8. data/lib/pact_broker/api/resources/badge_methods.rb +5 -1
  9. data/lib/pact_broker/api/resources/can_i_merge_badge.rb +6 -0
  10. data/lib/pact_broker/api/resources/labels.rb +13 -0
  11. data/lib/pact_broker/api/resources/provider_states.rb +38 -0
  12. data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +5 -1
  13. data/lib/pact_broker/api.rb +5 -0
  14. data/lib/pact_broker/config/runtime_configuration.rb +1 -0
  15. data/lib/pact_broker/db/data_migrations/set_interactions_counts.rb +2 -0
  16. data/lib/pact_broker/db/migrate_data.rb +28 -16
  17. data/lib/pact_broker/deployments/deployed_version.rb +3 -2
  18. data/lib/pact_broker/deployments/released_version.rb +1 -0
  19. data/lib/pact_broker/doc/views/pact/provider-states.markdown +28 -0
  20. data/lib/pact_broker/domain/verification.rb +1 -0
  21. data/lib/pact_broker/integrations/integration.rb +5 -3
  22. data/lib/pact_broker/matrix/matrix_row_instance_methods.rb +7 -1
  23. data/lib/pact_broker/pacticipants/repository.rb +4 -1
  24. data/lib/pact_broker/pacts/content.rb +24 -7
  25. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +1 -0
  26. data/lib/pact_broker/pacts/provider_state_service.rb +22 -0
  27. data/lib/pact_broker/pacts/selector.rb +4 -0
  28. data/lib/pact_broker/pacts/selectors.rb +4 -0
  29. data/lib/pact_broker/services.rb +9 -0
  30. data/lib/pact_broker/tasks/clean_task.rb +1 -1
  31. data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +4 -3
  32. data/lib/pact_broker/verifications/pact_version_provider_tag_successful_verification.rb +1 -0
  33. data/lib/pact_broker/version.rb +1 -1
  34. data/lib/pact_broker/versions/branch_head.rb +5 -4
  35. data/lib/pact_broker/webhooks/execution.rb +2 -1
  36. data/lib/sequel/extensions/pg_advisory_lock.rb +2 -2
  37. data/pact_broker.gemspec +1 -3
  38. metadata +13 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e21e3c2fc82cfe4697582921613bd435e026cf6f381c64c33d703b8c31c586be
4
- data.tar.gz: 6b6bc75a486f936441b172c7a80a7e8541f3bbb1731be03b1e33a869327014bf
3
+ metadata.gz: 7f58c954e3864629cd056224198acfe87df68d7a38ff2a098bf1c7e78541a8d1
4
+ data.tar.gz: 6f59e94416775c9beb054cd7ef0ca77e055505e99864a8cc0c0dd4c8a0bf3f9b
5
5
  SHA512:
6
- metadata.gz: 2afe779170a4910f06ace0a29b8ee66fa81bc355fc1a1c22a532fb3f9f64f5775309543c23b3b7ae4c4c837c1a66d0b10ddb0f62e8e9f586b7fd4942dc29d33c
7
- data.tar.gz: 3b2738f3785dc1c272d4e1ba24104b4786bd467780808d41bdf2dd7f2ce0e83f0f11645a8ca3b8fd16642055a897d60b573ea7fc8392751cf0a59ecafeba6130
6
+ metadata.gz: d64bab2b42d053d80a63c797e2a3ee84f2731a8eee85368a31bb1d70a102ef38df362feb7ef9151b2890307944123e0a0ec04acb82e1c7d956f88c12d6935116
7
+ data.tar.gz: 8c46ee348ffad72bad86d132873e1d812c70585b570d8e63c7b71187dfd653afa1eea795f804b8fb2d2ed3fe1f7d372996ff4eb598fcc17a775cd214be5cb236
data/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ <a name="v2.113.0"></a>
2
+ ### v2.113.0 (2025-02-13)
3
+
4
+ #### Features
5
+
6
+ * aggregated provider state endpoint (#734) ([108d11a7](/../../commit/108d11a7))
7
+ * add more logging to data migrations ([9482d44d](/../../commit/9482d44d))
8
+
9
+ #### Bug Fixes
10
+
11
+ * make sure last_action_date always returns a DateTime object ([d60c264e](/../../commit/d60c264e))
12
+
13
+ <a name="v2.112.0"></a>
14
+ ### v2.112.0 (2024-09-09)
15
+
16
+ #### Features
17
+
18
+ * implemented setting cache for can-i-merge badges based on default configuration ([e2bce55e](/../../commit/e2bce55e))
19
+ * add application/hal+json content type for webhook logs (#679) ([e84de4f4](/../../commit/e84de4f4))
20
+
21
+ #### Bug Fixes
22
+
23
+ * make clean_task.rb print the payload correctly ([10fd69e2](/../../commit/10fd69e2))
24
+
1
25
  <a name="v2.111.0"></a>
2
26
  ### v2.111.0 (2024-07-26)
3
27
 
data/Gemfile CHANGED
@@ -3,15 +3,17 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
 
6
- gem "rake", "~>12.3.3"
7
- gem "sqlite3", "~>1.3"
6
+ gem "rake", "~>13.0"
7
+ gem "sqlite3", ">=2.0.0"
8
8
  gem "conventional-changelog", "~>1.3"
9
9
  gem "bump", "~> 0.5"
10
+ gem "padrino-core", ">= 0.14.3", "~> 0.14", require: false
11
+ gem "sinatra", "~> 3.0", require: false
10
12
 
11
13
  group :development do
12
14
  gem "pry-byebug"
13
- gem "rubocop", "~>1.1"
14
- gem "rubocop-performance", "~> 1.11"
15
+ gem "rubocop", "~>1.7"
16
+ gem "rubocop-performance", "~> 1.23"
15
17
  gem "sequel-annotate", "~>1.3"
16
18
  gem "yard", "~> 0.9"
17
19
  end
@@ -21,7 +23,6 @@ group :test do
21
23
  gem "pact", "~>1.14"
22
24
  gem "rspec-pact-matchers", "~>0.1"
23
25
  gem "bundler-audit", "~>0.4"
24
- gem "fakefs", "~>0.4"
25
26
  gem "webmock", "~>3.9"
26
27
  gem "rspec", "~>3.0"
27
28
  gem "rspec-its", "~>1.2"
@@ -248,8 +248,8 @@ The number of seconds after which an SQL query will be aborted. Only supported f
248
248
 
249
249
  **Environment variable name:** `PACT_BROKER_DATABASE_STATEMENT_TIMEOUT`<br/>
250
250
  **YAML configuration key name:** `database_statement_timeout`<br/>
251
- **Default:** `15`<br/>
252
- **Allowed values:** A positive integer or float.<br/>
251
+ **Default:** `15000`<br/>
252
+ **Allowed values:** A positive integer in milliseconds<br/>
253
253
  **More information:** https://www.postgresql.org/docs/9.3/runtime-config-client.html<br/>
254
254
 
255
255
  ### metrics_sql_statement_timeout
@@ -0,0 +1,9 @@
1
+ # Business Domain Models
2
+
3
+ Sorry this is so scarce. I'm in a hurry, and this is better than nothing.
4
+
5
+ ![Pact Publication](./images/domain-model-of-pact-publication.png)
6
+
7
+ ![Pact Publication with verification](./images/domain-model-of-pact-publication-with-verification.png)
8
+
9
+ ![Technically more correct but harder to understand diagram](./images/domain-model-of-pact-publication-with-verification-technically-more-correct-but-harder-to-understand.png)
@@ -0,0 +1,19 @@
1
+ require "pact_broker/api/decorators/base_decorator"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Decorators
6
+ class ProviderStateDecorator < BaseDecorator
7
+ camelize_property_names
8
+
9
+ property :name
10
+ property :params
11
+
12
+ end
13
+
14
+ class ProviderStatesDecorator < BaseDecorator
15
+ collection :providerStates, getter: -> (context) { context[:represented].sort_by(&:name) }, :extend => PactBroker::Api::Decorators::ProviderStateDecorator
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ require_relative "base_decorator"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Decorators
6
+ class TriggeredWebhookLogsDecorator < BaseDecorator
7
+ class WebhookExecutionDecorator < BaseDecorator
8
+ property :success
9
+ property :logs
10
+ property :created_at, as: :createdAt
11
+ end
12
+
13
+
14
+ nested :triggeredWebhook, embedded: true do
15
+ property :uuid
16
+ end
17
+
18
+ collection :webhook_executions, as: :executions, :class => PactBroker::Webhooks::Execution, :extend => WebhookExecutionDecorator
19
+
20
+ link :self do | options |
21
+ {
22
+ title: "Triggered webhook logs",
23
+ href: options[:resource_url]
24
+ }
25
+ end
26
+
27
+ link :'pb:webhook' do | context |
28
+ if represented.webhook
29
+ {
30
+ href: webhook_url(represented.webhook.uuid, context[:base_url]),
31
+ title: "Webhook"
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -32,7 +32,7 @@ module PactBroker
32
32
  end
33
33
 
34
34
  def moved_temporarily?
35
- response.headers["Cache-Control"] = "no-cache"
35
+ set_cache_control("no-cache")
36
36
  begin
37
37
  badge_url
38
38
  rescue StandardError => e
@@ -46,6 +46,10 @@ module PactBroker
46
46
  raise NotImplementedError
47
47
  end
48
48
 
49
+ def set_cache_control(cache_control_str)
50
+ response.headers["Cache-Control"] = cache_control_str
51
+ end
52
+
49
53
  private
50
54
 
51
55
  def label
@@ -15,6 +15,8 @@ module PactBroker
15
15
  # when there is no main branch version, we return an error badge url
16
16
  badge_service.error_badge_url("main branch version", "not found")
17
17
  else
18
+ # when badge is available, set cache based on configuration
19
+ set_cache_control(default_cache_for_succesful_badge)
18
20
  # we call badge_service to build the badge url
19
21
  badge_service.can_i_merge_badge_url(deployable: results)
20
22
  end
@@ -22,6 +24,10 @@ module PactBroker
22
24
 
23
25
  private
24
26
 
27
+ def default_cache_for_succesful_badge
28
+ PactBroker.configuration.badge_default_cache_setting
29
+ end
30
+
25
31
  def results
26
32
  # can_i_merge returns true or false if the main branch version is compatible with all the integrations
27
33
  @results ||= matrix_service.can_i_merge(pacticipant: pacticipant, latest_main_branch_version: version)
@@ -16,6 +16,10 @@ module PactBroker
16
16
  ["GET", "OPTIONS"]
17
17
  end
18
18
 
19
+ def malformed_request?
20
+ super || request.get? && validation_errors_for_schema?(schema, request.query)
21
+ end
22
+
19
23
  def policy_name
20
24
  :'labels::labels'
21
25
  end
@@ -28,6 +32,15 @@ module PactBroker
28
32
  )
29
33
  end
30
34
 
35
+ private
36
+
37
+ def schema
38
+ if request.get?
39
+ PactBroker::Api::Contracts::PaginationQueryParamsSchema
40
+ end
41
+ end
42
+
43
+
31
44
  def labels
32
45
  label_service.get_all_unique_labels(pagination_options)
33
46
  end
@@ -0,0 +1,38 @@
1
+ require "pact_broker/api/resources/base_resource"
2
+ require "pact_broker/api/decorators/provider_states_decorator"
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Resources
7
+ class ProviderStates < BaseResource
8
+ def content_types_provided
9
+ [["application/hal+json", :to_json]]
10
+ end
11
+
12
+ def allowed_methods
13
+ ["GET", "OPTIONS"]
14
+ end
15
+
16
+ def resource_exists?
17
+ !!provider
18
+ end
19
+
20
+ def to_json
21
+ decorator_class(:provider_states_decorator).new(provider_states).to_json(decorator_options)
22
+ end
23
+
24
+ def policy_name
25
+ :'pacts::pacts'
26
+ end
27
+
28
+ private
29
+
30
+ # attr_reader :provider_states
31
+
32
+ def provider_states
33
+ @provider_states ||= provider_state_service.list_provider_states(provider)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -7,7 +7,7 @@ module PactBroker
7
7
  class TriggeredWebhookLogs < BaseResource
8
8
 
9
9
  def content_types_provided
10
- [["text/plain", :to_text]]
10
+ [["text/plain", :to_text], ["application/hal+json", :to_json]]
11
11
  end
12
12
 
13
13
  def allowed_methods
@@ -27,6 +27,10 @@ module PactBroker
27
27
  end
28
28
  end
29
29
 
30
+ def to_json
31
+ decorator_class(:triggered_webhook_logs_decorator).new(triggered_webhook).to_json(**decorator_options)
32
+ end
33
+
30
34
  def policy_name
31
35
  :'webhooks::triggered_webhook'
32
36
  end
@@ -44,6 +44,11 @@ module PactBroker
44
44
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "diff", "version", :comparison_consumer_version], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_consumer_version"}
45
45
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "diff", "pact-version", :comparison_pact_version_sha], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_pact_version_sha"}
46
46
 
47
+ # Provider states
48
+
49
+ add ["pacts", "provider", :provider_name, "provider-states"], Api::Resources::ProviderStates, { resource_name: "provider_states" }
50
+
51
+
47
52
  # Verifications
48
53
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results"], Api::Resources::Verifications, {resource_name: "verification_results"}
49
54
  add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "metadata", :metadata, "verification-results"], Api::Resources::Verifications, {resource_name: "verification_results"}
@@ -76,6 +76,7 @@ module PactBroker
76
76
  badge_provider_mode: :redirect,
77
77
  enable_public_badge_access: false,
78
78
  shields_io_base_url: "https://img.shields.io",
79
+ badge_default_cache_setting: "max-age=30",
79
80
  use_case_sensitive_resource_names: true,
80
81
  pact_content_diff_timeout: 15
81
82
  )
@@ -4,6 +4,8 @@ module PactBroker
4
4
  module DB
5
5
  module DataMigrations
6
6
  class SetInteractionsCounts
7
+ # This was never included in PactBroker::DB::MigrateData::MIGRATIONS
8
+
7
9
  def self.call(connection)
8
10
  self_join = {
9
11
  Sequel[:pact_publications][:consumer_id] => Sequel[:pp2][:consumer_id],
@@ -13,23 +13,35 @@ end
13
13
  module PactBroker
14
14
  module DB
15
15
  class MigrateData
16
+ include PactBroker::Logging
17
+
18
+ MIGRATIONS = [
19
+ DataMigrations::SetPacticipantIdsForVerifications,
20
+ DataMigrations::SetConsumerIdsForPactPublications,
21
+ DataMigrations::SetLatestVersionSequenceValue,
22
+ DataMigrations::SetWebhooksEnabled,
23
+ DataMigrations::DeleteDeprecatedWebhookExecutions,
24
+ DataMigrations::SetCreatedAtForLatestPactPublications,
25
+ DataMigrations::SetCreatedAtForLatestVerifications,
26
+ DataMigrations::SetExtraColumnsForTags,
27
+ DataMigrations::SetPacticipantDisplayName,
28
+ DataMigrations::SetWebhookUuid,
29
+ DataMigrations::SetConsumerVersionOrderForPactPublications,
30
+ DataMigrations::CreateBranches,
31
+ DataMigrations::MigrateIntegrations,
32
+ DataMigrations::MigratePactVersionProviderTagSuccessfulVerifications,
33
+ DataMigrations::SetContractDataUpdatedAtForIntegrations
34
+ ].freeze
35
+
36
+ def self.registered_migrations
37
+ MIGRATIONS
38
+ end
39
+
16
40
  def self.call database_connection, _options = {}
17
- DataMigrations::SetPacticipantIdsForVerifications.call(database_connection)
18
- DataMigrations::SetConsumerIdsForPactPublications.call(database_connection)
19
- DataMigrations::SetLatestVersionSequenceValue.call(database_connection)
20
- DataMigrations::SetWebhooksEnabled.call(database_connection)
21
- DataMigrations::DeleteDeprecatedWebhookExecutions.call(database_connection)
22
- DataMigrations::SetCreatedAtForLatestPactPublications.call(database_connection)
23
- DataMigrations::SetCreatedAtForLatestVerifications.call(database_connection)
24
- DataMigrations::SetExtraColumnsForTags.call(database_connection)
25
- DataMigrations::SetPacticipantDisplayName.call(database_connection)
26
- DataMigrations::SetWebhookUuid.call(database_connection)
27
- DataMigrations::SetConsumerVersionOrderForPactPublications.call(database_connection)
28
- DataMigrations::SetExtraColumnsForTags.call(database_connection)
29
- DataMigrations::CreateBranches.call(database_connection)
30
- DataMigrations::MigrateIntegrations.call(database_connection)
31
- DataMigrations::MigratePactVersionProviderTagSuccessfulVerifications.call(database_connection)
32
- DataMigrations::SetContractDataUpdatedAtForIntegrations.call(database_connection)
41
+ registered_migrations.each do | migration |
42
+ logger.debug "Running data migration #{migration.to_s.split("::").last.gsub(/([a-z\d])([A-Z])/, '\1 \2').split.join("-")}"
43
+ migration.call(database_connection)
44
+ end
33
45
  end
34
46
  end
35
47
  end
@@ -129,8 +129,9 @@ end
129
129
  # target_for_index | text | NOT NULL DEFAULT ''::text
130
130
  # auto_created | boolean | DEFAULT false
131
131
  # Indexes:
132
- # deployed_versions_pkey | PRIMARY KEY btree (id)
133
- # deployed_versions_uuid_index | UNIQUE btree (uuid)
132
+ # deployed_versions_pkey | PRIMARY KEY btree (id)
133
+ # deployed_versions_uuid_index | UNIQUE btree (uuid)
134
+ # deployed_versions_version_id_ndx | btree (version_id)
134
135
  # Foreign key constraints:
135
136
  # deployed_versions_environment_id_fkey | (environment_id) REFERENCES environments(id)
136
137
  # deployed_versions_version_id_fkey | (version_id) REFERENCES versions(id)
@@ -87,6 +87,7 @@ end
87
87
  # released_versions_uuid_index | UNIQUE btree (uuid)
88
88
  # released_versions_version_id_environment_id_index | UNIQUE btree (version_id, environment_id)
89
89
  # released_version_support_ended_at_index | btree (support_ended_at)
90
+ # released_versions_version_id_ndx | btree (version_id)
90
91
  # Foreign key constraints:
91
92
  # released_versions_environment_id_fkey | (environment_id) REFERENCES environments(id)
92
93
  # released_versions_version_id_fkey | (version_id) REFERENCES versions(id)
@@ -0,0 +1,28 @@
1
+ # Provider States - Aggregated view by provider
2
+
3
+ Allowed methods: `GET`
4
+
5
+ Path: `/pacts/provider/{provider}/provider-states`
6
+
7
+ This resource returns a aggregated de-duplicated list of all provider states for a given provider.
8
+
9
+ Provider states are collected from the latest pact on the main branch for any dependant consumers.
10
+
11
+ Example response
12
+
13
+ ```json
14
+ {
15
+ "providerStates": [
16
+ {
17
+ "name": "an error occurs retrieving an alligator"
18
+ },
19
+ {
20
+ "name": "there is an alligator named Mary"
21
+ },
22
+ {
23
+ "name": "there is not an alligator named Mary"
24
+ }
25
+ ]
26
+ }
27
+ ```
28
+
@@ -266,6 +266,7 @@ end
266
266
  # verifications_pact_version_id_id_index | btree (pact_version_id, id)
267
267
  # verifications_provider_id_consumer_id_index | btree (provider_id, consumer_id)
268
268
  # verifications_provider_id_index | btree (provider_id)
269
+ # verifications_provider_version_id_index | btree (provider_version_id)
269
270
  # Foreign key constraints:
270
271
  # fk_verifications_versions | (provider_version_id) REFERENCES versions(id)
271
272
  # verifications_consumer_id_fkey | (consumer_id) REFERENCES pacticipants(id)
@@ -149,9 +149,11 @@ end
149
149
 
150
150
  # Table: integrations
151
151
  # Columns:
152
- # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
153
- # consumer_id | integer | NOT NULL
154
- # provider_id | integer | NOT NULL
152
+ # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
153
+ # consumer_id | integer | NOT NULL
154
+ # provider_id | integer | NOT NULL
155
+ # created_at | timestamp without time zone | NOT NULL
156
+ # contract_data_updated_at | timestamp without time zone |
155
157
  # Indexes:
156
158
  # integrations_pkey | PRIMARY KEY btree (id)
157
159
  # integrations_consumer_id_provider_id_unique | UNIQUE btree (consumer_id, provider_id)
@@ -129,7 +129,13 @@ module PactBroker
129
129
  end
130
130
 
131
131
  def last_action_date
132
- return_or_raise_if_not_set(:last_action_date)
132
+ date = return_or_raise_if_not_set(:last_action_date)
133
+
134
+ if date.class == String
135
+ DateTime.parse(date)
136
+ else
137
+ date
138
+ end
133
139
  end
134
140
 
135
141
  def has_verification?
@@ -37,7 +37,10 @@ module PactBroker
37
37
  end
38
38
 
39
39
  def find(options = {}, pagination_options = {}, eager_load_associations = [])
40
- query = scope_for(PactBroker::Domain::Pacticipant).select_all_qualified
40
+ query = scope_for(PactBroker::Domain::Pacticipant)
41
+ return [] if query.empty?
42
+
43
+ query = query.select_all_qualified
41
44
  query = query.filter(:name, options[:query_string]) if options[:query_string]
42
45
  query = query.label(options[:label_name]) if options[:label_name]
43
46
  query.order_ignore_case(Sequel[:pacticipants][:name]).eager(*eager_load_associations).all_with_pagination_options(pagination_options)
@@ -5,7 +5,10 @@ require "pact_broker/hash_refinements"
5
5
 
6
6
  module PactBroker
7
7
  module Pacts
8
+ ProviderState = Struct.new(:name, :params)
8
9
  class Content
10
+
11
+
9
12
  include GenerateInteractionSha
10
13
  using PactBroker::HashRefinements
11
14
 
@@ -33,9 +36,21 @@ module PactBroker
33
36
  Content.from_hash(SortContent.call(pact_hash))
34
37
  end
35
38
 
39
+ def provider_states
40
+ messages_and_or_interactions_or_empty_array.flat_map do | interaction |
41
+ if interaction["providerState"].is_a?(String)
42
+ [ProviderState.new(interaction["providerState"])]
43
+ elsif interaction["providerStates"].is_a?(Array)
44
+ interaction["providerStates"].collect do | provider_state |
45
+ ProviderState.new(provider_state["name"], provider_state["params"])
46
+ end
47
+ end
48
+ end.compact
49
+ end
50
+
36
51
  def interactions_missing_test_results
37
- return [] unless messages_or_interactions
38
- messages_or_interactions.reject do | interaction |
52
+ return [] unless messages_and_or_interactions
53
+ messages_and_or_interactions.reject do | interaction |
39
54
  interaction["tests"]&.any?
40
55
  end
41
56
  end
@@ -90,7 +105,7 @@ module PactBroker
90
105
  end
91
106
 
92
107
  def interaction_ids
93
- messages_or_interaction_or_empty_array.collect do | interaction |
108
+ messages_and_or_interactions_or_empty_array.collect do | interaction |
94
109
  interaction["_id"]
95
110
  end.compact
96
111
  end
@@ -116,12 +131,14 @@ module PactBroker
116
131
  pact_hash.is_a?(Hash) && pact_hash["interactions"].is_a?(Array) ? pact_hash["interactions"] : nil
117
132
  end
118
133
 
119
- def messages_or_interactions
120
- messages || interactions
134
+ def messages_and_or_interactions
135
+ if messages || interactions
136
+ (messages || []) + (interactions || [])
137
+ end
121
138
  end
122
139
 
123
- def messages_or_interaction_or_empty_array
124
- messages_or_interactions || []
140
+ def messages_and_or_interactions_or_empty_array
141
+ messages_and_or_interactions || []
125
142
  end
126
143
 
127
144
  def pact_specification_version
@@ -24,6 +24,7 @@ end
24
24
  # Indexes:
25
25
  # latest_pact_publication_ids_for_consume_pact_publication_id_key | UNIQUE btree (pact_publication_id)
26
26
  # unq_latest_ppid_prov_conver | UNIQUE btree (provider_id, consumer_version_id)
27
+ # latest_pp_ids_for_cons_ver_con_ver_id_ndx | btree (consumer_version_id)
27
28
  # lpp_provider_id_consumer_id_index | btree (provider_id, consumer_id)
28
29
  # Foreign key constraints:
29
30
  # latest_pact_publication_ids_for_consum_consumer_version_id_fkey | (consumer_version_id) REFERENCES versions(id) ON DELETE CASCADE
@@ -0,0 +1,22 @@
1
+ require "pact_broker/services"
2
+ require "pact_broker/pacts/selectors"
3
+ require "pact_broker/pacts/pact_publication"
4
+ require "pact_broker/repositories"
5
+
6
+
7
+ module PactBroker
8
+ module Pacts
9
+ class ProviderStateService
10
+ # extend self
11
+ extend PactBroker::Services
12
+ extend PactBroker::Repositories::Scopes
13
+
14
+ def self.list_provider_states(provider)
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
+ query.all.flat_map do | pact_publication |
17
+ pact_publication.to_domain.content_object.provider_states
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -155,6 +155,10 @@ module PactBroker
155
155
  new(latest: true, branch: branch)
156
156
  end
157
157
 
158
+ def self.latest_for_main_branch
159
+ new(latest: true, main_branch: true)
160
+ end
161
+
158
162
  def self.latest_for_tag_with_fallback(tag, fallback_tag)
159
163
  new(latest: true, tag: tag, fallback_tag: fallback_tag)
160
164
  end
@@ -27,6 +27,10 @@ module PactBroker
27
27
  Selectors.new([Selector.latest_for_branch(branch)])
28
28
  end
29
29
 
30
+ def self.create_for_latest_from_main_branch
31
+ Selectors.new([Selector.latest_for_main_branch])
32
+ end
33
+
30
34
  def self.create_for_overall_latest
31
35
  Selectors.new([Selector.overall_latest])
32
36
  end
@@ -93,6 +93,10 @@ module PactBroker
93
93
  get_service(:branch_service)
94
94
  end
95
95
 
96
+ def provider_state_service
97
+ get_service(:provider_state_service)
98
+ end
99
+
96
100
  # rubocop: disable Metrics/MethodLength
97
101
  def register_default_services
98
102
  register_service(:index_service) do
@@ -194,6 +198,11 @@ module PactBroker
194
198
  require "pact_broker/versions/branch_service"
195
199
  PactBroker::Versions::BranchService
196
200
  end
201
+
202
+ register_service(:provider_state_service) do
203
+ require "pact_broker/pacts/provider_state_service"
204
+ PactBroker::Pacts::ProviderStateService
205
+ end
197
206
  end
198
207
  # rubocop: enable Metrics/MethodLength
199
208
  end
@@ -105,7 +105,7 @@ module PactBroker
105
105
 
106
106
  def output(string, payload = {})
107
107
  prefix = dry_run ? "[DRY RUN] " : ""
108
- logger ? logger.info("#{prefix}#{string}") : puts("#{prefix}#{string} #{payload.to_json}")
108
+ logger ? logger.info("#{prefix}#{string}", payload) : puts("#{prefix}#{string} #{payload.to_json}")
109
109
  end
110
110
 
111
111
  def add_defaults_to_keep_selectors
@@ -23,9 +23,10 @@ end
23
23
  # verification_id | integer | NOT NULL
24
24
  # created_at | timestamp without time zone |
25
25
  # Indexes:
26
- # latest_v_id_for_pv_and_pv_pv_id_pv_id_unq | UNIQUE btree (pact_version_id, provider_version_id)
27
- # latest_v_id_for_pv_and_pv_v_id_unq | UNIQUE btree (verification_id)
28
- # latest_v_id_for_pv_and_pv_pv_id_v_id | btree (pact_version_id, verification_id)
26
+ # latest_v_id_for_pv_and_pv_pv_id_pv_id_unq | UNIQUE btree (pact_version_id, provider_version_id)
27
+ # latest_v_id_for_pv_and_pv_v_id_unq | UNIQUE btree (verification_id)
28
+ # latest_v_id_for_pv_and_pv_pv_id_v_id | btree (pact_version_id, verification_id)
29
+ # latest_verif_id_for_pact_ver_and_prov_ver_prov_ver_id_ndx | btree (provider_version_id)
29
30
  # Foreign key constraints:
30
31
  # latest_v_id_for_pv_and_pv_consumer_id_fk | (consumer_id) REFERENCES pacticipants(id) ON DELETE CASCADE
31
32
  # latest_v_id_for_pv_and_pv_pact_version_id_fk | (pact_version_id) REFERENCES pact_versions(id) ON DELETE CASCADE
@@ -22,6 +22,7 @@ end
22
22
  # Indexes:
23
23
  # pact_version_provider_tag_successful_verifications_pkey | PRIMARY KEY btree (id)
24
24
  # pact_version_provider_tag_verifications_pv_pvtn_wip_unique | UNIQUE btree (pact_version_id, provider_version_tag_name, wip)
25
+ # pact_ver_prov_tag_success_verif_verif_id_ndx | btree (verification_id)
25
26
  # Foreign key constraints:
26
27
  # pact_version_provider_tag_successful_verifications_pv_id_fk | (pact_version_id) REFERENCES pact_versions(id) ON DELETE CASCADE
27
28
  # pact_version_provider_tag_successful_verifications_v_id_fk | (verification_id) REFERENCES verifications(id) ON DELETE SET NULL
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = "2.111.0"
2
+ VERSION = "2.113.0"
3
3
  end
@@ -32,10 +32,11 @@ end
32
32
  # pacticipant_id | integer | NOT NULL
33
33
  # branch_name | text | NOT NULL
34
34
  # Indexes:
35
- # branch_heads_branch_id_index | UNIQUE btree (branch_id)
36
- # branch_heads_branch_name_index | btree (branch_name)
37
- # branch_heads_pacticipant_id_index | btree (pacticipant_id)
38
- # branch_heads_version_id_index | btree (version_id)
35
+ # branch_heads_branch_id_index | UNIQUE btree (branch_id)
36
+ # branch_heads_branch_name_index | btree (branch_name)
37
+ # branch_heads_branch_version_id_index | btree (branch_version_id)
38
+ # branch_heads_pacticipant_id_index | btree (pacticipant_id)
39
+ # branch_heads_version_id_index | btree (version_id)
39
40
  # Foreign key constraints:
40
41
  # branch_heads_branch_id_fkey | (branch_id) REFERENCES branches(id) ON DELETE CASCADE
41
42
  # branch_heads_branch_version_id_fkey | (branch_version_id) REFERENCES branch_versions(id) ON DELETE CASCADE
@@ -29,12 +29,13 @@ end
29
29
  # Table: webhook_executions
30
30
  # Columns:
31
31
  # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
32
- # triggered_webhook_id | integer |
33
32
  # success | boolean | NOT NULL
34
33
  # logs | text |
35
34
  # created_at | timestamp without time zone | NOT NULL
35
+ # triggered_webhook_id | integer |
36
36
  # Indexes:
37
37
  # webhook_executions_pkey | PRIMARY KEY btree (id)
38
+ # webhook_executions_pact_publication_id_index | btree (pact_publication_id)
38
39
  # webhook_executions_triggered_webhook_id_index | btree (triggered_webhook_id)
39
40
  # Foreign key constraints:
40
41
  # webhook_executions_consumer_id_fkey | (consumer_id) REFERENCES pacticipants(id)
@@ -3,6 +3,7 @@
3
3
  # locks to be registered because different threads running the same code
4
4
  # should not cause a Sequel::Error to be raised.
5
5
  # Also, I wanted it to use Concurrent::Hash for multi-threaded environments.
6
+ # Made minor change in begin ensure block in with_advisory_lock method.
6
7
 
7
8
  require "sequel"
8
9
  require "zlib"
@@ -57,10 +58,9 @@ module Sequel
57
58
  synchronize do
58
59
  if get(Sequel.function(lock_function, *function_params))
59
60
  begin
60
- result = yield
61
+ yield
61
62
  ensure
62
63
  get(Sequel.function(UNLOCK_FUNCTION, *function_params))
63
- result
64
64
  end
65
65
  end
66
66
  end
data/pact_broker.gemspec CHANGED
@@ -60,9 +60,7 @@ Gem::Specification.new do |gem|
60
60
  gem.add_runtime_dependency "semver2", "~> 3.4.2"
61
61
  gem.add_runtime_dependency "rack", ">= 2.2.3", "~> 2.2" # TODO update to 3
62
62
  gem.add_runtime_dependency "redcarpet", ">= 3.5.1", "~>3.5"
63
- gem.add_runtime_dependency "pact-support" , "~> 1.16", ">= 1.16.4"
64
- gem.add_runtime_dependency "padrino-core", ">= 0.14.3", "~> 0.14"
65
- gem.add_runtime_dependency "sinatra", "~> 3.0"
63
+ gem.add_runtime_dependency "pact-support" , ">= 1.21.2", "~> 1.21"
66
64
  gem.add_runtime_dependency "haml", "~>5.0"
67
65
  gem.add_runtime_dependency "sucker_punch", "~>3.0"
68
66
  gem.add_runtime_dependency "rack-protection", "~> 3.0"
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact_broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.111.0
4
+ version: 2.113.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bethany Skurrie
8
8
  - Sergei Matheson
9
9
  - Warner Godfrey
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2024-08-12 00:00:00.000000000 Z
12
+ date: 2025-02-13 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: json
@@ -186,58 +185,24 @@ dependencies:
186
185
  version: '3.5'
187
186
  - !ruby/object:Gem::Dependency
188
187
  name: pact-support
189
- requirement: !ruby/object:Gem::Requirement
190
- requirements:
191
- - - "~>"
192
- - !ruby/object:Gem::Version
193
- version: '1.16'
194
- - - ">="
195
- - !ruby/object:Gem::Version
196
- version: 1.16.4
197
- type: :runtime
198
- prerelease: false
199
- version_requirements: !ruby/object:Gem::Requirement
200
- requirements:
201
- - - "~>"
202
- - !ruby/object:Gem::Version
203
- version: '1.16'
204
- - - ">="
205
- - !ruby/object:Gem::Version
206
- version: 1.16.4
207
- - !ruby/object:Gem::Dependency
208
- name: padrino-core
209
188
  requirement: !ruby/object:Gem::Requirement
210
189
  requirements:
211
190
  - - ">="
212
191
  - !ruby/object:Gem::Version
213
- version: 0.14.3
192
+ version: 1.21.2
214
193
  - - "~>"
215
194
  - !ruby/object:Gem::Version
216
- version: '0.14'
195
+ version: '1.21'
217
196
  type: :runtime
218
197
  prerelease: false
219
198
  version_requirements: !ruby/object:Gem::Requirement
220
199
  requirements:
221
200
  - - ">="
222
201
  - !ruby/object:Gem::Version
223
- version: 0.14.3
224
- - - "~>"
225
- - !ruby/object:Gem::Version
226
- version: '0.14'
227
- - !ruby/object:Gem::Dependency
228
- name: sinatra
229
- requirement: !ruby/object:Gem::Requirement
230
- requirements:
231
- - - "~>"
232
- - !ruby/object:Gem::Version
233
- version: '3.0'
234
- type: :runtime
235
- prerelease: false
236
- version_requirements: !ruby/object:Gem::Requirement
237
- requirements:
202
+ version: 1.21.2
238
203
  - - "~>"
239
204
  - !ruby/object:Gem::Version
240
- version: '3.0'
205
+ version: '1.21'
241
206
  - !ruby/object:Gem::Dependency
242
207
  name: haml
243
208
  requirement: !ruby/object:Gem::Requirement
@@ -582,6 +547,7 @@ files:
582
547
  - docs/api/PACTICIPANTS.md
583
548
  - docs/api/PAGINATION.md
584
549
  - docs/api/WEBHOOKS.md
550
+ - docs/developer/business_domain_models.md
585
551
  - docs/developer/design_pattern_for_eager_loading_collections.md
586
552
  - docs/developer/matrix.md
587
553
  - docs/developer/rack.md
@@ -672,6 +638,7 @@ files:
672
638
  - lib/pact_broker/api/decorators/pacts_for_verification_query_decorator.rb
673
639
  - lib/pact_broker/api/decorators/pagination_links.rb
674
640
  - lib/pact_broker/api/decorators/provider_pacts_decorator.rb
641
+ - lib/pact_broker/api/decorators/provider_states_decorator.rb
675
642
  - lib/pact_broker/api/decorators/publish_contract_decorator.rb
676
643
  - lib/pact_broker/api/decorators/publish_contracts_decorator.rb
677
644
  - lib/pact_broker/api/decorators/publish_contracts_results_decorator.rb
@@ -685,6 +652,7 @@ files:
685
652
  - lib/pact_broker/api/decorators/tagged_pact_versions_decorator.rb
686
653
  - lib/pact_broker/api/decorators/timestamps.rb
687
654
  - lib/pact_broker/api/decorators/triggered_webhook_decorator.rb
655
+ - lib/pact_broker/api/decorators/triggered_webhook_logs_decorator.rb
688
656
  - lib/pact_broker/api/decorators/triggered_webhooks_decorator.rb
689
657
  - lib/pact_broker/api/decorators/validation_errors_decorator.rb
690
658
  - lib/pact_broker/api/decorators/validation_errors_problem_json_decorator.rb
@@ -773,6 +741,7 @@ files:
773
741
  - lib/pact_broker/api/resources/previous_distinct_pact_version.rb
774
742
  - lib/pact_broker/api/resources/provider_pacts.rb
775
743
  - lib/pact_broker/api/resources/provider_pacts_for_verification.rb
744
+ - lib/pact_broker/api/resources/provider_states.rb
776
745
  - lib/pact_broker/api/resources/publish_contracts.rb
777
746
  - lib/pact_broker/api/resources/relationships.rb
778
747
  - lib/pact_broker/api/resources/released_version.rb
@@ -898,6 +867,7 @@ files:
898
867
  - lib/pact_broker/doc/views/pact/latest-pact-version.markdown
899
868
  - lib/pact_broker/doc/views/pact/matrix-for-consumer-version.markdown
900
869
  - lib/pact_broker/doc/views/pact/pact-webhooks.markdown
870
+ - lib/pact_broker/doc/views/pact/provider-states.markdown
901
871
  - lib/pact_broker/doc/views/pact/publish-verification-results.markdown
902
872
  - lib/pact_broker/doc/views/pact/tag-prod-version.markdown
903
873
  - lib/pact_broker/doc/views/pact/tag-version.markdown
@@ -999,6 +969,7 @@ files:
999
969
  - lib/pact_broker/pacts/pacts_for_verification_repository.rb
1000
970
  - lib/pact_broker/pacts/parse.rb
1001
971
  - lib/pact_broker/pacts/placeholder_pact.rb
972
+ - lib/pact_broker/pacts/provider_state_service.rb
1002
973
  - lib/pact_broker/pacts/repository.rb
1003
974
  - lib/pact_broker/pacts/selected_pact.rb
1004
975
  - lib/pact_broker/pacts/selector.rb
@@ -1253,7 +1224,6 @@ homepage: https://github.com/pact-foundation/pact_broker
1253
1224
  licenses:
1254
1225
  - MIT
1255
1226
  metadata: {}
1256
- post_install_message:
1257
1227
  rdoc_options: []
1258
1228
  require_paths:
1259
1229
  - lib
@@ -1268,8 +1238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1268
1238
  - !ruby/object:Gem::Version
1269
1239
  version: '0'
1270
1240
  requirements: []
1271
- rubygems_version: 3.5.17
1272
- signing_key:
1241
+ rubygems_version: 3.6.3
1273
1242
  specification_version: 4
1274
1243
  summary: See description
1275
1244
  test_files: []