pact_broker 2.80.0 → 2.81.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/CHANGELOG.md +21 -0
  4. data/db/ddl_statements/latest_verifications_for_pact_versions.rb +28 -0
  5. data/db/migrations/20210711_add_consumer_version_order_to_pact_publication.rb +12 -0
  6. data/db/migrations/20210712_add_interaction_count_to_pact_versions.rb +8 -0
  7. data/lib/db.rb +4 -0
  8. data/lib/pact_broker/api.rb +8 -10
  9. data/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +25 -5
  10. data/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +0 -1
  11. data/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +24 -0
  12. data/lib/pact_broker/api/resources/dashboard.rb +4 -1
  13. data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +3 -7
  14. data/lib/pact_broker/api/resources/index.rb +10 -12
  15. data/lib/pact_broker/api/resources/latest_provider_pacts.rb +1 -1
  16. data/lib/pact_broker/api/resources/pagination_methods.rb +14 -0
  17. data/lib/pact_broker/api/resources/tag.rb +14 -0
  18. data/lib/pact_broker/configuration.rb +4 -1
  19. data/lib/pact_broker/db/data_migrations/set_consumer_version_order_for_pact_publications.rb +28 -0
  20. data/lib/pact_broker/db/data_migrations/set_interactions_counts.rb +41 -0
  21. data/lib/pact_broker/db/migrate_data.rb +2 -0
  22. data/lib/pact_broker/db/seed_example_data.rb +5 -0
  23. data/lib/pact_broker/deployments/deployed_version_service.rb +13 -9
  24. data/lib/pact_broker/domain/verification.rb +40 -0
  25. data/lib/pact_broker/domain/version.rb +4 -0
  26. data/lib/pact_broker/index/service.rb +4 -5
  27. data/lib/pact_broker/integrations/integration.rb +27 -6
  28. data/lib/pact_broker/logging.rb +10 -0
  29. data/lib/pact_broker/matrix/unresolved_selector.rb +1 -1
  30. data/lib/pact_broker/metrics/service.rb +17 -0
  31. data/lib/pact_broker/pacts/all_pact_publications.rb +4 -2
  32. data/lib/pact_broker/pacts/content.rb +2 -2
  33. data/lib/pact_broker/pacts/metadata.rb +11 -5
  34. data/lib/pact_broker/pacts/pact_publication.rb +41 -6
  35. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +55 -11
  36. data/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +20 -0
  37. data/lib/pact_broker/pacts/pact_version.rb +14 -15
  38. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +86 -31
  39. data/lib/pact_broker/pacts/parse.rb +1 -0
  40. data/lib/pact_broker/pacts/repository.rb +51 -41
  41. data/lib/pact_broker/pacts/selector.rb +18 -2
  42. data/lib/pact_broker/pacts/service.rb +13 -22
  43. data/lib/pact_broker/pacts/verifiable_pact_messages.rb +11 -0
  44. data/lib/pact_broker/repositories/helpers.rb +4 -0
  45. data/lib/pact_broker/repositories/scopes.rb +15 -0
  46. data/lib/pact_broker/test/test_data_builder.rb +2 -1
  47. data/lib/pact_broker/ui/helpers/matrix_helper.rb +1 -0
  48. data/lib/pact_broker/ui/views/index/show-with-tags.haml +1 -1
  49. data/lib/pact_broker/ui/views/matrix/show.haml +2 -0
  50. data/lib/pact_broker/verifications/latest_verification_for_pact_version.rb +2 -2
  51. data/lib/pact_broker/verifications/repository.rb +9 -10
  52. data/lib/pact_broker/version.rb +1 -1
  53. data/public/javascripts/matrix.js +3 -0
  54. data/spec/features/create_tag_spec.rb +10 -0
  55. data/spec/features/execute_webhook_spec.rb +1 -3
  56. data/spec/features/get_integrations_spec.rb +2 -2
  57. data/spec/features/get_provider_pacts_for_verification_spec.rb +5 -3
  58. data/spec/features/metadata_spec.rb +66 -0
  59. data/spec/features/publish_verification_results_and_version_spec.rb +70 -0
  60. data/spec/fixtures/approvals/get_provider_pacts_for_verification.approved.json +2 -2
  61. data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_combinations_spec.rb +9 -0
  62. data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +15 -0
  63. data/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb +12 -0
  64. data/spec/lib/pact_broker/api/resources/dashboard_spec.rb +23 -2
  65. data/spec/lib/pact_broker/api/resources/latest_provider_pacts_spec.rb +3 -3
  66. data/spec/lib/pact_broker/api/resources/provider_pacts_spec.rb +1 -1
  67. data/spec/lib/pact_broker/api/resources/tag_spec.rb +39 -13
  68. data/spec/lib/pact_broker/db/data_migrations/set_interactions_counts_spec.rb +38 -0
  69. data/spec/lib/pact_broker/deployments/deployed_version_service_spec.rb +42 -0
  70. data/spec/lib/pact_broker/domain/verification_spec.rb +17 -0
  71. data/spec/lib/pact_broker/index/service_spec.rb +28 -16
  72. data/spec/lib/pact_broker/integrations/integration_spec.rb +21 -10
  73. data/spec/lib/pact_broker/metrics/service_spec.rb +25 -0
  74. data/spec/lib/pact_broker/pacts/content_spec.rb +1 -1
  75. data/spec/lib/pact_broker/pacts/metadata_spec.rb +95 -29
  76. data/spec/lib/pact_broker/pacts/pact_publication_selector_dataset_module_spec.rb +39 -0
  77. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +68 -12
  78. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_branch_spec.rb +1 -1
  79. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_spec.rb +1 -1
  80. data/spec/lib/pact_broker/pacts/repository_spec.rb +59 -52
  81. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +9 -0
  82. data/spec/lib/pact_broker/verifications/latest_verification_for_pact_version_spec.rb +18 -0
  83. data/spec/support/shared_context.rb +0 -1
  84. metadata +20 -3
@@ -5,6 +5,18 @@ module PactBroker
5
5
  module PactPublicationDatasetModule
6
6
  include PactPublicationSelectorDatasetModule
7
7
 
8
+ def for_consumer_id_and_provider_id(consumer_id, provider_id)
9
+ where(Sequel[:pact_publications][:consumer_id] => consumer_id, Sequel[:pact_publications][:provider_id] => provider_id)
10
+ end
11
+
12
+ def for_provider_name(provider_name)
13
+ where(provider: PactBroker::Domain::Pacticipant.find_by_name(provider_name))
14
+ end
15
+
16
+ def for_consumer_name(consumer_name)
17
+ where(consumer: PactBroker::Domain::Pacticipant.find_by_name(consumer_name))
18
+ end
19
+
8
20
  def for_provider provider
9
21
  where(provider: provider)
10
22
  end
@@ -13,6 +25,18 @@ module PactBroker
13
25
  where(consumer: consumer)
14
26
  end
15
27
 
28
+ def for_consumer_version_tag tag_name
29
+ join(:tags, { version_id: :consumer_version_id, Sequel[:tags][:name] => tag_name })
30
+ end
31
+
32
+ def for_consumer_name_and_maybe_version_number(consumer_name, consumer_version_number)
33
+ if consumer_version_number
34
+ where(consumer_version: PactBroker::Domain::Version.where_pacticipant_name_and_version_number(consumer_name, consumer_version_number))
35
+ else
36
+ where(consumer: PactBroker::Domain::Pacticipant.find_by_name(consumer_name))
37
+ end
38
+ end
39
+
16
40
  def latest_by_consumer_branch
17
41
  versions_join = {
18
42
  Sequel[:pact_publications][:consumer_version_id] => Sequel[:cv][:id]
@@ -39,20 +63,25 @@ module PactBroker
39
63
  end
40
64
 
41
65
  def overall_latest
42
- base_query = join_consumer_versions # won't need to do this when we add the order to latest_pact_publication_ids_for_consumer_versions
43
-
44
66
  self_join = {
45
67
  Sequel[:pact_publications][:consumer_id] => Sequel[:pp2][:consumer_id],
46
68
  Sequel[:pact_publications][:provider_id] => Sequel[:pp2][:provider_id]
47
69
  }
48
70
 
71
+ base_query = self
49
72
  base_query = base_query.select_all_qualified if no_columns_selected?
50
73
 
51
- base_query.left_join(base_query.select(:consumer_id, :provider_id, :order), self_join, { table_alias: :pp2 } ) do
52
- Sequel[:pp2][:order] > Sequel[:cv][:order]
74
+ base_query.left_join(base_query.select(:consumer_id, :provider_id, :consumer_version_order), self_join, { table_alias: :pp2 } ) do
75
+ Sequel[:pp2][:consumer_version_order] > Sequel[:pact_publications][:consumer_version_order]
53
76
  end
54
- .where(Sequel[:pp2][:order] => nil)
55
- .remove_overridden_revisions_from_complete_query
77
+ .where(Sequel[:pp2][:consumer_version_order] => nil)
78
+ .remove_overridden_revisions_from_complete_query # do we need this?
79
+ end
80
+
81
+ def overall_latest_for_consumer_id_and_provider_id(consumer_id, provider_id)
82
+ for_consumer_id_and_provider_id(consumer_id, provider_id)
83
+ .order(Sequel.desc(Sequel[:pact_publications][:consumer_version_order]), Sequel.desc(:revision_number))
84
+ .limit(1)
56
85
  end
57
86
 
58
87
  def latest_for_consumer_branch(branch)
@@ -151,13 +180,19 @@ module PactBroker
151
180
  end
152
181
 
153
182
  def remove_overridden_revisions(pact_publications_alias = :pact_publications)
154
- join(:latest_pact_publication_ids_for_consumer_versions, { Sequel[:lp][:pact_publication_id] => Sequel[pact_publications_alias][:id] }, { table_alias: :lp})
183
+ base = self
184
+ base = base.select_all_qualified if no_columns_selected?
185
+ base.join(:latest_pact_publication_ids_for_consumer_versions, { Sequel[:lp][:pact_publication_id] => Sequel[pact_publications_alias][:id] }, { table_alias: :lp})
155
186
  end
156
187
 
157
188
  def remove_overridden_revisions_from_complete_query
158
- from_self(alias: :p)
159
- .select(Sequel[:p].*)
160
- .remove_overridden_revisions(:p)
189
+ from_self(alias: :pact_publications)
190
+ .select(Sequel[:pact_publications].*)
191
+ .remove_overridden_revisions(:pact_publications)
192
+ end
193
+
194
+ def for_pact_version_id(pact_version_id)
195
+ where(Sequel[:pact_publications][:pact_version_id] => pact_version_id)
161
196
  end
162
197
 
163
198
  def join_consumer_versions(table_alias = :cv, extra_join_criteria = {}, &block)
@@ -198,6 +233,11 @@ module PactBroker
198
233
  join(:pact_versions, { Sequel[:pact_publications][:pact_version_id] => Sequel[:pact_versions][:id] })
199
234
  end
200
235
 
236
+ def for_pact_version_sha(pact_version_sha)
237
+ join_pact_versions
238
+ .where(Sequel[:pact_versions][:sha] => pact_version_sha)
239
+ end
240
+
201
241
  def eager_load_pact_versions
202
242
  eager(:pact_versions)
203
243
  end
@@ -228,7 +268,11 @@ module PactBroker
228
268
  end
229
269
 
230
270
  def order_by_consumer_version_order
231
- order_append(Sequel[:cv][:order])
271
+ order_append(:consumer_version_order, :revision_number)
272
+ end
273
+
274
+ def latest
275
+ order(:consumer_version_order, :revision_number).last
232
276
  end
233
277
 
234
278
  def where_consumer_if_set(consumer)
@@ -13,7 +13,9 @@ module PactBroker
13
13
  query = query.for_environment(selector.environment_name)
14
14
  end
15
15
 
16
+
16
17
  # Do the "latest" logic last so that the provider/consumer criteria get included in the "latest" query before the join, rather than after
18
+ query = query.latest_for_main_branches if selector.latest_for_main_branch?
17
19
  query = query.latest_for_consumer_branch(selector.branch) if selector.latest_for_branch?
18
20
  query = query.latest_for_consumer_tag(selector.tag) if selector.latest_for_tag?
19
21
  query = query.overall_latest if selector.overall_latest?
@@ -21,6 +23,24 @@ module PactBroker
21
23
  end
22
24
  # rubocop: enable Metrics/CyclomaticComplexity
23
25
 
26
+ def latest_for_main_branches
27
+ self_join = {
28
+ Sequel[:pact_publications][:provider_id] => Sequel[:pp2][:provider_id],
29
+ Sequel[:pact_publications][:consumer_id] => Sequel[:pp2][:consumer_id],
30
+ Sequel[:cv][:branch] => Sequel[:pp2][:branch]
31
+ }
32
+
33
+ base_query = join_consumers(:consumers)
34
+ .join_consumer_versions(:cv, { Sequel[:cv][:branch] => Sequel[:consumers][:main_branch] })
35
+
36
+ base_query = base_query.select_all_qualified if no_columns_selected?
37
+
38
+ base_query.left_join(base_query.select(:provider_id, :consumer_id, Sequel[:cv][:branch], :consumer_version_order), self_join, { table_alias: :pp2 }) do
39
+ Sequel[:pp2][:consumer_version_order] > Sequel[:pact_publications][:consumer_version_order]
40
+ end
41
+ .where(Sequel[:pp2][:consumer_version_order] => nil)
42
+ end
43
+
24
44
  def for_currently_deployed_versions(environment_name)
25
45
  deployed_versions_join = {
26
46
  Sequel[:pact_publications][:consumer_version_id] => Sequel[:deployed_versions][:version_id]
@@ -10,9 +10,18 @@ module PactBroker
10
10
 
11
11
  one_to_many :pact_publications, reciprocal: :pact_version
12
12
  one_to_many :verifications, reciprocal: :verification, order: :id, class: "PactBroker::Domain::Verification"
13
- one_to_one :latest_verification, class: "PactBroker::Verifications::LatestVerificationForPactVersion", key: :pact_version_id, primary_key: :id
14
13
  associate(:many_to_one, :provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
15
14
  associate(:many_to_one, :consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
15
+ associate(:many_to_many, :consumer_versions, class: "PactBroker::Domain::Version", join_table: :pact_publications, left_key: :pact_version_id, right_key: :consumer_version_id, order: :order)
16
+
17
+ one_to_one(:latest_verification, class: "PactBroker::Domain::Verification", key: :pact_version_id, primary_key: :id) do | ds |
18
+ ds.unlimited.latest_by_pact_version
19
+ end
20
+
21
+ # do not eager load this - it won't work because of the limit(1)
22
+ one_through_one(:latest_consumer_version, class: "PactBroker::Domain::Version", join_table: :pact_publications, left_key: :pact_version_id, right_key: :consumer_version_id) do | ds |
23
+ ds.unlimited.order(Sequel.desc(:order)).limit(1)
24
+ end
16
25
 
17
26
  dataset_module do
18
27
  include PactBroker::Repositories::Helpers
@@ -50,23 +59,13 @@ module PactBroker
50
59
  pact_publications.last.consumer.name
51
60
  end
52
61
 
53
- def latest_consumer_version
54
- consumer_versions.last
55
- end
56
-
57
62
  def latest_pact_publication
58
- PactBroker::Pacts::LatestPactPublicationsByConsumerVersion
59
- .where(pact_version_id: id)
60
- .order(:consumer_version_order)
61
- .last || PactBroker::Pacts::AllPactPublications
62
- .where(pact_version_id: id)
63
- .order(:consumer_version_order)
64
- .last
63
+ PactBroker::Pacts::PactPublication
64
+ .for_pact_version_id(id)
65
+ .remove_overridden_revisions_from_complete_query
66
+ .latest || PactBroker::Pacts::PactPublication.for_pact_version_id(id).latest
65
67
  end
66
68
 
67
- def consumer_versions
68
- PactBroker::Domain::Version.where(id: PactBroker::Pacts::PactPublication.select(:consumer_version_id).where(pact_version_id: id)).order(:order)
69
- end
70
69
 
71
70
  def latest_consumer_version_number
72
71
  latest_consumer_version.number
@@ -8,6 +8,7 @@ require "pact_broker/pacts/selected_pact"
8
8
  require "pact_broker/pacts/selector"
9
9
  require "pact_broker/pacts/selectors"
10
10
  require "pact_broker/feature_toggle"
11
+ require "pact_broker/repositories/scopes"
11
12
 
12
13
  module PactBroker
13
14
  module Pacts
@@ -16,6 +17,7 @@ module PactBroker
16
17
  include PactBroker::Repositories
17
18
  include PactBroker::Services
18
19
  include PactBroker::Repositories::Helpers
20
+ include PactBroker::Repositories::Scopes
19
21
 
20
22
  def find(provider_name, consumer_version_selectors)
21
23
  selected_pacts = find_pacts_by_selector(provider_name, consumer_version_selectors) +
@@ -35,43 +37,43 @@ module PactBroker
35
37
  # provider tags they are pending for.
36
38
  # Don't include pact publications that were created before the provider tag was first used
37
39
  # (that is, before the provider's git branch was created).
38
- def find_wip provider_name, provider_version_branch, provider_tags_names = [], options = {}
40
+ def find_wip provider_name, provider_version_branch, provider_tags_names, specified_pact_version_shas, options = {}
39
41
  # TODO not sure about this
40
- return [] if provider_tags_names.empty? && provider_version_branch == nil
42
+ if provider_tags_names.empty? && provider_version_branch == nil
43
+ log_debug_for_wip do
44
+ logger.debug("No provider tags or branch provided. Cannot calculate WIP pacts. Returning an empty list.")
45
+ end
46
+ return []
47
+ end
41
48
 
42
49
  if provider_version_branch
43
- return find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch, options)
50
+ return find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch, specified_pact_version_shas, options)
44
51
  end
45
52
 
46
53
  provider = pacticipant_repository.find_by_name(provider_name)
47
54
  wip_start_date = options.fetch(:include_wip_pacts_since)
48
- provider_tags = provider_tag_objects_for(provider, provider_tags_names)
49
55
 
50
56
  wip_by_consumer_tags = find_wip_pact_versions_for_provider_by_provider_tags(
51
57
  provider,
52
58
  provider_tags_names,
53
- provider_tags,
54
59
  wip_start_date,
55
- :latest_by_consumer_tag)
60
+ specified_pact_version_shas,
61
+ :latest_by_consumer_tag
62
+ )
56
63
 
57
64
  wip_by_consumer_branches = find_wip_pact_versions_for_provider_by_provider_tags(
58
65
  provider,
59
66
  provider_tags_names,
60
- provider_tags,
61
67
  wip_start_date,
62
- :latest_by_consumer_branch)
68
+ specified_pact_version_shas,
69
+ :latest_by_consumer_branch
70
+ )
63
71
 
64
72
  deduplicate_verifiable_pacts(wip_by_consumer_tags + wip_by_consumer_branches).sort
65
73
  end
66
74
 
67
75
  private
68
76
 
69
- # For the times when it doesn't make sense to use the scoped class, this is a way to
70
- # indicate that it is an intentional use of the PactVersion class directly.
71
- def unscoped(scope)
72
- scope
73
- end
74
-
75
77
  # Note: created_at is coming back as a string for sqlite
76
78
  # Can't work out how to to tell Sequel that this should be a date
77
79
  def to_datetime string_or_datetime
@@ -107,6 +109,7 @@ module PactBroker
107
109
  else
108
110
  consumer_version_selectors.select(&:latest_for_tag?) +
109
111
  consumer_version_selectors.select(&:latest_for_branch?) +
112
+ consumer_version_selectors.select(&:latest_for_main_branch?) +
110
113
  consumer_version_selectors.select(&:overall_latest?) +
111
114
  consumer_version_selectors.select(&:currently_deployed?) +
112
115
  consumer_version_selectors.select(&:currently_supported?)
@@ -193,16 +196,19 @@ module PactBroker
193
196
  end
194
197
 
195
198
  # TODO ? find the WIP pacts by consumer branch
196
- def find_wip_pact_versions_for_provider_by_provider_tags(provider, provider_tags_names, _provider_tags, wip_start_date, pact_publication_scope)
199
+ def find_wip_pact_versions_for_provider_by_provider_tags(provider, provider_tags_names, wip_start_date, specified_pact_version_shas, pact_publication_scope)
197
200
  potential_wip_pacts_by_consumer_tag_query = PactPublication.for_provider(provider).created_after(wip_start_date).send(pact_publication_scope)
198
- potential_wip_pacts_by_consumer_tag = potential_wip_pacts_by_consumer_tag_query.all
201
+
202
+ log_debug_for_wip do
203
+ log_pact_publications("Potential WIP pacts for provider tag(s) #{provider_tags_names.join(", ")} created after #{wip_start_date} by #{pact_publication_scope}", potential_wip_pacts_by_consumer_tag_query)
204
+ end
199
205
 
200
206
  tag_to_pact_publications = provider_tags_names.each_with_object({}) do | provider_tag_name, tag_to_pact_publication |
201
207
  tag_to_pact_publication[provider_tag_name] = remove_non_wip_for_tag(
202
- potential_wip_pacts_by_consumer_tag,
203
208
  potential_wip_pacts_by_consumer_tag_query,
204
209
  provider,
205
- provider_tag_name
210
+ provider_tag_name,
211
+ specified_pact_version_shas
206
212
  )
207
213
  end
208
214
 
@@ -222,20 +228,30 @@ module PactBroker
222
228
  end
223
229
  end
224
230
 
225
- def find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch, options)
231
+ def find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch, specified_pact_version_shas, options)
226
232
  provider = pacticipant_repository.find_by_name(provider_name)
227
233
  wip_start_date = options.fetch(:include_wip_pacts_since)
228
234
 
235
+ potential_wip_by_consumer_branch = PactPublication.for_provider(provider).created_after(wip_start_date).latest_by_consumer_branch
236
+ potential_wip_by_consumer_tag = PactPublication.for_provider(provider).created_after(wip_start_date).latest_by_consumer_tag
237
+
238
+ log_debug_for_wip do
239
+ log_pact_publications("Potential WIP pacts for provider branch #{provider_version_branch} created after #{wip_start_date} by consumer branch", potential_wip_by_consumer_branch)
240
+ log_pact_publications("Potential WIP pacts for provider branch #{provider_version_branch} created after #{wip_start_date} by consumer tag", potential_wip_by_consumer_tag)
241
+ end
242
+
229
243
  wip_pact_publications_by_branch = remove_non_wip_for_branch(
230
- PactPublication.for_provider(provider).created_after(wip_start_date).latest_by_consumer_branch,
244
+ potential_wip_by_consumer_branch,
231
245
  provider,
232
- provider_version_branch
246
+ provider_version_branch,
247
+ specified_pact_version_shas
233
248
  )
234
249
 
235
250
  wip_pact_publications_by_tag = remove_non_wip_for_branch(
236
- PactPublication.for_provider(provider).created_after(wip_start_date).latest_by_consumer_tag,
251
+ potential_wip_by_consumer_tag,
237
252
  provider,
238
- provider_version_branch
253
+ provider_version_branch,
254
+ specified_pact_version_shas
239
255
  )
240
256
 
241
257
  verifiable_pacts = (wip_pact_publications_by_branch + wip_pact_publications_by_tag).collect do | pact_publication |
@@ -272,18 +288,57 @@ module PactBroker
272
288
  end
273
289
  end
274
290
 
275
- def remove_non_wip_for_branch(pact_publications, provider, provider_version_branch)
276
- remaining_pact_publications = PactPublication.subtract(pact_publications.all, pact_publications.successfully_verified_by_provider_branch_when_not_wip(provider.id, provider_version_branch).all)
277
- PactPublication.subtract(remaining_pact_publications, pact_publications.successfully_verified_by_provider_another_branch_before_this_branch_first_created(provider.id, provider_version_branch).all)
291
+
292
+ def remove_non_wip_for_branch(pact_publications_query, provider, provider_version_branch, specified_pact_version_shas)
293
+ specified_explicitly = pact_publications_query.for_pact_version_sha(specified_pact_version_shas)
294
+ verified_by_this_branch = pact_publications_query.successfully_verified_by_provider_branch_when_not_wip(provider.id, provider_version_branch)
295
+ verified_by_other_branch = pact_publications_query.successfully_verified_by_provider_another_branch_before_this_branch_first_created(provider.id, provider_version_branch)
296
+
297
+ log_debug_for_wip do
298
+ log_pact_publications("Ignoring pacts explicitly specified in the selectors", specified_explicitly)
299
+ log_pact_publications("Ignoring pacts successfully verified by this provider branch when not WIP", verified_by_this_branch)
300
+ log_pact_publications("Ignoring pacts successfully verified by another provider branch when not WIP", verified_by_other_branch)
301
+ end
302
+
303
+ PactPublication.subtract(pact_publications_query.all, specified_explicitly.all, verified_by_this_branch.all, verified_by_other_branch.all)
278
304
  end
279
305
 
280
- def remove_non_wip_for_tag(pact_publications, query, provider, tag)
281
- pact_publications = PactPublication.subtract(pact_publications, query.successfully_verified_by_provider_tag_when_not_wip(provider.id, tag).all)
282
- PactPublication.subtract(pact_publications, query.successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider.id, tag).all)
306
+ def remove_non_wip_for_tag(pact_publications_query, provider, tag, specified_pact_version_shas)
307
+ specified_explicitly = pact_publications_query.for_pact_version_sha(specified_pact_version_shas)
308
+ verified_by_this_tag = pact_publications_query.successfully_verified_by_provider_tag_when_not_wip(provider.id, tag)
309
+ verified_by_another_tag = pact_publications_query.successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider.id, tag)
310
+
311
+ log_debug_for_wip do
312
+ log_pact_publications("Ignoring pacts explicitly specified in the selectors", specified_explicitly)
313
+ log_pact_publications("Ignoring pacts successfully verified by this provider tag when not WIP", verified_by_this_tag)
314
+ log_pact_publications("Ignoring pacts successfully verified by another provider tag when not WIP", verified_by_another_tag)
315
+ end
316
+
317
+ PactPublication.subtract(pact_publications_query.all, specified_explicitly.all, verified_by_this_tag.all, verified_by_another_tag.all)
318
+ end
319
+
320
+ def collect_consumer_name_and_version_number(pact_publications_query)
321
+ pact_publications_query.eager(:provider).eager(:consumer).eager(:consumer_version).order(:consumer_version_order).all.sort.collect do |p|
322
+ tag_suffix = p.values[:tag_name] ? " (tag #{p.values[:tag_name]})" : ""
323
+ "#{p.consumer_name} #{p.consumer_version_number}" + tag_suffix
324
+ end
283
325
  end
284
326
 
285
- def scope_for(scope)
286
- PactBroker.policy_scope!(scope)
327
+ def log_pact_publications(message, pact_publications_query)
328
+ pact_publication_descriptions = collect_consumer_name_and_version_number(pact_publications_query)
329
+ if pact_publication_descriptions.any?
330
+ logger.debug("#{message}", payload: pact_publication_descriptions)
331
+ else
332
+ logger.debug("#{message} (none)")
333
+ end
334
+ end
335
+
336
+ def log_debug_for_wip
337
+ if logger.debug?
338
+ log_with_tag(:wip) do
339
+ yield
340
+ end
341
+ end
287
342
  end
288
343
  end
289
344
  end
@@ -1,4 +1,5 @@
1
1
  require "pact_broker/json"
2
+ require "json"
2
3
 
3
4
  module PactBroker
4
5
  module Pacts
@@ -20,6 +20,7 @@ require "pact_broker/pacts/selector"
20
20
  require "pact_broker/pacts/selectors"
21
21
  require "pact_broker/feature_toggle"
22
22
  require "pact_broker/pacts/pacts_for_verification_repository"
23
+ require "pact_broker/pacts/content"
23
24
 
24
25
  module PactBroker
25
26
  module Pacts
@@ -51,7 +52,8 @@ module PactBroker
51
52
  provider_id: params[:provider_id],
52
53
  consumer_id: params[:consumer_id],
53
54
  pact_version: pact_version,
54
- revision_number: 1
55
+ revision_number: 1,
56
+ consumer_version_order: params.fetch(:version).order,
55
57
  ).upsert
56
58
  update_latest_pact_publication_ids(pact_publication)
57
59
  pact_publication.to_domain
@@ -71,6 +73,7 @@ module PactBroker
71
73
  provider_id: existing_model.provider_id,
72
74
  revision_number: next_revision_number(existing_model),
73
75
  consumer_id: existing_model.consumer_id,
76
+ consumer_version_order: existing_model.consumer_version_order,
74
77
  pact_version_id: pact_version.id,
75
78
  created_at: Sequel.datetime_class.now
76
79
  ).upsert
@@ -139,38 +142,36 @@ module PactBroker
139
142
  scope_for(PactVersion).where(consumer: consumer, provider: provider).delete
140
143
  end
141
144
 
142
- def find_latest_pact_versions_for_provider provider_name, tag = nil
145
+ def find_latest_pacts_for_provider provider_name, tag = nil
146
+ query = scope_for(PactPublication)
147
+ .for_provider_name(provider_name)
148
+ .eager(:consumer)
149
+
143
150
  if tag
144
- scope_for(LatestTaggedPactPublications).provider(provider_name).order_ignore_case(:consumer_name).where(tag_name: tag).collect(&:to_domain)
151
+ query = query.latest_for_consumer_tag(tag)
145
152
  else
146
- scope_for(LatestPactPublications).provider(provider_name).order_ignore_case(:consumer_name).collect(&:to_domain)
153
+ query = query.overall_latest
147
154
  end
155
+
156
+ query.sort_by{ | p| p.consumer_name.downcase }.collect(&:to_head_pact)
148
157
  end
149
158
 
150
159
  def find_for_verification(provider_name, consumer_version_selectors)
151
160
  PactsForVerificationRepository.new.find(provider_name, consumer_version_selectors)
152
161
  end
153
162
 
154
- def find_wip_pact_versions_for_provider provider_name, provider_version_branch, provider_tags_names = [], options = {}
155
- PactsForVerificationRepository.new.find_wip(provider_name, provider_version_branch, provider_tags_names, options)
163
+ def find_wip_pact_versions_for_provider provider_name, provider_version_branch, provider_tags_names, specified_pact_version_shas, options = {}
164
+ PactsForVerificationRepository.new.find_wip(provider_name, provider_version_branch, provider_tags_names, specified_pact_version_shas, options)
156
165
  end
157
166
 
158
167
  def find_pact_versions_for_provider provider_name, tag = nil
159
- if tag
160
- scope_for(LatestPactPublicationsByConsumerVersion)
161
- .join(:tags, {version_id: :consumer_version_id})
162
- .provider(provider_name)
163
- .order_ignore_case(:consumer_name)
164
- .order_append(:consumer_version_order)
165
- .where(Sequel[:tags][:name] => tag)
166
- .collect(&:to_domain)
167
- else
168
- scope_for(LatestPactPublicationsByConsumerVersion)
169
- .provider(provider_name)
170
- .order_ignore_case(:consumer_name)
171
- .order_append(:consumer_version_order)
172
- .collect(&:to_domain)
173
- end
168
+ query = scope_for(PactPublication)
169
+ .select_all_qualified
170
+ .for_provider_name(provider_name)
171
+ .eager(:consumer)
172
+ .eager(:provider)
173
+ query = query.for_consumer_version_tag(tag) if tag
174
+ query.collect(&:to_domain).sort
174
175
  end
175
176
 
176
177
  # Returns latest pact version for the consumer_version_number
@@ -189,7 +190,12 @@ module PactBroker
189
190
  end
190
191
 
191
192
  def find_latest_pacts
192
- scope_for(LatestPactPublications).order(:consumer_name, :provider_name).collect(&:to_domain)
193
+ scope_for(PactPublication)
194
+ .overall_latest
195
+ .eager(:consumer)
196
+ .eager(:provider)
197
+ .collect(&:to_domain)
198
+ .sort
193
199
  end
194
200
 
195
201
  def find_latest_pact(consumer_name, provider_name, tag = nil)
@@ -220,29 +226,31 @@ module PactBroker
220
226
  end
221
227
 
222
228
  # rubocop: disable Metrics/CyclomaticComplexity, Metrics/MethodLength
223
- def find_pact consumer_name, consumer_version, provider_name, pact_version_sha = nil
224
- pact_publication_by_consumer_version = scope_for(LatestPactPublicationsByConsumerVersion)
225
- .consumer(consumer_name)
226
- .provider(provider_name)
227
- .maybe_consumer_version_number(consumer_version)
229
+ def find_pact consumer_name, consumer_version_number, provider_name, pact_version_sha = nil
230
+ pact_publication_by_consumer_version = scope_for(PactPublication)
231
+ .select_all_qualified
232
+ .for_consumer_name_and_maybe_version_number(consumer_name, consumer_version_number)
233
+ .for_provider_name(provider_name)
234
+ .remove_overridden_revisions
228
235
  .limit(1)
229
236
 
230
- latest_pact_publication_by_sha = scope_for(AllPactPublications)
231
- .consumer(consumer_name)
232
- .provider(provider_name)
233
- .pact_version_sha(pact_version_sha)
237
+ latest_pact_publication_by_sha = scope_for(PactPublication)
238
+ .select_all_qualified
239
+ .for_consumer_name(consumer_name)
240
+ .for_provider_name(provider_name)
241
+ .for_pact_version_sha(pact_version_sha)
234
242
  .reverse_order(:consumer_version_order, :revision_number)
235
243
  .limit(1)
236
244
 
237
- if consumer_version && !pact_version_sha
245
+ if consumer_version_number && !pact_version_sha
238
246
  pact_publication_by_consumer_version
239
247
  .eager(:tags)
240
248
  .collect(&:to_domain_with_content).first
241
- elsif pact_version_sha && !consumer_version
249
+ elsif pact_version_sha && !consumer_version_number
242
250
  latest_pact_publication_by_sha
243
251
  .eager(:tags)
244
252
  .collect(&:to_domain_with_content).first
245
- elsif consumer_version && pact_version_sha
253
+ elsif consumer_version_number && pact_version_sha
246
254
  pact_publication = pact_publication_by_consumer_version.all.first
247
255
  if pact_publication && pact_publication.pact_version.sha == pact_version_sha
248
256
  pact_publication.tags
@@ -261,12 +269,12 @@ module PactBroker
261
269
  end
262
270
  # rubocop: enable Metrics/CyclomaticComplexity, Metrics/MethodLength
263
271
 
264
- def find_all_revisions consumer_name, consumer_version, provider_name
265
- scope_for(AllPactPublications)
266
- .consumer(consumer_name)
267
- .provider(provider_name)
268
- .consumer_version_number(consumer_version)
269
- .order(:consumer_version_order, :revision_number).collect(&:to_domain_with_content)
272
+ def find_all_revisions consumer_name, consumer_version_number, provider_name
273
+ scope_for(PactPublication)
274
+ .for_provider_name(provider_name)
275
+ .for_consumer_name_and_maybe_version_number(consumer_name, consumer_version_number)
276
+ .order_by_consumer_version_order
277
+ .collect(&:to_domain_with_content)
270
278
  end
271
279
 
272
280
  def find_previous_pact pact, tag = nil
@@ -348,7 +356,9 @@ module PactBroker
348
356
  provider_id: provider_id,
349
357
  sha: sha,
350
358
  content: json_content,
351
- created_at: Sequel.datetime_class.now
359
+ created_at: Sequel.datetime_class.now,
360
+ interactions_count: Content.from_json(json_content).interactions&.count || 0,
361
+ messages_count: Content.from_json(json_content).messages&.count || 0
352
362
  ).upsert
353
363
  end
354
364