pact_broker 2.99.0 → 2.102.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -0
  3. data/Gemfile +1 -0
  4. data/README.md +14 -4
  5. data/db/migrations/20220622_default_allow_dangerous_contract_modification_to_false_for_new_installations.rb +22 -0
  6. data/db/migrations/20220625_delete_pacticipants_with_no_name.rb +62 -0
  7. data/db/migrations/migration_helper.rb +6 -0
  8. data/docs/CONFIGURATION.md +3 -1
  9. data/docs/api/PACTICIPANTS.md +290 -0
  10. data/docs/api/WEBHOOKS.md +40 -40
  11. data/lib/pact_broker/api/contracts/pacticipant_create_schema.rb +28 -0
  12. data/lib/pact_broker/api/decorators/embedded_version_decorator.rb +0 -1
  13. data/lib/pact_broker/api/decorators/reason_decorator.rb +1 -15
  14. data/lib/pact_broker/api/decorators/triggered_webhook_decorator.rb +1 -2
  15. data/lib/pact_broker/api/resources/all_webhooks.rb +1 -4
  16. data/lib/pact_broker/api/resources/base_resource.rb +58 -5
  17. data/lib/pact_broker/api/resources/branch_version.rb +10 -1
  18. data/lib/pact_broker/api/resources/clean.rb +11 -9
  19. data/lib/pact_broker/api/resources/currently_deployed_versions_for_environment.rb +0 -4
  20. data/lib/pact_broker/api/resources/currently_supported_versions_for_environment.rb +0 -4
  21. data/lib/pact_broker/api/resources/deployed_version.rb +20 -16
  22. data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +1 -1
  23. data/lib/pact_broker/api/resources/environment.rb +5 -5
  24. data/lib/pact_broker/api/resources/environments.rb +1 -5
  25. data/lib/pact_broker/api/resources/label.rb +4 -0
  26. data/lib/pact_broker/api/resources/matrix_for_consumer_and_provider.rb +10 -0
  27. data/lib/pact_broker/api/resources/pact.rb +14 -5
  28. data/lib/pact_broker/api/resources/pact_webhooks.rb +1 -4
  29. data/lib/pact_broker/api/resources/pacticipant.rb +11 -5
  30. data/lib/pact_broker/api/resources/pacticipant_resource_methods.rb +0 -1
  31. data/lib/pact_broker/api/resources/pacticipant_webhooks.rb +1 -4
  32. data/lib/pact_broker/api/resources/pacticipants.rb +7 -6
  33. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +19 -11
  34. data/lib/pact_broker/api/resources/publish_contracts.rb +12 -16
  35. data/lib/pact_broker/api/resources/released_version.rb +20 -8
  36. data/lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb +11 -7
  37. data/lib/pact_broker/api/resources/tag.rb +7 -3
  38. data/lib/pact_broker/api/resources/verifications.rb +7 -9
  39. data/lib/pact_broker/api/resources/version.rb +8 -8
  40. data/lib/pact_broker/api/resources/webhook.rb +5 -4
  41. data/lib/pact_broker/api/resources/webhook_execution.rb +4 -6
  42. data/lib/pact_broker/config/runtime_configuration.rb +1 -1
  43. data/lib/pact_broker/contracts/contract_to_publish.rb +4 -0
  44. data/lib/pact_broker/contracts/contracts_to_publish.rb +4 -0
  45. data/lib/pact_broker/contracts/service.rb +23 -5
  46. data/lib/pact_broker/doc/views/index/pacticipant-branch-version.markdown +13 -2
  47. data/lib/pact_broker/doc/views/provider-pacts-for-verification.markdown +1 -1
  48. data/lib/pact_broker/domain/pacticipant.rb +1 -0
  49. data/lib/pact_broker/domain/tag.rb +8 -32
  50. data/lib/pact_broker/domain/verification.rb +3 -2
  51. data/lib/pact_broker/domain/version.rb +26 -10
  52. data/lib/pact_broker/locale/en.yml +8 -4
  53. data/lib/pact_broker/matrix/deployment_status_summary.rb +28 -19
  54. data/lib/pact_broker/matrix/parse_query.rb +5 -0
  55. data/lib/pact_broker/matrix/quick_row.rb +5 -2
  56. data/lib/pact_broker/matrix/repository.rb +3 -3
  57. data/lib/pact_broker/matrix/resolved_selector.rb +47 -10
  58. data/lib/pact_broker/matrix/service.rb +17 -7
  59. data/lib/pact_broker/matrix/unresolved_selector.rb +14 -2
  60. data/lib/pact_broker/messages.rb +0 -15
  61. data/lib/pact_broker/pacticipants/find_potential_duplicate_pacticipant_names.rb +3 -3
  62. data/lib/pact_broker/pacticipants/repository.rb +5 -4
  63. data/lib/pact_broker/pacticipants/service.rb +11 -1
  64. data/lib/pact_broker/pacts/generate_sha.rb +1 -0
  65. data/lib/pact_broker/pacts/pact_version.rb +1 -0
  66. data/lib/pact_broker/pacts/verifiable_pact_messages.rb +4 -2
  67. data/lib/pact_broker/repositories/helpers.rb +13 -0
  68. data/lib/pact_broker/string_refinements.rb +8 -0
  69. data/lib/pact_broker/test/http_test_data_builder.rb +15 -0
  70. data/lib/pact_broker/test/test_data_builder.rb +20 -0
  71. data/lib/pact_broker/ui/controllers/index.rb +3 -1
  72. data/lib/pact_broker/ui/views/index/show.haml +3 -4
  73. data/lib/pact_broker/ui/views/matrix/show.haml +5 -2
  74. data/lib/pact_broker/verifications/pact_version_provider_tag_successful_verification.rb +15 -0
  75. data/lib/pact_broker/version.rb +1 -1
  76. data/lib/pact_broker/versions/branch_service.rb +7 -0
  77. data/lib/pact_broker/versions/branch_version_repository.rb +17 -0
  78. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +1 -1
  79. data/lib/rack/pact_broker/cascade.rb +87 -0
  80. data/lib/webmachine/describe_routes.rb +43 -9
  81. metadata +8 -5
  82. data/lib/db.rb +0 -79
  83. data/lib/pact_broker/api/resources/default_base_resource.rb +0 -0
@@ -39,53 +39,28 @@ module PactBroker
39
39
  end
40
40
 
41
41
  def latest_tags
42
- self_join = {
43
- Sequel[:tags][:pacticipant_id] => Sequel[:tags_2][:pacticipant_id],
44
- Sequel[:tags][:name] => Sequel[:tags_2][:name]
45
- }
46
-
47
- PactBroker::Domain::Tag
42
+ Tag
48
43
  .select_all_qualified
49
- .left_join(:tags, self_join, { table_alias: :tags_2 }) do
50
- Sequel[:tags_2][:version_order] > Sequel[:tags][:version_order]
51
- end
52
- .where(Sequel[:tags_2][:name] => nil)
44
+ .max_group_by(:version_order, [:pacticipant_id, :name])
53
45
  end
54
46
 
55
47
  # Does NOT care about whether or not there is a pact publication
56
48
  # for the version
57
49
  def latest_tags_for_pacticipant_ids(pacticipant_ids)
58
- self_join = {
59
- Sequel[:tags][:pacticipant_id] => Sequel[:tags_2][:pacticipant_id],
60
- Sequel[:tags][:name] => Sequel[:tags_2][:name],
61
- Sequel[:tags_2][:pacticipant_id] => pacticipant_ids,
62
- }
63
-
64
50
  Tag
65
51
  .select_all_qualified
66
- .left_join(:tags, self_join, { table_alias: :tags_2 }) do
67
- Sequel[:tags_2][:version_order] > Sequel[:tags][:version_order]
52
+ .max_group_by(:version_order, [:pacticipant_id, :name]) do | ds |
53
+ ds.where(Sequel[:tags][:pacticipant_id] => pacticipant_ids)
68
54
  end
69
- .where(Sequel[:tags_2][:name] => nil)
70
- .where(Sequel[:tags][:pacticipant_id] => pacticipant_ids)
71
55
  end
72
56
 
73
57
  def latest_tags_for_pacticipant_ids_and_tag_names(pacticipant_ids, tag_names)
74
- self_join = {
75
- Sequel[:tags][:pacticipant_id] => Sequel[:tags_2][:pacticipant_id],
76
- Sequel[:tags][:name] => Sequel[:tags_2][:name],
77
- Sequel[:tags_2][:pacticipant_id] => pacticipant_ids,
78
- Sequel[:tags_2][:name] => tag_names
79
- }
80
-
81
58
  Tag
82
59
  .select_all_qualified
83
- .left_join(:tags, self_join, { table_alias: :tags_2 }) do
84
- Sequel[:tags_2][:version_order] > Sequel[:tags][:version_order]
60
+ .max_group_by(:version_order, [:pacticipant_id, :name]) do | ds |
61
+ ds.where(Sequel[:tags][:name] => tag_names)
62
+ .where(Sequel[:tags][:pacticipant_id] => pacticipant_ids)
85
63
  end
86
- .where(Sequel[:tags_2][:name] => nil)
87
- .where(Sequel[:tags][:pacticipant_id] => pacticipant_ids)
88
- .where(Sequel[:tags][:name] => tag_names)
89
64
  end
90
65
 
91
66
  # ignores tags that don't have a pact publication
@@ -110,6 +85,7 @@ module PactBroker
110
85
  .join(lp, versions_pact_publications_join)
111
86
  end
112
87
 
88
+ # TODO convert this to use max and join
113
89
  def head_tags_for_pact_publication(pact_publication)
114
90
  Tag.where(version_id: pact_publication.consumer_version_id).all.select do | tag |
115
91
  tag_pp_join = {
@@ -274,5 +274,6 @@ end
274
274
  # verifications_pact_version_id_fkey | (pact_version_id) REFERENCES pact_versions(id)
275
275
  # verifications_provider_id_fkey | (provider_id) REFERENCES pacticipants(id)
276
276
  # Referenced By:
277
- # latest_verification_id_for_pact_version_and_provider_version | latest_v_id_for_pv_and_pv_verification_id_fk | (verification_id) REFERENCES verifications(id) ON DELETE CASCADE
278
- # triggered_webhooks | triggered_webhooks_verification_id_fkey | (verification_id) REFERENCES verifications(id)
277
+ # latest_verification_id_for_pact_version_and_provider_version | latest_v_id_for_pv_and_pv_verification_id_fk | (verification_id) REFERENCES verifications(id) ON DELETE CASCADE
278
+ # pact_version_provider_tag_successful_verifications | pact_version_provider_tag_successful_verifications_v_id_fk | (verification_id) REFERENCES verifications(id) ON DELETE SET NULL
279
+ # triggered_webhooks | triggered_webhooks_verification_id_fkey | (verification_id) REFERENCES verifications(id)
@@ -141,10 +141,12 @@ module PactBroker
141
141
  where(id: PactBroker::Versions::BranchVersion.select(:version_id))
142
142
  else
143
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)
144
+ branch_version_ids = PactBroker::Versions::BranchVersion
145
+ .select(:version_id, :branch_name)
146
146
  .where(branch_id: matching_branch_ids)
147
- where(id: matching_branch_version_ids)
147
+ select_append(:branch_name)
148
+ .join(branch_version_ids, { Sequel[first_source_alias][:id] => Sequel[:bv][:version_id] }, { table_alias: :bv})
149
+
148
150
  end
149
151
  end
150
152
 
@@ -152,18 +154,22 @@ module PactBroker
152
154
  if branch_name == true
153
155
  where(id: PactBroker::Versions::BranchHead.select(:version_id))
154
156
  else
155
- where(id: PactBroker::Versions::BranchHead.select(:version_id).where(branch_name: branch_name))
157
+ branch_heads = PactBroker::Versions::BranchHead.select(:version_id, :branch_name).where(branch_name: branch_name)
158
+ select_append(:branch_name)
159
+ .join(branch_heads, { Sequel[first_source_alias][:id] => Sequel[:bh][:version_id] }, { table_alias: :bh })
156
160
  end
157
161
  end
158
162
 
159
163
 
160
164
  def for_main_branches
161
- matching_branch_version_ids = PactBroker::Versions::BranchVersion
162
- .select(:version_id)
165
+ branch_version_ids = PactBroker::Versions::BranchVersion
166
+ .select(:version_id, :branch_name)
163
167
  .join(:pacticipants, { Sequel[:branch_versions][:pacticipant_id] => Sequel[:pacticipants][:id] })
164
168
  .join(:branches, { Sequel[:branches][:id] => Sequel[:branch_versions][:branch_id], Sequel[:branches][:name] => Sequel[:pacticipants][:main_branch] })
165
169
 
166
- where(id: matching_branch_version_ids)
170
+ select_append(Sequel[:bv][:branch_name])
171
+ .join(branch_version_ids, { Sequel[first_source_alias][:id] => Sequel[:bv][:version_id] }, table_alias: :bv)
172
+
167
173
  end
168
174
 
169
175
  def latest_for_main_branches
@@ -171,11 +177,13 @@ module PactBroker
171
177
  Sequel[:branch_heads][:pacticipant_id] => Sequel[:pacticipants][:id],
172
178
  Sequel[:branch_heads][:branch_name] => Sequel[:pacticipants][:main_branch]
173
179
  }
174
- matching_branch_version_ids = PactBroker::Versions::BranchHead
175
- .select(:version_id)
180
+ branch_head_version_ids = PactBroker::Versions::BranchHead
181
+ .select(:version_id, :branch_name)
176
182
  .join(:pacticipants, pacticipants_join)
177
183
 
178
- where(id: matching_branch_version_ids)
184
+ select_append(Sequel[:bh][:branch_name])
185
+ .join(branch_head_version_ids, { Sequel[first_source_alias][:id] => Sequel[:bh][:version_id] }, table_alias: :bh)
186
+
179
187
  end
180
188
 
181
189
  def where_number(number)
@@ -322,6 +330,14 @@ module PactBroker
322
330
  def tag_names
323
331
  tags.collect(&:name)
324
332
  end
333
+
334
+ def branch
335
+ raise NotImplementedError
336
+ end
337
+
338
+ def branch= branch
339
+ raise NotImplementedError
340
+ end
325
341
  end
326
342
  end
327
343
  end
@@ -87,6 +87,7 @@ en:
87
87
  environment_name_must_be_unique: Another environment with name '%{name}' already exists.
88
88
  cannot_specify_tag_and_environment: Cannot specify both a 'to' tag and an environment.
89
89
  cannot_specify_latest_and_environment: Cannot specify both latest=true and an environment.
90
+ cannot_specify_more_than_one_destination_identifier: Cannot specify more than one of tag, environment and mainBranch.
90
91
  environment_with_name_not_found: "Environment with name '%{name}' does not exist"
91
92
  cannot_modify_version_branch: "The branch for a pacticipant version cannot be changed once set (currently '%{old_branch}', proposed value '%{new_branch}'). Your pact publication/verification publication configurations may be in conflict with each other if you are seeing this error. If the current branch value is incorrect, you must delete the pacticipant version resource at %{version_url} and publish the pacts/verification results again with a consistent branch name."
92
93
  invalid_content_for_content_type: "The content could not be parsed as %{content_type}"
@@ -95,15 +96,18 @@ en:
95
96
  invalid_limit: The limit must be 1 or greater.
96
97
  duplicate_pacticipant: |
97
98
  This is the first time a pact has been published for "%{new_name}".
98
- The name "%{new_name}" is very similar to the following existing consumers/providers:
99
+ The name "%{new_name}" is very similar to the following existing pacticipants:
99
100
  %{existing_names}
100
101
  If you meant to specify one of the above names, please correct the pact configuration, and re-publish the pact.
101
- If the pact is intended to be for a new consumer or provider, please manually create "%{new_name}" using the following command, and then re-publish the pact:
102
- $ curl -v -XPOST -H "Content-Type: application/json" -d "{\"name\": \"%{new_name}\"}" %{create_pacticipant_url}
103
- If the pact broker requires basic authentication, add '-u <username:password>' to the command.
102
+ If the pact is intended to be for a new consumer or provider, please manually create "%{new_name}" using the following command from the Pact Broker CLI, and then re-publish the pact:
103
+
104
+ pact-broker create-or-update-pacticipant --name "%{new_name}" --broker-base-url %{base_url}
105
+
106
+ For information on the Pact Broker CLI see https://docs.pact.io/go/pbc-cli
104
107
  To disable this check, set `check_for_potential_duplicate_pacticipant_names` to false in the configuration.
105
108
  new_line_in_url_path: URL path cannot contain a new line character.
106
109
  tab_in_url_path: URL path cannot contain a tab character.
110
+ non_utf_8_char_in_request_body: "Request body has a non UTF-8 character at char %{char_number} and cannot be parsed as JSON. Fragment preceding invalid character is: '%{fragment}'"
107
111
 
108
112
  "400":
109
113
  title: 400 Malformed Request
@@ -62,7 +62,7 @@ module PactBroker
62
62
  def bad_practice_warnings
63
63
  warnings = []
64
64
 
65
- if no_to_tag_or_environment_specified?
65
+ if resolved_selectors.count(&:specified?) == 1 && no_to_tag_or_branch_or_environment_specified?
66
66
  warnings << NoEnvironmentSpecified.new
67
67
  end
68
68
 
@@ -91,8 +91,8 @@ module PactBroker
91
91
  .any?
92
92
  end
93
93
 
94
- def no_to_tag_or_environment_specified?
95
- !(query_results.options[:tag] || query_results.options[:environment_name])
94
+ def no_to_tag_or_branch_or_environment_specified?
95
+ !(query_results.options[:tag] || query_results.options[:environment_name] || query_results.options[:main_branch])
96
96
  end
97
97
 
98
98
  def considered_specified_selectors_that_do_not_exist
@@ -170,16 +170,6 @@ module PactBroker
170
170
  end.flatten
171
171
  end
172
172
 
173
- def selectors_without_a_version_for(integration)
174
- selectors_with_non_existing_versions.select do | selector |
175
- integration.involves_pacticipant_with_name?(selector.pacticipant_name)
176
- end
177
- end
178
-
179
- def selectors_with_non_existing_versions
180
- @selectors_with_non_existing_versions ||= resolved_selectors.select(&:latest_tagged_version_that_does_not_exist?)
181
- end
182
-
183
173
  def missing_specified_version_reasons(selectors)
184
174
  selectors.collect(&:version_does_not_exist_description)
185
175
  end
@@ -192,13 +182,32 @@ module PactBroker
192
182
  PactNotEverVerifiedByProvider.new(*selectors_for(row))
193
183
  end
194
184
 
195
- def selector_for(pacticipant_name)
196
- resolved_selectors.find{ | s| s.pacticipant_name == pacticipant_name } ||
197
- dummy_selectors.find{ | s| s.pacticipant_name == pacticipant_name }
185
+ # Find the resolved version selector that caused the matrix row with the
186
+ # specified pacticipant name and version number to be returned in the query.
187
+ #
188
+ # @return [PactBroker::Matrix::ResolvedSelector]
189
+ def selector_for(pacticipant_name, pacticipant_version_number)
190
+ found = resolved_selectors.select{ | s| s.pacticipant_name == pacticipant_name }
191
+
192
+ if found.size == 1
193
+ found.first
194
+ elsif pacticipant_version_number
195
+ found.find{ |s| s.pacticipant_version_number == pacticipant_version_number } || dummy_selector_for(pacticipant_name)
196
+ else
197
+ dummy_selector_for(pacticipant_name)
198
+ end
199
+ end
200
+
201
+ def selectors_for(row_or_integration)
202
+ if row_or_integration.respond_to?(:consumer_version_number)
203
+ [selector_for(row_or_integration.consumer_name, row_or_integration.consumer_version_number), selector_for(row_or_integration.provider_name, row_or_integration.provider_version_number)]
204
+ else
205
+ [selector_for(row_or_integration.consumer_name, nil), selector_for(row_or_integration.provider_name, nil)]
206
+ end
198
207
  end
199
208
 
200
- def selectors_for(row)
201
- [selector_for(row.consumer_name), selector_for(row.provider_name)]
209
+ def dummy_selector_for(pacticipant_name)
210
+ dummy_selectors.find{ | s| s.pacticipant_name == pacticipant_name }
202
211
  end
203
212
 
204
213
  # When the user has not specified a version of the provider (eg no 'latest' and/or 'tag', which means 'all versions')
@@ -232,7 +241,7 @@ module PactBroker
232
241
  considered_rows.select(&:success).collect do | row |
233
242
  begin
234
243
  if row.verification.interactions_missing_test_results.any? && !row.verification.all_interactions_missing_test_results?
235
- InteractionsMissingVerifications.new(selector_for(row.consumer_name), selector_for(row.provider_name), row.verification.interactions_missing_test_results)
244
+ InteractionsMissingVerifications.new(selector_for(row.consumer_name, row.consumer_version_number), selector_for(row.provider_name, row.provider_version_number), row.verification.interactions_missing_test_results)
236
245
  end
237
246
  rescue StandardError => e
238
247
  logger.warn("Error determining if there were missing interaction verifications", e)
@@ -48,6 +48,10 @@ module PactBroker
48
48
  options[:environment_name] = params["environment"]
49
49
  end
50
50
 
51
+ if params.key?("mainBranch") && params["mainBranch"] != ""
52
+ options[:main_branch] = params["mainBranch"] == "true"
53
+ end
54
+
51
55
  if params["ignore"].is_a?(Array)
52
56
  options[:ignore_selectors] = params["ignore"].collect{ |i| parse_selector(i) }
53
57
  else
@@ -65,6 +69,7 @@ module PactBroker
65
69
  p.branch = i["branch"] if i["branch"] && i["branch"] != ""
66
70
  p.tag = i["tag"] if i["tag"] && i["tag"] != ""
67
71
  p.environment_name = i["environment"] if i["environment"] && i["environment"] != ""
72
+ p.main_branch = true if i["mainBranch"] && i["mainBranch"] == "true"
68
73
  p
69
74
  end
70
75
  # rubocop: enable Metrics/CyclomaticComplexity
@@ -72,6 +72,8 @@ module PactBroker
72
72
  SELECT_ALL_COLUMN_ARGS = [:select_all_columns] + ALL_COLUMNS
73
73
  SELECT_PACTICIPANT_IDS_ARGS = [:select_pacticipant_ids, Sequel[:p][:consumer_id], Sequel[:p][:provider_id]]
74
74
 
75
+ EAGER_LOADED_RELATIONSHIPS_FOR_VERSION = { current_deployed_versions: :environment, current_supported_released_versions: :environment, branch_versions: [:branch_head, :version, branch: :pacticipant] }
76
+
75
77
  associate(:many_to_one, :pact_publication, :class => "PactBroker::Pacts::PactPublication", :key => :pact_publication_id, :primary_key => :id)
76
78
  associate(:many_to_one, :provider, :class => "PactBroker::Domain::Pacticipant", :key => :provider_id, :primary_key => :id)
77
79
  associate(:many_to_one, :consumer, :class => "PactBroker::Domain::Pacticipant", :key => :consumer_id, :primary_key => :id)
@@ -141,6 +143,7 @@ module PactBroker
141
143
  order(Sequel.desc(:consumer_version_created_at), Sequel.desc(:pact_order))
142
144
  end
143
145
 
146
+ # eager load tags?
144
147
  def eager_all_the_things
145
148
  eager(
146
149
  :consumer,
@@ -148,8 +151,8 @@ module PactBroker
148
151
  :verification,
149
152
  :pact_publication,
150
153
  :pact_version,
151
- consumer_version: { current_deployed_versions: :environment, current_supported_released_versions: :environment, branch_versions: [:branch_head, :version, branch: :pacticipant] },
152
- provider_version: { current_deployed_versions: :environment, current_supported_released_versions: :environment, branch_versions: [:branch_head, :version, branch: :pacticipant] },
154
+ consumer_version: EAGER_LOADED_RELATIONSHIPS_FOR_VERSION,
155
+ provider_version: EAGER_LOADED_RELATIONSHIPS_FOR_VERSION,
153
156
  consumer_version_tags: { version: :pacticipant },
154
157
  provider_version_tags: { version: :pacticipant }
155
158
  )
@@ -262,10 +262,9 @@ module PactBroker
262
262
  end
263
263
 
264
264
  # The user has specified --to TAG or --to-environment ENVIRONMENT in the CLI
265
- # (or nothing, which to defaults to "with the latest version of the other integrated applications")
266
- # The branch isn't implemented in the CLI yet (March 2022), but the API supports it.
265
+ # (or nothing, which to defaults to latest=true - "with the latest version of the other integrated applications")
267
266
  def infer_selectors_for_integrations?(options)
268
- options[:latest] || options[:tag] || options[:branch] || options[:environment_name]
267
+ options[:latest] || options[:tag] || options[:branch] || options[:environment_name] || options[:main_branch]
269
268
  end
270
269
 
271
270
  # When only one selector is specified, (eg. checking to see if Foo version 2 can be deployed to prod),
@@ -282,6 +281,7 @@ module PactBroker
282
281
  selector = UnresolvedSelector.new(pacticipant_name: pacticipant_name)
283
282
  selector.tag = options[:tag] if options[:tag]
284
283
  selector.branch = options[:branch] if options[:branch]
284
+ selector.main_branch = options[:main_branch] if options[:main_branch]
285
285
  selector.latest = options[:latest] if options[:latest]
286
286
  selector.environment_name = options[:environment_name] if options[:environment_name]
287
287
  selector
@@ -45,7 +45,8 @@ module PactBroker
45
45
  pacticipant_version_number: version.number,
46
46
  latest: original_selector[:latest],
47
47
  tag: original_selector[:tag],
48
- branch: original_selector[:branch],
48
+ branch: original_selector[:branch] || (original_selector[:main_branch] ? version&.values[:branch_name] : nil),
49
+ main_branch: original_selector[:main_branch],
49
50
  environment_name: original_selector[:environment_name],
50
51
  type: type,
51
52
  ignore: ignore,
@@ -64,6 +65,7 @@ module PactBroker
64
65
  latest: original_selector[:latest],
65
66
  tag: original_selector[:tag],
66
67
  branch: original_selector[:branch],
68
+ main_branch: original_selector[:main_branch],
67
69
  environment_name: original_selector[:environment_name],
68
70
  type: type,
69
71
  ignore: ignore,
@@ -99,10 +101,16 @@ module PactBroker
99
101
  self[:tag]
100
102
  end
101
103
 
104
+ # @return [String] the name of the branch
102
105
  def branch
103
106
  self[:branch]
104
107
  end
105
108
 
109
+ # @return [Boolean]
110
+ def main_branch?
111
+ self[:main_branch]
112
+ end
113
+
106
114
  def environment_name
107
115
  self[:environment_name]
108
116
  end
@@ -116,7 +124,7 @@ module PactBroker
116
124
  end
117
125
 
118
126
  def only_pacticipant_name_specified?
119
- !!pacticipant_name && !branch && !tag && !latest? && !pacticipant_version_number
127
+ !!pacticipant_name && !branch && !tag && !latest? && !pacticipant_version_number && !main_branch?
120
128
  end
121
129
 
122
130
  def latest_tagged?
@@ -127,6 +135,10 @@ module PactBroker
127
135
  latest? && branch
128
136
  end
129
137
 
138
+ def latest_from_main_branch?
139
+ latest? && main_branch?
140
+ end
141
+
130
142
  def pacticipant_or_version_does_not_exist?
131
143
  pacticipant_does_not_exist? || version_does_not_exist?
132
144
  end
@@ -139,10 +151,6 @@ module PactBroker
139
151
  !version_exists?
140
152
  end
141
153
 
142
- def latest_tagged_version_that_does_not_exist?
143
- version_does_not_exist? && latest_tagged?
144
- end
145
-
146
154
  def specified_version_that_does_not_exist?
147
155
  specified? && version_does_not_exist?
148
156
  end
@@ -174,16 +182,25 @@ module PactBroker
174
182
  !ignore?
175
183
  end
176
184
 
177
- # rubocop: disable Metrics/CyclomaticComplexity
185
+ # rubocop: disable Metrics/CyclomaticComplexity, Metrics/MethodLength
178
186
  def description
179
187
  if latest_tagged? && pacticipant_version_number
180
188
  "the latest version of #{pacticipant_name} with tag #{tag} (#{pacticipant_version_number})"
181
189
  elsif latest_tagged?
182
190
  "the latest version of #{pacticipant_name} with tag #{tag} (no such version exists)"
191
+ elsif main_branch? && pacticipant_version_number.nil?
192
+ "a version of #{pacticipant_name} from the main branch (no such version exists)"
193
+ elsif latest_from_main_branch? && pacticipant_version_number.nil?
194
+ "the latest version of #{pacticipant_name} from the main branch (no such verison exists)"
183
195
  elsif latest_from_branch? && pacticipant_version_number
184
196
  "the latest version of #{pacticipant_name} from branch #{branch} (#{pacticipant_version_number})"
185
197
  elsif latest_from_branch?
186
198
  "the latest version of #{pacticipant_name} from branch #{branch} (no such version exists)"
199
+ elsif branch && pacticipant_version_number
200
+ prefix = one_of_many? ? "one of the versions " : "the version "
201
+ prefix + "of #{pacticipant_name} from branch #{branch} (#{pacticipant_version_number})"
202
+ elsif branch
203
+ "a version of #{pacticipant_name} from branch #{branch} (no such version exists)"
187
204
  elsif latest? && pacticipant_version_number
188
205
  "the latest version of #{pacticipant_name} (#{pacticipant_version_number})"
189
206
  elsif latest?
@@ -194,9 +211,9 @@ module PactBroker
194
211
  "a version of #{pacticipant_name} with tag #{tag} (no such version exists)"
195
212
  elsif environment_name && pacticipant_version_number
196
213
  prefix = one_of_many? ? "one of the versions" : "the version"
197
- "#{prefix} of #{pacticipant_name} currently deployed to #{environment_name} (#{pacticipant_version_number})"
214
+ "#{prefix} of #{pacticipant_name} currently deployed or released to #{environment_name} (#{pacticipant_version_number})"
198
215
  elsif environment_name
199
- "the version of #{pacticipant_name} currently deployed to #{environment_name} (no such version exists)"
216
+ "a version of #{pacticipant_name} currently deployed or released to #{environment_name} (no version is currently recorded as deployed/released in this environment)"
200
217
  elsif pacticipant_version_number && version_does_not_exist?
201
218
  "version #{pacticipant_version_number} of #{pacticipant_name} (no such version exists)"
202
219
  elsif pacticipant_version_number
@@ -207,7 +224,27 @@ module PactBroker
207
224
  "any version of #{pacticipant_name}"
208
225
  end
209
226
  end
210
- # rubocop: enable Metrics/CyclomaticComplexity
227
+ # rubocop: enable Metrics/CyclomaticComplexity, Metrics/MethodLength
228
+
229
+ def version_does_not_exist_description
230
+ if version_does_not_exist?
231
+ if tag
232
+ "No version with tag #{tag} exists for #{pacticipant_name}"
233
+ elsif branch
234
+ "No version of #{pacticipant_name} from branch #{branch} exists"
235
+ elsif main_branch?
236
+ "No version of #{pacticipant_name} from the main branch exists"
237
+ elsif environment_name
238
+ "No version of #{pacticipant_name} is currently recorded as deployed or released in environment #{environment_name}"
239
+ elsif pacticipant_version_number
240
+ "No pacts or verifications have been published for version #{pacticipant_version_number} of #{pacticipant_name}"
241
+ else
242
+ "No pacts or verifications have been published for #{pacticipant_name}"
243
+ end
244
+ else
245
+ ""
246
+ end
247
+ end
211
248
  end
212
249
  end
213
250
  end
@@ -52,7 +52,7 @@ module PactBroker
52
52
  end
53
53
  end
54
54
 
55
- # rubocop: disable Metrics/CyclomaticComplexity, Metrics/MethodLength
55
+ # rubocop: disable Metrics/CyclomaticComplexity
56
56
  def validate_selectors selectors, options = {}
57
57
  error_messages = []
58
58
 
@@ -73,6 +73,18 @@ module PactBroker
73
73
  end
74
74
  end
75
75
 
76
+ if selectors.size == 0
77
+ error_messages << "Please provide 1 or more version selectors."
78
+ end
79
+
80
+ error_messages + validate_options(options)
81
+ end
82
+ # rubocop: enable Metrics/CyclomaticComplexity
83
+
84
+ # rubocop: disable Metrics/CyclomaticComplexity
85
+ def validate_options(options = {})
86
+ error_messages = []
87
+
76
88
  options.fetch(:ignore_selectors, []).each do | s |
77
89
  if s[:pacticipant_name].nil?
78
90
  error_messages << "Please specify the pacticipant name to ignore"
@@ -83,12 +95,10 @@ module PactBroker
83
95
  end
84
96
  end
85
97
 
86
- if selectors.size == 0
87
- error_messages << "Please provide 1 or more version selectors."
88
- end
98
+ destination_identifiers = [options[:tag], options[:environment_name], options[:main_branch]&.to_s].compact
89
99
 
90
- if options[:tag]&.not_blank? && options[:environment_name]&.not_blank?
91
- error_messages << message("errors.validation.cannot_specify_tag_and_environment")
100
+ if destination_identifiers.size > 1
101
+ error_messages << message("errors.validation.cannot_specify_more_than_one_destination_identifier")
92
102
  end
93
103
 
94
104
  if options[:latest] && options[:environment_name]&.not_blank?
@@ -105,7 +115,7 @@ module PactBroker
105
115
 
106
116
  error_messages
107
117
  end
108
- # rubocop: enable Metrics/CyclomaticComplexity, Metrics/MethodLength
118
+ # rubocop: enable Metrics/CyclomaticComplexity
109
119
  end
110
120
  end
111
121
  end
@@ -11,7 +11,7 @@ module PactBroker
11
11
 
12
12
  # TODO rename branch to branch_name
13
13
  def self.from_hash(hash)
14
- new(hash.symbolize_keys.snakecase_keys.slice(:pacticipant_name, :pacticipant_version_number, :latest, :tag, :branch, :environment_name))
14
+ new(hash.symbolize_keys.snakecase_keys.slice(:pacticipant_name, :pacticipant_version_number, :latest, :tag, :branch, :environment_name, :main_branch))
15
15
  end
16
16
 
17
17
  def pacticipant_name
@@ -42,6 +42,11 @@ module PactBroker
42
42
  self[:branch]
43
43
  end
44
44
 
45
+ # @return [Boolean]
46
+ def main_branch
47
+ self[:main_branch]
48
+ end
49
+
45
50
  def environment_name
46
51
  self[:environment_name]
47
52
  end
@@ -58,6 +63,11 @@ module PactBroker
58
63
  self[:branch] = branch
59
64
  end
60
65
 
66
+ # @param [Boolean] main_branch
67
+ def main_branch= main_branch
68
+ self[:main_branch] = main_branch
69
+ end
70
+
61
71
  def environment_name= environment_name
62
72
  self[:environment_name] = environment_name
63
73
  end
@@ -79,9 +89,11 @@ module PactBroker
79
89
  self[:max_age]
80
90
  end
81
91
 
92
+ # rubocop: disable Metrics/CyclomaticComplexity
82
93
  def all_for_pacticipant?
83
- !!pacticipant_name && !pacticipant_version_number && !tag && !branch && !latest && !environment_name && !max_age
94
+ !!pacticipant_name && !pacticipant_version_number && !tag && !branch && !latest && !environment_name && !max_age && !main_branch
84
95
  end
96
+ # rubocop: enable Metrics/CyclomaticComplexity
85
97
 
86
98
  def latest_for_pacticipant_and_tag?
87
99
  !!(pacticipant_name && tag && latest)
@@ -23,15 +23,6 @@ module PactBroker
23
23
  message("errors.validation." + key, options)
24
24
  end
25
25
 
26
- def potential_duplicate_pacticipant_message new_name, potential_duplicate_pacticipants, base_url
27
- existing_names = potential_duplicate_pacticipants.
28
- collect{ | p | "* #{p.name}" }.join("\n")
29
- message("errors.duplicate_pacticipant",
30
- new_name: new_name,
31
- existing_names: existing_names,
32
- create_pacticipant_url: pacticipants_url(base_url))
33
- end
34
-
35
26
  def pluralize(word, count)
36
27
  if count == 1
37
28
  word
@@ -43,11 +34,5 @@ module PactBroker
43
34
  end
44
35
  end
45
36
  end
46
-
47
- private
48
-
49
- def pacticipants_url base_url
50
- PactBroker::Api::PactBrokerUrls.pacticipants_url base_url
51
- end
52
37
  end
53
38
  end
@@ -5,12 +5,12 @@ module PactBroker
5
5
  class FindPotentialDuplicatePacticipantNames
6
6
  attr_reader :new_name, :existing_names
7
7
 
8
- def initialize new_name, existing_names
8
+ def initialize(new_name, existing_names)
9
9
  @new_name = new_name
10
10
  @existing_names = existing_names
11
11
  end
12
12
 
13
- def self.call new_name, existing_names
13
+ def self.call(new_name, existing_names)
14
14
  new(new_name, existing_names).call
15
15
  end
16
16
 
@@ -22,7 +22,7 @@ module PactBroker
22
22
  end
23
23
  end
24
24
 
25
- def clean name
25
+ def clean(name)
26
26
  self.class.split(name).collect{|w| w.chomp("s") } - ["api", "provider", "service"]
27
27
  end
28
28
 
@@ -59,22 +59,23 @@ module PactBroker
59
59
  repository_name: params[:repository_name],
60
60
  repository_namespace: params[:repository_namespace],
61
61
  main_branch: params[:main_branch]
62
- ).insert_ignore
62
+ ).insert_ignore.refresh
63
63
  end
64
64
 
65
65
  def update(pacticipant_name, pacticipant)
66
66
  pacticipant.name = pacticipant_name
67
- pacticipant.save
67
+ pacticipant.save.refresh
68
68
  end
69
69
 
70
- def replace(_pacticipant_name, open_struct_pacticipant)
70
+ def replace(pacticipant_name, open_struct_pacticipant)
71
71
  PactBroker::Domain::Pacticipant.new(
72
+ name: pacticipant_name,
72
73
  display_name: open_struct_pacticipant.display_name,
73
74
  repository_url: open_struct_pacticipant.repository_url,
74
75
  repository_name: open_struct_pacticipant.repository_name,
75
76
  repository_namespace: open_struct_pacticipant.repository_namespace,
76
77
  main_branch: open_struct_pacticipant.main_branch
77
- ).save
78
+ ).upsert
78
79
  end
79
80
 
80
81
  def delete(pacticipant)