pact_broker 2.117.1 → 2.119.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/db/migrations/20251106_add_branch_versions_version_id_branch_name_index.rb +21 -0
- data/db/migrations/20251202_add_has_messages_column_to_pact_versions.rb +7 -0
- data/db/migrations/20251202_populate_has_messages_in_pact_versions.rb +29 -0
- data/db/migrations/20260119_add_index_on_consumer_id_provider_id_to_pact_versions.rb +20 -0
- data/db/migrations/20260123_drop_branch_versions_branch_name_index.rb +17 -0
- data/db/migrations/20260210_add_index_on_pact_version_id_to_latest_pact_publication.rb +22 -0
- data/db/migrations/20260217_add_wip_query_optimization_indexes.rb +31 -0
- data/lib/pact_broker/api/decorators/version_decorator.rb +1 -1
- data/lib/pact_broker/api/resources/index.rb +3 -3
- data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +1 -1
- data/lib/pact_broker/api.rb +3 -3
- data/lib/pact_broker/config/runtime_configuration.rb +9 -8
- data/lib/pact_broker/configuration.rb +26 -0
- data/lib/pact_broker/deployments/deployed_version_service.rb +1 -0
- data/lib/pact_broker/doc/views/index/latest-branch-pact-versions.markdown +1 -1
- data/lib/pact_broker/doc/views/index/latest-main-branch-pact-versions.markdown +1 -1
- data/lib/pact_broker/doc/views/index/main-branch-pact-versions.markdown +1 -1
- data/lib/pact_broker/domain/pacticipant.rb +12 -1
- data/lib/pact_broker/logging.rb +10 -0
- data/lib/pact_broker/pacts/interactions/types.rb +44 -0
- data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +5 -1
- data/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +11 -2
- data/lib/pact_broker/pacts/pact_publication_wip_dataset_module.rb +13 -4
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +90 -2
- data/lib/pact_broker/pacts/repository.rb +7 -4
- data/lib/pact_broker/pacts/service.rb +1 -1
- data/lib/pact_broker/test/test_data_builder.rb +13 -7
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/branch_version_repository.rb +15 -9
- data/lib/pact_broker/webhooks/event_listener.rb +1 -1
- data/lib/pact_broker/webhooks/execution_configuration.rb +4 -0
- data/lib/pact_broker/webhooks/redact_logs.rb +4 -4
- data/lib/sequel/plugins/upsert.rb +7 -0
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e28c13c74efb9e4cd894da6d14e18a28ea6d15c3240f4defc2b2fe246d1fafb0
|
|
4
|
+
data.tar.gz: 6194f39dd67344eed51782de55bea6d95ee937716bd59afbe8b6ee2cfe473b08
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40138782cf26259e00e0f2417d9243f5066f4b6dd77ad076869f12f47adcfb7f4a85481e4b9f3cff4ba9ba9bf03881bbb69e71fa7b269bd868a472ed74c2b91e
|
|
7
|
+
data.tar.gz: 056be7ffcb8273b41d7e1292307b495a6277b71248b685515185f0239b477aa8fb6ff6646ef9ac22e86cfb87aa10bfe969ff93a1868ef10e1e81a3ae793f381a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
<a name="v2.119.0"></a>
|
|
2
|
+
### v2.119.0 (2026-04-02)
|
|
3
|
+
|
|
4
|
+
#### Features
|
|
5
|
+
|
|
6
|
+
* support customising webhook requests ([d20a8274](/../../commit/d20a8274))
|
|
7
|
+
* Optimize WIP Query Performance to Prevent Timeouts on Large Datasets (#902) ([711ac3c6](/../../commit/711ac3c6))
|
|
8
|
+
|
|
9
|
+
#### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* add missing import and small improvement to batch delete (#899) ([2e83d012](/../../commit/2e83d012))
|
|
12
|
+
* new unit test failure ([6c39e927](/../../commit/6c39e927))
|
|
13
|
+
* avoid N+1 cascade ([681d98d9](/../../commit/681d98d9))
|
|
14
|
+
* dont create index for mysql ([1ec72cc8](/../../commit/1ec72cc8))
|
|
15
|
+
* Pacticipant API returning undeployed versions in pacticipant deployed-environments endpoint (#889) ([e217d3ba](/../../commit/e217d3ba))
|
|
16
|
+
|
|
17
|
+
* **PACT-5504**
|
|
18
|
+
* use batch delete to speed up deletion ([e908035a](/../../commit/e908035a))
|
|
19
|
+
|
|
20
|
+
<a name="v2.118.0"></a>
|
|
21
|
+
### v2.118.0 (2026-01-02)
|
|
22
|
+
|
|
23
|
+
#### Features
|
|
24
|
+
|
|
25
|
+
* added has_messages column to pact_versions table (#880) ([34741dae](/../../commit/34741dae))
|
|
26
|
+
|
|
27
|
+
#### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* remove route overlap and add tests for new routes ([45a81474](/../../commit/45a81474))
|
|
30
|
+
* restore latest pact for branch endpoint ([cb867957](/../../commit/cb867957))
|
|
31
|
+
|
|
1
32
|
<a name="v2.117.1"></a>
|
|
2
33
|
### v2.117.1 (2025-11-02)
|
|
3
34
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative "migration_helper"
|
|
2
|
+
|
|
3
|
+
include PactBroker::MigrationHelper
|
|
4
|
+
|
|
5
|
+
Sequel.migration do
|
|
6
|
+
up do
|
|
7
|
+
if !mysql?
|
|
8
|
+
alter_table(:branch_versions) do
|
|
9
|
+
add_index([:version_id, :branch_name], name: "branch_versions_version_id_branch_name_idx")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
down do
|
|
15
|
+
if !mysql?
|
|
16
|
+
alter_table(:branch_versions) do
|
|
17
|
+
drop_index([:version_id, :branch_name], name: "branch_versions_version_id_branch_name_idx")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require "pact_broker/pacts/content"
|
|
2
|
+
require "pact_broker/pacts/interactions/types"
|
|
3
|
+
|
|
4
|
+
Sequel.migration do
|
|
5
|
+
up do
|
|
6
|
+
batch_size = 500
|
|
7
|
+
offset = 0
|
|
8
|
+
|
|
9
|
+
loop do
|
|
10
|
+
rows = from(:pact_versions).order(:id).limit(batch_size).offset(offset).all
|
|
11
|
+
break if rows.empty?
|
|
12
|
+
|
|
13
|
+
rows.each do |row|
|
|
14
|
+
content = PactBroker::Pacts::Content.from_json(row[:content])
|
|
15
|
+
has_messages = PactBroker::Pacts::Interactions::Types.for(content).has_messages?
|
|
16
|
+
|
|
17
|
+
from(:pact_versions)
|
|
18
|
+
.where(id: row[:id])
|
|
19
|
+
.update(has_messages: has_messages)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
offset += batch_size
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
down do
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Sequel.migration do
|
|
2
|
+
up do
|
|
3
|
+
if !mysql?
|
|
4
|
+
alter_table(:pact_versions) do
|
|
5
|
+
add_index :consumer_id, name: :pact_versions_consumer_id_index
|
|
6
|
+
add_index :provider_id, name: :pact_versions_provider_id_index
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
down do
|
|
12
|
+
if !mysql?
|
|
13
|
+
alter_table(:pact_versions) do
|
|
14
|
+
drop_index :consumer_id, name: :pact_versions_consumer_id_index
|
|
15
|
+
drop_index :provider_id, name: :pact_versions_provider_id_index
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Sequel.migration do
|
|
2
|
+
up do
|
|
3
|
+
if !mysql?
|
|
4
|
+
alter_table(:branch_versions) do
|
|
5
|
+
drop_index([:branch_name], name: "branch_versions_branch_name_index")
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
down do
|
|
11
|
+
if !mysql?
|
|
12
|
+
alter_table(:branch_versions) do
|
|
13
|
+
add_index([:branch_name], name: "branch_versions_branch_name_index")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require_relative "migration_helper"
|
|
2
|
+
|
|
3
|
+
include PactBroker::MigrationHelper
|
|
4
|
+
|
|
5
|
+
Sequel.migration do
|
|
6
|
+
up do
|
|
7
|
+
if !mysql?
|
|
8
|
+
alter_table(:latest_pact_publication_ids_for_consumer_versions) do
|
|
9
|
+
add_index :pact_version_id, name: :latest_pp_ids_for_cons_ver_pact_version_id_index
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
down do
|
|
15
|
+
if !mysql?
|
|
16
|
+
alter_table(:latest_pact_publication_ids_for_consumer_versions) do
|
|
17
|
+
drop_index :pact_version_id, name: :latest_pp_ids_for_cons_ver_pact_version_id_index
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require_relative "migration_helper"
|
|
2
|
+
|
|
3
|
+
include PactBroker::MigrationHelper
|
|
4
|
+
|
|
5
|
+
Sequel.migration do
|
|
6
|
+
no_transaction if PactBroker::MigrationHelper.postgres?
|
|
7
|
+
|
|
8
|
+
up do
|
|
9
|
+
if !mysql?
|
|
10
|
+
alter_table(:pact_publications) do
|
|
11
|
+
add_index([:provider_id, :created_at], name: "idx_pp_provider_created", concurrently: postgres?)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
alter_table(:verifications) do
|
|
15
|
+
add_index([:provider_id, :provider_version_id, :success, :wip, :pact_version_id], name: "idx_verifications_provider_lookup", concurrently: postgres?)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
down do
|
|
21
|
+
if !mysql?
|
|
22
|
+
alter_table(:pact_publications) do
|
|
23
|
+
drop_index([:provider_id, :created_at], name: "idx_pp_provider_created")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
alter_table(:verifications) do
|
|
27
|
+
drop_index([:provider_id, :provider_version_id, :success, :wip, :pact_version_id], name: "idx_verifications_provider_lookup")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -25,7 +25,7 @@ module PactBroker
|
|
|
25
25
|
def self.eager_load_associations
|
|
26
26
|
[
|
|
27
27
|
:pacticipant,
|
|
28
|
-
:
|
|
28
|
+
{ pact_publications: [:consumer, :provider, { pact_version: :latest_verification }, :tags, :head_pact_publications_for_tags] },
|
|
29
29
|
{ branch_versions: [:version, :branch_head, { branch: :pacticipant }] },
|
|
30
30
|
{ tags: :head_tag }
|
|
31
31
|
]
|
|
@@ -57,19 +57,19 @@ module PactBroker
|
|
|
57
57
|
},
|
|
58
58
|
"pb:latest-branch-pact-versions" =>
|
|
59
59
|
{
|
|
60
|
-
href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}/latest",
|
|
60
|
+
href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}/latest/versions",
|
|
61
61
|
title: "Latest version of pact for a provider, for a named consumers branch",
|
|
62
62
|
templated: true
|
|
63
63
|
},
|
|
64
64
|
"pb:main-branch-pact-versions" =>
|
|
65
65
|
{
|
|
66
|
-
href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch",
|
|
66
|
+
href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch/versions",
|
|
67
67
|
title: "All versions of pacts for a provider, for a named consumers main branch",
|
|
68
68
|
templated: true
|
|
69
69
|
},
|
|
70
70
|
"pb:latest-main-branch-pact-versions" =>
|
|
71
71
|
{
|
|
72
|
-
href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch/latest",
|
|
72
|
+
href: base_url + "/pacts/provider/{provider}/consumer/{consumer}/branch/latest/versions",
|
|
73
73
|
title: "Latest version of pact for a provider, for a named consumers main branch",
|
|
74
74
|
templated: true
|
|
75
75
|
},
|
|
@@ -94,7 +94,7 @@ module PactBroker
|
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
def log_request
|
|
97
|
-
logger.
|
|
97
|
+
logger.debug "Fetching pacts for verification by #{provider_name}", provider_name: provider_name, params: query
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def nested_query
|
data/lib/pact_broker/api.rb
CHANGED
|
@@ -33,10 +33,10 @@ module PactBroker
|
|
|
33
33
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "versions"], Api::Resources::PactVersions, {resource_name: "pact_publications"}
|
|
34
34
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "versions", :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication", deprecated: true} # Not the standard URL, but keep for backwards compatibility
|
|
35
35
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "tag", :tag], Api::Resources::TaggedPactVersions, {resource_name: "tagged_pact_publications"}
|
|
36
|
-
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch"], Api::Resources::PactVersionsForBranch, {resource_name: "pact_publications_for_main_branch"}
|
|
37
|
-
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", "latest"], Api::Resources::PactVersionsForBranch, {resource_name: "latest_pact_publications_for_main_branch"}
|
|
38
|
-
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", :branch_name, "latest"], Api::Resources::PactVersionsForBranch, {resource_name: "latest_pact_publications_for_branch"}
|
|
36
|
+
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", "versions"], Api::Resources::PactVersionsForBranch, {resource_name: "pact_publications_for_main_branch"}
|
|
39
37
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", :branch_name], Api::Resources::PactVersionsForBranch, {resource_name: "pact_publications_for_branch"}
|
|
38
|
+
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", "latest", "versions"], Api::Resources::PactVersionsForBranch, {resource_name: "latest_pact_publications_for_main_branch"}
|
|
39
|
+
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", :branch_name, "latest", "versions"], Api::Resources::PactVersionsForBranch, {resource_name: "latest_pact_publications_for_branch"}
|
|
40
40
|
|
|
41
41
|
# Pacts
|
|
42
42
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication"}
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
require "anyway_config"
|
|
2
|
-
require "pact_broker/config/runtime_configuration_logging_methods"
|
|
3
|
-
require "pact_broker/config/runtime_configuration_database_methods"
|
|
4
|
-
require "pact_broker/config/runtime_configuration_coercion_methods"
|
|
5
|
-
require "pact_broker/version"
|
|
6
|
-
require "pact_broker/config/runtime_configuration_basic_auth_methods"
|
|
7
|
-
require "pact_broker/string_refinements"
|
|
8
|
-
require "pact_broker/hash_refinements"
|
|
9
|
-
require "pact_broker/error"
|
|
10
2
|
|
|
11
3
|
module Anyway
|
|
12
4
|
module Tracing
|
|
@@ -20,6 +12,15 @@ module Anyway
|
|
|
20
12
|
end
|
|
21
13
|
end
|
|
22
14
|
|
|
15
|
+
require "pact_broker/config/runtime_configuration_logging_methods"
|
|
16
|
+
require "pact_broker/config/runtime_configuration_database_methods"
|
|
17
|
+
require "pact_broker/config/runtime_configuration_coercion_methods"
|
|
18
|
+
require "pact_broker/version"
|
|
19
|
+
require "pact_broker/config/runtime_configuration_basic_auth_methods"
|
|
20
|
+
require "pact_broker/string_refinements"
|
|
21
|
+
require "pact_broker/hash_refinements"
|
|
22
|
+
require "pact_broker/error"
|
|
23
|
+
|
|
23
24
|
module PactBroker
|
|
24
25
|
module Config
|
|
25
26
|
class RuntimeConfiguration < Anyway::Config
|
|
@@ -201,6 +201,32 @@ module PactBroker
|
|
|
201
201
|
webhook_host_whitelist&.any?
|
|
202
202
|
end
|
|
203
203
|
|
|
204
|
+
def dynamic_wip_window_enabled?
|
|
205
|
+
ENV["PACT_BROKER_DYNAMIC_WIP_WINDOW"]&.downcase == "true"
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Maximum lookback window (days) to query for unverified pacts. Prevents timeout on large datasets.
|
|
209
|
+
def max_wip_lookback_days
|
|
210
|
+
ENV["PACT_BROKER_MAX_WIP_LOOKBACK_DAYS"]&.to_i || 14
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Minimum WIP window (days) to ensure recent pacts are always included, even if P80 is very low.
|
|
214
|
+
def min_wip_window_days
|
|
215
|
+
ENV["PACT_BROKER_MIN_WIP_WINDOW_DAYS"]&.to_i || 7
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Lookback window (days) for checking if a pact was verified by another branch before this branch was created.
|
|
219
|
+
# Uses verification execution_date to find recent branch activity, avoiding false negatives when old
|
|
220
|
+
# version numbers are reused across branches.
|
|
221
|
+
def verified_by_other_branch_before_this_branch_look_back
|
|
222
|
+
ENV["PACT_BROKER_VERIFIED_BY_OTHER_BRANCH_LOOKBACK_DAYS"]&.to_i || 30
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Default WIP window (days) used when dynamic calculation fails or no unverified pacts exist.
|
|
226
|
+
def default_wip_window_days
|
|
227
|
+
ENV["PACT_BROKER_DEFAULT_WIP_WINDOW_DAYS"]&.to_i || 7
|
|
228
|
+
end
|
|
229
|
+
|
|
204
230
|
def enable_badge_resources= enable_badge_resources
|
|
205
231
|
puts "Pact Broker configuration property `enable_badge_resources` is deprecated. Please use `enable_public_badge_access`"
|
|
206
232
|
self.enable_public_badge_access = enable_badge_resources
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Allowed methods: `GET`
|
|
4
4
|
|
|
5
|
-
Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}/latest`
|
|
5
|
+
Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/{branch}/latest/versions`
|
|
6
6
|
|
|
7
7
|
Returns the latest pact version with the specified consumer, provider and consumer version branch.
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Allowed methods: `GET`
|
|
4
4
|
|
|
5
|
-
Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/latest`
|
|
5
|
+
Path: `/pacts/provider/{provider}/consumer/{consumer}/branch/latest/versions`
|
|
6
6
|
|
|
7
7
|
Lists all latest pact version with the specified consumer, provider and the consumers main branch.
|
|
@@ -55,11 +55,22 @@ module PactBroker
|
|
|
55
55
|
PactBroker::Pacts::PactPublication.where(provider: self).delete
|
|
56
56
|
PactBroker::Domain::Verification.where(consumer: self).or(provider: self).delete
|
|
57
57
|
PactBroker::Domain::Version.where(pacticipant: self).delete
|
|
58
|
-
|
|
58
|
+
delete_pact_versions_in_batches
|
|
59
59
|
PactBroker::Domain::Label.where(pacticipant: self).destroy
|
|
60
60
|
super
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
BATCH_DELETE_SIZE = 500
|
|
64
|
+
def delete_pact_versions_in_batches
|
|
65
|
+
dataset = PactBroker::Pacts::PactVersion.where(consumer: self).or(provider: self).order(:id)
|
|
66
|
+
loop do
|
|
67
|
+
deleted = PactBroker::Pacts::PactVersion
|
|
68
|
+
.where(id: dataset.limit(BATCH_DELETE_SIZE).select(:id))
|
|
69
|
+
.delete
|
|
70
|
+
break if deleted.zero?
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
63
74
|
def before_save
|
|
64
75
|
super
|
|
65
76
|
self.display_name = generate_display_name(name) if display_name.blank?
|
data/lib/pact_broker/logging.rb
CHANGED
|
@@ -52,6 +52,16 @@ module PactBroker
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
def measure_debug(message, payload: {})
|
|
56
|
+
if logger.respond_to?(:measure_debug)
|
|
57
|
+
logger.measure_debug(message, payload: payload) do
|
|
58
|
+
yield
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
yield
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
55
65
|
def log_error e, description = nil
|
|
56
66
|
if logger.instance_of?(SemanticLogger::Logger)
|
|
57
67
|
if description
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module PactBroker
|
|
2
|
+
module Pacts
|
|
3
|
+
module Interactions
|
|
4
|
+
class Types
|
|
5
|
+
# Pact Spec v4+ message interaction types
|
|
6
|
+
MESSAGE_TYPES = [
|
|
7
|
+
"Asynchronous/Messages",
|
|
8
|
+
"Synchronous/Messages"
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
def initialize(content)
|
|
12
|
+
@content = content
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.for(content)
|
|
16
|
+
new(content)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def has_messages?
|
|
20
|
+
if spec_version < 4.0
|
|
21
|
+
# Pre-v4: messages in "messages" key
|
|
22
|
+
content.messages&.any? || false
|
|
23
|
+
else
|
|
24
|
+
# V4+: messages are typed interactions
|
|
25
|
+
content.interactions&.any? { |i| message_interaction?(i) } || false
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
attr_reader :content
|
|
32
|
+
|
|
33
|
+
def message_interaction?(interaction)
|
|
34
|
+
interaction.is_a?(Hash) &&
|
|
35
|
+
MESSAGE_TYPES.include?(interaction["type"])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def spec_version
|
|
39
|
+
content.pact_specification_version.to_f
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -287,9 +287,13 @@ module PactBroker
|
|
|
287
287
|
# NEW LOGIC
|
|
288
288
|
# @return [Sequel::Dataset<PactBroker::Pacts::PactPublication>]
|
|
289
289
|
def for_all_tag_heads
|
|
290
|
+
# Optimization: Only aggregate tags for consumers that have pacts for this provider.
|
|
291
|
+
relevant_consumer_ids = self.select(:consumer_id).distinct
|
|
292
|
+
|
|
290
293
|
head_tags = PactBroker::Domain::Tag
|
|
291
294
|
.select_group(:pacticipant_id, :name)
|
|
292
|
-
.select_append{ max(version_order).as(:latest_version_order) }
|
|
295
|
+
.select_append{ max(:version_order).as(:latest_version_order) }
|
|
296
|
+
.where(pacticipant_id: relevant_consumer_ids)
|
|
293
297
|
|
|
294
298
|
head_tags_join = {
|
|
295
299
|
Sequel[:pact_publications][:consumer_id] => Sequel[:head_tags][:pacticipant_id],
|
|
@@ -46,9 +46,18 @@ module PactBroker
|
|
|
46
46
|
|
|
47
47
|
def for_main_branches
|
|
48
48
|
consumers_join = { Sequel[:pact_publications][:consumer_id] => Sequel[:consumers][:id] }
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
branch_versions_join = {
|
|
50
|
+
Sequel[:branch_versions][:version_id] => Sequel[:pact_publications][:consumer_version_id],
|
|
51
|
+
Sequel[:branch_versions][:branch_name] => Sequel[:consumers][:main_branch]
|
|
52
|
+
}
|
|
53
|
+
base_query = self
|
|
54
|
+
|
|
55
|
+
if no_columns_selected?
|
|
56
|
+
base_query = base_query.select_all_qualified.select_append(Sequel[:branch_versions][:branch_name].as(:branch_name))
|
|
57
|
+
end
|
|
58
|
+
base_query
|
|
51
59
|
.join(:pacticipants, consumers_join, { table_alias: :consumers })
|
|
60
|
+
.join(:branch_versions, branch_versions_join)
|
|
52
61
|
.remove_overridden_revisions_from_complete_query
|
|
53
62
|
end
|
|
54
63
|
|
|
@@ -19,13 +19,19 @@ module PactBroker
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def join_branch_versions_excluding_branch(provider_id, branch_name)
|
|
22
|
+
# Only check branches that have been active in the last N days
|
|
23
|
+
# to avoid old stale branches causing cartesian explosion.
|
|
24
|
+
# Filter by verification execution_date rather than version created_at
|
|
25
|
+
# to avoid incorrectly excluding old versions with recent verifications.
|
|
26
|
+
recent_branch_cutoff = DateTime.now - PactBroker.configuration.verified_by_other_branch_before_this_branch_look_back
|
|
27
|
+
|
|
22
28
|
branch_versions_join = {
|
|
23
29
|
Sequel[:verifications][:provider_version_id] => Sequel[:branch_versions][:version_id],
|
|
24
30
|
Sequel[:branch_versions][:pacticipant_id] => provider_id
|
|
25
31
|
}
|
|
26
|
-
join(:branch_versions, branch_versions_join)
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
join(:branch_versions, branch_versions_join)
|
|
33
|
+
.where { Sequel[:verifications][:execution_date] >= recent_branch_cutoff }
|
|
34
|
+
.where { Sequel.lit("branch_versions.branch_name != ?", branch_name) }
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
def join_provider_versions_for_provider_id_and_branch(provider_id, provider_version_branch)
|
|
@@ -45,10 +51,13 @@ module PactBroker
|
|
|
45
51
|
end
|
|
46
52
|
|
|
47
53
|
def successfully_verified_by_provider_branch_when_not_wip(provider_id, provider_version_branch)
|
|
54
|
+
# Only check verifications from last N days (old verifications unlikely relevant for WIP)
|
|
55
|
+
recent_cutoff = DateTime.now - PactBroker.configuration.verified_by_other_branch_before_this_branch_look_back
|
|
48
56
|
successful_verifications = VerificationForWipCalculations
|
|
49
57
|
.select(:pact_version_id)
|
|
50
58
|
.distinct
|
|
51
59
|
.successful_non_wip_by_provider(provider_id)
|
|
60
|
+
.where { Sequel[:verifications][:execution_date] >= recent_cutoff }
|
|
52
61
|
.join_provider_versions_for_provider_id_and_branch(provider_id, provider_version_branch)
|
|
53
62
|
|
|
54
63
|
|
|
@@ -65,8 +74,8 @@ module PactBroker
|
|
|
65
74
|
.select(:pact_version_id)
|
|
66
75
|
.distinct
|
|
67
76
|
.successful_non_wip_by_provider(provider_id)
|
|
68
|
-
.join_branch_versions_excluding_branch(provider_id, provider_version_branch)
|
|
69
77
|
.verified_before_creation_date_of(first_version_for_branch)
|
|
78
|
+
.join_branch_versions_excluding_branch(provider_id, provider_version_branch)
|
|
70
79
|
|
|
71
80
|
from_self(alias: :pp)
|
|
72
81
|
.select(Sequel[:pp].*)
|
|
@@ -57,7 +57,7 @@ module PactBroker
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
provider = pacticipant_repository.find_by_name(provider_name)
|
|
60
|
-
wip_start_date = options
|
|
60
|
+
wip_start_date = determine_wip_start_date(provider, options)
|
|
61
61
|
|
|
62
62
|
wip_by_consumer_tags = find_wip_pact_versions_for_provider_by_provider_tags(
|
|
63
63
|
provider,
|
|
@@ -80,6 +80,94 @@ module PactBroker
|
|
|
80
80
|
|
|
81
81
|
private
|
|
82
82
|
|
|
83
|
+
# Determine the WIP start date based on configuration and options
|
|
84
|
+
def determine_wip_start_date(provider, options)
|
|
85
|
+
dynamic_enabled = PactBroker.configuration.dynamic_wip_window_enabled?
|
|
86
|
+
logger.debug("Dynamic WIP window: #{dynamic_enabled ? 'enabled' : 'disabled'}") if logger.debug?
|
|
87
|
+
|
|
88
|
+
if dynamic_enabled
|
|
89
|
+
calculate_wip_window(provider)
|
|
90
|
+
else
|
|
91
|
+
wip_start_date = options.fetch(:include_wip_pacts_since)
|
|
92
|
+
logger.debug("Using user-specified WIP window: #{wip_start_date}") if logger.debug?
|
|
93
|
+
wip_start_date
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Calculate optimal WIP window using P80 (80th percentile) of unverified pact ages
|
|
98
|
+
# Uses percentile instead of MAX to focus on active work and ignore abandoned pacts
|
|
99
|
+
# Returns: Date from N days ago (min 7 for weekly coverage, max 14 to align with query scope)
|
|
100
|
+
def calculate_wip_window(provider)
|
|
101
|
+
# Step 1: Get list of unverified pact ages in days (e.g., [2, 5, 7, 10, 12, 14])
|
|
102
|
+
unverified_ages = get_unverified_pact_ages_in_days(provider)
|
|
103
|
+
|
|
104
|
+
# Step 2: If no unverified pacts, use default configured window
|
|
105
|
+
if unverified_ages.empty?
|
|
106
|
+
default_window = PactBroker.configuration.default_wip_window_days
|
|
107
|
+
logger.debug("No unverified pacts found for #{provider.name}, using default #{default_window}-day window") if logger.debug?
|
|
108
|
+
return Date.today - default_window
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Step 3: Calculate 80th percentile (ignore oldest 20% as abandoned work)
|
|
112
|
+
p80_age = percentile_80(unverified_ages)
|
|
113
|
+
|
|
114
|
+
# Step 4: Ensure window is between configured min-max days, then return date
|
|
115
|
+
min_window = PactBroker.configuration.min_wip_window_days
|
|
116
|
+
max_window = PactBroker.configuration.max_wip_lookback_days
|
|
117
|
+
window_days = clamp_between(p80_age, min_window, max_window)
|
|
118
|
+
wip_start_date = Date.today - window_days
|
|
119
|
+
|
|
120
|
+
if logger.debug?
|
|
121
|
+
logger.debug("Dynamic WIP window for #{provider.name}: found #{unverified_ages.size} unverified pacts, P80=#{p80_age} days, window=#{window_days} days (#{wip_start_date})")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
wip_start_date
|
|
125
|
+
rescue StandardError => e
|
|
126
|
+
default_window = PactBroker.configuration.default_wip_window_days
|
|
127
|
+
logger.error("Failed to calculate dynamic WIP window for provider #{provider.name}", error: e.class.name, message: e.message)
|
|
128
|
+
Date.today - default_window
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Get ages (in days) of pacts that haven't been successfully verified yet
|
|
132
|
+
# Only looks back the configured max_wip_lookback_days to keep query fast
|
|
133
|
+
def get_unverified_pact_ages_in_days(provider)
|
|
134
|
+
max_days = PactBroker.configuration.max_wip_lookback_days
|
|
135
|
+
cutoff_date = DateTime.now - max_days
|
|
136
|
+
|
|
137
|
+
# Use database-specific date arithmetic that works on both PostgreSQL and SQLite
|
|
138
|
+
# PostgreSQL: CURRENT_DATE - created_at::date returns integer days
|
|
139
|
+
# SQLite: julianday(date('now')) - julianday(date(created_at)) returns float days
|
|
140
|
+
db = PactPublication.db
|
|
141
|
+
age_expr = if db.database_type == :postgres
|
|
142
|
+
Sequel.lit("CURRENT_DATE - ?::date", Sequel[:pact_publications][:created_at])
|
|
143
|
+
else
|
|
144
|
+
# SQLite
|
|
145
|
+
Sequel.function(:julianday, Sequel.function(:date, "now")) -
|
|
146
|
+
Sequel.function(:julianday, Sequel.function(:date, Sequel[:pact_publications][:created_at]))
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
PactPublication
|
|
150
|
+
.where(Sequel[:pact_publications][:provider_id] => provider.id)
|
|
151
|
+
.where { Sequel[:pact_publications][:created_at] >= cutoff_date }
|
|
152
|
+
.left_join(:verifications, { pact_version_id: :pact_version_id, success: true })
|
|
153
|
+
.where(Sequel[:verifications][:id] => nil)
|
|
154
|
+
.select_map { Sequel.cast(age_expr, :integer).as(:age_days) }
|
|
155
|
+
.compact
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Calculate 80th percentile: find value where 80% of data points are less than or equal
|
|
159
|
+
# Example: [2,3,5,7,10,12,14,20] → 80% index = 6 → value = 14
|
|
160
|
+
def percentile_80(values)
|
|
161
|
+
sorted = values.sort
|
|
162
|
+
index = [(sorted.length * 0.80).ceil - 1, 0].max
|
|
163
|
+
sorted[index]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Constrain value between min and max bounds
|
|
167
|
+
def clamp_between(value, min, max)
|
|
168
|
+
[[value, max].min, min].max
|
|
169
|
+
end
|
|
170
|
+
|
|
83
171
|
# Note: created_at is coming back as a string for sqlite
|
|
84
172
|
# Can't work out how to to tell Sequel that this should be a date
|
|
85
173
|
def to_datetime string_or_datetime
|
|
@@ -227,7 +315,7 @@ module PactBroker
|
|
|
227
315
|
|
|
228
316
|
def find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch, explicitly_specified_verifiable_pacts, options)
|
|
229
317
|
provider = pacticipant_repository.find_by_name(provider_name)
|
|
230
|
-
wip_start_date = options
|
|
318
|
+
wip_start_date = determine_wip_start_date(provider, options)
|
|
231
319
|
|
|
232
320
|
potential_wip_by_consumer_branch = PactPublication.for_provider(provider).created_after(wip_start_date).for_all_branch_heads
|
|
233
321
|
potential_wip_by_consumer_tag = PactPublication.for_provider(provider).created_after(wip_start_date).for_all_tag_heads
|
|
@@ -14,6 +14,7 @@ require "pact_broker/pacts/selectors"
|
|
|
14
14
|
require "pact_broker/feature_toggle"
|
|
15
15
|
require "pact_broker/pacts/pacts_for_verification_repository"
|
|
16
16
|
require "pact_broker/pacts/content"
|
|
17
|
+
require "pact_broker/pacts/interactions/types"
|
|
17
18
|
require "pact_broker/policies"
|
|
18
19
|
|
|
19
20
|
module PactBroker
|
|
@@ -148,7 +149,7 @@ module PactBroker
|
|
|
148
149
|
query = query.overall_latest
|
|
149
150
|
end
|
|
150
151
|
|
|
151
|
-
query.all.
|
|
152
|
+
query.all.sort.collect(&:to_head_pact)
|
|
152
153
|
end
|
|
153
154
|
|
|
154
155
|
def find_pacts_by_consumer_branch(provider_name, options = {})
|
|
@@ -178,7 +179,7 @@ module PactBroker
|
|
|
178
179
|
query = query.for_branch_name(branch)
|
|
179
180
|
end
|
|
180
181
|
end
|
|
181
|
-
query.all.
|
|
182
|
+
query.all.sort.collect(&:to_head_pact)
|
|
182
183
|
end
|
|
183
184
|
|
|
184
185
|
def find_for_verification(provider_name, consumer_version_selectors)
|
|
@@ -394,14 +395,16 @@ module PactBroker
|
|
|
394
395
|
end
|
|
395
396
|
|
|
396
397
|
def create_pact_version consumer_id, provider_id, sha, json_content
|
|
398
|
+
content = Content.from_json(json_content)
|
|
397
399
|
PactBroker::Pacts::PactVersion.new(
|
|
398
400
|
consumer_id: consumer_id,
|
|
399
401
|
provider_id: provider_id,
|
|
400
402
|
sha: sha,
|
|
401
403
|
content: json_content,
|
|
402
404
|
created_at: Sequel.datetime_class.now,
|
|
403
|
-
interactions_count:
|
|
404
|
-
messages_count:
|
|
405
|
+
interactions_count: content.interactions&.count || 0,
|
|
406
|
+
messages_count: content.messages&.count || 0,
|
|
407
|
+
has_messages: Interactions::Types.for(content).has_messages?
|
|
405
408
|
).upsert
|
|
406
409
|
end
|
|
407
410
|
|
|
@@ -210,7 +210,7 @@ module PactBroker
|
|
|
210
210
|
|
|
211
211
|
# When no publication for the given consumer/provider/consumer version number exists
|
|
212
212
|
def create_pact(params, version, provider)
|
|
213
|
-
logger.
|
|
213
|
+
logger.debug("Creating new pact publication", params.without(:json_content))
|
|
214
214
|
logger.debug("Content #{params[:json_content]}")
|
|
215
215
|
json_content = add_interaction_ids(params[:json_content])
|
|
216
216
|
pact = pact_repository.create(
|
|
@@ -456,6 +456,9 @@ module PactBroker
|
|
|
456
456
|
parameters = default_parameters.merge(parameters)
|
|
457
457
|
parameters.delete(:provider_version)
|
|
458
458
|
verification = PactBroker::Domain::Verification.new(parameters)
|
|
459
|
+
if pact.nil?
|
|
460
|
+
@pact = find_pact(@consumer.name, @consumer_version.number, @provider.name)
|
|
461
|
+
end
|
|
459
462
|
pact_version = PactBroker::Pacts::Repository.new.find_pact_version(@consumer, @provider, pact.pact_version_sha)
|
|
460
463
|
@provider_version = version_repository.find_by_pacticipant_id_and_number_or_create(provider.id, provider_version_number)
|
|
461
464
|
branch_version = PactBroker::Versions::BranchVersionRepository.new.add_branch(@provider_version, branch) if branch
|
|
@@ -714,13 +717,16 @@ module PactBroker
|
|
|
714
717
|
def default_json_content
|
|
715
718
|
{
|
|
716
719
|
"consumer" => {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
720
|
+
"name" => consumer.name
|
|
721
|
+
},
|
|
722
|
+
"provider" => {
|
|
723
|
+
"name" => provider.name
|
|
724
|
+
},
|
|
725
|
+
"interactions" => [],
|
|
726
|
+
"metadata" => {
|
|
727
|
+
"pactSpecification" => { "version" => "4.0" }
|
|
728
|
+
},
|
|
729
|
+
"random" => rand
|
|
724
730
|
}.to_json
|
|
725
731
|
end
|
|
726
732
|
|
data/lib/pact_broker/version.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "pact_broker/versions/branch_version"
|
|
2
2
|
require "pact_broker/services"
|
|
3
|
+
require "pact_broker/logging"
|
|
3
4
|
|
|
4
5
|
module PactBroker
|
|
5
6
|
module Versions
|
|
@@ -21,16 +22,21 @@ module PactBroker
|
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def add_branch(version, branch_name, auto_created: false)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
branch_version.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
PactBroker.logger.debug("BranchVersionRepository#add_branch method called with version #{version.inspect} and branch_name '#{branch_name}'")
|
|
26
|
+
Sequel::Model.db.transaction do
|
|
27
|
+
branch = find_or_create_branch(version.pacticipant, branch_name)
|
|
28
|
+
branch_version = version.branch_version_for_branch(branch)
|
|
29
|
+
if branch_version
|
|
30
|
+
PactBroker.logger.info("Updating branch version #{branch_version.inspect}, time: #{Time.now}")
|
|
31
|
+
branch_version.update(updated_at: Sequel.datetime_class.now)
|
|
32
|
+
else
|
|
33
|
+
PactBroker.logger.info("Creating branch version time: #{Time.now}")
|
|
34
|
+
branch_version = PactBroker::Versions::BranchVersion.new(version: version, branch: branch, auto_created: auto_created).insert_ignore
|
|
35
|
+
PactBroker::Versions::BranchHead.new(branch: branch, branch_version: branch_version).upsert
|
|
36
|
+
end
|
|
37
|
+
pacticipant_service.maybe_set_main_branch(version.pacticipant, branch_name)
|
|
38
|
+
branch_version
|
|
31
39
|
end
|
|
32
|
-
pacticipant_service.maybe_set_main_branch(version.pacticipant, branch_name)
|
|
33
|
-
branch_version
|
|
34
40
|
end
|
|
35
41
|
|
|
36
42
|
# Deletes a branch version - that is, removes a version from a branch.
|
|
@@ -56,7 +56,7 @@ module PactBroker
|
|
|
56
56
|
logger.debug("Event detected", event_name: event.name, event_comment: event.comment)
|
|
57
57
|
if event.triggered_webhooks&.any?
|
|
58
58
|
triggered_webhook_descriptions = event.triggered_webhooks.collect{ |tw| { event_name: event.name, webhook_uuid: tw.webhook_uuid, triggered_webhook_uuid: tw.uuid, webhook_description: tw.webhook.description } }
|
|
59
|
-
logger.
|
|
59
|
+
logger.debug("Triggered webhooks for #{event.name}", triggered_webhooks: triggered_webhook_descriptions)
|
|
60
60
|
else
|
|
61
61
|
logger.debug "No enabled webhooks found for event #{event.name}"
|
|
62
62
|
end
|
|
@@ -7,12 +7,12 @@ module PactBroker
|
|
|
7
7
|
|
|
8
8
|
using PactBroker::StringRefinements
|
|
9
9
|
|
|
10
|
-
def redact_logs(logs, values)
|
|
11
|
-
RedactLogs.call(logs, values)
|
|
10
|
+
def redact_logs(logs, values, pattern_substitutions = [])
|
|
11
|
+
RedactLogs.call(logs, values, pattern_substitutions)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def self.call logs, values
|
|
15
|
-
substitutions = HEADER_SUBSTITUTIONS + value_substitutions(values)
|
|
14
|
+
def self.call logs, values, pattern_substitutions = []
|
|
15
|
+
substitutions = HEADER_SUBSTITUTIONS + pattern_substitutions + value_substitutions(values)
|
|
16
16
|
|
|
17
17
|
substitutions.reduce(logs) do | agg_logs, (find, replace) |
|
|
18
18
|
agg_logs.gsub(find, replace)
|
|
@@ -68,6 +68,7 @@ module Sequel
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def manual_upsert(opts)
|
|
71
|
+
sync_deserialized_values_to_values
|
|
71
72
|
# Can use slice when we drop support for Ruby 2.4
|
|
72
73
|
query = values.select{ |k, _| self.class.upsert_plugin_identifying_columns.include?(k) }
|
|
73
74
|
existing_record = model.where(query).single_record
|
|
@@ -79,6 +80,12 @@ module Sequel
|
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
|
|
83
|
+
def sync_deserialized_values_to_values
|
|
84
|
+
if respond_to?(:deserialized_values) && deserialized_values.is_a?(Hash)
|
|
85
|
+
deserialized_values.each { |k, v| values[k] = v }
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
82
89
|
# naughty override of Sequel private method to
|
|
83
90
|
# avoid having to rewrite the whole save method logic
|
|
84
91
|
def _insert_dataset
|
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.119.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bethany Skurrie
|
|
@@ -579,6 +579,13 @@ files:
|
|
|
579
579
|
- db/migrations/20231002_add_version_id_index_to_released_version.rb
|
|
580
580
|
- db/migrations/20231003_add_version_id_index_to_deployed_version.rb
|
|
581
581
|
- db/migrations/20240112_add_client_language_verified_by_to_verification.rb
|
|
582
|
+
- db/migrations/20251106_add_branch_versions_version_id_branch_name_index.rb
|
|
583
|
+
- db/migrations/20251202_add_has_messages_column_to_pact_versions.rb
|
|
584
|
+
- db/migrations/20251202_populate_has_messages_in_pact_versions.rb
|
|
585
|
+
- db/migrations/20260119_add_index_on_consumer_id_provider_id_to_pact_versions.rb
|
|
586
|
+
- db/migrations/20260123_drop_branch_versions_branch_name_index.rb
|
|
587
|
+
- db/migrations/20260210_add_index_on_pact_version_id_to_latest_pact_publication.rb
|
|
588
|
+
- db/migrations/20260217_add_wip_query_optimization_indexes.rb
|
|
582
589
|
- db/migrations/migration_helper.rb
|
|
583
590
|
- docs/CONFIGURATION.md
|
|
584
591
|
- docs/api/PACTICIPANTS.md
|
|
@@ -1001,6 +1008,7 @@ files:
|
|
|
1001
1008
|
- lib/pact_broker/pacts/generate_interaction_sha.rb
|
|
1002
1009
|
- lib/pact_broker/pacts/generate_sha.rb
|
|
1003
1010
|
- lib/pact_broker/pacts/head_pact.rb
|
|
1011
|
+
- lib/pact_broker/pacts/interactions/types.rb
|
|
1004
1012
|
- lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb
|
|
1005
1013
|
- lib/pact_broker/pacts/lazy_loaders.rb
|
|
1006
1014
|
- lib/pact_broker/pacts/merger.rb
|
|
@@ -1287,7 +1295,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
1287
1295
|
- !ruby/object:Gem::Version
|
|
1288
1296
|
version: '0'
|
|
1289
1297
|
requirements: []
|
|
1290
|
-
rubygems_version:
|
|
1298
|
+
rubygems_version: 4.0.10
|
|
1291
1299
|
specification_version: 4
|
|
1292
1300
|
summary: See description
|
|
1293
1301
|
test_files: []
|