pact_broker 2.109.0 → 2.110.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +1 -2
- data/docs/developer/design_pattern_for_eager_loading_collections.md +23 -0
- data/docs/developer/matrix.md +95 -0
- data/docs/developer/rack.md +11 -0
- data/lib/pact_broker/api/contracts/consumer_version_selector_contract.rb +1 -1
- data/lib/pact_broker/api/decorators/base_decorator.rb +10 -1
- data/lib/pact_broker/api/decorators/version_decorator.rb +14 -0
- data/lib/pact_broker/api/resources/branch_versions.rb +1 -1
- data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +5 -0
- data/lib/pact_broker/api/resources/versions.rb +1 -1
- data/lib/pact_broker/app.rb +24 -9
- data/lib/pact_broker/contracts/service.rb +6 -2
- data/lib/pact_broker/db/advisory_lock.rb +58 -0
- data/lib/pact_broker/domain/version.rb +3 -2
- data/lib/pact_broker/integrations/integration.rb +11 -1
- data/lib/pact_broker/integrations/repository.rb +46 -7
- data/lib/pact_broker/integrations/service.rb +2 -0
- data/lib/pact_broker/locale/en.yml +1 -1
- data/lib/pact_broker/matrix/matrix_row.rb +0 -1
- data/lib/pact_broker/matrix/resolved_selector.rb +0 -1
- data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +56 -2
- data/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +1 -0
- data/lib/pact_broker/pacts/pact_publication_wip_dataset_module.rb +59 -79
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +5 -4
- data/lib/pact_broker/pacts/repository.rb +2 -2
- data/lib/pact_broker/pacts/selector.rb +8 -2
- data/lib/pact_broker/tasks/clean_task.rb +68 -26
- data/lib/pact_broker/test/test_data_builder.rb +8 -3
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/branch_service.rb +1 -0
- data/lib/pact_broker/versions/repository.rb +2 -20
- data/lib/pact_broker/versions/service.rb +2 -6
- data/lib/pact_broker/webhooks/execution.rb +8 -8
- data/lib/sequel/extensions/pg_advisory_lock.rb +101 -0
- data/pact_broker.gemspec +1 -1
- metadata +10 -5
@@ -57,6 +57,13 @@ module PactBroker
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
# Returns the latest pact for each branch, returning a pact for every branch, even if
|
61
|
+
# the most recent version of that branch does not have a pact.
|
62
|
+
# This is different from for_all_branch_heads, which will find the branch head versions,
|
63
|
+
# and return the pacts associated with those versions.
|
64
|
+
# This method should not be used for 'pacts for verification', because it will return
|
65
|
+
# a pact for branches where that integration should no longer exist.
|
66
|
+
# @return [Dataset<PactBroker::Pacts::PactPublication>]
|
60
67
|
def latest_by_consumer_branch
|
61
68
|
branch_versions_join = {
|
62
69
|
Sequel[:pact_publications][:consumer_version_id] => Sequel[:branch_versions][:version_id]
|
@@ -111,10 +118,29 @@ module PactBroker
|
|
111
118
|
.limit(1)
|
112
119
|
end
|
113
120
|
|
114
|
-
#
|
121
|
+
# Returns the pacts (if they exist) for all the branch heads.
|
122
|
+
# If the version for the branch head does not have a pact, then no pact is returned,
|
123
|
+
# (unlike latest_by_consumer_branch)
|
124
|
+
# This is much more performant than latest_by_consumer_branch and should be used
|
125
|
+
# for the 'pacts for verification' response
|
126
|
+
# @return [Dataset<PactBroker::Pacts::PactPublication>]
|
127
|
+
def for_all_branch_heads
|
128
|
+
base_query = self
|
129
|
+
base_query = base_query.join(:branch_heads, { Sequel[:bh][:version_id] => Sequel[:pact_publications][:consumer_version_id] }, { table_alias: :bh })
|
130
|
+
|
131
|
+
if no_columns_selected?
|
132
|
+
base_query = base_query.select_all_qualified.select_append(Sequel[:bh][:branch_name].as(:branch_name))
|
133
|
+
end
|
134
|
+
|
135
|
+
base_query.remove_overridden_revisions
|
136
|
+
end
|
137
|
+
|
138
|
+
# Return the pacts (if they exist) for the branch heads of the given branch names
|
115
139
|
# This uses the new logic of finding the branch head and returning any associated pacts,
|
116
140
|
# rather than the old logic of returning the pact for the latest version
|
117
141
|
# on the branch that had a pact.
|
142
|
+
# @param [String] branch_name
|
143
|
+
# @return [Sequel::Dataset<PactBroker::Pacts::PactPublication>]
|
118
144
|
def for_branch_heads(branch_name)
|
119
145
|
branch_head_join = {
|
120
146
|
Sequel[:pact_publications][:consumer_version_id] => Sequel[:branch_heads][:version_id],
|
@@ -173,7 +199,10 @@ module PactBroker
|
|
173
199
|
# The latest pact publication for each tag
|
174
200
|
# This uses the old logic of "the latest pact for a version that has a tag" (which always returns a pact)
|
175
201
|
# rather than "the pact for the latest version with a tag"
|
176
|
-
#
|
202
|
+
#
|
203
|
+
# For 'pacts for verification' this has been replaced by for_all_tag_heads
|
204
|
+
# This should only be used for the UI
|
205
|
+
# @return [Sequel::Dataset<PactBroker::Pacts::PactPublication>]
|
177
206
|
def latest_by_consumer_tag
|
178
207
|
tags_join = {
|
179
208
|
Sequel[:pact_publications][:consumer_version_id] => Sequel[:tags][:version_id],
|
@@ -202,6 +231,7 @@ module PactBroker
|
|
202
231
|
# This uses the old logic of "the latest pact for a version that has a tag" (which always returns a pact)
|
203
232
|
# rather than "the pact for the latest version with a tag"
|
204
233
|
# Need to see about updating this.
|
234
|
+
# @return [Sequel::Dataset<PactBroker::Pacts::PactPublication>]
|
205
235
|
def latest_for_consumer_tag(tag_name)
|
206
236
|
tags_join = {
|
207
237
|
Sequel[:pact_publications][:consumer_version_id] => Sequel[:tags][:version_id],
|
@@ -252,6 +282,30 @@ module PactBroker
|
|
252
282
|
.remove_overridden_revisions_from_complete_query
|
253
283
|
end
|
254
284
|
|
285
|
+
# The pacts for the latest versions for each tag.
|
286
|
+
# Will not return a pact if the pact is no longer published for a particular tag
|
287
|
+
# NEW LOGIC
|
288
|
+
# @return [Sequel::Dataset<PactBroker::Pacts::PactPublication>]
|
289
|
+
def for_all_tag_heads
|
290
|
+
head_tags = PactBroker::Domain::Tag
|
291
|
+
.select_group(:pacticipant_id, :name)
|
292
|
+
.select_append{ max(version_order).as(:latest_version_order) }
|
293
|
+
|
294
|
+
head_tags_join = {
|
295
|
+
Sequel[:pact_publications][:consumer_id] => Sequel[:head_tags][:pacticipant_id],
|
296
|
+
Sequel[:pact_publications][:consumer_version_order] => Sequel[:head_tags][:latest_version_order]
|
297
|
+
}
|
298
|
+
|
299
|
+
base_query = self
|
300
|
+
if no_columns_selected?
|
301
|
+
base_query = base_query.select_all_qualified.select_append(Sequel[:head_tags][:name].as(:tag_name))
|
302
|
+
end
|
303
|
+
|
304
|
+
base_query
|
305
|
+
.join(head_tags, head_tags_join, { table_alias: :head_tags })
|
306
|
+
.remove_overridden_revisions_from_complete_query
|
307
|
+
end
|
308
|
+
|
255
309
|
def in_environments
|
256
310
|
currently_deployed_join = {
|
257
311
|
Sequel[:pact_publications][:consumer_version_id] => Sequel[:currently_deployed_version_ids][:version_id]
|
@@ -15,6 +15,7 @@ module PactBroker
|
|
15
15
|
|
16
16
|
# Do the "latest" logic last so that the provider/consumer criteria get included in the "latest" query before the join, rather than after
|
17
17
|
query = query.latest_for_main_branches if selector.latest_for_main_branch?
|
18
|
+
query = query.for_all_branch_heads if selector.latest_for_each_branch?
|
18
19
|
query = query.latest_for_consumer_branch(selector.branch) if selector.latest_for_branch?
|
19
20
|
query = query.for_latest_consumer_versions_with_tag(selector.tag) if selector.latest_for_tag?
|
20
21
|
query = query.overall_latest if selector.overall_latest?
|
@@ -1,35 +1,76 @@
|
|
1
1
|
module PactBroker
|
2
2
|
module Pacts
|
3
3
|
module PactPublicationWipDatasetModule
|
4
|
+
|
5
|
+
# Use a cut down model of the verifications table just for the WIP calculations.
|
6
|
+
# Don't need all the associations and normal domain methods.
|
7
|
+
class VerificationForWipCalculations < Sequel::Model(:verifications)
|
8
|
+
dataset_module do
|
9
|
+
def successful_non_wip_by_provider(provider_id)
|
10
|
+
distinct.where(success: true, wip: false, provider_id: provider_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
def verified_before_creation_date_of(record)
|
14
|
+
if record
|
15
|
+
verified_before_date(record.created_at)
|
16
|
+
else
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def join_branch_versions_excluding_branch(provider_id, branch_name)
|
22
|
+
branch_versions_join = {
|
23
|
+
Sequel[:verifications][:provider_version_id] => Sequel[:branch_versions][:version_id],
|
24
|
+
Sequel[:branch_versions][:pacticipant_id] => provider_id
|
25
|
+
}
|
26
|
+
join(:branch_versions, branch_versions_join) do
|
27
|
+
Sequel.lit("branch_versions.branch_name != ?", branch_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def join_provider_versions_for_provider_id_and_branch(provider_id, provider_version_branch)
|
32
|
+
branch_versions_join = {
|
33
|
+
Sequel[:verifications][:provider_version_id] => Sequel[:branch_versions][:version_id],
|
34
|
+
Sequel[:branch_versions][:pacticipant_id] => provider_id,
|
35
|
+
Sequel[:branch_versions][:branch_name] => provider_version_branch
|
36
|
+
}
|
37
|
+
|
38
|
+
join(:branch_versions, branch_versions_join)
|
39
|
+
end
|
40
|
+
|
41
|
+
def verified_before_date(date)
|
42
|
+
where { Sequel[:verifications][:execution_date] < date }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
4
47
|
def successfully_verified_by_provider_branch_when_not_wip(provider_id, provider_version_branch)
|
48
|
+
successful_verifications = VerificationForWipCalculations
|
49
|
+
.select(:pact_version_id)
|
50
|
+
.distinct
|
51
|
+
.successful_non_wip_by_provider(provider_id)
|
52
|
+
.join_provider_versions_for_provider_id_and_branch(provider_id, provider_version_branch)
|
53
|
+
|
54
|
+
|
5
55
|
from_self(alias: :pp)
|
6
56
|
.select(Sequel[:pp].*)
|
7
|
-
.where(Sequel[:pp][:provider_id] => provider_id)
|
8
|
-
.join_successful_non_wip_verifications_for_provider_id(provider_id)
|
9
|
-
.join_provider_versions_for_provider_id_and_branch(provider_id, provider_version_branch)
|
10
57
|
.distinct
|
58
|
+
.join(successful_verifications, { Sequel[:pp][:pact_version_id] => Sequel[:v][:pact_version_id] }, { table_alias: :v })
|
11
59
|
end
|
12
60
|
|
13
61
|
def successfully_verified_by_provider_another_branch_before_this_branch_first_created(provider_id, provider_version_branch)
|
14
62
|
first_version_for_branch = PactBroker::Domain::Version.first_for_pacticipant_id_and_branch(provider_id, provider_version_branch)
|
15
63
|
|
64
|
+
successful_verifications = VerificationForWipCalculations
|
65
|
+
.select(:pact_version_id)
|
66
|
+
.distinct
|
67
|
+
.successful_non_wip_by_provider(provider_id)
|
68
|
+
.join_branch_versions_excluding_branch(provider_id, provider_version_branch)
|
69
|
+
.verified_before_creation_date_of(first_version_for_branch)
|
70
|
+
|
16
71
|
from_self(alias: :pp)
|
17
72
|
.select(Sequel[:pp].*)
|
18
|
-
.
|
19
|
-
.join_provider_versions_for_provider_id(provider_id)
|
20
|
-
.join_branch_versions_excluding_branch(provider_version_branch)
|
21
|
-
.where(Sequel[:pp][:provider_id] => provider_id)
|
22
|
-
.verified_before_creation_date_of(first_version_for_branch)
|
23
|
-
.distinct
|
24
|
-
end
|
25
|
-
|
26
|
-
def join_branch_versions_excluding_branch(branch_name)
|
27
|
-
branch_versions_join = {
|
28
|
-
Sequel[:provider_versions][:id] => Sequel[:branch_versions][:version_id]
|
29
|
-
}
|
30
|
-
join(:branch_versions, branch_versions_join) do
|
31
|
-
Sequel.lit("branch_versions.branch_name != ?", branch_name)
|
32
|
-
end
|
73
|
+
.join(successful_verifications, { Sequel[:pp][:pact_version_id] => Sequel[:v][:pact_version_id] }, { table_alias: :v })
|
33
74
|
end
|
34
75
|
|
35
76
|
def successfully_verified_by_provider_tag_when_not_wip(provider_tag)
|
@@ -43,7 +84,6 @@ module PactBroker
|
|
43
84
|
.select(Sequel[:pp].*)
|
44
85
|
.join(:pact_version_provider_tag_successful_verifications, pact_version_provider_tag_verifications_join, { table_alias: :sv })
|
45
86
|
.distinct
|
46
|
-
|
47
87
|
end
|
48
88
|
|
49
89
|
def successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider_id, provider_tag)
|
@@ -71,66 +111,6 @@ module PactBroker
|
|
71
111
|
end
|
72
112
|
.distinct
|
73
113
|
end
|
74
|
-
|
75
|
-
protected
|
76
|
-
|
77
|
-
def verified_before_date(date)
|
78
|
-
where { Sequel[:verifications][:execution_date] < date }
|
79
|
-
end
|
80
|
-
|
81
|
-
def join_successful_non_wip_verifications_for_provider_id(provider_id, &block)
|
82
|
-
verifications_join = {
|
83
|
-
pact_version_id: :pact_version_id,
|
84
|
-
Sequel[:verifications][:success] => true,
|
85
|
-
Sequel[:verifications][:wip] => false,
|
86
|
-
Sequel[:verifications][:provider_id] => provider_id
|
87
|
-
}
|
88
|
-
join(:verifications, verifications_join, {}, &block)
|
89
|
-
end
|
90
|
-
|
91
|
-
def join_provider_version_tags &block
|
92
|
-
tags_join = {
|
93
|
-
Sequel[:verifications][:provider_version_id] => Sequel[:provider_tags][:version_id],
|
94
|
-
}
|
95
|
-
join(:tags, tags_join, { table_alias: :provider_tags }, &block)
|
96
|
-
end
|
97
|
-
|
98
|
-
def join_provider_version_tags_for_tag(tag)
|
99
|
-
tags_join = {
|
100
|
-
Sequel[:verifications][:provider_version_id] => Sequel[:provider_tags][:version_id],
|
101
|
-
Sequel[:provider_tags][:name] => tag
|
102
|
-
}
|
103
|
-
join(:tags, tags_join, { table_alias: :provider_tags } )
|
104
|
-
end
|
105
|
-
|
106
|
-
def join_provider_versions_for_provider_id_and_branch(provider_id, provider_version_branch)
|
107
|
-
versions_join = {
|
108
|
-
Sequel[:verifications][:provider_version_id] => Sequel[:provider_versions][:id],
|
109
|
-
Sequel[:provider_versions][:pacticipant_id] => provider_id
|
110
|
-
}
|
111
|
-
branch_versions_join = {
|
112
|
-
Sequel[:provider_versions][:id] => Sequel[:branch_versions][:version_id],
|
113
|
-
Sequel[:branch_versions][:branch_name] => provider_version_branch
|
114
|
-
}
|
115
|
-
join(:versions, versions_join, { table_alias: :provider_versions } )
|
116
|
-
.join(:branch_versions, branch_versions_join)
|
117
|
-
end
|
118
|
-
|
119
|
-
def join_provider_versions_for_provider_id(provider_id, &block)
|
120
|
-
versions_join = {
|
121
|
-
Sequel[:verifications][:provider_version_id] => Sequel[:provider_versions][:id],
|
122
|
-
Sequel[:provider_versions][:pacticipant_id] => provider_id
|
123
|
-
}
|
124
|
-
join(:versions, versions_join, { table_alias: :provider_versions }, &block)
|
125
|
-
end
|
126
|
-
|
127
|
-
def verified_before_creation_date_of(record)
|
128
|
-
if record
|
129
|
-
verified_before_date(record.created_at)
|
130
|
-
else
|
131
|
-
self
|
132
|
-
end
|
133
|
-
end
|
134
114
|
end
|
135
115
|
end
|
136
116
|
end
|
@@ -7,6 +7,7 @@ require "pact_broker/pacts/selector"
|
|
7
7
|
require "pact_broker/pacts/selectors"
|
8
8
|
require "pact_broker/feature_toggle"
|
9
9
|
require "pact_broker/repositories/scopes"
|
10
|
+
require "pact_broker/matrix/unresolved_selector"
|
10
11
|
|
11
12
|
module PactBroker
|
12
13
|
module Pacts
|
@@ -63,7 +64,7 @@ module PactBroker
|
|
63
64
|
provider_tags_names,
|
64
65
|
wip_start_date,
|
65
66
|
explicitly_specified_verifiable_pacts,
|
66
|
-
:
|
67
|
+
:for_all_tag_heads
|
67
68
|
)
|
68
69
|
|
69
70
|
wip_by_consumer_branches = find_wip_pact_versions_for_provider_by_provider_tags(
|
@@ -71,7 +72,7 @@ module PactBroker
|
|
71
72
|
provider_tags_names,
|
72
73
|
wip_start_date,
|
73
74
|
explicitly_specified_verifiable_pacts,
|
74
|
-
:
|
75
|
+
:for_all_branch_heads
|
75
76
|
)
|
76
77
|
|
77
78
|
deduplicate_verifiable_pacts(wip_by_consumer_tags + wip_by_consumer_branches).sort
|
@@ -228,8 +229,8 @@ module PactBroker
|
|
228
229
|
provider = pacticipant_repository.find_by_name(provider_name)
|
229
230
|
wip_start_date = options.fetch(:include_wip_pacts_since)
|
230
231
|
|
231
|
-
potential_wip_by_consumer_branch = PactPublication.for_provider(provider).created_after(wip_start_date).
|
232
|
-
potential_wip_by_consumer_tag = PactPublication.for_provider(provider).created_after(wip_start_date).
|
232
|
+
potential_wip_by_consumer_branch = PactPublication.for_provider(provider).created_after(wip_start_date).for_all_branch_heads
|
233
|
+
potential_wip_by_consumer_tag = PactPublication.for_provider(provider).created_after(wip_start_date).for_all_tag_heads
|
233
234
|
|
234
235
|
log_debug_for_wip do
|
235
236
|
log_pact_publications_from_query("Potential WIP pacts for provider branch #{provider_version_branch} created after #{wip_start_date} by consumer branch", potential_wip_by_consumer_branch)
|
@@ -33,8 +33,8 @@ module PactBroker
|
|
33
33
|
scope
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
# @return [PactBroker::Domain::Pact]
|
37
|
+
def create(params)
|
38
38
|
pact_version = find_or_create_pact_version(
|
39
39
|
params.fetch(:consumer_id),
|
40
40
|
params.fetch(:provider_id),
|
@@ -31,6 +31,8 @@ module PactBroker
|
|
31
31
|
def type
|
32
32
|
if latest_for_main_branch?
|
33
33
|
:latest_for_main_branch
|
34
|
+
elsif latest_for_each_branch?
|
35
|
+
:latest_for_each_branch
|
34
36
|
elsif latest_for_branch?
|
35
37
|
:latest_for_branch
|
36
38
|
elsif matching_branch?
|
@@ -265,12 +267,16 @@ module PactBroker
|
|
265
267
|
# Not sure if the fallback_tag logic is needed
|
266
268
|
def latest_for_branch? potential_branch = nil
|
267
269
|
if potential_branch
|
268
|
-
|
270
|
+
latest == true && branch == potential_branch
|
269
271
|
else
|
270
|
-
|
272
|
+
latest == true && branch.is_a?(String)
|
271
273
|
end
|
272
274
|
end
|
273
275
|
|
276
|
+
def latest_for_each_branch?
|
277
|
+
latest == true && branch == true
|
278
|
+
end
|
279
|
+
|
274
280
|
def all_for_tag_and_consumer?
|
275
281
|
!!(tag && !latest? && consumer)
|
276
282
|
end
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# This task is used to clean up old data in a Pact Broker database
|
2
|
+
# to stop performance issues from slowing down responses when there is
|
3
|
+
# too much data.
|
4
|
+
# See https://docs.pact.io/pact_broker/administration/maintenance
|
5
|
+
|
1
6
|
module PactBroker
|
2
7
|
module DB
|
3
8
|
class CleanTask < ::Rake::TaskLib
|
@@ -7,11 +12,13 @@ module PactBroker
|
|
7
12
|
attr_accessor :version_deletion_limit
|
8
13
|
attr_accessor :logger
|
9
14
|
attr_accessor :dry_run
|
15
|
+
attr_accessor :use_lock # allow disabling of postgres lock if it is causing problems
|
10
16
|
|
11
17
|
def initialize &block
|
12
18
|
require "pact_broker/db/clean_incremental"
|
13
19
|
@version_deletion_limit = 1000
|
14
20
|
@dry_run = false
|
21
|
+
@use_lock = true
|
15
22
|
@keep_version_selectors = PactBroker::DB::CleanIncremental::DEFAULT_KEEP_SELECTORS
|
16
23
|
rake_task(&block)
|
17
24
|
end
|
@@ -28,42 +35,77 @@ module PactBroker
|
|
28
35
|
namespace :db do
|
29
36
|
desc "Clean unnecessary pacts and verifications from database"
|
30
37
|
task :clean do | _t, _args |
|
31
|
-
|
32
38
|
instance_eval(&block)
|
33
39
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
40
|
+
with_lock do
|
41
|
+
perform_clean
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def perform_clean
|
49
|
+
require "pact_broker/db/clean_incremental"
|
50
|
+
require "pact_broker/error"
|
51
|
+
require "yaml"
|
52
|
+
require "benchmark"
|
38
53
|
|
39
|
-
|
54
|
+
raise PactBroker::Error.new("You must specify the version_deletion_limit") unless version_deletion_limit
|
40
55
|
|
41
|
-
|
56
|
+
if keep_version_selectors.nil? || keep_version_selectors.empty?
|
57
|
+
raise PactBroker::Error.new("You must specify which versions to keep")
|
58
|
+
else
|
59
|
+
add_defaults_to_keep_selectors
|
60
|
+
output "Deleting oldest #{version_deletion_limit} versions, keeping versions that match the configured selectors", keep_version_selectors.collect(&:to_hash)
|
61
|
+
end
|
42
62
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
63
|
+
start_time = Time.now
|
64
|
+
results = PactBroker::DB::CleanIncremental.call(database_connection,
|
65
|
+
keep: keep_version_selectors,
|
66
|
+
limit: version_deletion_limit,
|
67
|
+
logger: logger,
|
68
|
+
dry_run: dry_run
|
69
|
+
)
|
70
|
+
end_time = Time.now
|
71
|
+
elapsed_seconds = (end_time - start_time).to_i
|
72
|
+
output "Results (#{elapsed_seconds} seconds)", results
|
73
|
+
end
|
49
74
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
75
|
+
# Use a Postgres advisory lock to ensure that only one clean can run at a time.
|
76
|
+
# This allows a cron schedule to be used on the Pact Broker Docker image when deployed
|
77
|
+
# on a multi-instance architecture, without all the instances stepping on each other's toes.
|
78
|
+
#
|
79
|
+
# Any tasks that attempt to run while a clean job is running will skip the clean
|
80
|
+
# and exit with a message and a success code.
|
81
|
+
#
|
82
|
+
# To test that the lock works, run:
|
83
|
+
# script/docker/db-start.sh
|
84
|
+
# script/docker/db-migrate.sh
|
85
|
+
# for i in {0..3}; do PACT_BROKER_TEST_DATABASE_URL=postgres://postgres:postgres@localhost/postgres bundle exec rake pact_broker:db:clean &; done;
|
86
|
+
#
|
87
|
+
# There will be 3 messages saying "Clean was not performed" and output from one thread showing the clean is being done.
|
88
|
+
def with_lock
|
89
|
+
if use_lock
|
90
|
+
require "pact_broker/db/advisory_lock"
|
91
|
+
|
92
|
+
lock = PactBroker::DB::AdvisoryLock.new(database_connection, :clean, :pg_try_advisory_lock)
|
93
|
+
results = lock.with_lock do
|
94
|
+
yield
|
95
|
+
end
|
96
|
+
|
97
|
+
if !lock.lock_obtained?
|
98
|
+
output("Clean was not performed as a clean is already in progress. Exiting.")
|
61
99
|
end
|
100
|
+
results
|
101
|
+
else
|
102
|
+
yield
|
62
103
|
end
|
63
104
|
end
|
64
105
|
|
65
|
-
def output
|
66
|
-
|
106
|
+
def output(string, payload = {})
|
107
|
+
prefix = dry_run ? "[DRY RUN] " : ""
|
108
|
+
logger ? logger.info("#{prefix}#{string}") : puts("#{prefix}#{string} #{payload.to_json}")
|
67
109
|
end
|
68
110
|
|
69
111
|
def add_defaults_to_keep_selectors
|
@@ -43,7 +43,6 @@ module PactBroker
|
|
43
43
|
include PactBroker::Services
|
44
44
|
using PactBroker::StringRefinements
|
45
45
|
|
46
|
-
|
47
46
|
attr_reader :pacticipant
|
48
47
|
attr_reader :consumer
|
49
48
|
attr_reader :provider
|
@@ -192,8 +191,11 @@ module PactBroker
|
|
192
191
|
self
|
193
192
|
end
|
194
193
|
|
194
|
+
# Create an Integration object for the current consumer and provider
|
195
|
+
# @return [PactBroker::Test::TestDataBuilder]
|
195
196
|
def create_integration
|
196
|
-
PactBroker::Integrations::Repository.new.create_for_pact(consumer.id, provider.id)
|
197
|
+
@integration = PactBroker::Integrations::Repository.new.create_for_pact(consumer.id, provider.id)
|
198
|
+
set_created_at_if_set(@now, :integrations, { consumer_id: consumer.id, provider_id: provider.id })
|
197
199
|
self
|
198
200
|
end
|
199
201
|
|
@@ -280,7 +282,9 @@ module PactBroker
|
|
280
282
|
self
|
281
283
|
end
|
282
284
|
|
283
|
-
|
285
|
+
# Creates a pact (and integration if one does not already exist) from the given params
|
286
|
+
# @return [PactBroker::Test::TestDataBuilder]
|
287
|
+
def create_pact(params = {})
|
284
288
|
params.delete(:comment)
|
285
289
|
json_content = params[:json_content] || default_json_content
|
286
290
|
pact_version_sha = params[:pact_version_sha] || generate_pact_version_sha(json_content)
|
@@ -293,6 +297,7 @@ module PactBroker
|
|
293
297
|
json_content: prepare_json_content(json_content),
|
294
298
|
version: @consumer_version
|
295
299
|
)
|
300
|
+
integration_service.handle_bulk_contract_data_published([@pact])
|
296
301
|
pact_versions_count_after = PactBroker::Pacts::PactVersion.count
|
297
302
|
set_created_at_if_set(params[:created_at], :pact_publications, id: @pact.id)
|
298
303
|
set_created_at_if_set(params[:created_at], :pact_versions, sha: @pact.pact_version_sha) if pact_versions_count_after > pact_versions_count_before
|
data/lib/pact_broker/version.rb
CHANGED
@@ -57,29 +57,11 @@ module PactBroker
|
|
57
57
|
.single_record
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
|
-
# Newer "find all" implementations for other models pass the relations to eager load in
|
62
|
-
# from the decorator via the resource.
|
63
|
-
def find_all_pacticipant_versions_in_reverse_order name, pagination_options = {}
|
64
|
-
pacticipant = pacticipant_repository.find_by_name!(name)
|
65
|
-
query = PactBroker::Domain::Version
|
66
|
-
.where(pacticipant: pacticipant)
|
67
|
-
.eager(:pacticipant)
|
68
|
-
.eager(branch_versions: [:version, :branch_head, { branch: :pacticipant }])
|
69
|
-
.eager(tags: :head_tag)
|
70
|
-
.eager(:pact_publications)
|
71
|
-
.reverse_order(:order)
|
72
|
-
query.all_with_pagination_options(pagination_options)
|
73
|
-
end
|
74
|
-
|
75
|
-
def find_pacticipant_versions_in_reverse_order(pacticipant_name, options = {}, pagination_options = {})
|
60
|
+
def find_pacticipant_versions_in_reverse_order(pacticipant_name, options = {}, pagination_options = {}, eager_load_associations = [])
|
76
61
|
pacticipant = pacticipant_repository.find_by_name!(pacticipant_name)
|
77
62
|
query = PactBroker::Domain::Version
|
78
63
|
.where(pacticipant: pacticipant)
|
79
|
-
.eager(
|
80
|
-
.eager(branch_versions: [:version, :branch_head, { branch: :pacticipant }])
|
81
|
-
.eager(tags: :head_tag)
|
82
|
-
.eager(:pact_publications)
|
64
|
+
.eager(*eager_load_associations)
|
83
65
|
.reverse_order(:order)
|
84
66
|
|
85
67
|
if options[:branch_name]
|
@@ -26,12 +26,8 @@ module PactBroker
|
|
26
26
|
version_repository.find_latest_by_pacticipant_name_and_branch_name(pacticipant_name, branch_name)
|
27
27
|
end
|
28
28
|
|
29
|
-
def self.
|
30
|
-
version_repository.
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.find_pacticipant_versions_in_reverse_order(pacticipant_name, options, pagination_options = {})
|
34
|
-
version_repository.find_pacticipant_versions_in_reverse_order(pacticipant_name, options, pagination_options)
|
29
|
+
def self.find_pacticipant_versions_in_reverse_order(pacticipant_name, options, pagination_options = {}, eager_load_associations = [])
|
30
|
+
version_repository.find_pacticipant_versions_in_reverse_order(pacticipant_name, options, pagination_options, eager_load_associations)
|
35
31
|
end
|
36
32
|
|
37
33
|
def self.create_or_overwrite(pacticipant_name, version_number, version)
|
@@ -2,14 +2,14 @@ require "pact_broker/dataset"
|
|
2
2
|
|
3
3
|
module PactBroker
|
4
4
|
module Webhooks
|
5
|
-
class Execution < Sequel::Model(
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
class Execution < Sequel::Model(:webhook_executions)
|
6
|
+
# Ignore the columns that were used before the TriggeredWebhook class existed.
|
7
|
+
# It used to go Webhook -> Execution, and now it goes Webhook -> TriggeredWebhook -> Execution
|
8
|
+
# If we ever release a major version where we drop unused columns, those columns could be deleted.
|
9
|
+
EXECUTION_COLUMNS = Sequel::Model.db.schema(:webhook_executions).collect(&:first) - [:webhook_id, :pact_publication_id, :consumer_id, :provider_id]
|
10
|
+
|
11
|
+
set_dataset(Sequel::Model.db[:webhook_executions].select(*EXECUTION_COLUMNS))
|
12
|
+
|
13
13
|
set_primary_key :id
|
14
14
|
plugin :timestamps
|
15
15
|
|