pact_broker 2.82.0 → 2.85.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +53 -0
  4. data/Dockerfile +1 -1
  5. data/db/migrations/20210815_add_provider_version_id_index_to_verifications.rb +7 -0
  6. data/db/migrations/20210816_create_branches_tables.rb +40 -0
  7. data/db/migrations/20210818_add_consumer_version_selectors_to_verification.rb +8 -0
  8. data/db/migrations/20210831_add_index_to_pact_publications.rb +7 -0
  9. data/db/migrations/20210908_add_auto_created.rb +24 -0
  10. data/db/migrations/20210913_add_pending_to_verifications.rb +7 -0
  11. data/issue-reproduction/Dockerfile-pact-broker +1 -1
  12. data/lib/pact/doc/markdown/consumer_contract_renderer.rb +3 -3
  13. data/lib/pact_broker/api/contracts/{verifiable_pacts_json_query_schema.rb → pacts_for_verification_json_query_schema.rb} +1 -1
  14. data/lib/pact_broker/api/contracts/{verifiable_pacts_query_schema.rb → pacts_for_verification_query_string_schema.rb} +1 -1
  15. data/lib/pact_broker/api/decorators/branch_version_decorator.rb +20 -0
  16. data/lib/pact_broker/api/decorators/dashboard_decorator.rb +4 -2
  17. data/lib/pact_broker/api/decorators/embedded_branch_version_decorator.rb +21 -0
  18. data/lib/pact_broker/api/decorators/embedded_tag_decorator.rb +0 -5
  19. data/lib/pact_broker/api/decorators/matrix_decorator.rb +11 -2
  20. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +8 -0
  21. data/lib/pact_broker/api/decorators/{verifiable_pacts_query_decorator.rb → pacts_for_verification_query_decorator.rb} +2 -2
  22. data/lib/pact_broker/api/decorators/reason_decorator.rb +2 -2
  23. data/lib/pact_broker/api/decorators/verification_summary_decorator.rb +1 -2
  24. data/lib/pact_broker/api/decorators/version_decorator.rb +1 -1
  25. data/lib/pact_broker/api/middleware/configuration.rb +33 -0
  26. data/lib/pact_broker/api/pact_broker_urls.rb +13 -1
  27. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +15 -11
  28. data/lib/pact_broker/api/resources/branch_version.rb +48 -0
  29. data/lib/pact_broker/api/resources/index.rb +6 -0
  30. data/lib/pact_broker/api/resources/pact_versions_for_branch.rb +40 -0
  31. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +6 -6
  32. data/lib/pact_broker/api/resources/verifications.rb +7 -2
  33. data/lib/pact_broker/api/resources/version.rb +0 -8
  34. data/lib/pact_broker/api.rb +2 -0
  35. data/lib/pact_broker/app.rb +2 -0
  36. data/lib/pact_broker/badges/service.rb +3 -1
  37. data/lib/pact_broker/config/runtime_configuration.rb +12 -0
  38. data/lib/pact_broker/configuration.rb +33 -29
  39. data/lib/pact_broker/contracts/service.rb +1 -1
  40. data/lib/pact_broker/db/clean/selector.rb +54 -0
  41. data/lib/pact_broker/db/clean.rb +7 -1
  42. data/lib/pact_broker/db/clean_incremental.rb +13 -5
  43. data/lib/pact_broker/db/data_migrations/create_branches.rb +97 -0
  44. data/lib/pact_broker/db/data_migrations/set_pacticipant_main_branch.rb +2 -0
  45. data/lib/pact_broker/db/migrate_data.rb +1 -1
  46. data/lib/pact_broker/db/models.rb +6 -0
  47. data/lib/pact_broker/deployments/deployed_version.rb +4 -0
  48. data/lib/pact_broker/deployments/deployed_version_service.rb +4 -3
  49. data/lib/pact_broker/deployments/environment.rb +4 -0
  50. data/lib/pact_broker/deployments/environment_service.rb +13 -8
  51. data/lib/pact_broker/diagnostic/resources/base_resource.rb +4 -0
  52. data/lib/pact_broker/diagnostic/resources/dependencies.rb +1 -1
  53. data/lib/pact_broker/diagnostic/resources/heartbeat.rb +2 -3
  54. data/lib/pact_broker/doc/views/index/pacticipant-branch-version.markdown +14 -0
  55. data/lib/pact_broker/doc/views/webhooks.markdown +1 -0
  56. data/lib/pact_broker/domain/index_item.rb +15 -17
  57. data/lib/pact_broker/domain/pacticipant.rb +11 -0
  58. data/lib/pact_broker/domain/tag.rb +1 -2
  59. data/lib/pact_broker/domain/verification.rb +29 -14
  60. data/lib/pact_broker/domain/version.rb +112 -29
  61. data/lib/pact_broker/domain/webhook.rb +22 -10
  62. data/lib/pact_broker/domain/webhook_request.rb +2 -2
  63. data/lib/pact_broker/index/service.rb +83 -28
  64. data/lib/pact_broker/locale/en.yml +4 -0
  65. data/lib/pact_broker/matrix/quick_row.rb +6 -6
  66. data/lib/pact_broker/matrix/service.rb +4 -0
  67. data/lib/pact_broker/matrix/unresolved_selector.rb +3 -2
  68. data/lib/pact_broker/metrics/service.rb +7 -1
  69. data/lib/pact_broker/pacts/metadata.rb +7 -2
  70. data/lib/pact_broker/pacts/pact_publication.rb +59 -25
  71. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +113 -33
  72. data/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +18 -13
  73. data/lib/pact_broker/pacts/pact_publication_wip_dataset_module.rb +16 -4
  74. data/lib/pact_broker/pacts/pact_version.rb +13 -1
  75. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +4 -10
  76. data/lib/pact_broker/pacts/repository.rb +6 -1
  77. data/lib/pact_broker/pacts/selected_pact.rb +20 -0
  78. data/lib/pact_broker/pacts/selector.rb +98 -33
  79. data/lib/pact_broker/pacts/service.rb +21 -0
  80. data/lib/pact_broker/repositories.rb +5 -0
  81. data/lib/pact_broker/services.rb +9 -0
  82. data/lib/pact_broker/test/http_test_data_builder.rb +35 -9
  83. data/lib/pact_broker/test/test_data_builder.rb +32 -26
  84. data/lib/pact_broker/ui/app.rb +7 -1
  85. data/lib/pact_broker/ui/controllers/dashboard.rb +80 -0
  86. data/lib/pact_broker/ui/controllers/groups.rb +23 -8
  87. data/lib/pact_broker/ui/helpers/url_helper.rb +5 -1
  88. data/lib/pact_broker/ui/view_models/index_item.rb +56 -3
  89. data/lib/pact_broker/ui/view_models/matrix_branch.rb +39 -0
  90. data/lib/pact_broker/ui/view_models/matrix_line.rb +11 -16
  91. data/lib/pact_broker/ui/view_models/matrix_tag.rb +0 -1
  92. data/lib/pact_broker/ui/views/dashboard/show.haml +195 -0
  93. data/lib/pact_broker/ui/views/groups/show.html.erb +60 -14
  94. data/lib/pact_broker/ui/views/index/_dashboard_navbar.haml +7 -0
  95. data/lib/pact_broker/ui/views/index/_navbar.haml +0 -7
  96. data/lib/pact_broker/ui/views/index/show-with-tags.haml +14 -11
  97. data/lib/pact_broker/ui/views/index/show.haml +35 -13
  98. data/lib/pact_broker/ui/views/matrix/show.haml +15 -11
  99. data/lib/pact_broker/verifications/pseudo_branch_status.rb +2 -0
  100. data/lib/pact_broker/verifications/repository.rb +6 -11
  101. data/lib/pact_broker/verifications/service.rb +11 -5
  102. data/lib/pact_broker/version.rb +1 -1
  103. data/lib/pact_broker/versions/branch.rb +29 -0
  104. data/lib/pact_broker/versions/branch_head.rb +45 -0
  105. data/lib/pact_broker/versions/branch_service.rb +24 -0
  106. data/lib/pact_broker/versions/branch_version.rb +64 -0
  107. data/lib/pact_broker/versions/branch_version_repository.rb +34 -0
  108. data/lib/pact_broker/versions/eager_loaders.rb +0 -42
  109. data/lib/pact_broker/versions/repository.rb +25 -12
  110. data/lib/pact_broker/versions/service.rb +3 -22
  111. data/lib/pact_broker/webhooks/event_listener.rb +3 -3
  112. data/lib/pact_broker/webhooks/execution_configuration.rb +16 -0
  113. data/lib/pact_broker/webhooks/execution_configuration_creator.rb +3 -0
  114. data/lib/pact_broker/webhooks/job.rb +1 -1
  115. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +20 -3
  116. data/lib/pact_broker/webhooks/trigger_service.rb +2 -2
  117. data/lib/pact_broker/webhooks/webhook_execution_result.rb +3 -7
  118. data/lib/pact_broker/webhooks/webhook_request_logger.rb +4 -12
  119. data/lib/pact_broker/webhooks/webhook_request_template.rb +6 -8
  120. data/lib/sequel/plugins/insert_ignore.rb +4 -0
  121. data/lib/sequel/plugins/upsert.rb +4 -0
  122. data/pact_broker.gemspec +4 -0
  123. data/public/javascripts/index.js +152 -50
  124. data/public/javascripts/pact.js +14 -14
  125. data/public/stylesheets/index.css +1 -2
  126. data/public/stylesheets/pact.css +11 -0
  127. data/scaffolding/templates/decorator.rb.erb +3 -1
  128. data/scaffolding/templates/migration.erb +1 -1
  129. data/scaffolding/templates/model.erb +2 -2
  130. data/scaffolding/templates/repository.rb.erb +2 -2
  131. data/scaffolding/templates/repository_spec.rb.erb +1 -1
  132. data/scaffolding/templates/resource.erb +2 -2
  133. data/scaffolding/templates/resource_spec.rb.erb +1 -1
  134. data/scaffolding/templates/service.rb.erb +3 -3
  135. data/scaffolding/templates/service_spec.rb.erb +1 -1
  136. data/script/data/auto-create-things-for-tags.rb +2 -0
  137. data/script/data/branches.rb +35 -0
  138. data/script/data/contract-published-requiring-verification.rb +1 -1
  139. data/script/data/environments.rb +0 -0
  140. data/script/data/issue-494.rb +25 -0
  141. data/script/data/pending.rb +26 -0
  142. data/script/data/tags.rb +35 -0
  143. data/script/data/webhook.rb +22 -0
  144. data/script/seed.rb +50 -89
  145. data/spec/features/create_branch_version_spec.rb +29 -0
  146. data/spec/features/create_tag_spec.rb +1 -1
  147. data/spec/features/create_version_spec.rb +2 -4
  148. data/spec/features/delete_pact_versions_for_branch_spec.rb +34 -0
  149. data/spec/features/get_branch_version_spec.rb +12 -0
  150. data/spec/features/publish_pact_all_in_one_spec.rb +0 -1
  151. data/spec/features/update_version_spec.rb +0 -55
  152. data/spec/fixtures/approvals/modifiable_resources.approved.json +7 -0
  153. data/spec/fixtures/approvals/publish_contract_nothing_exists.approved.json +1 -2
  154. data/spec/fixtures/approvals/publish_contract_nothing_exists_with_webhook.approved.json +1 -2
  155. data/spec/fixtures/approvals/publish_contract_verification_already_exists.approved.json +1 -2
  156. data/spec/fixtures/dashboard.json +4 -2
  157. data/spec/integration/app_spec.rb +6 -6
  158. data/spec/integration/ui/index_spec.rb +0 -2
  159. data/spec/integration/ui/matrix_spec.rb +0 -1
  160. data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +2 -2
  161. data/spec/lib/pact_broker/api/contracts/{verifiable_pacts_json_query_schema_combinations_spec.rb → pacts_for_verification_json_query_schema_combinations_spec.rb} +6 -6
  162. data/spec/lib/pact_broker/api/contracts/{verifiable_pacts_json_query_schema_spec.rb → pacts_for_verification_json_query_schema_spec.rb} +3 -3
  163. data/spec/lib/pact_broker/api/contracts/{verifiable_pacts_query_schema_spec.rb → pacts_for_verification_query_string_schema_spec.rb} +3 -3
  164. data/spec/lib/pact_broker/api/decorators/dashboard_decorator_spec.rb +7 -7
  165. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +19 -4
  166. data/spec/lib/pact_broker/api/decorators/{verifiable_pacts_query_decorator_spec.rb → pacts_for_verification_query_decorator_spec.rb} +3 -3
  167. data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +2 -2
  168. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +2 -0
  169. data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +7 -3
  170. data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +1 -1
  171. data/spec/lib/pact_broker/api/middleware/configuration_spec.rb +43 -0
  172. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +6 -4
  173. data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +1 -1
  174. data/spec/lib/pact_broker/badges/service_spec.rb +22 -0
  175. data/spec/lib/pact_broker/contracts/service_spec.rb +24 -3
  176. data/spec/lib/pact_broker/db/clean_spec.rb +2 -2
  177. data/spec/lib/pact_broker/db/data_migrations/create_branches_spec.rb +57 -0
  178. data/spec/lib/pact_broker/diagnostic/resources/dependencies_spec.rb +4 -4
  179. data/spec/lib/pact_broker/diagnostic/resources/heartbeat_spec.rb +3 -4
  180. data/spec/lib/pact_broker/domain/index_item_spec.rb +1 -1
  181. data/spec/lib/pact_broker/domain/version_spec.rb +127 -36
  182. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +2 -1
  183. data/spec/lib/pact_broker/domain/webhook_spec.rb +15 -5
  184. data/spec/lib/pact_broker/index/service_spec.rb +1 -5
  185. data/spec/lib/pact_broker/index/service_view_spec.rb +144 -0
  186. data/spec/lib/pact_broker/matrix/service_spec.rb +10 -1
  187. data/spec/lib/pact_broker/metrics/service_spec.rb +4 -1
  188. data/spec/lib/pact_broker/pacts/metadata_spec.rb +11 -3
  189. data/spec/lib/pact_broker/pacts/pact_publication_dataset_module_spec.rb +109 -10
  190. data/spec/lib/pact_broker/pacts/pact_publication_latest_verification_spec.rb +29 -0
  191. data/spec/lib/pact_broker/pacts/pact_publication_selector_dataset_module_spec.rb +3 -2
  192. data/spec/lib/pact_broker/pacts/pact_publication_spec.rb +5 -5
  193. data/spec/lib/pact_broker/pacts/repository_find_for_currently_deployed_spec.rb +2 -2
  194. data/spec/lib/pact_broker/pacts/repository_find_for_currently_supported_releases_spec.rb +2 -2
  195. data/spec/lib/pact_broker/pacts/repository_spec.rb +15 -2
  196. data/spec/lib/pact_broker/pacts/selector_spec.rb +45 -3
  197. data/spec/lib/pact_broker/pacts/service_spec.rb +61 -0
  198. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +5 -5
  199. data/spec/lib/pact_broker/relationships/groupify_spec.rb +0 -5
  200. data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +21 -6
  201. data/spec/lib/pact_broker/verifications/pseudo_branch_status_spec.rb +9 -1
  202. data/spec/lib/pact_broker/verifications/repository_spec.rb +39 -30
  203. data/spec/lib/pact_broker/verifications/service_spec.rb +9 -5
  204. data/spec/lib/pact_broker/versions/branch_service_spec.rb +71 -0
  205. data/spec/lib/pact_broker/versions/branch_version_repository_spec.rb +81 -0
  206. data/spec/lib/pact_broker/versions/branch_version_spec.rb +27 -0
  207. data/spec/lib/pact_broker/versions/repository_spec.rb +91 -6
  208. data/spec/lib/pact_broker/versions/service_spec.rb +4 -3
  209. data/spec/lib/pact_broker/webhooks/job_spec.rb +4 -4
  210. data/spec/lib/pact_broker/webhooks/render_spec.rb +6 -0
  211. data/spec/lib/pact_broker/webhooks/trigger_service_spec.rb +9 -5
  212. data/spec/lib/pact_broker/webhooks/webhook_request_logger_spec.rb +6 -12
  213. data/spec/lib/pact_broker/webhooks/webhook_request_template_spec.rb +3 -2
  214. data/spec/lib/sequel/plugins/upsert_spec.rb +11 -5
  215. data/spec/migrations/44_add_provider_version_to_verification_spec.rb +6 -9
  216. data/spec/service_consumers/pact_helper.rb +2 -0
  217. data/spec/spec_helper.rb +1 -1
  218. data/spec/support/generated_markdown.md +3 -3
  219. metadata +90 -17
  220. data/lib/pact_broker/versions/lazy_loaders.rb +0 -13
  221. data/spec/lib/pact_broker/api/resources/webhook_execution_result_spec.rb +0 -56
@@ -5,23 +5,25 @@ module PactBroker
5
5
  module Domain
6
6
  class IndexItem
7
7
  attr_reader :consumer,
8
- :provider,
9
- :latest_pact,
10
- :latest_verification,
11
- :webhooks,
12
- :triggered_webhooks,
13
- :latest_verification_latest_tags
8
+ :provider,
9
+ :consumer_version,
10
+ :latest_pact,
11
+ :latest_verification,
12
+ :webhooks,
13
+ :triggered_webhooks,
14
+ :latest_verification_latest_tags,
14
15
 
15
16
  # rubocop:disable Metrics/ParameterLists
16
- def self.create(consumer, provider, latest_pact, latest, latest_verification, webhooks = [], triggered_webhooks = [], tags = [], latest_verification_latest_tags = [], latest_for_branch = nil)
17
- new(consumer, provider, latest_pact, latest, latest_verification, webhooks, triggered_webhooks, tags, latest_verification_latest_tags, latest_for_branch)
17
+ def self.create(consumer, provider, consumer_version, latest_pact, latest, latest_verification, webhooks = [], triggered_webhooks = [], tags = [], latest_verification_latest_tags = [], latest_for_branch = nil)
18
+ new(consumer, provider, consumer_version, latest_pact, latest, latest_verification, webhooks, triggered_webhooks, tags, latest_verification_latest_tags, latest_for_branch)
18
19
  end
19
20
  # rubocop:enable Metrics/ParameterLists
20
21
 
21
22
  # rubocop:disable Metrics/ParameterLists
22
- def initialize(consumer, provider, latest_pact = nil, latest = true, latest_verification = nil, webhooks = [], triggered_webhooks = [], tags = [], latest_verification_latest_tags = [], latest_for_branch = nil)
23
+ def initialize(consumer, provider, consumer_version = nil, latest_pact = nil, latest = true, latest_verification = nil, webhooks = [], triggered_webhooks = [], tags = [], latest_verification_latest_tags = [], latest_for_branch = nil)
23
24
  @consumer = consumer
24
25
  @provider = provider
26
+ @consumer_version = consumer_version
25
27
  @latest_pact = latest_pact
26
28
  @latest = latest
27
29
  @latest_verification = latest_verification
@@ -68,12 +70,8 @@ module PactBroker
68
70
  consumer_version.order
69
71
  end
70
72
 
71
- def consumer_version
72
- @latest_pact.consumer_version
73
- end
74
-
75
- def consumer_version_branch
76
- consumer_version.branch
73
+ def consumer_version_branches
74
+ consumer_version.branch_heads.collect(&:branch_name)
77
75
  end
78
76
 
79
77
  def consumer_version_environment_names
@@ -92,8 +90,8 @@ module PactBroker
92
90
  @latest_verification ? @latest_verification.provider_version_number : nil
93
91
  end
94
92
 
95
- def provider_version_branch
96
- provider_version&.branch
93
+ def provider_version_branches
94
+ provider_version&.branch_heads&.collect(&:branch_name) || []
97
95
  end
98
96
 
99
97
  def provider_version_environment_names
@@ -22,6 +22,8 @@ module PactBroker
22
22
  one_to_many :labels, :order => :name, :reciprocal => :pacticipant
23
23
  one_to_many :pacts
24
24
  one_to_one :latest_version, :class => "PactBroker::Versions::LatestVersion", primary_key: :id, key: :pacticipant_id
25
+ one_to_many :branch_heads, class: "PactBroker::Versions::BranchHead", primary_key: :id, key: :pacticipant_id
26
+ one_to_many :branches, class: "PactBroker::Versions::Branch", primary_key: :id, key: :pacticipant_id
25
27
 
26
28
  dataset_module do
27
29
  include PactBroker::Repositories::Helpers
@@ -38,6 +40,10 @@ module PactBroker
38
40
  def find_by_name(name)
39
41
  where(name_like(:name, name))
40
42
  end
43
+
44
+ def where_name(name)
45
+ where(name_like(:name, name))
46
+ end
41
47
  end
42
48
 
43
49
  def before_destroy
@@ -66,6 +72,10 @@ module PactBroker
66
72
  def any_versions?
67
73
  PactBroker::Domain::Version.where(pacticipant: self).any?
68
74
  end
75
+
76
+ def branch_head_for(branch_name)
77
+ branch_heads.find{ | branch_head | branch_head.branch_name == branch_name }
78
+ end
69
79
  end
70
80
  end
71
81
  end
@@ -87,6 +97,7 @@ end
87
97
  # pacticipants_name_key | UNIQUE btree (name)
88
98
  # ndx_ppt_name | btree (name)
89
99
  # Referenced By:
100
+ # branches | branches_pacticipant_id_fkey | (pacticipant_id) REFERENCES pacticipants(id) ON DELETE CASCADE
90
101
  # currently_deployed_version_ids | currently_deployed_version_ids_pacticipant_id_fkey | (pacticipant_id) REFERENCES pacticipants(id) ON DELETE CASCADE
91
102
  # labels | labels_pacticipant_id_fkey | (pacticipant_id) REFERENCES pacticipants(id)
92
103
  # latest_pact_publication_ids_for_consumer_versions | latest_pact_publication_ids_for_consumer_versi_consumer_id_fkey | (consumer_id) REFERENCES pacticipants(id) ON DELETE CASCADE
@@ -130,6 +130,7 @@ module PactBroker
130
130
 
131
131
  # rubocop: disable Metrics/CyclomaticComplexity
132
132
  def before_save
133
+ super
133
134
  if version
134
135
  if version.order && self.version_order.nil?
135
136
  self.version_order = version.order
@@ -146,8 +147,6 @@ module PactBroker
146
147
 
147
148
  if version_order.nil? || pacticipant_id.nil?
148
149
  raise PactBroker::Error.new("Need to set version_order and pacticipant_id for tags now")
149
- else
150
- super
151
150
  end
152
151
  end
153
152
  # rubocop: enable Metrics/CyclomaticComplexity
@@ -9,6 +9,8 @@ module PactBroker
9
9
  module Domain
10
10
  class Verification < Sequel::Model
11
11
  using Sequel::SymbolAref
12
+ TO_JSON = lambda { | thing | Sequel.object_to_json(thing) }
13
+ FROM_JSON_WITH_SYMBOL_KEYS = lambda { | json | JSON.parse(json, symbolize_names: true) }
12
14
 
13
15
  set_primary_key :id
14
16
  associate(:many_to_one, :pact_version, class: "PactBroker::Pacts::PactVersion", key: :pact_version_id, primary_key: :id)
@@ -16,7 +18,8 @@ module PactBroker
16
18
  associate(:many_to_one, :provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
17
19
  associate(:many_to_one, :consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
18
20
  associate(:one_to_many, :provider_version_tags, :class => "PactBroker::Domain::Tag", primary_key: :provider_version_id, key: :version_id)
19
- plugin :serialization, :json, :test_results
21
+ plugin :serialization, :json, :test_results, :tag_names
22
+ serialize_attributes [TO_JSON, FROM_JSON_WITH_SYMBOL_KEYS], :consumer_version_selector_hashes
20
23
 
21
24
  def before_create
22
25
  super
@@ -203,6 +206,15 @@ module PactBroker
203
206
  @pact_content_with_test_results = PactBroker::Pacts::Content.from_json(pact_version.content).with_test_results(test_results)
204
207
  end
205
208
 
209
+ # Whether the pact content was pending at the time the verification was run
210
+ def pact_pending?
211
+ pact_pending
212
+ end
213
+
214
+ def failed_and_pact_pending?
215
+ !success && pact_pending
216
+ end
217
+
206
218
  # So consumer_version_tag_name can be accessed by method name
207
219
  def method_missing(m, *args, &block)
208
220
  if values.key?(m) && args.size == 0
@@ -219,23 +231,26 @@ end
219
231
 
220
232
  # Table: verifications
221
233
  # Columns:
222
- # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
223
- # number | integer |
224
- # success | boolean | NOT NULL
225
- # provider_version | text |
226
- # build_url | text |
227
- # pact_version_id | integer | NOT NULL
228
- # execution_date | timestamp without time zone | NOT NULL
229
- # created_at | timestamp without time zone | NOT NULL
230
- # provider_version_id | integer |
231
- # test_results | text |
232
- # consumer_id | integer |
233
- # provider_id | integer |
234
- # wip | boolean | NOT NULL DEFAULT false
234
+ # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
235
+ # number | integer |
236
+ # success | boolean | NOT NULL
237
+ # provider_version | text |
238
+ # build_url | text |
239
+ # pact_version_id | integer | NOT NULL
240
+ # execution_date | timestamp without time zone | NOT NULL
241
+ # created_at | timestamp without time zone | NOT NULL
242
+ # provider_version_id | integer |
243
+ # test_results | text |
244
+ # consumer_id | integer |
245
+ # provider_id | integer |
246
+ # wip | boolean | NOT NULL DEFAULT false
247
+ # consumer_version_selector_hashes | text |
248
+ # tag_names | text |
235
249
  # Indexes:
236
250
  # verifications_pkey | PRIMARY KEY btree (id)
237
251
  # verifications_pact_version_id_number_index | UNIQUE btree (pact_version_id, number)
238
252
  # verifications_consumer_id_index | btree (consumer_id)
253
+ # verifications_pact_version_id_id_index | btree (pact_version_id, id)
239
254
  # verifications_provider_id_consumer_id_index | btree (provider_id, consumer_id)
240
255
  # verifications_provider_id_index | btree (provider_id)
241
256
  # Foreign key constraints:
@@ -3,7 +3,6 @@ require "pact_broker/domain/order_versions"
3
3
  require "pact_broker/repositories/helpers"
4
4
  require "pact_broker/tags/tag_with_latest_flag"
5
5
  require "pact_broker/versions/eager_loaders"
6
- require "pact_broker/versions/lazy_loaders"
7
6
 
8
7
  module PactBroker
9
8
  module Domain
@@ -22,7 +21,9 @@ module PactBroker
22
21
  end
23
22
  end
24
23
 
25
- class Version < Sequel::Model
24
+ VERSION_COLUMNS = [:id, :number, :repository_ref, :pacticipant_id, :order, :created_at, :updated_at, :build_url]
25
+
26
+ class Version < Sequel::Model(Sequel::Model.db[:versions].select(*VERSION_COLUMNS.collect{ | column | Sequel.qualify(:versions, column) }))
26
27
  plugin :timestamps, update_on_create: true
27
28
  plugin :upsert, { identifying_columns: [:pacticipant_id, :number], ignore_columns_on_update: [:id, :created_at, :order] }
28
29
 
@@ -30,6 +31,8 @@ module PactBroker
30
31
  one_to_many :pact_publications, order: :revision_number, class: "PactBroker::Pacts::PactPublication", key: :consumer_version_id
31
32
  associate(:many_to_one, :pacticipant, :class => "PactBroker::Domain::Pacticipant", :key => :pacticipant_id, :primary_key => :id)
32
33
  one_to_many :tags, :reciprocal => :version, order: :created_at
34
+ one_to_many :branch_versions, :reciprocal => :branch_version, class: "PactBroker::Versions::BranchVersion", order: [:created_at, :id]
35
+ one_to_many :branch_heads, reciprocal: :branch_head, class: "PactBroker::Versions::BranchHead", order: :branch_id
33
36
  one_to_many :current_deployed_versions, class: "PactBroker::Deployments::DeployedVersion", key: :version_id, primary_key: :id, order: [:created_at, :id] do | ds |
34
37
  ds.currently_deployed
35
38
  end
@@ -44,16 +47,15 @@ module PactBroker
44
47
  dataset: lambda { Version.latest_version_for_pacticipant(pacticipant) },
45
48
  eager_loader: PactBroker::Versions::EagerLoaders::LatestVersionForPacticipant
46
49
 
47
- many_to_one :latest_version_for_branch, read_only: true, key: :id,
48
- class: Version,
49
- dataset: PactBroker::Versions::LazyLoaders::LATEST_VERSION_FOR_BRANCH,
50
- eager_loader: PactBroker::Versions::EagerLoaders::LatestVersionForBranch
51
-
52
50
  dataset_module do
53
51
  include PactBroker::Repositories::Helpers
54
52
 
55
- def with_branch_set
56
- exclude(branch: nil)
53
+ def with_branch
54
+ where(id: PactBroker::Versions::BranchVersion.select(:version_id))
55
+ end
56
+
57
+ def with_user_created_branch
58
+ where(id: PactBroker::Versions::BranchVersion.select(:version_id).where(auto_created: false))
57
59
  end
58
60
 
59
61
  def latest_version_for_pacticipant(pacticipant)
@@ -71,20 +73,16 @@ module PactBroker
71
73
  end
72
74
 
73
75
  def first_for_pacticipant_id_and_branch(pacticipant_id, branch)
74
- where(pacticipant_id: pacticipant_id, branch: branch).order(:created_at).first
76
+ first_version_id = PactBroker::Versions::BranchVersion
77
+ .select(:version_id)
78
+ .where(pacticipant_id: pacticipant_id, branch_name: branch)
79
+ .order(:created_at)
80
+ .limit(1)
81
+ where(id: first_version_id).single_record
75
82
  end
76
83
 
77
- def latest_versions_for_pacticipant_branches(pacticipant_id, branches)
78
- query = Version.where(Sequel[:versions][:pacticipant_id] => pacticipant_id, Sequel[:versions][:branch] => branches)
79
-
80
- self_join = {
81
- Sequel[:versions][:pacticipant_id] => Sequel[:versions_2][:pacticipant_id],
82
- Sequel[:versions][:branch] => Sequel[:versions_2][:branch]
83
- }
84
- query.select_all_qualified.left_join(query, self_join, table_alias: :versions_2) do
85
- Sequel[:versions_2][:order] > Sequel[:versions][:order]
86
- end
87
- .where(Sequel[:versions_2][:order] => nil)
84
+ def latest_versions_for_pacticipant_branches(pacticipant_id, branch_names)
85
+ where(id: PactBroker::Versions::BranchHead.where(pacticipant_id: pacticipant_id, branch_name: branch_names).select(:version_id))
88
86
  end
89
87
 
90
88
  def where_pacticipant_name(pacticipant_name)
@@ -115,6 +113,16 @@ module PactBroker
115
113
  where(id: supported_version_query.select(:version_id))
116
114
  end
117
115
 
116
+ def currently_deployed
117
+ deployed_version_query = PactBroker::Deployments::DeployedVersion.currently_deployed
118
+ where(id: deployed_version_query.select(:version_id))
119
+ end
120
+
121
+ def currently_supported
122
+ supported_version_query = PactBroker::Deployments::ReleasedVersion.currently_supported
123
+ where(id: supported_version_query.select(:version_id))
124
+ end
125
+
118
126
  def where_tag(tag)
119
127
  if tag == true
120
128
  join(:tags, Sequel[:tags][:version_id] => Sequel[first_source_alias][:id])
@@ -128,8 +136,46 @@ module PactBroker
128
136
  end
129
137
  end
130
138
 
131
- def where_branch(branch)
132
- where(branch: branch)
139
+ def where_branch_name(branch_name)
140
+ if branch_name == true
141
+ where(id: PactBroker::Versions::BranchVersion.select(:version_id))
142
+ else
143
+ matching_branch_ids = PactBroker::Versions::Branch.select(:id).where(name: branch_name)
144
+ matching_branch_version_ids = PactBroker::Versions::BranchVersion
145
+ .select(:version_id)
146
+ .where(branch_id: matching_branch_ids)
147
+ where(id: matching_branch_version_ids)
148
+ end
149
+ end
150
+
151
+ def where_branch_head_name(branch_name)
152
+ if branch_name == true
153
+ where(id: PactBroker::Versions::BranchHead.select(:version_id))
154
+ else
155
+ where(id: PactBroker::Versions::BranchHead.select(:version_id).where(branch_name: branch_name))
156
+ end
157
+ end
158
+
159
+
160
+ def for_main_branches
161
+ matching_branch_version_ids = PactBroker::Versions::BranchVersion
162
+ .select(:version_id)
163
+ .join(:pacticipants, { Sequel[:branch_versions][:pacticipant_id] => Sequel[:pacticipants][:id] })
164
+ .join(:branches, { Sequel[:branches][:id] => Sequel[:branch_versions][:branch_id], Sequel[:branches][:name] => Sequel[:pacticipants][:main_branch] })
165
+
166
+ where(id: matching_branch_version_ids)
167
+ end
168
+
169
+ def latest_for_main_branches
170
+ pacticipants_join = {
171
+ Sequel[:branch_heads][:pacticipant_id] => Sequel[:pacticipants][:id],
172
+ Sequel[:branch_heads][:branch_name] => Sequel[:pacticipants][:main_branch]
173
+ }
174
+ matching_branch_version_ids = PactBroker::Versions::BranchHead
175
+ .select(:version_id)
176
+ .join(:pacticipants, pacticipants_join)
177
+
178
+ where(id: matching_branch_version_ids)
133
179
  end
134
180
 
135
181
  def where_number(number)
@@ -161,12 +207,33 @@ module PactBroker
161
207
  query = self
162
208
  query = query.where_pacticipant_name(selector.pacticipant_name) if selector.pacticipant_name
163
209
  query = query.currently_in_environment(selector.environment_name, selector.pacticipant_name) if selector.environment_name
210
+ query = query.currently_deployed if selector.respond_to?(:currently_deployed?) && selector.currently_deployed?
211
+ query = query.currently_supported if selector.respond_to?(:currently_supported?) && selector.currently_supported?
164
212
  query = query.where_tag(selector.tag) if selector.tag
165
- query = query.where_branch(selector.branch) if selector.branch
166
- query = query.where_number(selector.pacticipant_version_number) if selector.pacticipant_version_number
167
- query = query.where_age_less_than(selector.max_age) if selector.max_age
213
+ query = query.where_number(selector.pacticipant_version_number) if selector.respond_to?(:pacticipant_version_number) && selector.pacticipant_version_number
214
+ query = query.where_age_less_than(selector.max_age) if selector.respond_to?(:max_age) && selector.max_age
168
215
 
169
- if selector.latest
216
+ latest_applied = false
217
+
218
+ if selector.respond_to?(:main_branch) && selector.main_branch
219
+ if selector.latest
220
+ latest_applied = true
221
+ query = query.latest_for_main_branches
222
+ else
223
+ query = query.for_main_branches
224
+ end
225
+ end
226
+
227
+ if selector.branch
228
+ if selector.latest
229
+ latest_applied = true
230
+ query = query.where_branch_head_name(selector.branch)
231
+ else
232
+ query = query.where_branch_name(selector.branch)
233
+ end
234
+ end
235
+
236
+ if selector.latest && !latest_applied
170
237
  calculate_max_version_order_and_join_back_to_versions(query, selector)
171
238
  else
172
239
  query
@@ -226,12 +293,28 @@ module PactBroker
226
293
  end
227
294
 
228
295
  def latest_for_branch?
229
- branch ? latest_version_for_branch.order == order : nil
296
+ branch_heads.any?
230
297
  end
231
298
 
232
299
  def latest_for_pacticipant?
233
300
  latest_version_for_pacticipant == self
234
301
  end
302
+
303
+ def branch_version_for_branch(branch)
304
+ branch_versions.find { | branch_version | branch_version.branch_id == branch.id }
305
+ end
306
+
307
+ def branch_version_for_branch_name(branch_name)
308
+ branch_versions.find { | branch_version | branch_version.branch_name == branch_name }
309
+ end
310
+
311
+ def branch_names
312
+ branch_versions.collect(&:branch_name)
313
+ end
314
+
315
+ def tag_names
316
+ tags.collect(&:name)
317
+ end
235
318
  end
236
319
  end
237
320
  end
@@ -245,7 +328,6 @@ end
245
328
  # order | integer |
246
329
  # created_at | timestamp without time zone | NOT NULL
247
330
  # updated_at | timestamp without time zone | NOT NULL
248
- # branch | text |
249
331
  # build_url | text |
250
332
  # Indexes:
251
333
  # versions_pkey | PRIMARY KEY btree (id)
@@ -258,6 +340,7 @@ end
258
340
  # Foreign key constraints:
259
341
  # versions_pacticipant_id_fkey | (pacticipant_id) REFERENCES pacticipants(id)
260
342
  # Referenced By:
343
+ # branch_versions | branch_versions_versions_fk | (version_id) REFERENCES versions(id) ON DELETE CASCADE
261
344
  # currently_deployed_version_ids | currently_deployed_version_ids_version_id_fkey | (version_id) REFERENCES versions(id) ON DELETE CASCADE
262
345
  # deployed_versions | deployed_versions_version_id_fkey | (version_id) REFERENCES versions(id)
263
346
  # latest_pact_publication_ids_for_consumer_versions | latest_pact_publication_ids_for_consum_consumer_version_id_fkey | (consumer_version_id) REFERENCES versions(id) ON DELETE CASCADE
@@ -50,17 +50,12 @@ module PactBroker
50
50
  def execute pact, verification, event_context, options
51
51
  logger.info "Executing #{self} event_context=#{event_context}"
52
52
  template_params = template_parameters(pact, verification, event_context, options)
53
- webhook_request = request.build(template_params)
53
+ webhook_request = request.build(template_params, options.fetch(:user_agent))
54
54
  http_response, error = execute_request(webhook_request)
55
-
56
- logs = generate_logs(webhook_request, http_response, error, event_context, options.fetch(:logging_options))
55
+ success = success?(http_response, options)
57
56
  http_request = webhook_request.http_request
58
- PactBroker::Webhooks::WebhookExecutionResult.new(
59
- http_request,
60
- http_response,
61
- logs,
62
- error
63
- )
57
+ logs = generate_logs(webhook_request, http_response, success, error, event_context, options.fetch(:logging_options))
58
+ result(http_request, http_response, success, logs, error)
64
59
  end
65
60
 
66
61
  def to_s
@@ -116,16 +111,33 @@ module PactBroker
116
111
  PactBroker::Webhooks::PactAndVerificationParameters.new(pact, verification, event_context).to_hash
117
112
  end
118
113
 
119
- def generate_logs(webhook_request, http_response, error, event_context, logging_options)
114
+ def success?(http_response, options)
115
+ !http_response.nil? && options.fetch(:http_success_codes).include?(http_response.code.to_i)
116
+ end
117
+
118
+ # rubocop: disable Metrics/ParameterLists
119
+ def generate_logs(webhook_request, http_response, success, error, event_context, logging_options)
120
120
  webhook_request_logger = PactBroker::Webhooks::WebhookRequestLogger.new(logging_options)
121
121
  webhook_request_logger.log(
122
122
  uuid,
123
123
  webhook_request,
124
124
  http_response,
125
+ success,
125
126
  error,
126
127
  event_context
127
128
  )
128
129
  end
130
+ # robocop: enable Metrics/ParameterLists
131
+
132
+ def result(http_request, http_response, success, logs, error)
133
+ PactBroker::Webhooks::WebhookExecutionResult.new(
134
+ http_request,
135
+ http_response,
136
+ success,
137
+ logs,
138
+ error
139
+ )
140
+ end
129
141
  end
130
142
  end
131
143
  end