pact_broker 2.45.0 → 2.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +0 -13
- data/CHANGELOG.md +21 -0
- data/lib/db.rb +7 -1
- data/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +1 -1
- data/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +1 -1
- data/lib/pact_broker/api/decorators/triggered_webhook_decorator.rb +9 -1
- data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +24 -16
- data/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +1 -1
- data/lib/pact_broker/api/resources/base_resource.rb +1 -1
- data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +1 -1
- data/lib/pact_broker/app.rb +7 -2
- data/lib/pact_broker/configuration.rb +1 -5
- data/lib/pact_broker/matrix/repository.rb +2 -2
- data/lib/pact_broker/pacts/pact_publication.rb +53 -0
- data/lib/pact_broker/pacts/pact_version.rb +16 -6
- data/lib/pact_broker/pacts/repository.rb +81 -27
- data/lib/pact_broker/pacts/verifiable_pact_messages.rb +30 -0
- data/lib/pact_broker/repositories/helpers.rb +4 -0
- data/lib/pact_broker/test/test_data_builder.rb +4 -0
- data/lib/pact_broker/version.rb +1 -1
- data/pact_broker.gemspec +1 -1
- data/script/generate-certificates-for-webooks-certificate-spec.rb +8 -0
- data/script/release.sh +4 -3
- data/script/seed-for-webhook-test.rb +59 -0
- data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +1 -1
- data/spec/lib/pact_broker/api/contracts/verifiable_pacts_query_schema_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/triggered_webhook_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/verifiable_pact_decorator_spec.rb +24 -2
- data/spec/lib/pact_broker/api/resources/base_resource_spec.rb +23 -1
- data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +55 -12
- data/spec/support/verification_job.rb +2 -0
- metadata +5 -5
- data/lib/rack/pact_broker/store_base_url.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4afa0b6a3444f1fdf6ea852bed8016f63cccd1a5373aa0903be0d206f528bc6
|
4
|
+
data.tar.gz: cd86a0d032bb39ffe2f4318116cc9e51886fc3d3e84bf8c537d6bae5ee0f9d52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 217a6da9c4b27d6959695eefa1c6b8c13526c827222d114cb6527d20fc9fceec194498ffa84ee6f10e574f96a353429bfdacf18f6b6494826e12aea5d58fc7ba
|
7
|
+
data.tar.gz: 1632aac1111449205a45ca9367093d2e4557e75a163a8c516248486f7a7e884cbf9205302ba8c5e1f4c01c8ff604bbebdaeef6729a1bc03e9dd97ec7f0afa850
|
data/.travis.yml
CHANGED
@@ -27,16 +27,3 @@ script:
|
|
27
27
|
- bundle exec rake
|
28
28
|
- if [ "$DATABASE_ADAPTER" == "postgres" ]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT || true; fi
|
29
29
|
# - if [ ! -z "$(ruby --version | grep '2\.4\.')" ]; then ./script/db-spec.sh; fi
|
30
|
-
jobs:
|
31
|
-
include:
|
32
|
-
- stage: gem release
|
33
|
-
before_script: echo ""
|
34
|
-
script: echo "Deploying to rubygems.org ..."
|
35
|
-
deploy:
|
36
|
-
provider: rubygems
|
37
|
-
api_key:
|
38
|
-
secure: AzTHDbKRr1ZO4E2mRyvU054Tx8c2cZbKkoDBZjSAQ2CY3E7oH137NTAIGd4BthH/E9mbEXtGpZIDfWPbaOcUJQ5Bz24CWTKmGyic6FrPhJnOW5CKVSLGCDPzpmqHULv/GTN16YN0Dh1HLeGYZzlHlxT0+4AVvbvBAleHrAFeJs8=
|
39
|
-
gem: pact_broker
|
40
|
-
on:
|
41
|
-
tags: true
|
42
|
-
repo: pact-foundation/pact_broker
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
<a name="v2.46.0"></a>
|
2
|
+
### v2.46.0 (2020-01-30)
|
3
|
+
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* allow the base URL of the application to be set for the API ([73bd4c44](/../../commit/73bd4c44))
|
8
|
+
* correct logs relation to pb:logs in the triggered webhooks resource ([89ea1a58](/../../commit/89ea1a58))
|
9
|
+
|
10
|
+
* **pacts for verification**
|
11
|
+
* add pre and post verification messages that can be displayed to the user based on whether or not the verification has passed or failed ([bb079858](/../../commit/bb079858))
|
12
|
+
* allow all versions for a particular tag to be verified (eg. all prod versions of a mobile consumer) ([e16feef6](/../../commit/e16feef6))
|
13
|
+
* optimise queries for determining which provider version tags are pending ([b4e1461a](/../../commit/b4e1461a))
|
14
|
+
|
15
|
+
|
16
|
+
#### Bug Fixes
|
17
|
+
|
18
|
+
* **pacts for verification**
|
19
|
+
* set includePendingStatus to false by default ([9b3162ac](/../../commit/9b3162ac))
|
20
|
+
|
21
|
+
|
1
22
|
<a name="v2.45.0"></a>
|
2
23
|
### v2.45.0 (2020-01-30)
|
3
24
|
|
data/lib/db.rb
CHANGED
@@ -25,11 +25,17 @@ module DB
|
|
25
25
|
# pool, as noted in the documentation for the extension.
|
26
26
|
#
|
27
27
|
def self.connect db_credentials
|
28
|
+
# Keep this conifiguration in sync with lib/pact_broker/app.rb#configure_database_connection
|
28
29
|
Sequel.datetime_class = DateTime
|
29
30
|
# logger = Logger.new($stdout)
|
30
31
|
con = Sequel.connect(db_credentials.merge(:logger => logger, :pool_class => Sequel::ThreadedConnectionPool, :encoding => 'utf8'))
|
31
32
|
con.extension(:connection_validator)
|
32
33
|
con.extension(:pagination)
|
34
|
+
con.extend_datasets do
|
35
|
+
def any?
|
36
|
+
!empty?
|
37
|
+
end
|
38
|
+
end
|
33
39
|
con.pool.connection_validation_timeout = -1 #Check the connection on every request
|
34
40
|
con.timezone = :utc
|
35
41
|
con.run("SET sql_mode='STRICT_TRANS_TABLES';") if db_credentials[:adapter].to_s =~ /mysql/
|
@@ -49,7 +55,7 @@ module DB
|
|
49
55
|
end
|
50
56
|
|
51
57
|
def self.mysql?
|
52
|
-
PACT_BROKER_DB.adapter_scheme.to_s =~ /mysql/
|
58
|
+
!!(PACT_BROKER_DB.adapter_scheme.to_s =~ /mysql/)
|
53
59
|
end
|
54
60
|
|
55
61
|
PACT_BROKER_DB ||= connection_for_env ENV.fetch('RACK_ENV')
|
@@ -18,7 +18,7 @@ module PactBroker
|
|
18
18
|
optional(:consumerVersionSelectors).each do
|
19
19
|
schema do
|
20
20
|
required(:tag).filled(:str?)
|
21
|
-
|
21
|
+
optional(:latest).filled(included_in?: [true, false])
|
22
22
|
end
|
23
23
|
end
|
24
24
|
optional(:includePendingStatus).filled(included_in?: [true, false])
|
@@ -17,7 +17,7 @@ module PactBroker
|
|
17
17
|
optional(:consumer_version_selectors).each do
|
18
18
|
schema do
|
19
19
|
required(:tag).filled(:str?)
|
20
|
-
|
20
|
+
optional(:latest).filled(included_in?: ["true", "false"])
|
21
21
|
end
|
22
22
|
end
|
23
23
|
optional(:include_pending_status).filled(included_in?: ["true", "false"])
|
@@ -12,7 +12,7 @@ module PactBroker
|
|
12
12
|
|
13
13
|
property :created_at, as: :triggeredAt
|
14
14
|
|
15
|
-
link :logs do | context |
|
15
|
+
link :'pb:logs' do | context |
|
16
16
|
{
|
17
17
|
href: triggered_webhook_logs_url(represented, context[:base_url]),
|
18
18
|
title: "Webhook execution logs",
|
@@ -20,6 +20,14 @@ module PactBroker
|
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
+
link :logs do | context |
|
24
|
+
{
|
25
|
+
href: triggered_webhook_logs_url(represented, context[:base_url]),
|
26
|
+
title: "DEPRECATED - Use pb:logs",
|
27
|
+
name: represented.request_description
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
23
31
|
link :'pb:webhook' do | context |
|
24
32
|
{
|
25
33
|
href: webhook_url(represented.webhook_uuid, context[:base_url]),
|
@@ -30,25 +30,33 @@ module PactBroker
|
|
30
30
|
property :notices, getter: -> (context) { context[:decorator].notices(context[:options][:user_options]) }
|
31
31
|
property :noteToDevelopers, getter: -> (_) { "Please print out the text from the 'notices' rather than using the inclusionReason and the pendingReason fields. These will be removed when this API moves out of beta."}
|
32
32
|
|
33
|
-
def inclusion_reason(pact_url)
|
34
|
-
PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url).inclusion_reason
|
35
|
-
end
|
36
|
-
|
37
|
-
def pending_reason(pact_url)
|
38
|
-
PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url).pending_reason
|
39
|
-
end
|
40
|
-
|
41
33
|
def notices(user_options)
|
34
|
+
# TODO move this out of the decorator
|
42
35
|
pact_url = pact_version_url(represented, user_options[:base_url])
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
messages = PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url)
|
37
|
+
|
38
|
+
the_notices = [{
|
39
|
+
when: 'before_verification',
|
40
|
+
text: messages.inclusion_reason
|
46
41
|
}]
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
42
|
+
|
43
|
+
if user_options[:include_pending_status]
|
44
|
+
append_notice(the_notices, 'before_verification', messages.pending_reason)
|
45
|
+
append_notice(the_notices, 'after_verification:success_true_published_false', messages.verification_success_true_published_false)
|
46
|
+
append_notice(the_notices, 'after_verification:success_false_published_false', messages.verification_success_false_published_false)
|
47
|
+
append_notice(the_notices, 'after_verification:success_true_published_true', messages.verification_success_true_published_true)
|
48
|
+
append_notice(the_notices, 'after_verification:success_false_published_true', messages.verification_success_false_published_true)
|
49
|
+
end
|
50
|
+
the_notices
|
51
|
+
end
|
52
|
+
|
53
|
+
def append_notice the_notices, the_when, text
|
54
|
+
if text
|
55
|
+
the_notices << {
|
56
|
+
when: the_when,
|
57
|
+
text: text
|
58
|
+
}
|
59
|
+
end
|
52
60
|
end
|
53
61
|
end
|
54
62
|
|
@@ -19,7 +19,7 @@ module PactBroker
|
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
22
|
-
property :include_pending_status, default:
|
22
|
+
property :include_pending_status, default: false,
|
23
23
|
setter: ->(fragment:, represented:, **) {
|
24
24
|
represented.include_pending_status = (fragment == 'true' || fragment == true)
|
25
25
|
}
|
@@ -26,7 +26,7 @@ module PactBroker
|
|
26
26
|
|
27
27
|
def triggered_webhook
|
28
28
|
@triggered_webhook ||= begin
|
29
|
-
criteria = {webhook_uuid: identifier_from_path[:uuid], trigger_uuid: identifier_from_path[:trigger_uuid]}
|
29
|
+
criteria = { webhook_uuid: identifier_from_path[:uuid], trigger_uuid: identifier_from_path[:trigger_uuid] }
|
30
30
|
PactBroker::Webhooks::TriggeredWebhook.where(criteria).single_record
|
31
31
|
end
|
32
32
|
end
|
data/lib/pact_broker/app.rb
CHANGED
@@ -4,7 +4,6 @@ require 'pact_broker/project_root'
|
|
4
4
|
require 'pact_broker/logging/default_formatter'
|
5
5
|
require 'rack-protection'
|
6
6
|
require 'rack/hal_browser'
|
7
|
-
require 'rack/pact_broker/store_base_url'
|
8
7
|
require 'rack/pact_broker/add_pact_broker_version_header'
|
9
8
|
require 'rack/pact_broker/convert_file_extension_to_accept_header'
|
10
9
|
require 'rack/pact_broker/database_transaction'
|
@@ -106,11 +105,18 @@ module PactBroker
|
|
106
105
|
end
|
107
106
|
|
108
107
|
def configure_database_connection
|
108
|
+
# Keep this configuration in sync with lib/db.rb
|
109
109
|
PactBroker::DB.connection = configuration.database_connection
|
110
110
|
PactBroker::DB.connection.timezone = :utc
|
111
|
+
PactBroker::DB.connection.extend_datasets do
|
112
|
+
def any?
|
113
|
+
!empty?
|
114
|
+
end
|
115
|
+
end
|
111
116
|
PactBroker::DB.validate_connection_config if configuration.validate_database_connection_config
|
112
117
|
PactBroker::DB.set_mysql_strict_mode_if_mysql
|
113
118
|
PactBroker::DB.connection.extension(:pagination)
|
119
|
+
|
114
120
|
Sequel.datetime_class = DateTime
|
115
121
|
Sequel.database_timezone = :utc # Store all dates in UTC, assume any date without a TZ is UTC
|
116
122
|
Sequel.application_timezone = :local # Convert dates to localtime when retrieving from database
|
@@ -152,7 +158,6 @@ module PactBroker
|
|
152
158
|
end
|
153
159
|
@app_builder.use Rack::PactBroker::InvalidUriProtection
|
154
160
|
@app_builder.use Rack::PactBroker::ResetThreadData
|
155
|
-
@app_builder.use Rack::PactBroker::StoreBaseURL
|
156
161
|
@app_builder.use Rack::PactBroker::AddPactBrokerVersionHeader
|
157
162
|
@app_builder.use Rack::PactBroker::AddVaryHeader
|
158
163
|
@app_builder.use Rack::Static, :urls => ["/stylesheets", "/css", "/fonts", "/js", "/javascripts", "/images"], :root => PactBroker.project_root.join("public")
|
@@ -33,7 +33,7 @@ module PactBroker
|
|
33
33
|
:seed_example_data
|
34
34
|
]
|
35
35
|
|
36
|
-
attr_accessor :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :example_data_seeder, :seed_example_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection
|
36
|
+
attr_accessor :base_url, :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :example_data_seeder, :seed_example_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection
|
37
37
|
attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser, :sha_generator
|
38
38
|
attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
|
39
39
|
attr_accessor :check_for_potential_duplicate_pacticipant_names
|
@@ -176,10 +176,6 @@ module PactBroker
|
|
176
176
|
self.enable_public_badge_access = enable_badge_resources
|
177
177
|
end
|
178
178
|
|
179
|
-
def base_url
|
180
|
-
ENV['PACT_BROKER_BASE_URL']
|
181
|
-
end
|
182
|
-
|
183
179
|
def save_to_database
|
184
180
|
# Can't require a Sequel::Model class before the connection has been set
|
185
181
|
require 'pact_broker/config/save'
|
@@ -97,9 +97,9 @@ module PactBroker
|
|
97
97
|
|
98
98
|
private
|
99
99
|
|
100
|
-
# If
|
100
|
+
# If a specified pacticipant is a consumer, then its provider is required to be deployed
|
101
101
|
# to the same environment before the consumer can be deployed.
|
102
|
-
# If
|
102
|
+
# If a specified pacticipant is a provider only, then it may be deployed
|
103
103
|
# without the consumer being present.
|
104
104
|
def is_a_row_for_this_integration_required?(specified_pacticipant_names, consumer_name)
|
105
105
|
specified_pacticipant_names.include?(consumer_name)
|
@@ -25,10 +25,63 @@ module PactBroker
|
|
25
25
|
dataset_module do
|
26
26
|
include PactBroker::Repositories::Helpers
|
27
27
|
|
28
|
+
def remove_overridden_revisions
|
29
|
+
join(:latest_pact_publication_ids_for_consumer_versions, { Sequel[:lp][:pact_publication_id] => Sequel[:pact_publications][:id] }, { table_alias: :lp})
|
30
|
+
end
|
31
|
+
|
32
|
+
def join_consumer_versions(table_alias = :cv)
|
33
|
+
join(:versions, { Sequel[:pact_publications][:consumer_version_id] => Sequel[table_alias][:id] }, { table_alias: table_alias })
|
34
|
+
end
|
35
|
+
|
36
|
+
def join_consumer_version_tags(table_alias = :ct)
|
37
|
+
join(:tags, { Sequel[table_alias][:version_id] => Sequel[:pact_publications][:consumer_version_id]}, { table_alias: table_alias })
|
38
|
+
end
|
39
|
+
|
40
|
+
def join_consumer_version_tags_with_names(consumer_version_tag_names)
|
41
|
+
join(:tags, {
|
42
|
+
Sequel[:ct][:version_id] => Sequel[:pact_publications][:consumer_version_id],
|
43
|
+
Sequel[:ct][:name] => consumer_version_tag_names
|
44
|
+
}, {
|
45
|
+
table_alias: :ct
|
46
|
+
})
|
47
|
+
end
|
48
|
+
|
49
|
+
def join_providers(table_alias = :providers)
|
50
|
+
join(:pacticipants, { Sequel[:pact_publications][:provider_id] => Sequel[table_alias][:id] }, { table_alias: table_alias })
|
51
|
+
end
|
52
|
+
|
53
|
+
def join_consumers(table_alias = :consumers)
|
54
|
+
join(:pacticipants, { Sequel[:pact_publications][:consumer_id] => Sequel[table_alias][:id] }, { table_alias: table_alias })
|
55
|
+
end
|
56
|
+
|
57
|
+
def join_pact_versions
|
58
|
+
join(:pact_versions, { Sequel[:pact_publications][:pact_version_id] => Sequel[:pact_versions][:id] })
|
59
|
+
end
|
60
|
+
|
61
|
+
def eager_load_pact_versions
|
62
|
+
eager(:pact_versions)
|
63
|
+
end
|
64
|
+
|
28
65
|
def tag tag_name
|
29
66
|
filter = name_like(Sequel.qualify(:tags, :name), tag_name)
|
30
67
|
join(:tags, {version_id: :consumer_version_id}).where(filter)
|
31
68
|
end
|
69
|
+
|
70
|
+
def provider_name_like(name)
|
71
|
+
where(name_like(Sequel[:providers][:name], name))
|
72
|
+
end
|
73
|
+
|
74
|
+
def consumer_version_tag(tag)
|
75
|
+
where(Sequel[:ct][:name] => tag)
|
76
|
+
end
|
77
|
+
|
78
|
+
def order_by_consumer_name
|
79
|
+
order_append_ignore_case(Sequel[:consumers][:name])
|
80
|
+
end
|
81
|
+
|
82
|
+
def order_by_consumer_version_order
|
83
|
+
order_append(Sequel[:cv][:order])
|
84
|
+
end
|
32
85
|
end
|
33
86
|
|
34
87
|
def before_create
|
@@ -52,21 +52,31 @@ module PactBroker
|
|
52
52
|
|
53
53
|
def select_provider_tags_with_successful_verifications(tags)
|
54
54
|
tags.select do | tag |
|
55
|
+
verifications_join = {
|
56
|
+
Sequel[:verifications][:pact_version_id] => Sequel[:pact_versions][:id],
|
57
|
+
Sequel[:verifications][:success] => true
|
58
|
+
}
|
59
|
+
tags_join = {
|
60
|
+
Sequel[:tags][:version_id] => Sequel[:versions][:id],
|
61
|
+
Sequel[:tags][:name] => tag
|
62
|
+
}
|
55
63
|
PactVersion.where(Sequel[:pact_versions][:id] => id)
|
56
|
-
.join(:verifications,
|
64
|
+
.join(:verifications, verifications_join)
|
57
65
|
.join(:versions, Sequel[:versions][:id] => Sequel[:verifications][:provider_version_id])
|
58
|
-
.join(:tags,
|
59
|
-
.where(Sequel[:tags][:name] => tag)
|
60
|
-
.where(Sequel[:verifications][:success] => true)
|
66
|
+
.join(:tags, tags_join)
|
61
67
|
.any?
|
62
68
|
end
|
63
69
|
end
|
64
70
|
|
65
71
|
def verified_successfully_by_any_provider_version?
|
72
|
+
verifications_join = {
|
73
|
+
Sequel[:verifications][:pact_version_id] => Sequel[:pact_versions][:id],
|
74
|
+
Sequel[:verifications][:pact_version_id] => id,
|
75
|
+
Sequel[:verifications][:success] => true
|
76
|
+
}
|
66
77
|
PactVersion.where(Sequel[:pact_versions][:id] => id)
|
67
|
-
.join(:verifications,
|
78
|
+
.join(:verifications, verifications_join)
|
68
79
|
.join(:versions, Sequel[:versions][:id] => Sequel[:verifications][:provider_version_id])
|
69
|
-
.where(Sequel[:verifications][:success] => true)
|
70
80
|
.any?
|
71
81
|
end
|
72
82
|
|
@@ -13,6 +13,7 @@ require 'pact_broker/pacts/parse'
|
|
13
13
|
require 'pact_broker/matrix/head_row'
|
14
14
|
require 'pact_broker/pacts/latest_pact_publication_id_for_consumer_version'
|
15
15
|
require 'pact_broker/pacts/verifiable_pact'
|
16
|
+
require 'pact_broker/repositories/helpers'
|
16
17
|
|
17
18
|
module PactBroker
|
18
19
|
module Pacts
|
@@ -20,6 +21,7 @@ module PactBroker
|
|
20
21
|
|
21
22
|
include PactBroker::Logging
|
22
23
|
include PactBroker::Repositories
|
24
|
+
include PactBroker::Repositories::Helpers
|
23
25
|
|
24
26
|
def create params
|
25
27
|
pact_version = find_or_create_pact_version(
|
@@ -125,36 +127,60 @@ module PactBroker
|
|
125
127
|
end
|
126
128
|
end
|
127
129
|
|
130
|
+
def find_all_pact_versions_for_provider_with_tags provider_name, consumer_version_tag_names
|
131
|
+
provider = pacticipant_repository.find_by_name(provider_name)
|
132
|
+
|
133
|
+
PactPublication
|
134
|
+
.select_all_qualified
|
135
|
+
.select_append(Sequel[:cv][:order].as(:consumer_version_order))
|
136
|
+
.remove_overridden_revisions
|
137
|
+
.join_consumer_versions(:cv)
|
138
|
+
.join_consumer_version_tags_with_names(consumer_version_tag_names)
|
139
|
+
.where(provider: provider)
|
140
|
+
.eager(:consumer)
|
141
|
+
.eager(:consumer_version)
|
142
|
+
.eager(:provider)
|
143
|
+
.eager(:pact_version)
|
144
|
+
.all
|
145
|
+
.group_by(&:pact_version_id)
|
146
|
+
.values
|
147
|
+
.collect{ | pacts| pacts.sort_by{|pact| pact.values.fetch(:consumer_version_order) }.last }
|
148
|
+
.collect(&:to_domain)
|
149
|
+
end
|
150
|
+
|
128
151
|
# To find the work in progress pacts for this verification execution:
|
129
152
|
# For each provider tag that will be applied to this verification result (usually there will just be one, but
|
130
153
|
# we have to allow for multiple tags),
|
131
154
|
# find the head pacts (the pacts that are the latest for their tag) that have been successfully
|
132
155
|
# verified against the provider tag.
|
133
156
|
# Then, find all the head pacts, and remove the ones that have been successfully verified by ALL
|
134
|
-
# of the provider tags supplied.
|
157
|
+
# of the provider tags supplied, and the ones that were published before the include_wip_pacts_since date.
|
135
158
|
# Then, for all of the head pacts that are remaining (these are the WIP ones) work out which
|
136
159
|
# provider tags they are pending for.
|
137
|
-
# Don't include pact publications that were created
|
160
|
+
# Don't include pact publications that were created before the provider tag was first used
|
161
|
+
# (that is, before the provider's git branch was created).
|
138
162
|
def find_wip_pact_versions_for_provider provider_name, provider_tags_names = [], options = {}
|
163
|
+
# TODO not sure about this
|
139
164
|
return [] if provider_tags_names.empty?
|
140
165
|
|
141
166
|
provider = pacticipant_repository.find_by_name(provider_name)
|
142
167
|
|
143
|
-
# Hash of provider tag
|
144
|
-
successfully_verified_head_pacts_for_provider_tags = find_successfully_verified_head_pacts_by_provider_tag(
|
168
|
+
# Hash of provider tag name => list of head pacts that have been successfully verified by that tag
|
169
|
+
successfully_verified_head_pacts_for_provider_tags = find_successfully_verified_head_pacts_by_provider_tag(provider.id, provider_tags_names, options)
|
170
|
+
# Create hash of provider tag name => list of pact publication ids
|
145
171
|
successfully_verified_head_pact_publication_ids_for_each_provider_tag = successfully_verified_head_pacts_for_provider_tags.each_with_object({}) do | (provider_tag_name, head_pacts), hash |
|
146
|
-
hash[provider_tag_name] = head_pacts.collect(&:id)
|
172
|
+
hash[provider_tag_name] = head_pacts.collect(&:id).uniq
|
147
173
|
end
|
148
174
|
|
149
|
-
# list of pact_publication_ids that are NOT work in progress
|
150
|
-
|
175
|
+
# list of head pact_publication_ids that are NOT work in progress because they've been verified by all of the provider version tags supplied
|
176
|
+
non_wip_pact_publication_ids = successfully_verified_head_pacts_for_provider_tags.values.collect{ |head_pacts| head_pacts.collect(&:id) }.reduce(:&)
|
151
177
|
|
152
|
-
|
153
|
-
|
154
|
-
|
178
|
+
wip_pact_publication_ids = find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags(
|
179
|
+
provider.id,
|
180
|
+
non_wip_pact_publication_ids,
|
155
181
|
options)
|
156
182
|
|
157
|
-
|
183
|
+
wip_pacts = AllPactPublications.where(id: wip_pact_publication_ids).order_ignore_case(:consumer_name).order_append(:consumer_version_order)
|
158
184
|
|
159
185
|
# The first instance (by date) of each provider tag with that name
|
160
186
|
provider_tag_collection = PactBroker::Domain::Tag
|
@@ -166,7 +192,7 @@ module PactBroker
|
|
166
192
|
.where(name: provider_tags_names)
|
167
193
|
.all
|
168
194
|
|
169
|
-
|
195
|
+
wip_pacts.collect do | pact|
|
170
196
|
pending_tag_names = find_provider_tags_for_which_pact_publication_id_is_pending(pact, successfully_verified_head_pact_publication_ids_for_each_provider_tag)
|
171
197
|
pre_existing_tag_names = find_provider_tag_names_that_were_first_used_before_pact_published(pact, provider_tag_collection)
|
172
198
|
|
@@ -313,13 +339,33 @@ module PactBroker
|
|
313
339
|
|
314
340
|
# Returns a list of Domain::Pact objects the represent pact publications
|
315
341
|
def find_for_verification(provider_name, consumer_version_selectors)
|
342
|
+
find_pacts_for_which_the_latest_version_or_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors) +
|
343
|
+
find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
|
344
|
+
end
|
345
|
+
|
346
|
+
private
|
347
|
+
|
348
|
+
def find_pacts_for_which_the_latest_version_or_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors)
|
349
|
+
# The tags for which only the latest version is specified
|
316
350
|
latest_tags = consumer_version_selectors.any? ?
|
317
351
|
consumer_version_selectors.select(&:latest).collect(&:tag) :
|
318
352
|
nil
|
353
|
+
|
319
354
|
find_latest_pact_versions_for_provider(provider_name, latest_tags)
|
320
355
|
end
|
321
356
|
|
322
|
-
|
357
|
+
def find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
|
358
|
+
# The tags for which all versions are specified
|
359
|
+
all_tags = consumer_version_selectors.any? ?
|
360
|
+
consumer_version_selectors.reject(&:latest).collect(&:tag) :
|
361
|
+
nil
|
362
|
+
|
363
|
+
if all_tags
|
364
|
+
find_all_pact_versions_for_provider_with_tags(provider_name, all_tags)
|
365
|
+
else
|
366
|
+
[]
|
367
|
+
end
|
368
|
+
end
|
323
369
|
|
324
370
|
def find_previous_distinct_pact_by_sha pact
|
325
371
|
current_pact_content_sha =
|
@@ -389,27 +435,35 @@ module PactBroker
|
|
389
435
|
end
|
390
436
|
end
|
391
437
|
|
392
|
-
def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags(
|
438
|
+
def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags(provider_id, pact_publication_ids_successfully_verified_by_all_provider_tags, options)
|
393
439
|
# Exclude the head pacts that have been successfully verified by all the specified provider tags
|
394
|
-
|
395
|
-
.
|
396
|
-
.exclude(id: pact_publication_ids_successfully_verified_by_all_provider_tags)
|
440
|
+
LatestTaggedPactPublications
|
441
|
+
.where(provider_id: provider_id)
|
397
442
|
.where(Sequel.lit('latest_tagged_pact_publications.created_at > ?', options.fetch(:include_wip_pacts_since)))
|
443
|
+
.exclude(id: pact_publication_ids_successfully_verified_by_all_provider_tags)
|
398
444
|
.select_for_subquery(:id)
|
399
445
|
end
|
400
446
|
|
401
|
-
# Find the head pacts that have been successfully verified by a provider version with the specified
|
402
|
-
#
|
403
|
-
|
447
|
+
# Find the head pacts that have been successfully verified by a provider version with the specified
|
448
|
+
# provider version tags.
|
449
|
+
# Returns a Hash of provider_tag => LatestTaggedPactPublications with only pact publication id and tag_name populated
|
450
|
+
# This is the list of pacts we are EXCLUDING from the WIP list because they have already been verified successfully
|
451
|
+
def find_successfully_verified_head_pacts_by_provider_tag(provider_id, provider_tags, options)
|
404
452
|
provider_tags.compact.each_with_object({}) do | provider_tag, hash |
|
453
|
+
verifications_join = {
|
454
|
+
pact_version_id: :pact_version_id,
|
455
|
+
Sequel[:verifications][:success] => true,
|
456
|
+
Sequel[:verifications][:provider_id] => provider_id
|
457
|
+
}
|
458
|
+
tags_join = {
|
459
|
+
Sequel[:verifications][:provider_version_id] => Sequel[:provider_tags][:version_id],
|
460
|
+
Sequel[:provider_tags][:name] => provider_tag
|
461
|
+
}
|
405
462
|
head_pacts = LatestTaggedPactPublications
|
406
|
-
.
|
407
|
-
.join(:
|
408
|
-
.
|
409
|
-
.
|
410
|
-
.where(Sequel[:verifications][:success] => true)
|
411
|
-
.or(Sequel.lit('latest_tagged_pact_publications.created_at < ?', options.fetch(:include_wip_pacts_since)))
|
412
|
-
.select(Sequel[:latest_tagged_pact_publications][:id].as(:id), :tag_name)
|
463
|
+
.select(Sequel[:latest_tagged_pact_publications][:id].as(:id))
|
464
|
+
.join(:verifications, verifications_join)
|
465
|
+
.join(:tags, tags_join, { table_alias: :provider_tags } )
|
466
|
+
.where(Sequel[:latest_tagged_pact_publications][:provider_id] => provider_id)
|
413
467
|
.all
|
414
468
|
hash[provider_tag] = head_pacts
|
415
469
|
end
|
@@ -35,6 +35,28 @@ module PactBroker
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
def verification_success_true_published_false
|
39
|
+
if pending?
|
40
|
+
"This pact is still in pending state for #{pending_provider_tags_description} as the successful verification results #{with_these_tags}have not yet been published."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def verification_success_true_published_true
|
45
|
+
if pending?
|
46
|
+
"This pact is no longer in pending state for #{pending_provider_tags_description}, as a successful verification result #{with_these_tags}has been published. If a verification for a version with fails in the future, it will fail the build. #{READ_MORE_PENDING}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def verification_success_false_published_false
|
51
|
+
if pending?
|
52
|
+
"This pact is still in pending state for #{pending_provider_tags_description} as a successful verification result #{with_these_tags}has not yet been published"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def verification_success_false_published_true
|
57
|
+
verification_success_false_published_false
|
58
|
+
end
|
59
|
+
|
38
60
|
private
|
39
61
|
|
40
62
|
attr_reader :verifiable_pact, :pact_version_url
|
@@ -77,6 +99,14 @@ module PactBroker
|
|
77
99
|
else "a version of #{provider_name} with tag #{join(non_pending_provider_tags)}"
|
78
100
|
end
|
79
101
|
end
|
102
|
+
|
103
|
+
def with_these_tags
|
104
|
+
case pending_provider_tags.size
|
105
|
+
when 0 then ""
|
106
|
+
when 1 then "with this tag "
|
107
|
+
else "with these tags "
|
108
|
+
end
|
109
|
+
end
|
80
110
|
end
|
81
111
|
end
|
82
112
|
end
|
@@ -23,6 +23,10 @@ module PactBroker
|
|
23
23
|
order(Sequel.function(:lower, column_name))
|
24
24
|
end
|
25
25
|
|
26
|
+
def order_append_ignore_case column_name = :name
|
27
|
+
order_append(Sequel.function(:lower, column_name))
|
28
|
+
end
|
29
|
+
|
26
30
|
def mysql?
|
27
31
|
Sequel::Model.db.adapter_scheme.to_s =~ /mysql/
|
28
32
|
end
|
@@ -252,6 +252,10 @@ module PactBroker
|
|
252
252
|
create_webhook(parameters.merge(consumer: nil, provider: nil))
|
253
253
|
end
|
254
254
|
|
255
|
+
def create_global_contract_content_changed_webhook parameters = {}
|
256
|
+
create_webhook(parameters.merge(consumer: nil, provider: nil, event_names: [PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED]))
|
257
|
+
end
|
258
|
+
|
255
259
|
def create_global_verification_webhook parameters = {}
|
256
260
|
create_webhook(parameters.merge(consumer: nil, provider: nil, event_names: [PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED]))
|
257
261
|
end
|
data/lib/pact_broker/version.rb
CHANGED
data/pact_broker.gemspec
CHANGED
@@ -48,7 +48,7 @@ Gem::Specification.new do |gem|
|
|
48
48
|
gem.add_runtime_dependency 'roar', '~> 1.1'
|
49
49
|
gem.add_runtime_dependency 'reform', '~> 2.2'
|
50
50
|
gem.add_runtime_dependency 'dry-validation', '~> 0.10.5'
|
51
|
-
gem.add_runtime_dependency 'sequel', '~> 5.
|
51
|
+
gem.add_runtime_dependency 'sequel', '~> 5.28'
|
52
52
|
gem.add_runtime_dependency 'webmachine', '1.5.0'
|
53
53
|
gem.add_runtime_dependency 'semver2', '~> 3.4.2'
|
54
54
|
gem.add_runtime_dependency 'rack', '>= 2.0.8', '~>2.0'
|
@@ -1,4 +1,12 @@
|
|
1
1
|
#Code to generate certificates
|
2
|
+
|
3
|
+
# To generate a self signed CA certificate for use in a server:
|
4
|
+
# root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
|
5
|
+
# root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
|
6
|
+
# root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
7
|
+
# root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
|
8
|
+
# root_ca.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
|
9
|
+
|
2
10
|
require 'openssl'
|
3
11
|
|
4
12
|
root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
|
data/script/release.sh
CHANGED
@@ -5,6 +5,7 @@ bundle exec rake generate_changelog
|
|
5
5
|
git add CHANGELOG.md lib/pact_broker/version.rb
|
6
6
|
VERSION=$(ruby -r ./lib/pact_broker/version.rb -e "puts PactBroker::VERSION")
|
7
7
|
git commit -m "chore(release): version ${VERSION}"
|
8
|
-
|
9
|
-
git
|
10
|
-
git push origin
|
8
|
+
bundle exec rake release
|
9
|
+
# git tag -a v${VERSION} -m "chore(release): version ${VERSION}"
|
10
|
+
# git push origin v${VERSION}
|
11
|
+
# git push origin master
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
raise "Please supply database path" unless ARGV[0]
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift './lib'
|
6
|
+
$LOAD_PATH.unshift './spec'
|
7
|
+
$LOAD_PATH.unshift './tasks'
|
8
|
+
ENV['RACK_ENV'] = 'development'
|
9
|
+
require 'sequel'
|
10
|
+
require 'logger'
|
11
|
+
DATABASE_CREDENTIALS = {logger: Logger.new($stdout), adapter: "sqlite", database: ARGV[0], :encoding => 'utf8'}.tap { |it| puts it }
|
12
|
+
#DATABASE_CREDENTIALS = {adapter: "postgres", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8'}
|
13
|
+
|
14
|
+
connection = Sequel.connect(DATABASE_CREDENTIALS)
|
15
|
+
connection.timezone = :utc
|
16
|
+
# Uncomment these lines to open a pry session for inspecting the database
|
17
|
+
|
18
|
+
require 'pact_broker/db'
|
19
|
+
PactBroker::DB.connection = connection
|
20
|
+
require 'pact_broker'
|
21
|
+
require 'support/test_data_builder'
|
22
|
+
|
23
|
+
require 'database/table_dependency_calculator'
|
24
|
+
PactBroker::Database::TableDependencyCalculator.call(connection).each do | table_name |
|
25
|
+
connection[table_name].delete
|
26
|
+
end
|
27
|
+
|
28
|
+
webhook_body = {
|
29
|
+
'pactUrl' => '${pactbroker.pactUrl}',
|
30
|
+
'verificationResultUrl' => '${pactbroker.verificationResultUrl}',
|
31
|
+
'consumerVersionNumber' => '${pactbroker.consumerVersionNumber}',
|
32
|
+
'providerVersionNumber' => '${pactbroker.providerVersionNumber}',
|
33
|
+
'providerVersionTags' => '${pactbroker.providerVersionTags}',
|
34
|
+
'consumerVersionTags' => '${pactbroker.consumerVersionTags}',
|
35
|
+
'consumerName' => '${pactbroker.consumerName}',
|
36
|
+
'providerName' => '${pactbroker.providerName}',
|
37
|
+
'githubVerificationStatus' => '${pactbroker.githubVerificationStatus}'
|
38
|
+
}
|
39
|
+
|
40
|
+
# .create_global_webhook(
|
41
|
+
# method: 'POST',
|
42
|
+
# url: "http://localhost:9292/pact-changed-webhook",
|
43
|
+
# body: webhook_body.to_json,
|
44
|
+
# username: "foo",
|
45
|
+
# password: "bar")
|
46
|
+
|
47
|
+
PactBroker.configuration.base_equality_only_on_content_that_affects_verification_results = false
|
48
|
+
|
49
|
+
TestDataBuilder.new
|
50
|
+
.create_global_contract_content_changed_webhook(
|
51
|
+
method: 'POST',
|
52
|
+
url: "http://localhost:9292/pact-changed-webhook",
|
53
|
+
body: webhook_body.to_json,
|
54
|
+
username: "foo",
|
55
|
+
password: "bar")
|
56
|
+
.create_global_verification_webhook(
|
57
|
+
method: 'POST',
|
58
|
+
url: "http://localhost:9292/verification-published-webhook",
|
59
|
+
body: webhook_body.to_json)
|
@@ -43,7 +43,7 @@ module PactBroker
|
|
43
43
|
subject { JSON.parse(json, symbolize_names: true) }
|
44
44
|
|
45
45
|
it "includes a link to the logs" do
|
46
|
-
expect(subject[:_links][:logs][:href]).to eq logs_url
|
46
|
+
expect(subject[:_links][:'pb:logs'][:href]).to eq logs_url
|
47
47
|
end
|
48
48
|
|
49
49
|
it "includes a link to the webhook" do
|
@@ -8,6 +8,10 @@ module PactBroker
|
|
8
8
|
allow_any_instance_of(PactBroker::Api::PactBrokerUrls).to receive(:pact_version_url).and_return('/pact-version-url')
|
9
9
|
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:inclusion_reason).and_return("the inclusion reason")
|
10
10
|
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:pending_reason).and_return(pending_reason)
|
11
|
+
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_true_published_false).and_return('verification_success_true_published_false')
|
12
|
+
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_false_published_false).and_return('verification_success_false_published_false')
|
13
|
+
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_true_published_true).and_return('verification_success_true_published_true')
|
14
|
+
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_false_published_true).and_return('verification_success_false_published_true')
|
11
15
|
end
|
12
16
|
let(:pending_reason) { "the pending reason" }
|
13
17
|
let(:expected_hash) do
|
@@ -16,9 +20,23 @@ module PactBroker
|
|
16
20
|
"pending" => true,
|
17
21
|
"notices" => [
|
18
22
|
{
|
23
|
+
"when" => "before_verification",
|
19
24
|
"text" => "the inclusion reason"
|
20
|
-
},
|
25
|
+
},{
|
26
|
+
"when" => "before_verification",
|
21
27
|
"text" => pending_reason
|
28
|
+
},{
|
29
|
+
"when" => "after_verification:success_true_published_false",
|
30
|
+
"text" => "verification_success_true_published_false"
|
31
|
+
},{
|
32
|
+
"when" => "after_verification:success_false_published_false",
|
33
|
+
"text" => "verification_success_false_published_false"
|
34
|
+
},{
|
35
|
+
"when" => "after_verification:success_true_published_true",
|
36
|
+
"text" => "verification_success_true_published_true"
|
37
|
+
},{
|
38
|
+
"when" => "after_verification:success_false_published_true",
|
39
|
+
"text" => "verification_success_false_published_true"
|
22
40
|
}
|
23
41
|
]
|
24
42
|
},
|
@@ -60,7 +78,7 @@ module PactBroker
|
|
60
78
|
end
|
61
79
|
|
62
80
|
it "creates the inclusion message" do
|
63
|
-
expect(PactBroker::Pacts::VerifiablePactMessages).to receive(:new).
|
81
|
+
expect(PactBroker::Pacts::VerifiablePactMessages).to receive(:new).with(pact, '/pact-version-url').and_call_original
|
64
82
|
subject
|
65
83
|
end
|
66
84
|
|
@@ -76,6 +94,10 @@ module PactBroker
|
|
76
94
|
expect(subject['verificationProperties']).to_not have_key('pendingReason')
|
77
95
|
expect(notices).to_not include(pending_reason)
|
78
96
|
end
|
97
|
+
|
98
|
+
it "does not include the pending notices" do
|
99
|
+
expect(subject['verificationProperties']['notices'].size).to eq 1
|
100
|
+
end
|
79
101
|
end
|
80
102
|
|
81
103
|
context "when wip is true" do
|
@@ -4,7 +4,7 @@ module PactBroker
|
|
4
4
|
module Api
|
5
5
|
module Resources
|
6
6
|
describe BaseResource do
|
7
|
-
let(:request) { double('request', uri: uri).as_null_object }
|
7
|
+
let(:request) { double('request', uri: uri, base_uri: URI("http://example.org/")).as_null_object }
|
8
8
|
let(:response) { double('response') }
|
9
9
|
let(:uri) { URI('http://example.org/path?query') }
|
10
10
|
|
@@ -19,6 +19,28 @@ module PactBroker
|
|
19
19
|
expect(subject.headers['Access-Control-Allow-Methods']).to eq "GET, OPTIONS"
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
describe "base_url" do
|
24
|
+
context "when PactBroker.configuration.base_url is not nil" do
|
25
|
+
before do
|
26
|
+
allow(PactBroker.configuration).to receive(:base_url).and_return("http://foo")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns the configured base URL" do
|
30
|
+
expect(subject.base_url).to eq "http://foo"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when PactBroker.configuration.base_url is nil" do
|
35
|
+
before do
|
36
|
+
allow(PactBroker.configuration).to receive(:base_url).and_return(nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns the base URL from the request" do
|
40
|
+
expect(subject.base_url).to eq "http://example.org"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
22
44
|
end
|
23
45
|
|
24
46
|
ALL_RESOURCES = ObjectSpace.each_object(::Class).select {|klass| klass < BaseResource }
|
@@ -11,21 +11,35 @@ module PactBroker
|
|
11
11
|
subject.find{ |pact| pact.consumer_version_number == consumer_version_number }
|
12
12
|
end
|
13
13
|
|
14
|
+
def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_version_number)
|
15
|
+
subject.find{ |pact| pact.consumer_name == consumer_name && pact.consumer_version_number == consumer_version_number }
|
16
|
+
end
|
17
|
+
|
14
18
|
before do
|
15
|
-
td.create_pact_with_hierarchy("Foo", "
|
19
|
+
td.create_pact_with_hierarchy("Foo", "foo-latest-prod-version", "Bar")
|
16
20
|
.create_consumer_version_tag("prod")
|
17
|
-
.create_consumer_version("not-latest-dev", tag_names: ["dev"])
|
21
|
+
.create_consumer_version("not-latest-dev-version", tag_names: ["dev"])
|
18
22
|
.comment("next pact not selected")
|
19
23
|
.create_pact
|
20
|
-
.create_consumer_version("
|
24
|
+
.create_consumer_version("foo-latest-dev-version", tag_names: ["dev"])
|
21
25
|
.create_pact
|
22
26
|
.create_consumer("Baz")
|
23
|
-
.create_consumer_version("baz-latest-dev", tag_names: ["dev"])
|
27
|
+
.create_consumer_version("baz-latest-dev-version", tag_names: ["dev"])
|
24
28
|
.create_pact
|
25
29
|
end
|
26
30
|
|
27
31
|
subject { Repository.new.find_for_verification("Bar", consumer_version_selectors) }
|
28
32
|
|
33
|
+
context "when there are no selectors" do
|
34
|
+
let(:consumer_version_selectors) { [] }
|
35
|
+
|
36
|
+
it "returns the latest pact for each consumer" do
|
37
|
+
expect(subject.size).to eq 2
|
38
|
+
expect(find_by_consumer_name_and_consumer_version_number("Foo", "foo-latest-dev-version")).to_not be nil
|
39
|
+
expect(find_by_consumer_name_and_consumer_version_number("Baz", "baz-latest-dev-version")).to_not be nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
29
43
|
context "when consumer tag names are specified" do
|
30
44
|
let(:pact_selector_1) { double('selector', tag: 'dev', latest: true) }
|
31
45
|
let(:pact_selector_2) { double('selector', tag: 'prod', latest: true) }
|
@@ -34,14 +48,43 @@ module PactBroker
|
|
34
48
|
end
|
35
49
|
|
36
50
|
it "returns the latest pact with the specified tags for each consumer" do
|
37
|
-
expect(find_by_consumer_version_number("
|
38
|
-
expect(find_by_consumer_version_number("
|
39
|
-
expect(find_by_consumer_version_number("baz-latest-dev")).to_not be nil
|
51
|
+
expect(find_by_consumer_version_number("foo-latest-prod-version")).to_not be nil
|
52
|
+
expect(find_by_consumer_version_number("foo-latest-dev-version")).to_not be nil
|
53
|
+
expect(find_by_consumer_version_number("baz-latest-dev-version")).to_not be nil
|
40
54
|
expect(subject.size).to eq 3
|
41
55
|
end
|
42
56
|
|
43
57
|
it "sets the latest_consumer_version_tag_names" do
|
44
|
-
expect(find_by_consumer_version_number("
|
58
|
+
expect(find_by_consumer_version_number("foo-latest-prod-version").tag).to eq 'prod'
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when all versions with a given tag are requested" do
|
62
|
+
before do
|
63
|
+
td.create_pact_with_hierarchy("Foo2", "prod-version-1", "Bar2")
|
64
|
+
.create_consumer_version_tag("prod")
|
65
|
+
.create_consumer_version("not-prod-version", tag_names: %w[master])
|
66
|
+
.create_pact
|
67
|
+
.create_consumer_version("prod-version-2", tag_names: %w[prod])
|
68
|
+
.create_pact
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:consumer_version_selectors) { [pact_selector_1] }
|
72
|
+
let(:pact_selector_1) { double('selector', tag: 'prod', latest: nil) }
|
73
|
+
|
74
|
+
subject { Repository.new.find_for_verification("Bar2", consumer_version_selectors) }
|
75
|
+
|
76
|
+
it "returns all the versions with the specified tag" do
|
77
|
+
expect(subject.size).to be 2
|
78
|
+
expect(find_by_consumer_version_number("prod-version-1")).to_not be nil
|
79
|
+
expect(find_by_consumer_version_number("prod-version-2")).to_not be nil
|
80
|
+
end
|
81
|
+
|
82
|
+
it "dedupes them to ensure that each pact version is only verified once" do
|
83
|
+
td.create_consumer_version("prod-version-3", tag_names: %w[prod])
|
84
|
+
.republish_same_pact
|
85
|
+
expect(subject.size).to be 2
|
86
|
+
expect(subject.collect(&:consumer_version_number)).to eq %w[prod-version-1 prod-version-3]
|
87
|
+
end
|
45
88
|
end
|
46
89
|
end
|
47
90
|
|
@@ -49,14 +92,14 @@ module PactBroker
|
|
49
92
|
let(:consumer_version_selectors) { [] }
|
50
93
|
|
51
94
|
it "returns the latest pact for each provider" do
|
52
|
-
expect(find_by_consumer_version_number("
|
53
|
-
expect(find_by_consumer_version_number("baz-latest-dev")).to_not be nil
|
95
|
+
expect(find_by_consumer_version_number("foo-latest-dev-version")).to_not be nil
|
96
|
+
expect(find_by_consumer_version_number("baz-latest-dev-version")).to_not be nil
|
54
97
|
expect(subject.size).to eq 2
|
55
98
|
end
|
56
99
|
|
57
100
|
it "does not set the tag name" do
|
58
|
-
expect(find_by_consumer_version_number("
|
59
|
-
expect(find_by_consumer_version_number("
|
101
|
+
expect(find_by_consumer_version_number("foo-latest-dev-version").tag).to be nil
|
102
|
+
expect(find_by_consumer_version_number("foo-latest-dev-version").overall_latest?).to be true
|
60
103
|
end
|
61
104
|
end
|
62
105
|
end
|
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.46.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: 2020-01-
|
13
|
+
date: 2020-01-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: httparty
|
@@ -94,14 +94,14 @@ dependencies:
|
|
94
94
|
requirements:
|
95
95
|
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '5.
|
97
|
+
version: '5.28'
|
98
98
|
type: :runtime
|
99
99
|
prerelease: false
|
100
100
|
version_requirements: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '5.
|
104
|
+
version: '5.28'
|
105
105
|
- !ruby/object:Gem::Dependency
|
106
106
|
name: webmachine
|
107
107
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1147,7 +1147,6 @@ files:
|
|
1147
1147
|
- lib/rack/pact_broker/no_auth.rb
|
1148
1148
|
- lib/rack/pact_broker/request_target.rb
|
1149
1149
|
- lib/rack/pact_broker/reset_thread_data.rb
|
1150
|
-
- lib/rack/pact_broker/store_base_url.rb
|
1151
1150
|
- lib/rack/pact_broker/ui_authentication.rb
|
1152
1151
|
- lib/rack/pact_broker/ui_request_filter.rb
|
1153
1152
|
- lib/webmachine/rack_adapter_monkey_patch.rb
|
@@ -1232,6 +1231,7 @@ files:
|
|
1232
1231
|
- script/restart.sh
|
1233
1232
|
- script/run-with-ssl.rb
|
1234
1233
|
- script/seed-example-matrix.rb
|
1234
|
+
- script/seed-for-webhook-test.rb
|
1235
1235
|
- script/seed-matrix.rb
|
1236
1236
|
- script/seed.rb
|
1237
1237
|
- script/update-hal-browser
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module PactBroker
|
3
|
-
class StoreBaseURL
|
4
|
-
def initialize app
|
5
|
-
@app = app
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(env)
|
9
|
-
Thread.current[:pact_broker_thread_data].base_url ||= (ENV['PACT_BROKER_BASE_URL'] || ::Rack::Request.new(env).base_url)
|
10
|
-
@app.call(env)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|