pact_broker 2.91.0 → 2.93.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/db/migrations/20210608_add_uuid_to_webhook.rb +1 -0
- data/db/migrations/20211120_create_pact_version_provider_tag_successful_verifications.rb +23 -0
- data/db/migrations/20211121_migrate_pact_version_provider_tag_successful_verifications_data.rb +11 -0
- data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +2 -2
- data/lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb +5 -1
- data/lib/pact_broker/api/resources/verifications.rb +1 -1
- data/lib/pact_broker/config/runtime_configuration_database_methods.rb +6 -0
- data/lib/pact_broker/db/clean_incremental.rb +26 -9
- data/lib/pact_broker/db/data_migrations/migrate_pact_version_provider_tag_successful_verifications.rb +38 -0
- data/lib/pact_broker/db/migrate_data.rb +1 -0
- data/lib/pact_broker/deployments/deployed_version.rb +9 -1
- data/lib/pact_broker/domain/pacticipant.rb +36 -6
- data/lib/pact_broker/initializers/database_connection.rb +6 -4
- data/lib/pact_broker/metrics/service.rb +1 -1
- data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +42 -43
- data/lib/pact_broker/pacts/pact_publication_wip_dataset_module.rb +37 -4
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +1 -1
- data/lib/pact_broker/pacts/service.rb +3 -3
- data/lib/pact_broker/pacts/sort_content.rb +1 -1
- data/lib/pact_broker/test/http_test_data_builder.rb +1 -0
- data/lib/pact_broker/test/test_data_builder.rb +36 -9
- data/lib/pact_broker/verifications/pact_version_provider_tag_successful_verification.rb +11 -0
- data/lib/pact_broker/verifications/repository.rb +16 -0
- data/lib/pact_broker/version.rb +1 -1
- metadata +7 -4
- data/lib/pact_broker/versions/latest_version.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6014e4f21b22b1055f87d7f937b7d7942cb62f1ab7e6501299c8787e83986e22
|
4
|
+
data.tar.gz: 58b9668d0f34631533a507bce423d80fd0a1a8e2f98c04838a69ac83dc290f18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f26bd4ebafd8e30a3b8d96c2eb7c2ed5f594ef8cdfb477b89260169db34b77a32f01605b74f0a75e7f118eea1f8364e0c4f3e8d93df76617b041b526a3ff99e5
|
7
|
+
data.tar.gz: 807f0c5055108dfd8b8057a64580943dc6b1aeedb669156c1dcdad09cd4926ca8d6616646af62721f12ec2ab285a9cd9556d2821fc35177c7d04768a85c66347
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,45 @@
|
|
1
|
+
<a name="v2.93.2"></a>
|
2
|
+
### v2.93.2 (2021-12-23)
|
3
|
+
|
4
|
+
#### Bug Fixes
|
5
|
+
|
6
|
+
* Improve SortContent performance on large contracts (#538) ([1914c01f](/../../commit/1914c01f))
|
7
|
+
|
8
|
+
<a name="v2.93.1"></a>
|
9
|
+
### v2.93.1 (2021-12-21)
|
10
|
+
|
11
|
+
#### Bug Fixes
|
12
|
+
|
13
|
+
* optimise query for calculating the latest overall pacts ([f44aaa70](/../../commit/f44aaa70))
|
14
|
+
|
15
|
+
<a name="v2.93.0"></a>
|
16
|
+
### v2.93.0 (2021-12-07)
|
17
|
+
|
18
|
+
#### Features
|
19
|
+
|
20
|
+
* remove feature flag for new_wip_calculations ([972ceadd](/../../commit/972ceadd))
|
21
|
+
* call the database clean within a transaction ([408c84ef](/../../commit/408c84ef))
|
22
|
+
|
23
|
+
#### Bug Fixes
|
24
|
+
|
25
|
+
* fix clean performance fix (#530) ([6c71e57b](/../../commit/6c71e57b))
|
26
|
+
* fix performance issue loading latest version for pacticipant ([c575d132](/../../commit/c575d132))
|
27
|
+
|
28
|
+
<a name="v2.92.0"></a>
|
29
|
+
### v2.92.0 (2021-11-27)
|
30
|
+
|
31
|
+
#### Features
|
32
|
+
|
33
|
+
* allow SQL caller logging to be enabled ([861d8f21](/../../commit/861d8f21))
|
34
|
+
* use a separate table to track the successful verifications of pact versions for each provider version tag (feature toggled with "new_wip_calculation") ([df0acfa3](/../../commit/df0acfa3))
|
35
|
+
|
36
|
+
#### Bug Fixes
|
37
|
+
|
38
|
+
* **cleanup**
|
39
|
+
* Improve delete orphans SQL query (#527) ([853354ea](/../../commit/853354ea))
|
40
|
+
|
41
|
+
* cast PACT_BROKER_DATABASE_CONNECTION_VALIDATION_TIMEOUT to an integer ([8816c61f](/../../commit/8816c61f))
|
42
|
+
|
1
43
|
<a name="v2.91.0"></a>
|
2
44
|
### v2.91.0 (2021-11-15)
|
3
45
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Sequel.migration do
|
2
|
+
up do
|
3
|
+
create_table(:pact_version_provider_tag_successful_verifications, charset: "utf8") do
|
4
|
+
primary_key :id
|
5
|
+
foreign_key :pact_version_id, :pact_versions, null: false, on_delete: :cascade, foreign_key_constraint_name: "pact_version_provider_tag_successful_verifications_pv_id_fk"
|
6
|
+
String :provider_version_tag_name, null: false
|
7
|
+
Boolean :wip, null: false
|
8
|
+
Integer :verification_id
|
9
|
+
DateTime :execution_date, null: false
|
10
|
+
index([:pact_version_id, :provider_version_tag_name, :wip], unique: true, name: "pact_version_provider_tag_verifications_pv_pvtn_wip_unique")
|
11
|
+
# The implication of the on_delete: :set_null for verification_id is
|
12
|
+
# that even if the verification result is deleted from the broker,
|
13
|
+
# the wip/pending status stays the same.
|
14
|
+
# We may or may not want this. Will have to wait and see.
|
15
|
+
# Have made the foreign key a separate declaration so it can more easily be remade.
|
16
|
+
foreign_key([:verification_id], :verifications, on_delete: :set_null, name: "pact_version_provider_tag_successful_verifications_v_id_fk")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
down do
|
21
|
+
drop_table(:pact_version_provider_tag_successful_verifications)
|
22
|
+
end
|
23
|
+
end
|
data/db/migrations/20211121_migrate_pact_version_provider_tag_successful_verifications_data.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require "pact_broker/db/data_migrations/migrate_pact_version_provider_tag_successful_verifications"
|
2
|
+
|
3
|
+
Sequel.migration do
|
4
|
+
up do
|
5
|
+
PactBroker::DB::DataMigrations::MigratePactVersionProviderTagSuccessfulVerifications.call(self)
|
6
|
+
end
|
7
|
+
|
8
|
+
down do
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -50,7 +50,7 @@ module PactBroker
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def from_json
|
53
|
-
handle_webhook_events do
|
53
|
+
handle_webhook_events(build_url: verification_params["buildUrl"]) do
|
54
54
|
verified_pacts = pact_service.find_for_verification_publication(pact_params, event_context[:consumer_version_selectors])
|
55
55
|
verification = verification_service.create(next_verification_number, verification_params, verified_pacts, event_context)
|
56
56
|
response.body = decorator_for(verification).to_json(decorator_options)
|
@@ -18,6 +18,7 @@ module PactBroker
|
|
18
18
|
database_sslmode: nil,
|
19
19
|
sql_log_level: :debug,
|
20
20
|
sql_log_warn_duration: 5,
|
21
|
+
sql_enable_caller_logging: false,
|
21
22
|
database_max_connections: nil,
|
22
23
|
database_pool_timeout: 5,
|
23
24
|
database_connect_max_retries: 0,
|
@@ -36,6 +37,7 @@ module PactBroker
|
|
36
37
|
encoding: "utf8",
|
37
38
|
sslmode: database_sslmode,
|
38
39
|
sql_log_level: sql_log_level,
|
40
|
+
enable_caller_logging: sql_enable_caller_logging,
|
39
41
|
log_warn_duration: sql_log_warn_duration,
|
40
42
|
max_connections: database_max_connections,
|
41
43
|
pool_timeout: database_pool_timeout,
|
@@ -65,6 +67,10 @@ module PactBroker
|
|
65
67
|
super(metrics_sql_statement_timeout&.to_i)
|
66
68
|
end
|
67
69
|
|
70
|
+
def database_connection_validation_timeout= database_connection_validation_timeout
|
71
|
+
super(database_connection_validation_timeout&.to_i)
|
72
|
+
end
|
73
|
+
|
68
74
|
def postgres?
|
69
75
|
database_credentials[:adapter] == "postgres"
|
70
76
|
end
|
@@ -66,13 +66,15 @@ module PactBroker
|
|
66
66
|
if dry_run?
|
67
67
|
dry_run_results
|
68
68
|
else
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
69
|
+
db.transaction do
|
70
|
+
before_counts = current_counts
|
71
|
+
PactBroker::Domain::Version.where(id: resolve_ids(version_ids_to_delete)).delete
|
72
|
+
delete_orphan_pact_versions
|
73
|
+
after_counts = current_counts
|
74
|
+
|
75
|
+
TABLES.each_with_object({}) do | table_name, comparison_counts |
|
76
|
+
comparison_counts[table_name.to_s] = { "deleted" => before_counts[table_name] - after_counts[table_name], "kept" => after_counts[table_name] }
|
77
|
+
end
|
76
78
|
end
|
77
79
|
end
|
78
80
|
end
|
@@ -92,8 +94,23 @@ module PactBroker
|
|
92
94
|
end
|
93
95
|
|
94
96
|
def delete_orphan_pact_versions
|
95
|
-
|
96
|
-
|
97
|
+
db[:pact_versions].where(id: orphan_pact_versions).delete
|
98
|
+
rescue Sequel::DatabaseError => e
|
99
|
+
raise unless e.cause.class.name == "Mysql2::Error"
|
100
|
+
|
101
|
+
ids = orphan_pact_versions.map { |row| row[:id] }
|
102
|
+
db[:pact_versions].where(id: ids).delete
|
103
|
+
end
|
104
|
+
|
105
|
+
def orphan_pact_versions
|
106
|
+
db[:pact_versions]
|
107
|
+
.left_join(:pact_publications, Sequel[:pact_publications][:pact_version_id]=> Sequel[:pact_versions][:id])
|
108
|
+
.left_join(:verifications, Sequel[:verifications][:pact_version_id]=> Sequel[:pact_versions][:id])
|
109
|
+
.select(Sequel[:pact_versions][:id])
|
110
|
+
.where(
|
111
|
+
Sequel[:pact_publications][:id] => nil,
|
112
|
+
Sequel[:verifications][:id] => nil
|
113
|
+
)
|
97
114
|
end
|
98
115
|
|
99
116
|
def version_info(version)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "pact_broker/db/data_migrations/helpers"
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module DB
|
5
|
+
module DataMigrations
|
6
|
+
class MigratePactVersionProviderTagSuccessfulVerifications
|
7
|
+
extend Helpers
|
8
|
+
|
9
|
+
def self.call(connection)
|
10
|
+
successful_verifications_join = {
|
11
|
+
Sequel[:sv][:pact_version_id] => Sequel[:verifications][:pact_version_id],
|
12
|
+
Sequel[:sv][:provider_version_tag_name] => Sequel[:tags][:name],
|
13
|
+
Sequel[:sv][:wip] => Sequel[:verifications][:wip]
|
14
|
+
}
|
15
|
+
|
16
|
+
missing_verifications = connection
|
17
|
+
.select(
|
18
|
+
Sequel[:verifications][:pact_version_id],
|
19
|
+
Sequel[:tags][:name],
|
20
|
+
Sequel[:verifications][:wip],
|
21
|
+
Sequel[:verifications][:id],
|
22
|
+
Sequel[:verifications][:execution_date]
|
23
|
+
)
|
24
|
+
.order(Sequel[:verifications][:execution_date], Sequel[:verifications][:id])
|
25
|
+
.from(:verifications)
|
26
|
+
.join(:tags, { Sequel[:verifications][:provider_version_id] => Sequel[:tags][:version_id] })
|
27
|
+
.left_outer_join(:pact_version_provider_tag_successful_verifications, successful_verifications_join, { table_alias: :sv })
|
28
|
+
.where(Sequel[:sv][:pact_version_id] => nil)
|
29
|
+
.where(Sequel[:verifications][:success] => true)
|
30
|
+
|
31
|
+
connection[:pact_version_provider_tag_successful_verifications]
|
32
|
+
.insert_ignore
|
33
|
+
.insert([:pact_version_id, :provider_version_tag_name, :wip, :verification_id, :execution_date], missing_verifications)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -28,6 +28,7 @@ module PactBroker
|
|
28
28
|
DataMigrations::SetExtraColumnsForTags.call(database_connection)
|
29
29
|
DataMigrations::CreateBranches.call(database_connection)
|
30
30
|
DataMigrations::MigrateIntegrations.call(database_connection)
|
31
|
+
DataMigrations::MigratePactVersionProviderTagSuccessfulVerifications.call(database_connection)
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -88,6 +88,15 @@ module PactBroker
|
|
88
88
|
!!currently_deployed_version_id
|
89
89
|
end
|
90
90
|
|
91
|
+
# target has been renamed to applicationInstance in the API.
|
92
|
+
def application_instance
|
93
|
+
target
|
94
|
+
end
|
95
|
+
|
96
|
+
def application_instance= application_instance
|
97
|
+
self.target = application_instance
|
98
|
+
end
|
99
|
+
|
91
100
|
def version_number
|
92
101
|
version.number
|
93
102
|
end
|
@@ -100,7 +109,6 @@ module PactBroker
|
|
100
109
|
self.class.where(id: id).record_undeployed
|
101
110
|
self.refresh
|
102
111
|
end
|
103
|
-
|
104
112
|
end
|
105
113
|
end
|
106
114
|
end
|
@@ -1,14 +1,44 @@
|
|
1
1
|
require "pact_broker/db"
|
2
2
|
require "pact_broker/messages"
|
3
3
|
require "pact_broker/repositories/helpers"
|
4
|
-
require "pact_broker/versions/latest_version"
|
5
4
|
require "pact_broker/domain/label"
|
6
5
|
require "pact_broker/string_refinements"
|
7
6
|
require "pact_broker/pacticipants/generate_display_name"
|
8
7
|
|
9
8
|
module PactBroker
|
10
9
|
module Domain
|
10
|
+
class LatestVersionForPacticipantEagerLoader
|
11
|
+
def self.call(eo, **_other)
|
12
|
+
populate_associations(eo[:rows])
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.populate_associations(pacticipants)
|
16
|
+
pacticipants.each { | pacticipant | pacticipant.associations[:latest_version] = nil }
|
17
|
+
pacticipant_ids = pacticipants.collect(&:id)
|
18
|
+
|
19
|
+
max_orders = PactBroker::Domain::Version
|
20
|
+
.where(pacticipant_id: pacticipant_ids)
|
21
|
+
.select_group(:pacticipant_id)
|
22
|
+
.select_append { max(order).as(latest_order) }
|
23
|
+
|
24
|
+
max_orders_join = {
|
25
|
+
Sequel[:max_orders][:latest_order] => Sequel[:versions][:order],
|
26
|
+
Sequel[:max_orders][:pacticipant_id] => Sequel[:versions][:pacticipant_id]
|
27
|
+
}
|
28
|
+
|
29
|
+
latest_versions = PactBroker::Domain::Version
|
30
|
+
.select_all_qualified
|
31
|
+
.join(max_orders, max_orders_join, { table_alias: :max_orders})
|
32
|
+
|
33
|
+
latest_versions.each do | version |
|
34
|
+
pacticipant = pacticipants.find{ | p | p.id == version.pacticipant_id }
|
35
|
+
pacticipant.associations[:latest_version] = version
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
11
40
|
class Pacticipant < Sequel::Model
|
41
|
+
|
12
42
|
include Messages
|
13
43
|
include PactBroker::Pacticipants::GenerateDisplayName
|
14
44
|
using PactBroker::StringRefinements
|
@@ -21,7 +51,11 @@ module PactBroker
|
|
21
51
|
one_to_many :versions, :order => :order, :reciprocal => :pacticipant
|
22
52
|
one_to_many :labels, :order => :name, :reciprocal => :pacticipant
|
23
53
|
one_to_many :pacts
|
24
|
-
one_to_one :latest_version, :class => "PactBroker::
|
54
|
+
one_to_one :latest_version, :class => "PactBroker::Domain::Version",
|
55
|
+
primary_key: :id, key: :pacticipant_id,
|
56
|
+
dataset: lambda { PactBroker::Domain::Version.where(pacticipant_id: id).order(Sequel.desc(:order)).limit(1) },
|
57
|
+
eager_loader: LatestVersionForPacticipantEagerLoader
|
58
|
+
|
25
59
|
one_to_many :branch_heads, class: "PactBroker::Versions::BranchHead", primary_key: :id, key: :pacticipant_id
|
26
60
|
one_to_many :branches, class: "PactBroker::Versions::Branch", primary_key: :id, key: :pacticipant_id
|
27
61
|
|
@@ -61,10 +95,6 @@ module PactBroker
|
|
61
95
|
self.main_branch = nil if main_branch.blank?
|
62
96
|
end
|
63
97
|
|
64
|
-
def latest_version
|
65
|
-
versions.last
|
66
|
-
end
|
67
|
-
|
68
98
|
def to_s
|
69
99
|
"Pacticipant: id=#{id}, name=#{name}"
|
70
100
|
end
|
@@ -9,7 +9,8 @@ module PactBroker
|
|
9
9
|
sequel_config = config.dup
|
10
10
|
max_retries = sequel_config.delete(:connect_max_retries) || 0
|
11
11
|
connection_validation_timeout = config.delete(:connection_validation_timeout)
|
12
|
-
|
12
|
+
enable_caller_logging = config.delete(:enable_caller_logging)
|
13
|
+
configure_logger(sequel_config, logger)
|
13
14
|
create_sqlite_database_dir(config)
|
14
15
|
|
15
16
|
connection = with_retries(max_retries, logger) do
|
@@ -18,7 +19,7 @@ module PactBroker
|
|
18
19
|
|
19
20
|
logger&.info "Connected to database #{sequel_config[:database]}"
|
20
21
|
|
21
|
-
configure_connection(connection, connection_validation_timeout)
|
22
|
+
configure_connection(connection, connection_validation_timeout, enable_caller_logging)
|
22
23
|
end
|
23
24
|
|
24
25
|
private_class_method def self.with_retries(max_retries, logger)
|
@@ -46,7 +47,7 @@ module PactBroker
|
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
|
-
private_class_method def self.configure_logger(sequel_config)
|
50
|
+
private_class_method def self.configure_logger(sequel_config, logger)
|
50
51
|
if sequel_config[:sql_log_level] == :none
|
51
52
|
sequel_config.delete(:sql_log_level)
|
52
53
|
elsif logger
|
@@ -72,8 +73,9 @@ module PactBroker
|
|
72
73
|
# when databases are restarted and connections are killed. This has a performance
|
73
74
|
# penalty, so consider increasing this timeout if building a frequently accessed service.
|
74
75
|
|
75
|
-
private_class_method def self.configure_connection(connection, connection_validation_timeout)
|
76
|
+
private_class_method def self.configure_connection(connection, connection_validation_timeout, enable_caller_logging)
|
76
77
|
connection.extension(:connection_validator)
|
78
|
+
connection.extension(:caller_logging) if enable_caller_logging
|
77
79
|
connection.pool.connection_validation_timeout = connection_validation_timeout if connection_validation_timeout
|
78
80
|
connection
|
79
81
|
end
|
@@ -18,7 +18,7 @@ module PactBroker
|
|
18
18
|
withMainBranchSetCount: PactBroker::Domain::Pacticipant.with_main_branch_set.count
|
19
19
|
},
|
20
20
|
integrations: {
|
21
|
-
count: PactBroker::
|
21
|
+
count: PactBroker::Pacts::PactPublication.select(:consumer_id, :provider_id).distinct.count
|
22
22
|
},
|
23
23
|
pactPublications: {
|
24
24
|
count: PactBroker::Pacts::PactPublication.count,
|
@@ -90,16 +90,18 @@ module PactBroker
|
|
90
90
|
def overall_latest
|
91
91
|
self_join = {
|
92
92
|
Sequel[:pact_publications][:consumer_id] => Sequel[:pp2][:consumer_id],
|
93
|
-
Sequel[:pact_publications][:provider_id] => Sequel[:pp2][:provider_id]
|
93
|
+
Sequel[:pact_publications][:provider_id] => Sequel[:pp2][:provider_id],
|
94
|
+
Sequel[:pact_publications][:consumer_version_order] => Sequel[:pp2][:max_consumer_version_order]
|
94
95
|
}
|
95
96
|
|
96
97
|
base_query = self
|
97
98
|
base_query = base_query.select_all_qualified if no_columns_selected?
|
98
99
|
|
99
|
-
base_query.
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
base_query.join(
|
101
|
+
base_query.select_group(:consumer_id, :provider_id).select_append{ max(:consumer_version_order).as(:max_consumer_version_order) },
|
102
|
+
self_join,
|
103
|
+
table_alias: :pp2
|
104
|
+
)
|
103
105
|
.remove_overridden_revisions_from_complete_query
|
104
106
|
end
|
105
107
|
|
@@ -140,65 +142,62 @@ module PactBroker
|
|
140
142
|
end
|
141
143
|
|
142
144
|
# The latest pact publication for each tag
|
145
|
+
# This uses the old logic of "the latest pact for a version that has a tag" (which always returns a pact)
|
146
|
+
# rather than "the pact for the latest version with a tag"
|
147
|
+
# Need to see about updating this.
|
143
148
|
def latest_by_consumer_tag
|
144
149
|
tags_join = {
|
145
|
-
Sequel[:pact_publications][:consumer_version_id] => Sequel[:tags][:version_id]
|
150
|
+
Sequel[:pact_publications][:consumer_version_id] => Sequel[:tags][:version_id],
|
146
151
|
}
|
147
152
|
|
148
|
-
|
153
|
+
max_orders = join(:tags, tags_join)
|
154
|
+
.select_group(:consumer_id, :provider_id, Sequel[:tags][:name].as(:tag_name))
|
155
|
+
.select_append{ max(consumer_version_order).as(latest_consumer_version_order) }
|
149
156
|
|
157
|
+
max_join = {
|
158
|
+
Sequel[:max_orders][:consumer_id] => Sequel[:pact_publications][:consumer_id],
|
159
|
+
Sequel[:max_orders][:provider_id] => Sequel[:pact_publications][:provider_id],
|
160
|
+
Sequel[:max_orders][:latest_consumer_version_order] => Sequel[:pact_publications][:consumer_version_order]
|
161
|
+
}
|
162
|
+
|
163
|
+
base_query = self
|
150
164
|
if no_columns_selected?
|
151
|
-
base_query = base_query.select_all_qualified.select_append(Sequel[:
|
165
|
+
base_query = base_query.select_all_qualified.select_append(Sequel[:max_orders][:tag_name])
|
152
166
|
end
|
153
167
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
Sequel[:tags][:name].as(:tag_name)
|
158
|
-
)
|
159
|
-
|
160
|
-
self_join = {
|
161
|
-
Sequel[:pact_publications][:consumer_id] => Sequel[:pp2][:consumer_id],
|
162
|
-
Sequel[:tags][:name] => Sequel[:pp2][:tag_name]
|
163
|
-
}
|
164
|
-
base_query.left_join(joined_query, self_join, { table_alias: :pp2 } ) do
|
165
|
-
Sequel[:pp2][:version_order] > Sequel[:tags][:version_order]
|
166
|
-
end
|
167
|
-
.where(Sequel[:pp2][:version_order] => nil)
|
168
|
-
.remove_overridden_revisions_from_complete_query
|
168
|
+
base_query
|
169
|
+
.join(max_orders, max_join, { table_alias: :max_orders })
|
170
|
+
.remove_overridden_revisions_from_complete_query
|
169
171
|
end
|
170
172
|
|
173
|
+
# This uses the old logic of "the latest pact for a version that has a tag" (which always returns a pact)
|
174
|
+
# rather than "the pact for the latest version with a tag"
|
175
|
+
# Need to see about updating this.
|
171
176
|
def latest_for_consumer_tag(tag_name)
|
172
177
|
tags_join = {
|
173
178
|
Sequel[:pact_publications][:consumer_version_id] => Sequel[:tags][:version_id],
|
174
179
|
Sequel[:tags][:name] => tag_name
|
175
180
|
}
|
176
181
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
end
|
181
|
-
|
182
|
-
base_query = base_query
|
183
|
-
.join(:tags, tags_join)
|
184
|
-
.where(Sequel[:tags][:name] => tag_name)
|
182
|
+
max_orders = join(:tags, tags_join)
|
183
|
+
.select_group(:consumer_id, :provider_id, Sequel[:tags][:name].as(:tag_name))
|
184
|
+
.select_append{ max(consumer_version_order).as(latest_consumer_version_order) }
|
185
185
|
|
186
|
-
joined_query = base_query.select(
|
187
|
-
Sequel[:pact_publications][:consumer_id],
|
188
|
-
Sequel[:tags][:name].as(:tag_name),
|
189
|
-
Sequel[:tags][:version_order]
|
190
|
-
)
|
191
186
|
|
192
|
-
|
193
|
-
Sequel[:
|
194
|
-
Sequel[:
|
187
|
+
max_join = {
|
188
|
+
Sequel[:max_orders][:consumer_id] => Sequel[:pact_publications][:consumer_id],
|
189
|
+
Sequel[:max_orders][:provider_id] => Sequel[:pact_publications][:provider_id],
|
190
|
+
Sequel[:max_orders][:latest_consumer_version_order] => Sequel[:pact_publications][:consumer_version_order]
|
195
191
|
}
|
196
192
|
|
197
|
-
base_query
|
198
|
-
|
193
|
+
base_query = self
|
194
|
+
if no_columns_selected?
|
195
|
+
base_query = base_query.select_all_qualified.select_append(Sequel[:max_orders][:tag_name])
|
199
196
|
end
|
200
|
-
|
201
|
-
|
197
|
+
|
198
|
+
base_query
|
199
|
+
.join(max_orders, max_join, { table_alias: :max_orders })
|
200
|
+
.remove_overridden_revisions_from_complete_query
|
202
201
|
end
|
203
202
|
|
204
203
|
# The pacts for the latest versions with the specified tag (new logic)
|
@@ -32,16 +32,23 @@ module PactBroker
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def successfully_verified_by_provider_tag_when_not_wip(
|
35
|
+
def successfully_verified_by_provider_tag_when_not_wip(provider_tag)
|
36
|
+
pact_version_provider_tag_verifications_join = {
|
37
|
+
Sequel[:sv][:pact_version_id] => Sequel[:pp][:pact_version_id],
|
38
|
+
Sequel[:sv][:provider_version_tag_name] => provider_tag,
|
39
|
+
Sequel[:sv][:wip] => false
|
40
|
+
}
|
41
|
+
|
36
42
|
from_self(alias: :pp)
|
37
43
|
.select(Sequel[:pp].*)
|
38
|
-
.
|
39
|
-
.join_successful_non_wip_verifications_for_provider_id(provider_id)
|
40
|
-
.join_provider_version_tags_for_tag(provider_tag)
|
44
|
+
.join(:pact_version_provider_tag_successful_verifications, pact_version_provider_tag_verifications_join, { table_alias: :sv })
|
41
45
|
.distinct
|
46
|
+
|
42
47
|
end
|
43
48
|
|
44
49
|
def successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider_id, provider_tag)
|
50
|
+
return new_successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider_id, provider_tag) if PactBroker.feature_enabled?(:new_wip_calculation)
|
51
|
+
|
45
52
|
first_tag_with_name = PactBroker::Domain::Tag.where(pacticipant_id: provider_id, name: provider_tag).order(:created_at).first
|
46
53
|
from_self(alias: :pp)
|
47
54
|
.select(Sequel[:pp].*)
|
@@ -54,6 +61,32 @@ module PactBroker
|
|
54
61
|
.distinct
|
55
62
|
end
|
56
63
|
|
64
|
+
def new_successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider_id, provider_tag)
|
65
|
+
first_tag_with_name = PactBroker::Domain::Tag.where(pacticipant_id: provider_id, name: provider_tag).order(:created_at).first
|
66
|
+
|
67
|
+
pact_version_provider_tag_verifications_join = {
|
68
|
+
Sequel[:sv][:pact_version_id] => Sequel[:pp][:pact_version_id],
|
69
|
+
Sequel[:sv][:wip] => false
|
70
|
+
}
|
71
|
+
|
72
|
+
created_at_criteria = if first_tag_with_name
|
73
|
+
Sequel.lit("sv.execution_date < ?", first_tag_with_name.created_at)
|
74
|
+
else
|
75
|
+
Sequel.lit("1 = 1")
|
76
|
+
end
|
77
|
+
|
78
|
+
from_self(alias: :pp)
|
79
|
+
.select(Sequel[:pp].*)
|
80
|
+
.where(Sequel[:pp][:provider_id] => provider_id)
|
81
|
+
.join(:pact_version_provider_tag_successful_verifications, pact_version_provider_tag_verifications_join, { table_alias: :sv }) do
|
82
|
+
Sequel.&(
|
83
|
+
Sequel.lit("sv.provider_version_tag_name NOT IN (?)", provider_tag),
|
84
|
+
created_at_criteria
|
85
|
+
)
|
86
|
+
end
|
87
|
+
.distinct
|
88
|
+
end
|
89
|
+
|
57
90
|
protected
|
58
91
|
|
59
92
|
def verified_before_date(date)
|
@@ -270,7 +270,7 @@ module PactBroker
|
|
270
270
|
|
271
271
|
def remove_non_wip_for_tag(pact_publications_query, provider, tag, specified_pact_version_shas)
|
272
272
|
specified_explicitly = pact_publications_query.for_pact_version_sha(specified_pact_version_shas)
|
273
|
-
verified_by_this_tag = pact_publications_query.successfully_verified_by_provider_tag_when_not_wip(
|
273
|
+
verified_by_this_tag = pact_publications_query.successfully_verified_by_provider_tag_when_not_wip(tag)
|
274
274
|
verified_by_another_tag = pact_publications_query.successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider.id, tag)
|
275
275
|
|
276
276
|
log_debug_for_wip do
|
@@ -43,7 +43,7 @@ module PactBroker
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def delete params
|
46
|
-
logger.info "Deleting pact version
|
46
|
+
logger.info "Deleting pact version", payload: params
|
47
47
|
pacts = pact_repository.find_all_revisions(params[:consumer_name], params[:consumer_version_number], params[:provider_name])
|
48
48
|
webhook_service.delete_all_webhook_related_objects_by_pact_publication_ids(pacts.collect(&:id))
|
49
49
|
pact_repository.delete(params)
|
@@ -156,7 +156,7 @@ module PactBroker
|
|
156
156
|
|
157
157
|
# Overwriting an existing pact with the same consumer/provider/consumer version number
|
158
158
|
def create_pact_revision params, existing_pact
|
159
|
-
logger.info "Updating existing pact publication", payload: params.
|
159
|
+
logger.info "Updating existing pact publication", payload: params.without(:json_content)
|
160
160
|
logger.debug "Content #{params[:json_content]}"
|
161
161
|
pact_version_sha = generate_sha(params[:json_content])
|
162
162
|
json_content = add_interaction_ids(params[:json_content])
|
@@ -185,7 +185,7 @@ module PactBroker
|
|
185
185
|
|
186
186
|
# When no publication for the given consumer/provider/consumer version number exists
|
187
187
|
def create_pact params, version, provider
|
188
|
-
logger.info "Creating new pact publication
|
188
|
+
logger.info "Creating new pact publication", payload: params.without(:json_content)
|
189
189
|
logger.debug "Content #{params[:json_content]}"
|
190
190
|
pact_version_sha = generate_sha(params[:json_content])
|
191
191
|
json_content = add_interaction_ids(params[:json_content])
|
@@ -34,7 +34,7 @@ module PactBroker
|
|
34
34
|
# You never can tell what people will do...
|
35
35
|
if probably_array.is_a?(Array)
|
36
36
|
array_with_ordered_hashes = order_hash_keys(probably_array)
|
37
|
-
array_with_ordered_hashes.
|
37
|
+
array_with_ordered_hashes.sort_by(&:to_json)
|
38
38
|
else
|
39
39
|
probably_array
|
40
40
|
end
|
@@ -273,6 +273,7 @@ module PactBroker
|
|
273
273
|
"eventName" => "${pactbroker.eventName}",
|
274
274
|
"consumerVersionNumber" => "${pactbroker.consumerVersionNumber}",
|
275
275
|
"consumerVersionTags" => "${pactbroker.consumerVersionTags}",
|
276
|
+
"consumerVersionBranch" => "${pactbroker.consumerVersionBranch}",
|
276
277
|
"githubVerificationStatus" => "${pactbroker.githubVerificationStatus}",
|
277
278
|
"providerVersionNumber" => "${pactbroker.providerVersionNumber}",
|
278
279
|
"providerVersionTags" => "${pactbroker.providerVersionTags}",
|
@@ -31,6 +31,8 @@ require "pact_broker/deployments/deployed_version_service"
|
|
31
31
|
require "pact_broker/deployments/released_version_service"
|
32
32
|
require "pact_broker/versions/branch_version_repository"
|
33
33
|
require "pact_broker/integrations/repository"
|
34
|
+
require "pact_broker/contracts/service"
|
35
|
+
|
34
36
|
require "ostruct"
|
35
37
|
|
36
38
|
module PactBroker
|
@@ -219,6 +221,27 @@ module PactBroker
|
|
219
221
|
self
|
220
222
|
end
|
221
223
|
|
224
|
+
def publish_pact(consumer_name:, provider_name:, consumer_version_number: , tags: nil, branch: nil, build_url: nil, json_content: nil)
|
225
|
+
json_content = json_content || random_json_content(consumer_name, provider_name)
|
226
|
+
contracts = [
|
227
|
+
PactBroker::Contracts::ContractToPublish.from_hash(consumer_name: consumer_name, provider_name: provider_name, decoded_content: json_content, content_type: "application/json", specification: "pact")
|
228
|
+
]
|
229
|
+
contracts_to_publish = PactBroker::Contracts::ContractsToPublish.from_hash(
|
230
|
+
pacticipant_name: consumer_name,
|
231
|
+
pacticipant_version_number: consumer_version_number,
|
232
|
+
tags: tags,
|
233
|
+
branch: branch,
|
234
|
+
build_url: build_url,
|
235
|
+
contracts: contracts
|
236
|
+
)
|
237
|
+
PactBroker::Contracts::Service.publish(contracts_to_publish, base_url: "http://example.org")
|
238
|
+
@consumer = find_pacticipant(consumer_name)
|
239
|
+
@consumer_version = find_version(consumer_name, consumer_version_number)
|
240
|
+
@provider = find_pacticipant(provider_name)
|
241
|
+
@pact = PactBroker::Pacts::PactPublication.last.to_domain
|
242
|
+
self
|
243
|
+
end
|
244
|
+
|
222
245
|
def create_pact params = {}
|
223
246
|
params.delete(:comment)
|
224
247
|
json_content = params[:json_content] || default_json_content
|
@@ -363,6 +386,7 @@ module PactBroker
|
|
363
386
|
end
|
364
387
|
|
365
388
|
def create_verification parameters = {}
|
389
|
+
# This should use the verification service. what a mess
|
366
390
|
parameters.delete(:comment)
|
367
391
|
branch = parameters.delete(:branch)
|
368
392
|
tag_names = [parameters.delete(:tag_names), parameters.delete(:tag_name)].flatten.compact
|
@@ -373,20 +397,23 @@ module PactBroker
|
|
373
397
|
parameters.delete(:provider_version)
|
374
398
|
verification = PactBroker::Domain::Verification.new(parameters)
|
375
399
|
pact_version = PactBroker::Pacts::Repository.new.find_pact_version(@consumer, @provider, pact.pact_version_sha)
|
376
|
-
@
|
377
|
-
@provider_version = PactBroker::Domain::Version.where(pacticipant_id: @provider.id, number: provider_version_number).single_record
|
400
|
+
@provider_version = version_repository.find_by_pacticipant_id_and_number_or_create(provider.id, provider_version_number)
|
378
401
|
PactBroker::Versions::BranchVersionRepository.new.add_branch(@provider_version, branch) if branch
|
379
402
|
|
380
|
-
set_created_at_if_set(parameters[:created_at], :verifications, id: @verification.id)
|
381
|
-
set_created_at_if_set(parameters[:created_at], :versions, id: @provider_version.id)
|
382
|
-
set_created_at_if_set(parameters[:created_at], :latest_verification_id_for_pact_version_and_provider_version, pact_version_id: pact_version_id, provider_version_id: @provider_version.id)
|
383
|
-
|
384
403
|
if tag_names.any?
|
385
404
|
tag_names.each do | tag_name |
|
386
|
-
PactBroker::Domain::Tag.new(name: tag_name, version: @provider_version).insert_ignore
|
405
|
+
PactBroker::Domain::Tag.new(name: tag_name, version: @provider_version, version_order: @provider_version.order).insert_ignore
|
387
406
|
set_created_at_if_set(parameters[:created_at], :tags, version_id: @provider_version.id, name: tag_name)
|
388
407
|
end
|
389
408
|
end
|
409
|
+
|
410
|
+
@verification = PactBroker::Verifications::Repository.new.create(verification, provider_version_number, pact_version)
|
411
|
+
|
412
|
+
set_created_at_if_set(parameters[:created_at], :verifications, id: @verification.id)
|
413
|
+
set_created_at_if_set(parameters[:created_at], :versions, id: @provider_version.id)
|
414
|
+
set_created_at_if_set(parameters[:created_at], :latest_verification_id_for_pact_version_and_provider_version, pact_version_id: pact_version_id, provider_version_id: @provider_version.id)
|
415
|
+
set_created_at_if_set(parameters[:created_at], :pact_version_provider_tag_successful_verifications, { verification_id: @verification.id }, :execution_date)
|
416
|
+
|
390
417
|
self
|
391
418
|
end
|
392
419
|
|
@@ -594,10 +621,10 @@ module PactBroker
|
|
594
621
|
PactBroker::Pacts::Content.from_json(json_content).with_ids(false).to_json
|
595
622
|
end
|
596
623
|
|
597
|
-
def set_created_at_if_set created_at, table_name, selector
|
624
|
+
def set_created_at_if_set created_at, table_name, selector, date_column_name = :created_at
|
598
625
|
date_to_set = created_at || @now
|
599
626
|
if date_to_set
|
600
|
-
Sequel::Model.db[table_name].where(selector).update(
|
627
|
+
Sequel::Model.db[table_name].where(selector).update(date_column_name => date_to_set)
|
601
628
|
if Sequel::Model.db.schema(table_name).any?{ |col| col.first == :updated_at }
|
602
629
|
Sequel::Model.db[table_name].where(selector.keys.first => selector.values.first).update(updated_at: date_to_set)
|
603
630
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "pact_broker/domain/verification"
|
2
|
+
|
3
|
+
# Represents a non WIP, successful verification for a provider version with a tag.
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
module Verifications
|
7
|
+
class PactVersionProviderTagSuccessfulVerification < Sequel::Model
|
8
|
+
plugin :insert_ignore, identifying_columns: [:pact_version_id, :provider_version_tag_name, :wip]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -2,6 +2,7 @@ require "sequel"
|
|
2
2
|
require "pact_broker/domain/verification"
|
3
3
|
require "pact_broker/verifications/sequence"
|
4
4
|
require "pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version"
|
5
|
+
require "pact_broker/verifications/pact_version_provider_tag_successful_verification"
|
5
6
|
|
6
7
|
module PactBroker
|
7
8
|
module Verifications
|
@@ -27,6 +28,7 @@ module PactBroker
|
|
27
28
|
verification.tag_names = version.tag_names # TODO pass this in from contracts service
|
28
29
|
verification.save
|
29
30
|
update_latest_verification_id(verification)
|
31
|
+
update_pact_version_provider_tag_verifications(verification, version.tag_names)
|
30
32
|
verification
|
31
33
|
end
|
32
34
|
|
@@ -46,6 +48,20 @@ module PactBroker
|
|
46
48
|
LatestVerificationIdForPactVersionAndProviderVersion.new(params).upsert
|
47
49
|
end
|
48
50
|
|
51
|
+
def update_pact_version_provider_tag_verifications(verification, tag_names)
|
52
|
+
if verification.success
|
53
|
+
tag_names&.each do | tag_name |
|
54
|
+
PactVersionProviderTagSuccessfulVerification.new(
|
55
|
+
pact_version_id: verification.pact_version_id,
|
56
|
+
provider_version_tag_name: tag_name,
|
57
|
+
wip: verification.wip,
|
58
|
+
verification_id: verification.id,
|
59
|
+
execution_date: verification.execution_date
|
60
|
+
).insert_ignore
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
49
65
|
def find consumer_name, provider_name, pact_version_sha, verification_number
|
50
66
|
PactBroker::Domain::Verification
|
51
67
|
.select_all_qualified
|
data/lib/pact_broker/version.rb
CHANGED
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.93.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bethany Skurrie
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-12-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: httparty
|
@@ -587,6 +587,8 @@ files:
|
|
587
587
|
- db/migrations/20211102_create_table_temp_integrations.rb
|
588
588
|
- db/migrations/20211103_migrate_integrations.rb
|
589
589
|
- db/migrations/20211104_switch_integrations_and_temp_integrations.rb
|
590
|
+
- db/migrations/20211120_create_pact_version_provider_tag_successful_verifications.rb
|
591
|
+
- db/migrations/20211121_migrate_pact_version_provider_tag_successful_verifications_data.rb
|
590
592
|
- db/migrations/migration_helper.rb
|
591
593
|
- docs/CONFIGURATION.md
|
592
594
|
- docs/api/WEBHOOKS.md
|
@@ -797,6 +799,7 @@ files:
|
|
797
799
|
- lib/pact_broker/db/data_migrations/delete_deprecated_webhook_executions.rb
|
798
800
|
- lib/pact_broker/db/data_migrations/helpers.rb
|
799
801
|
- lib/pact_broker/db/data_migrations/migrate_integrations.rb
|
802
|
+
- lib/pact_broker/db/data_migrations/migrate_pact_version_provider_tag_successful_verifications.rb
|
800
803
|
- lib/pact_broker/db/data_migrations/migrate_webhook_headers.rb
|
801
804
|
- lib/pact_broker/db/data_migrations/set_consumer_ids_for_pact_publications.rb
|
802
805
|
- lib/pact_broker/db/data_migrations/set_consumer_version_order_for_pact_publications.rb
|
@@ -1028,6 +1031,7 @@ files:
|
|
1028
1031
|
- lib/pact_broker/verifications/latest_verification_for_consumer_and_provider.rb
|
1029
1032
|
- lib/pact_broker/verifications/latest_verification_for_consumer_version_tag.rb
|
1030
1033
|
- lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb
|
1034
|
+
- lib/pact_broker/verifications/pact_version_provider_tag_successful_verification.rb
|
1031
1035
|
- lib/pact_broker/verifications/placeholder_verification.rb
|
1032
1036
|
- lib/pact_broker/verifications/pseudo_branch_status.rb
|
1033
1037
|
- lib/pact_broker/verifications/repository.rb
|
@@ -1043,7 +1047,6 @@ files:
|
|
1043
1047
|
- lib/pact_broker/versions/branch_version.rb
|
1044
1048
|
- lib/pact_broker/versions/branch_version_repository.rb
|
1045
1049
|
- lib/pact_broker/versions/eager_loaders.rb
|
1046
|
-
- lib/pact_broker/versions/latest_version.rb
|
1047
1050
|
- lib/pact_broker/versions/parse_semantic_version.rb
|
1048
1051
|
- lib/pact_broker/versions/repository.rb
|
1049
1052
|
- lib/pact_broker/versions/selector.rb
|
@@ -1220,7 +1223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1220
1223
|
- !ruby/object:Gem::Version
|
1221
1224
|
version: '0'
|
1222
1225
|
requirements: []
|
1223
|
-
rubygems_version: 3.
|
1226
|
+
rubygems_version: 3.3.1
|
1224
1227
|
signing_key:
|
1225
1228
|
specification_version: 4
|
1226
1229
|
summary: See description
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require "pact_broker/domain/version"
|
2
|
-
|
3
|
-
module PactBroker
|
4
|
-
module Versions
|
5
|
-
include PactBroker::Repositories::Helpers
|
6
|
-
|
7
|
-
class LatestVersion < PactBroker::Domain::Version
|
8
|
-
set_dataset(:latest_versions)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# Table: latest_versions
|
14
|
-
# Columns:
|
15
|
-
# id | integer |
|
16
|
-
# number | text |
|
17
|
-
# repository_ref | text |
|
18
|
-
# pacticipant_id | integer |
|
19
|
-
# order | integer |
|
20
|
-
# created_at | timestamp without time zone |
|
21
|
-
# updated_at | timestamp without time zone |
|