pact_broker 2.104.0 → 2.105.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/lib/pact_broker/api/middleware/http_debug_logs.rb +2 -2
- data/lib/pact_broker/app.rb +1 -1
- data/lib/pact_broker/config/runtime_configuration.rb +1 -0
- data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +3 -0
- data/lib/pact_broker/configuration.rb +1 -1
- data/lib/pact_broker/db/data_migrations/set_pacticipant_main_branch.rb +2 -2
- data/lib/pact_broker/domain/pact.rb +7 -1
- data/lib/pact_broker/initializers/database_connection.rb +1 -1
- data/lib/pact_broker/locale/en.yml +1 -0
- data/lib/pact_broker/matrix/can_i_deploy_query_schema.rb +6 -0
- data/lib/pact_broker/matrix/deployment_status_summary.rb +1 -1
- data/lib/pact_broker/matrix/resolved_selector.rb +2 -2
- data/lib/pact_broker/pacts/pact_version.rb +39 -0
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +74 -47
- data/lib/pact_broker/pacts/repository.rb +2 -2
- data/lib/pact_broker/pacts/service.rb +7 -8
- data/lib/pact_broker/pacts/squash_pacts_for_verification.rb +7 -4
- data/lib/pact_broker/tasks/clean_task.rb +1 -1
- data/lib/pact_broker/tasks/delete_overwritten_data_task.rb +1 -1
- data/lib/pact_broker/test/http_test_data_builder.rb +34 -26
- data/lib/pact_broker/test/test_data_builder.rb +28 -12
- data/lib/pact_broker/verifications/service.rb +1 -1
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/branch.rb +1 -0
- data/lib/pact_broker/webhooks/event_listener.rb +2 -2
- data/lib/pact_broker/webhooks/execution_configuration.rb +4 -0
- data/lib/pact_broker/webhooks/execution_configuration_creator.rb +1 -0
- data/lib/pact_broker/webhooks/webhook_request_logger.rb +1 -1
- data/pact_broker.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c43c0dbf719c9e927fad6ffcee28b559036726a61a41813a3451554e5f1db087
|
4
|
+
data.tar.gz: '0964dcfea819d1ccc1c1ccc15d8a7493670dfbefbde75aedb63ac9405c7c764d'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12f323b624a2ff4dcc7827e254ec71c83a1d3ffe89532746feb67e360aa5fda938927f43176b86ea08b7b3fddf66d4ef0a5c8cf9ec6b4190332e572a2fd4ad0a
|
7
|
+
data.tar.gz: a3a5aed03639c5ef8ab602da938e502e4b0434248c99de262bac7a1d6a09e42e4991d32748ae542bfdf1376db133957ff69652b99e49cc1fdfc22f0845907f22
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
<a name="v2.105.0"></a>
|
2
|
+
### v2.105.0 (2022-10-19)
|
3
|
+
|
4
|
+
#### Features
|
5
|
+
|
6
|
+
* update wording of version description for version in environment ([d122fa68](/../../commit/d122fa68))
|
7
|
+
|
8
|
+
* **webhooks**
|
9
|
+
* allow auth headers to be logged for debugging purposes (#575) ([102b1930](/../../commit/102b1930))
|
10
|
+
|
11
|
+
#### Bug Fixes
|
12
|
+
|
13
|
+
* add validation to ensure an environment or to tag is specified for the /can-i-deploy endpoint ([e9d772eb](/../../commit/e9d772eb))
|
14
|
+
* implement pending logic for provider branches ([7cdf1a7c](/../../commit/7cdf1a7c))
|
15
|
+
|
16
|
+
* **wip pacts**
|
17
|
+
* fix performance issue encountered when removing explicitly specified pacts from the list of potential WIP pacts (#573) ([757f0301](/../../commit/757f0301))
|
18
|
+
|
1
19
|
<a name="v2.104.0"></a>
|
2
20
|
### v2.104.0 (2022-09-17)
|
3
21
|
|
@@ -21,9 +21,9 @@ module PactBroker
|
|
21
21
|
env_to_log = env.reject { | header, _ | header.start_with?(*EXCLUDE_HEADERS) }
|
22
22
|
env_to_log["rack.session"] = env["rack.session"].to_hash if env["rack.session"]
|
23
23
|
env_to_log["rack.input"] = request_body(env) if env["rack.input"]
|
24
|
-
logger.debug("env",
|
24
|
+
logger.debug("env", env_to_log)
|
25
25
|
status, headers, body = @app.call(env)
|
26
|
-
logger.debug("response",
|
26
|
+
logger.debug("response", "status" => status, "headers" => headers, "body" => body)
|
27
27
|
[status, headers, body]
|
28
28
|
else
|
29
29
|
@app.call(env)
|
data/lib/pact_broker/app.rb
CHANGED
@@ -223,7 +223,7 @@ module PactBroker
|
|
223
223
|
except: configuration.rack_protection_except
|
224
224
|
}.compact
|
225
225
|
|
226
|
-
logger.info("Configuring Rack::Protection",
|
226
|
+
logger.info("Configuring Rack::Protection", rack_protection_options)
|
227
227
|
@app_builder.use Rack::Protection, rack_protection_options
|
228
228
|
|
229
229
|
is_hal_browser = ->(env) { env["PATH_INFO"] == "/hal-browser/browser.html" }
|
@@ -52,6 +52,7 @@ module PactBroker
|
|
52
52
|
webhook_http_code_success: [200, 201, 202, 203, 204, 205, 206],
|
53
53
|
webhook_scheme_whitelist: ["https"],
|
54
54
|
webhook_host_whitelist: [],
|
55
|
+
webhook_redact_sensitive_data: true,
|
55
56
|
disable_ssl_verification: false,
|
56
57
|
user_agent: "Pact Broker v#{PactBroker::VERSION}"
|
57
58
|
)
|
@@ -31,6 +31,9 @@ module PactBroker
|
|
31
31
|
source: source_info.dig(key, :source) || {:type=>:defaults}
|
32
32
|
}
|
33
33
|
end.sort_by { |key, _| key }.each { |key, value| log_config_inner(key, value, logger) }
|
34
|
+
if self.webhook_redact_sensitive_data == false
|
35
|
+
logger.warn("WARNING!!! webhook_redact_sensitive_data is set to false. This will allow authentication information to be included in the webhook logs. This should only be used for debugging purposes. Do not run the application permanently in production with this value.")
|
36
|
+
end
|
34
37
|
end
|
35
38
|
|
36
39
|
def log_config_inner(key, value, logger)
|
@@ -94,7 +94,7 @@ module PactBroker
|
|
94
94
|
end
|
95
95
|
|
96
96
|
if logger.debug?
|
97
|
-
logger.debug("Overridding runtime configuration",
|
97
|
+
logger.debug("Overridding runtime configuration", overrides: valid_overrides, ignoring: invalid_overrides)
|
98
98
|
end
|
99
99
|
|
100
100
|
valid_overrides.each do | key, value |
|
@@ -23,9 +23,9 @@ module PactBroker
|
|
23
23
|
|
24
24
|
if main_branch_name
|
25
25
|
connection[:pacticipants].where(id: pacticipant_row[:id], main_branch: nil).update(main_branch: main_branch_name)
|
26
|
-
logger.info("Setting main branch for pacticipant",
|
26
|
+
logger.info("Setting main branch for pacticipant", branch: main_branch_name, pacticipant_name: pacticipant_row[:name])
|
27
27
|
else
|
28
|
-
logger.info("Cannot determine main branch for pacticipant",
|
28
|
+
logger.info("Cannot determine main branch for pacticipant", branch: nil, pacticipant_name: pacticipant_row[:name])
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -94,7 +94,13 @@ module PactBroker
|
|
94
94
|
provider_version_tags - tags_with_successful_verifications_from_that_branch - tags_with_previous_successful_verifications_from_other_branches
|
95
95
|
end
|
96
96
|
|
97
|
-
|
97
|
+
# @param [String] branch_name the name of the provider branch that will be verifying the pacts
|
98
|
+
# @return Boolean whether or not the pact is in pending state (ie. the build should not fail if the verification fails)
|
99
|
+
def pending_for_provider_branch?(branch_name)
|
100
|
+
pact_version.pending_for_provider_branch?(branch_name)
|
101
|
+
end
|
102
|
+
|
103
|
+
def pending_for_any_provider_branch?
|
98
104
|
!pact_version.verified_successfully_by_any_provider_version?
|
99
105
|
end
|
100
106
|
|
@@ -4,7 +4,7 @@ require "fileutils"
|
|
4
4
|
|
5
5
|
module PactBroker
|
6
6
|
def self.create_database_connection(config, logger = nil)
|
7
|
-
logger&.info
|
7
|
+
logger&.info("Connecting to database:", config.merge(password: "*****"))
|
8
8
|
|
9
9
|
sequel_config = config.dup
|
10
10
|
max_retries = sequel_config.delete(:connect_max_retries) || 0
|
@@ -85,6 +85,7 @@ en:
|
|
85
85
|
invalid_webhook_uuid: The UUID can only contain the characters A-Z, a-z, 0-9, _ and -, and must be 16 or more characters.
|
86
86
|
pacticipant_not_found: No pacticipant with name '%{name}' found
|
87
87
|
environment_name_must_be_unique: Another environment with name '%{name}' already exists.
|
88
|
+
must_specify_environment_or_tag: Must specify either an environment or a 'to' tag.
|
88
89
|
cannot_specify_tag_and_environment: Cannot specify both a 'to' tag and an environment.
|
89
90
|
cannot_specify_latest_and_environment: Cannot specify both latest=true and an environment.
|
90
91
|
cannot_specify_more_than_one_destination_identifier: Cannot specify more than one of tag, environment and mainBranch.
|
@@ -2,12 +2,14 @@ require "dry-validation"
|
|
2
2
|
require "pact_broker/messages"
|
3
3
|
require "pact_broker/api/contracts/dry_validation_predicates"
|
4
4
|
require "pact_broker/project_root"
|
5
|
+
require "pact_broker/string_refinements"
|
5
6
|
|
6
7
|
module PactBroker
|
7
8
|
module Api
|
8
9
|
module Contracts
|
9
10
|
class CanIDeployQuerySchema
|
10
11
|
extend PactBroker::Messages
|
12
|
+
using PactBroker::StringRefinements
|
11
13
|
|
12
14
|
SCHEMA = Dry::Validation.Schema do
|
13
15
|
configure do
|
@@ -26,6 +28,10 @@ module PactBroker
|
|
26
28
|
result[:to] ||= []
|
27
29
|
result[:to] << message("errors.validation.cannot_specify_tag_and_environment")
|
28
30
|
end
|
31
|
+
if params[:to].blank? && params[:environment].blank?
|
32
|
+
result[:environment] ||= []
|
33
|
+
result[:environment] << message("errors.validation.must_specify_environment_or_tag")
|
34
|
+
end
|
29
35
|
result
|
30
36
|
end
|
31
37
|
|
@@ -161,7 +161,7 @@ module PactBroker
|
|
161
161
|
end
|
162
162
|
|
163
163
|
def log_required_integrations_without_a_row_occurred integrations
|
164
|
-
logger.info("required_integrations_without_a_row returned non empty",
|
164
|
+
logger.info("required_integrations_without_a_row returned non empty", integrations: integrations, considered_rows: considered_rows)
|
165
165
|
end
|
166
166
|
|
167
167
|
def row_exists_for_integration(integration)
|
@@ -211,9 +211,9 @@ module PactBroker
|
|
211
211
|
"a version of #{pacticipant_name} with tag #{tag} (no such version exists)"
|
212
212
|
elsif environment_name && pacticipant_version_number
|
213
213
|
prefix = one_of_many? ? "one of the versions" : "the version"
|
214
|
-
"#{prefix} of #{pacticipant_name} currently
|
214
|
+
"#{prefix} of #{pacticipant_name} currently in #{environment_name} (#{pacticipant_version_number})"
|
215
215
|
elsif environment_name
|
216
|
-
"a version of #{pacticipant_name} currently
|
216
|
+
"a version of #{pacticipant_name} currently in #{environment_name} (no version is currently recorded as deployed/released in this environment)"
|
217
217
|
elsif pacticipant_version_number && version_does_not_exist?
|
218
218
|
"version #{pacticipant_version_number} of #{pacticipant_name} (no such version exists)"
|
219
219
|
elsif pacticipant_version_number
|
@@ -80,6 +80,14 @@ module PactBroker
|
|
80
80
|
}
|
81
81
|
join(:tags, tags_join)
|
82
82
|
end
|
83
|
+
|
84
|
+
def join_branch_versions_for_branch_name_to_verifications(branch_name)
|
85
|
+
branch_versions_join = {
|
86
|
+
Sequel[:branch_versions][:version_id] => Sequel[:verifications][:provider_version_id],
|
87
|
+
Sequel[:branch_versions][:branch_name] => branch_name
|
88
|
+
}
|
89
|
+
join(:branch_versions, branch_versions_join)
|
90
|
+
end
|
83
91
|
end
|
84
92
|
|
85
93
|
def name
|
@@ -106,6 +114,10 @@ module PactBroker
|
|
106
114
|
latest_consumer_version.number
|
107
115
|
end
|
108
116
|
|
117
|
+
def pending_for_provider_branch?(branch_name)
|
118
|
+
!any_successful_verifications_from_provider_branch?(branch_name) && !any_successful_verifications_from_another_branch_from_before_this_branch_created?(branch_name)
|
119
|
+
end
|
120
|
+
|
109
121
|
def select_provider_tags_with_successful_verifications_from_another_branch_from_before_this_branch_created(tags)
|
110
122
|
tags.select do | tag |
|
111
123
|
first_tag_with_name = PactBroker::Domain::Tag.where(pacticipant_id: provider_id, name: tag).order(:created_at).first
|
@@ -157,6 +169,33 @@ module PactBroker
|
|
157
169
|
)
|
158
170
|
end
|
159
171
|
end
|
172
|
+
|
173
|
+
def any_successful_verifications_from_provider_branch?(branch_name)
|
174
|
+
PactVersion.where(Sequel[:pact_versions][:id] => id)
|
175
|
+
.join_successful_verifications
|
176
|
+
.join_branch_versions_for_branch_name_to_verifications(branch_name)
|
177
|
+
.any?
|
178
|
+
end
|
179
|
+
|
180
|
+
def any_successful_verifications_from_another_branch_from_before_this_branch_created?(branch_name)
|
181
|
+
branch = PactBroker::Versions::Branch.where(pacticipant_id: provider_id, name: branch_name).single_record
|
182
|
+
|
183
|
+
verifications_join = {
|
184
|
+
Sequel[:verifications][:pact_version_id] => Sequel[:pact_versions][:id],
|
185
|
+
Sequel[:verifications][:success] => true
|
186
|
+
}
|
187
|
+
query = PactVersion.where(Sequel[:pact_versions][:id] => id)
|
188
|
+
.join(:verifications, verifications_join)
|
189
|
+
.join(:branch_versions, Sequel[:branch_versions][:version_id] => Sequel[:verifications][:provider_version_id]) do
|
190
|
+
Sequel.lit("branch_versions.branch_name != ?", branch_name)
|
191
|
+
end
|
192
|
+
|
193
|
+
if branch
|
194
|
+
query = query.where { Sequel[:verifications][:created_at] < branch.created_at }
|
195
|
+
end
|
196
|
+
|
197
|
+
query.any?
|
198
|
+
end
|
160
199
|
end
|
161
200
|
end
|
162
201
|
end
|
@@ -12,6 +12,7 @@ require "pact_broker/repositories/scopes"
|
|
12
12
|
|
13
13
|
module PactBroker
|
14
14
|
module Pacts
|
15
|
+
# rubocop: disable Metrics/ClassLength
|
15
16
|
class PactsForVerificationRepository
|
16
17
|
include PactBroker::Logging
|
17
18
|
include PactBroker::Repositories
|
@@ -26,6 +27,7 @@ module PactBroker
|
|
26
27
|
:pact_version
|
27
28
|
]
|
28
29
|
|
30
|
+
# @return [VerifiablePact] an array of VerifiablePact objects
|
29
31
|
def find(provider_name, consumer_version_selectors)
|
30
32
|
selected_pacts = find_pacts_by_selector(provider_name, consumer_version_selectors)
|
31
33
|
selected_pacts = selected_pacts + find_pacts_for_fallback_tags(selected_pacts, provider_name, consumer_version_selectors)
|
@@ -43,7 +45,7 @@ module PactBroker
|
|
43
45
|
# provider tags they are pending for.
|
44
46
|
# Don't include pact publications that were created before the provider tag was first used
|
45
47
|
# (that is, before the provider's git branch was created).
|
46
|
-
def find_wip
|
48
|
+
def find_wip(provider_name, provider_version_branch, provider_tags_names, explicitly_specified_verifiable_pacts, options = {})
|
47
49
|
# TODO not sure about this
|
48
50
|
if provider_tags_names.empty? && provider_version_branch == nil
|
49
51
|
log_debug_for_wip do
|
@@ -53,7 +55,7 @@ module PactBroker
|
|
53
55
|
end
|
54
56
|
|
55
57
|
if provider_version_branch
|
56
|
-
return find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch,
|
58
|
+
return find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch, explicitly_specified_verifiable_pacts, options)
|
57
59
|
end
|
58
60
|
|
59
61
|
provider = pacticipant_repository.find_by_name(provider_name)
|
@@ -63,7 +65,7 @@ module PactBroker
|
|
63
65
|
provider,
|
64
66
|
provider_tags_names,
|
65
67
|
wip_start_date,
|
66
|
-
|
68
|
+
explicitly_specified_verifiable_pacts,
|
67
69
|
:latest_by_consumer_tag
|
68
70
|
)
|
69
71
|
|
@@ -71,7 +73,7 @@ module PactBroker
|
|
71
73
|
provider,
|
72
74
|
provider_tags_names,
|
73
75
|
wip_start_date,
|
74
|
-
|
76
|
+
explicitly_specified_verifiable_pacts,
|
75
77
|
:latest_by_consumer_branch
|
76
78
|
)
|
77
79
|
|
@@ -139,7 +141,7 @@ module PactBroker
|
|
139
141
|
selectors = selector_for_latest_main_version_or_overall_latest(provider)
|
140
142
|
selectors << Selector.for_currently_deployed
|
141
143
|
selectors << Selector.for_currently_supported
|
142
|
-
logger.debug("Default selectors",
|
144
|
+
logger.debug("Default selectors", selectors)
|
143
145
|
selectors
|
144
146
|
end
|
145
147
|
|
@@ -193,11 +195,11 @@ module PactBroker
|
|
193
195
|
end
|
194
196
|
|
195
197
|
# TODO ? find the WIP pacts by consumer branch
|
196
|
-
def find_wip_pact_versions_for_provider_by_provider_tags(provider, provider_tags_names, wip_start_date,
|
198
|
+
def find_wip_pact_versions_for_provider_by_provider_tags(provider, provider_tags_names, wip_start_date, explicitly_specified_verifiable_pacts, pact_publication_scope)
|
197
199
|
potential_wip_pacts_by_consumer_tag_query = PactPublication.for_provider(provider).created_after(wip_start_date).send(pact_publication_scope)
|
198
200
|
|
199
201
|
log_debug_for_wip do
|
200
|
-
|
202
|
+
log_pact_publications_from_query("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)
|
201
203
|
end
|
202
204
|
|
203
205
|
tag_to_pact_publications = provider_tags_names.each_with_object({}) do | provider_tag_name, tag_to_pact_publication |
|
@@ -205,7 +207,7 @@ module PactBroker
|
|
205
207
|
potential_wip_pacts_by_consumer_tag_query,
|
206
208
|
provider,
|
207
209
|
provider_tag_name,
|
208
|
-
|
210
|
+
explicitly_specified_verifiable_pacts
|
209
211
|
)
|
210
212
|
end
|
211
213
|
|
@@ -225,7 +227,7 @@ module PactBroker
|
|
225
227
|
end
|
226
228
|
end
|
227
229
|
|
228
|
-
def find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch,
|
230
|
+
def find_wip_pact_versions_for_provider_by_provider_branch(provider_name, provider_version_branch, explicitly_specified_verifiable_pacts, options)
|
229
231
|
provider = pacticipant_repository.find_by_name(provider_name)
|
230
232
|
wip_start_date = options.fetch(:include_wip_pacts_since)
|
231
233
|
|
@@ -233,22 +235,22 @@ module PactBroker
|
|
233
235
|
potential_wip_by_consumer_tag = PactPublication.for_provider(provider).created_after(wip_start_date).latest_by_consumer_tag
|
234
236
|
|
235
237
|
log_debug_for_wip do
|
236
|
-
|
237
|
-
|
238
|
+
log_pact_publications_from_query("Potential WIP pacts for provider branch #{provider_version_branch} created after #{wip_start_date} by consumer branch", potential_wip_by_consumer_branch)
|
239
|
+
log_pact_publications_from_query("Potential WIP pacts for provider branch #{provider_version_branch} created after #{wip_start_date} by consumer tag", potential_wip_by_consumer_tag)
|
238
240
|
end
|
239
241
|
|
240
242
|
wip_pact_publications_by_branch = remove_non_wip_for_branch(
|
241
243
|
potential_wip_by_consumer_branch,
|
242
244
|
provider,
|
243
245
|
provider_version_branch,
|
244
|
-
|
246
|
+
explicitly_specified_verifiable_pacts
|
245
247
|
)
|
246
248
|
|
247
249
|
wip_pact_publications_by_tag = remove_non_wip_for_branch(
|
248
250
|
potential_wip_by_consumer_tag,
|
249
251
|
provider,
|
250
252
|
provider_version_branch,
|
251
|
-
|
253
|
+
explicitly_specified_verifiable_pacts
|
252
254
|
)
|
253
255
|
|
254
256
|
verifiable_pacts = (wip_pact_publications_by_branch + wip_pact_publications_by_tag).collect do | pact_publication |
|
@@ -259,55 +261,61 @@ module PactBroker
|
|
259
261
|
deduplicate_verifiable_pacts(verifiable_pacts).sort
|
260
262
|
end
|
261
263
|
|
262
|
-
def remove_non_wip_for_branch(pact_publications_query, provider, provider_version_branch,
|
263
|
-
specified_explicitly = pact_publications_query.for_pact_version_sha(specified_pact_version_shas)
|
264
|
+
def remove_non_wip_for_branch(pact_publications_query, provider, provider_version_branch, explicitly_specified_verifiable_pacts)
|
264
265
|
verified_by_this_branch = pact_publications_query.successfully_verified_by_provider_branch_when_not_wip(provider.id, provider_version_branch)
|
265
266
|
verified_by_other_branch = pact_publications_query.successfully_verified_by_provider_another_branch_before_this_branch_first_created(provider.id, provider_version_branch)
|
266
267
|
|
267
268
|
log_debug_for_wip do
|
268
|
-
log_pact_publications("Ignoring pacts explicitly specified in the selectors",
|
269
|
-
|
270
|
-
|
269
|
+
log_pact_publications("Ignoring pacts explicitly specified in the selectors", explicitly_specified_verifiable_pacts)
|
270
|
+
log_pact_publications_from_query("Ignoring pacts successfully verified by this provider branch when not WIP", verified_by_this_branch)
|
271
|
+
log_pact_publications_from_query("Ignoring pacts successfully verified by another provider branch when not WIP", verified_by_other_branch)
|
271
272
|
end
|
272
273
|
|
273
|
-
PactPublication.subtract(
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
)
|
274
|
+
remove_explicitly_specified_verifiable_pacts(PactPublication.subtract(
|
275
|
+
pact_publications_query.eager(*PUBLICATION_ASSOCIATIONS_FOR_EAGER_LOAD).all,
|
276
|
+
verified_by_this_branch.all,
|
277
|
+
verified_by_other_branch.all),
|
278
|
+
explicitly_specified_verifiable_pacts)
|
279
279
|
end
|
280
280
|
|
281
|
-
def remove_non_wip_for_tag(pact_publications_query, provider, tag,
|
282
|
-
specified_explicitly = pact_publications_query.for_pact_version_sha(specified_pact_version_shas)
|
281
|
+
def remove_non_wip_for_tag(pact_publications_query, provider, tag, explicitly_specified_verifiable_pacts)
|
283
282
|
verified_by_this_tag = pact_publications_query.successfully_verified_by_provider_tag_when_not_wip(tag)
|
284
283
|
verified_by_another_tag = pact_publications_query.successfully_verified_by_provider_another_tag_before_this_tag_first_created(provider.id, tag)
|
285
284
|
|
286
285
|
log_debug_for_wip do
|
287
|
-
log_pact_publications("Ignoring pacts explicitly specified in the selectors",
|
288
|
-
|
289
|
-
|
286
|
+
log_pact_publications("Ignoring pacts explicitly specified in the selectors", explicitly_specified_verifiable_pacts)
|
287
|
+
log_pact_publications_from_query("Ignoring pacts successfully verified by this provider tag when not WIP", verified_by_this_tag)
|
288
|
+
log_pact_publications_from_query("Ignoring pacts successfully verified by another provider tag when not WIP", verified_by_another_tag)
|
290
289
|
end
|
291
290
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
291
|
+
remove_explicitly_specified_verifiable_pacts(
|
292
|
+
PactPublication.subtract(
|
293
|
+
pact_publications_query.eager(*PUBLICATION_ASSOCIATIONS_FOR_EAGER_LOAD).all,
|
294
|
+
verified_by_this_tag.all,
|
295
|
+
verified_by_another_tag.all),
|
296
|
+
explicitly_specified_verifiable_pacts)
|
297
297
|
end
|
298
298
|
|
299
|
-
def
|
300
|
-
pact_publications
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
299
|
+
def remove_explicitly_specified_verifiable_pacts(pact_publications, explicitly_specified_verifiable_pacts)
|
300
|
+
pact_publications.reject do | pact_publication |
|
301
|
+
explicitly_specified_verifiable_pacts.find{ | explict_pact |
|
302
|
+
explict_pact.consumer.id == pact_publication.consumer_id &&
|
303
|
+
explict_pact.provider.id == pact_publication.provider_id &&
|
304
|
+
explict_pact.pact_version_sha == pact_publication.pact_version_sha
|
305
|
+
}
|
306
|
+
end
|
307
|
+
end
|
305
308
|
|
309
|
+
def collect_consumer_name_and_version_number(pact_publications)
|
306
310
|
pact_publications.collect do |p|
|
307
|
-
suffix = if p.values
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
+
suffix = if p.respond_to?(:values)
|
312
|
+
if p.values[:tag_name]
|
313
|
+
" (tag #{p.values[:tag_name]})"
|
314
|
+
elsif p.values[:branch_name]
|
315
|
+
" (branch #{p.values[:branch_name]})"
|
316
|
+
else
|
317
|
+
""
|
318
|
+
end
|
311
319
|
else
|
312
320
|
""
|
313
321
|
end
|
@@ -316,10 +324,28 @@ module PactBroker
|
|
316
324
|
end
|
317
325
|
end
|
318
326
|
|
319
|
-
def
|
320
|
-
|
327
|
+
def with_sorted_eager_fields(pact_publications_query)
|
328
|
+
pact_publications_query
|
329
|
+
.eager(:provider)
|
330
|
+
.eager(:consumer, :consumer_version)
|
331
|
+
.order(:consumer_version_order)
|
332
|
+
.all_forbidding_lazy_load
|
333
|
+
.sort
|
334
|
+
end
|
335
|
+
|
336
|
+
def log_pact_publications_from_query(message, pact_publications_query)
|
337
|
+
pact_publication_descriptions = collect_consumer_name_and_version_number(with_sorted_eager_fields(pact_publications_query))
|
338
|
+
if pact_publication_descriptions.any?
|
339
|
+
logger.debug("#{message}", pact_publication_descriptions)
|
340
|
+
else
|
341
|
+
logger.debug("#{message} (none)")
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def log_pact_publications(message, pact_publications)
|
346
|
+
pact_publication_descriptions = collect_consumer_name_and_version_number(pact_publications)
|
321
347
|
if pact_publication_descriptions.any?
|
322
|
-
logger.debug("#{message}",
|
348
|
+
logger.debug("#{message}", pact_publication_descriptions)
|
323
349
|
else
|
324
350
|
logger.debug("#{message} (none)")
|
325
351
|
end
|
@@ -333,5 +359,6 @@ module PactBroker
|
|
333
359
|
end
|
334
360
|
end
|
335
361
|
end
|
362
|
+
# rubocop: enable Metrics/ClassLength
|
336
363
|
end
|
337
364
|
end
|
@@ -158,8 +158,8 @@ module PactBroker
|
|
158
158
|
PactsForVerificationRepository.new.find(provider_name, consumer_version_selectors)
|
159
159
|
end
|
160
160
|
|
161
|
-
def find_wip_pact_versions_for_provider provider_name, provider_version_branch, provider_tags_names,
|
162
|
-
PactsForVerificationRepository.new.find_wip(provider_name, provider_version_branch, provider_tags_names,
|
161
|
+
def find_wip_pact_versions_for_provider provider_name, provider_version_branch, provider_tags_names, explicitly_specified_verifiable_pacts, options = {}
|
162
|
+
PactsForVerificationRepository.new.find_wip(provider_name, provider_version_branch, provider_tags_names, explicitly_specified_verifiable_pacts, options)
|
163
163
|
end
|
164
164
|
|
165
165
|
def find_pact_versions_for_provider provider_name, tag = nil
|
@@ -43,7 +43,7 @@ module PactBroker
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def delete params
|
46
|
-
logger.info
|
46
|
+
logger.info("Deleting pact version", params)
|
47
47
|
pacts = pact_repository.find_all_revisions(params[:consumer_name], params[:consumer_version_number], params[:provider_name])
|
48
48
|
webhook_service.delete_all_webhook_related_objects_by_pact_publication_ids(pacts.collect(&:id))
|
49
49
|
pact_repository.delete(params)
|
@@ -122,12 +122,11 @@ module PactBroker
|
|
122
122
|
.find_for_verification(provider_name, consumer_version_selectors)
|
123
123
|
.collect do | selected_pact |
|
124
124
|
# Todo move this into the repository
|
125
|
-
squash_pacts_for_verification(provider_version_tags, selected_pact, options[:include_pending_status])
|
125
|
+
squash_pacts_for_verification(provider_version_tags, provider_version_branch, selected_pact, options[:include_pending_status])
|
126
126
|
end
|
127
127
|
|
128
128
|
verifiable_wip_pacts = if options[:include_wip_pacts_since]
|
129
|
-
|
130
|
-
pact_repository.find_wip_pact_versions_for_provider(provider_name, provider_version_branch, provider_version_tags, specified_pact_version_shas, options)
|
129
|
+
pact_repository.find_wip_pact_versions_for_provider(provider_name, provider_version_branch, provider_version_tags, explicitly_specified_verifiable_pacts, options)
|
131
130
|
else
|
132
131
|
[]
|
133
132
|
end
|
@@ -156,8 +155,8 @@ module PactBroker
|
|
156
155
|
|
157
156
|
# Overwriting an existing pact with the same consumer/provider/consumer version number
|
158
157
|
def create_pact_revision params, existing_pact
|
159
|
-
logger.info
|
160
|
-
logger.debug
|
158
|
+
logger.info("Updating existing pact publication", params.without(:json_content))
|
159
|
+
logger.debug("Content #{params[:json_content]}")
|
161
160
|
pact_version_sha = generate_sha(params[:json_content])
|
162
161
|
json_content = add_interaction_ids(params[:json_content])
|
163
162
|
update_params = { pact_version_sha: pact_version_sha, json_content: json_content }
|
@@ -185,8 +184,8 @@ module PactBroker
|
|
185
184
|
|
186
185
|
# When no publication for the given consumer/provider/consumer version number exists
|
187
186
|
def create_pact params, version, provider
|
188
|
-
logger.info
|
189
|
-
logger.debug
|
187
|
+
logger.info("Creating new pact publication", params.without(:json_content))
|
188
|
+
logger.debug("Content #{params[:json_content]}")
|
190
189
|
pact_version_sha = generate_sha(params[:json_content])
|
191
190
|
json_content = add_interaction_ids(params[:json_content])
|
192
191
|
pact = pact_repository.create(
|
@@ -5,17 +5,19 @@
|
|
5
5
|
module PactBroker
|
6
6
|
module Pacts
|
7
7
|
module SquashPactsForVerification
|
8
|
-
def self.call(provider_version_tags, selected_pact, include_pending_status = false)
|
8
|
+
def self.call(provider_version_tags, provider_version_branch, selected_pact, include_pending_status = false)
|
9
9
|
domain_pact = selected_pact.pact
|
10
10
|
|
11
11
|
if include_pending_status
|
12
12
|
pending_provider_tags = []
|
13
13
|
pending = nil
|
14
|
-
if
|
14
|
+
if provider_version_branch
|
15
|
+
pending = domain_pact.pending_for_provider_branch?(provider_version_branch)
|
16
|
+
elsif provider_version_tags.any?
|
15
17
|
pending_provider_tags = domain_pact.select_pending_provider_version_tags(provider_version_tags)
|
16
18
|
pending = pending_provider_tags.any?
|
17
19
|
else
|
18
|
-
pending = domain_pact.
|
20
|
+
pending = domain_pact.pending_for_any_provider_branch?
|
19
21
|
end
|
20
22
|
non_pending_provider_tags = provider_version_tags - pending_provider_tags
|
21
23
|
VerifiablePact.new(
|
@@ -23,7 +25,8 @@ module PactBroker
|
|
23
25
|
selected_pact.selectors,
|
24
26
|
pending,
|
25
27
|
pending_provider_tags,
|
26
|
-
non_pending_provider_tags
|
28
|
+
non_pending_provider_tags,
|
29
|
+
provider_version_branch
|
27
30
|
)
|
28
31
|
else
|
29
32
|
VerifiablePact.new(
|
@@ -63,7 +63,7 @@ module PactBroker
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def output string, payload = {}
|
66
|
-
logger ? logger.info(string, payload
|
66
|
+
logger ? logger.info(string, payload) : puts("#{string} #{payload.to_json}")
|
67
67
|
end
|
68
68
|
|
69
69
|
def add_defaults_to_keep_selectors
|
@@ -265,7 +265,9 @@ module PactBroker
|
|
265
265
|
"request" => {
|
266
266
|
"method" => "POST",
|
267
267
|
"url" => url,
|
268
|
-
"body" => body || default_body
|
268
|
+
"body" => body || default_body,
|
269
|
+
"username" => "user",
|
270
|
+
"password" => "pass"
|
269
271
|
}
|
270
272
|
}.compact
|
271
273
|
path = "webhooks/#{uuid}"
|
@@ -286,32 +288,9 @@ module PactBroker
|
|
286
288
|
def create_global_webhook_for_anything_published(uuid: nil, url: "https://postman-echo.com/post")
|
287
289
|
puts "Creating global webhook for contract changed event with uuid #{uuid}"
|
288
290
|
uuid ||= SecureRandom.uuid
|
289
|
-
|
290
|
-
"description" => "A webhook for all consumers and providers",
|
291
|
-
"events" => [{
|
292
|
-
"name" => "contract_published"
|
293
|
-
},{
|
294
|
-
"name" => "provider_verification_published"
|
295
|
-
}],
|
296
|
-
"request" => {
|
297
|
-
"method" => "POST",
|
298
|
-
"url" => url,
|
299
|
-
"headers" => { "Content-Type" => "application/json"},
|
300
|
-
"body" => {
|
301
|
-
"eventName" => "${pactbroker.eventName}",
|
302
|
-
"consumerVersionNumber" => "${pactbroker.consumerVersionNumber}",
|
303
|
-
"consumerVersionTags" => "${pactbroker.consumerVersionTags}",
|
304
|
-
"consumerVersionBranch" => "${pactbroker.consumerVersionBranch}",
|
305
|
-
"githubVerificationStatus" => "${pactbroker.githubVerificationStatus}",
|
306
|
-
"providerVersionNumber" => "${pactbroker.providerVersionNumber}",
|
307
|
-
"providerVersionTags" => "${pactbroker.providerVersionTags}",
|
308
|
-
"providerVersionBranch" => "${pactbroker.providerVersionBranch}",
|
309
|
-
"canIMerge" => "${pactbroker.providerMainBranchGithubVerificationStatus}"
|
310
|
-
}
|
311
|
-
}
|
312
|
-
}
|
291
|
+
|
313
292
|
path = "webhooks/#{uuid}"
|
314
|
-
client.put(path,
|
293
|
+
client.put(path, webhook_body_with_all_parameters(url).to_json).tap { |response| check_for_error(response) }
|
315
294
|
separate
|
316
295
|
self
|
317
296
|
end
|
@@ -438,6 +417,35 @@ module PactBroker
|
|
438
417
|
puts response.body
|
439
418
|
end
|
440
419
|
end
|
420
|
+
|
421
|
+
def webhook_body_with_all_parameters(url)
|
422
|
+
{
|
423
|
+
"description" => "A webhook for all consumers and providers",
|
424
|
+
"events" => [{
|
425
|
+
"name" => "contract_published"
|
426
|
+
},{
|
427
|
+
"name" => "provider_verification_published"
|
428
|
+
}],
|
429
|
+
"request" => {
|
430
|
+
"method" => "POST",
|
431
|
+
"url" => url,
|
432
|
+
"headers" => { "Content-Type" => "application/json"},
|
433
|
+
"username" => "user",
|
434
|
+
"password" => "pass",
|
435
|
+
"body" => {
|
436
|
+
"eventName" => "${pactbroker.eventName}",
|
437
|
+
"consumerVersionNumber" => "${pactbroker.consumerVersionNumber}",
|
438
|
+
"consumerVersionTags" => "${pactbroker.consumerVersionTags}",
|
439
|
+
"consumerVersionBranch" => "${pactbroker.consumerVersionBranch}",
|
440
|
+
"githubVerificationStatus" => "${pactbroker.githubVerificationStatus}",
|
441
|
+
"providerVersionNumber" => "${pactbroker.providerVersionNumber}",
|
442
|
+
"providerVersionTags" => "${pactbroker.providerVersionTags}",
|
443
|
+
"providerVersionBranch" => "${pactbroker.providerVersionBranch}",
|
444
|
+
"canIMerge" => "${pactbroker.providerMainBranchGithubVerificationStatus}"
|
445
|
+
}
|
446
|
+
}
|
447
|
+
}
|
448
|
+
end
|
441
449
|
end
|
442
450
|
end
|
443
451
|
end
|
@@ -399,22 +399,13 @@ module PactBroker
|
|
399
399
|
verification = PactBroker::Domain::Verification.new(parameters)
|
400
400
|
pact_version = PactBroker::Pacts::Repository.new.find_pact_version(@consumer, @provider, pact.pact_version_sha)
|
401
401
|
@provider_version = version_repository.find_by_pacticipant_id_and_number_or_create(provider.id, provider_version_number)
|
402
|
-
PactBroker::Versions::BranchVersionRepository.new.add_branch(@provider_version, branch) if branch
|
402
|
+
branch_version = PactBroker::Versions::BranchVersionRepository.new.add_branch(@provider_version, branch) if branch
|
403
403
|
|
404
|
-
|
405
|
-
tag_names.each do | tag_name |
|
406
|
-
PactBroker::Domain::Tag.new(name: tag_name, version: @provider_version, version_order: @provider_version.order).insert_ignore
|
407
|
-
set_created_at_if_set(parameters[:created_at], :tags, version_id: @provider_version.id, name: tag_name)
|
408
|
-
end
|
409
|
-
end
|
404
|
+
set_created_at_for_provider_tags(parameters, tag_names)
|
410
405
|
|
411
406
|
@verification = PactBroker::Verifications::Repository.new.create(verification, provider_version_number, pact_version)
|
412
407
|
|
413
|
-
|
414
|
-
set_created_at_if_set(parameters[:created_at], :versions, id: @provider_version.id)
|
415
|
-
set_created_at_if_set(parameters[:created_at], :latest_verification_id_for_pact_version_and_provider_version, pact_version_id: pact_version_id, provider_version_id: @provider_version.id)
|
416
|
-
set_created_at_if_set(parameters[:created_at], :pact_version_provider_tag_successful_verifications, { verification_id: @verification.id }, :execution_date)
|
417
|
-
|
408
|
+
set_created_at_for_verification_resources(parameters, pact_version.id, branch, branch_version)
|
418
409
|
self
|
419
410
|
end
|
420
411
|
|
@@ -674,6 +665,31 @@ module PactBroker
|
|
674
665
|
[nil, Domain::WebhookPacticipant.new(label: label)]
|
675
666
|
end
|
676
667
|
end
|
668
|
+
|
669
|
+
def set_created_at_for_provider_tags(parameters, tag_names)
|
670
|
+
if tag_names.any?
|
671
|
+
tag_names.each do | tag_name |
|
672
|
+
PactBroker::Domain::Tag.new(name: tag_name, version: @provider_version, version_order: @provider_version.order).insert_ignore
|
673
|
+
set_created_at_if_set(parameters[:created_at], :tags, version_id: @provider_version.id, name: tag_name)
|
674
|
+
end
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
def set_created_at_for_verification_resources(parameters, pact_version_id, branch, branch_version)
|
679
|
+
if branch
|
680
|
+
set_created_at_if_set(parameters[:created_at], :branch_versions, id: branch_version.id)
|
681
|
+
|
682
|
+
# if the branch has just been created...
|
683
|
+
if branch_version.branch.branch_versions.size == 1
|
684
|
+
set_created_at_if_set(parameters[:created_at], :branches, id: branch_version.branch.id)
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
set_created_at_if_set(parameters[:created_at], :verifications, id: @verification.id)
|
689
|
+
set_created_at_if_set(parameters[:created_at], :versions, id: @provider_version.id)
|
690
|
+
set_created_at_if_set(parameters[:created_at], :latest_verification_id_for_pact_version_and_provider_version, pact_version_id: pact_version_id, provider_version_id: @provider_version.id)
|
691
|
+
set_created_at_if_set(parameters[:created_at], :pact_version_provider_tag_successful_verifications, { verification_id: @verification.id }, :execution_date)
|
692
|
+
end
|
677
693
|
end
|
678
694
|
end
|
679
695
|
end
|
@@ -33,7 +33,7 @@ module PactBroker
|
|
33
33
|
# verified_pacts is an array of SelectedPact objects
|
34
34
|
def create next_verification_number, params, verified_pacts, event_context
|
35
35
|
first_verified_pact = verified_pacts.first
|
36
|
-
logger.info
|
36
|
+
logger.info("Creating verification #{next_verification_number} for pact_version_sha=#{first_verified_pact.pact_version_sha}", params.without("testResults"))
|
37
37
|
verification = PactBroker::Domain::Verification.new
|
38
38
|
provider_version_number = params.fetch("providerApplicationVersion")
|
39
39
|
PactBroker::Api::Decorators::VerificationDecorator.new(verification).from_hash(params)
|
data/lib/pact_broker/version.rb
CHANGED
@@ -8,6 +8,7 @@ module PactBroker
|
|
8
8
|
plugin :insert_ignore, identifying_columns: [:name, :pacticipant_id]
|
9
9
|
|
10
10
|
associate(:many_to_one, :pacticipant, :class => "PactBroker::Domain::Pacticipant", :key => :pacticipant_id, :primary_key => :id)
|
11
|
+
associate(:one_to_many, :branch_versions, :class => "PactBroker::Versions::BranchVersion", :key => :branch_id, :primary_key => :id)
|
11
12
|
|
12
13
|
dataset_module do
|
13
14
|
include PactBroker::Repositories::Helpers
|
@@ -53,10 +53,10 @@ module PactBroker
|
|
53
53
|
|
54
54
|
def log_detected_event
|
55
55
|
event = detected_events.last
|
56
|
-
logger.debug
|
56
|
+
logger.debug("Event detected", event_name: event.name, event_comment: event.comment)
|
57
57
|
if event.triggered_webhooks&.any?
|
58
58
|
triggered_webhook_descriptions = event.triggered_webhooks.collect{ |tw| { event_name: event.name, webhook_uuid: tw.webhook_uuid, triggered_webhook_uuid: tw.uuid, webhook_description: tw.webhook.description } }
|
59
|
-
logger.info
|
59
|
+
logger.info("Triggered webhooks for #{event.name}", triggered_webhooks: triggered_webhook_descriptions)
|
60
60
|
else
|
61
61
|
logger.debug "No enabled webhooks found for event #{event.name}"
|
62
62
|
end
|
@@ -25,6 +25,10 @@ module PactBroker
|
|
25
25
|
with_updated_attribute(logging_options: { failure_log_message: value })
|
26
26
|
end
|
27
27
|
|
28
|
+
def with_redact_sensitive_data(value)
|
29
|
+
with_updated_attribute(logging_options: { redact_sensitive_data: value })
|
30
|
+
end
|
31
|
+
|
28
32
|
def with_retry_schedule(value)
|
29
33
|
with_updated_attribute(retry_schedule: value)
|
30
34
|
end
|
@@ -10,6 +10,7 @@ module PactBroker
|
|
10
10
|
def self.call(resource)
|
11
11
|
PactBroker::Webhooks::ExecutionConfiguration.new
|
12
12
|
.with_show_response(PactBroker.configuration.show_webhook_response?)
|
13
|
+
.with_redact_sensitive_data(PactBroker.configuration.webhook_redact_sensitive_data)
|
13
14
|
.with_retry_schedule(PactBroker.configuration.webhook_retry_schedule)
|
14
15
|
.with_http_success_codes(PactBroker.configuration.webhook_http_code_success)
|
15
16
|
.with_user_agent(PactBroker.configuration.user_agent)
|
@@ -51,7 +51,7 @@ module PactBroker
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def log_request(webhook_request)
|
54
|
-
http_request = HttpRequestWithRedactedHeaders.new(webhook_request.http_request)
|
54
|
+
http_request = options[:redact_sensitive_data] ? HttpRequestWithRedactedHeaders.new(webhook_request.http_request) : webhook_request.http_request
|
55
55
|
logger.info "Making webhook #{webhook_request.uuid} request #{http_request.method.upcase} URI=#{webhook_request.url} (headers and body in debug logs)"
|
56
56
|
logger.debug "Webhook #{webhook_request.uuid} request headers=#{http_request.to_hash}"
|
57
57
|
logger.debug "Webhook #{webhook_request.uuid} request body=#{http_request.body}"
|
data/pact_broker.gemspec
CHANGED
@@ -78,7 +78,7 @@ Gem::Specification.new do |gem|
|
|
78
78
|
gem.add_runtime_dependency "dry-types", "~> 0.10.3" # https://travis-ci.org/pact-foundation/pact_broker/jobs/249448621
|
79
79
|
gem.add_runtime_dependency "dry-logic", "0.4.2" # Later version cases ArgumentError: wrong number of arguments
|
80
80
|
gem.add_runtime_dependency "table_print", "~> 1.5"
|
81
|
-
gem.add_runtime_dependency "semantic_logger", "~> 4.
|
81
|
+
gem.add_runtime_dependency "semantic_logger", "~> 4.11"
|
82
82
|
gem.add_runtime_dependency "sanitize", "6.0"
|
83
83
|
gem.add_runtime_dependency "wisper", "~> 2.0"
|
84
84
|
gem.add_runtime_dependency "anyway_config", "~> 2.1"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact_broker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.105.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bethany Skurrie
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-10-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -334,14 +334,14 @@ dependencies:
|
|
334
334
|
requirements:
|
335
335
|
- - "~>"
|
336
336
|
- !ruby/object:Gem::Version
|
337
|
-
version: '4.
|
337
|
+
version: '4.11'
|
338
338
|
type: :runtime
|
339
339
|
prerelease: false
|
340
340
|
version_requirements: !ruby/object:Gem::Requirement
|
341
341
|
requirements:
|
342
342
|
- - "~>"
|
343
343
|
- !ruby/object:Gem::Version
|
344
|
-
version: '4.
|
344
|
+
version: '4.11'
|
345
345
|
- !ruby/object:Gem::Dependency
|
346
346
|
name: sanitize
|
347
347
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1227,7 +1227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1227
1227
|
- !ruby/object:Gem::Version
|
1228
1228
|
version: '0'
|
1229
1229
|
requirements: []
|
1230
|
-
rubygems_version: 3.3.
|
1230
|
+
rubygems_version: 3.3.24
|
1231
1231
|
signing_key:
|
1232
1232
|
specification_version: 4
|
1233
1233
|
summary: See description
|