pact_broker 2.45.0 → 2.46.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|