pact_broker 2.86.0 → 2.87.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/release_gem.yml +1 -1
- data/CHANGELOG.md +35 -0
- data/db/migrations/20210929_increase_event_context_column_size.rb +14 -0
- data/docker-compose-test.yml +2 -0
- data/lib/pact/doc/interaction_view_model.rb +2 -2
- data/lib/pact/doc/markdown/consumer_contract_renderer.rb +1 -1
- data/lib/pact_broker/api/contracts/configuration.rb +33 -0
- data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +35 -16
- data/lib/pact_broker/api/decorators/matrix_decorator.rb +3 -1
- data/lib/pact_broker/api/decorators/verification_decorator.rb +5 -3
- data/lib/pact_broker/api/pact_broker_urls.rb +26 -6
- data/lib/pact_broker/api/resources/default_base_resource.rb +4 -0
- data/lib/pact_broker/api/resources/environment.rb +1 -1
- data/lib/pact_broker/api/resources/environments.rb +1 -1
- data/lib/pact_broker/api/resources/index.rb +7 -1
- data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
- data/lib/pact_broker/api/resources/verification.rb +5 -2
- data/lib/pact_broker/api/resources/webhook_execution_methods.rb +23 -17
- data/lib/pact_broker/api.rb +1 -0
- data/lib/pact_broker/application_context.rb +5 -0
- data/lib/pact_broker/db/delete_overwritten_data.rb +41 -23
- data/lib/pact_broker/deployments/deployed_version.rb +1 -0
- data/lib/pact_broker/deployments/deployed_version_service.rb +1 -0
- data/lib/pact_broker/deployments/environment_service.rb +4 -1
- data/lib/pact_broker/deployments/released_version_service.rb +1 -0
- data/lib/pact_broker/doc/controllers/app.rb +1 -0
- data/lib/pact_broker/doc/views/can-i-deploy.markdown +2 -1
- data/lib/pact_broker/doc/views/index/publish-contracts.markdown +38 -9
- data/lib/pact_broker/domain/index_item.rb +9 -0
- data/lib/pact_broker/domain/verification.rb +3 -0
- data/lib/pact_broker/index/service.rb +2 -2
- data/lib/pact_broker/locale/en.yml +3 -1
- data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +5 -3
- data/lib/pact_broker/pacticipants/repository.rb +1 -1
- data/lib/pact_broker/pacts/metadata.rb +7 -1
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +3 -2
- data/lib/pact_broker/pacts/service.rb +5 -5
- data/lib/pact_broker/string_refinements.rb +1 -1
- data/lib/pact_broker/test/http_test_data_builder.rb +2 -0
- data/lib/pact_broker/ui/helpers/url_helper.rb +12 -0
- data/lib/pact_broker/ui/view_models/index_item.rb +15 -1
- data/lib/pact_broker/ui/view_models/index_item_branch_head.rb +39 -0
- data/lib/pact_broker/ui/view_models/index_item_provider_branch_head.rb +39 -0
- data/lib/pact_broker/ui/views/dashboard/show.haml +14 -7
- data/lib/pact_broker/verifications/service.rb +3 -3
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/branch_head.rb +0 -2
- data/lib/pact_broker/versions/branch_version.rb +1 -0
- data/lib/pact_broker/versions/repository.rb +0 -1
- data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +17 -3
- data/lib/pact_broker/webhooks/trigger_service.rb +1 -1
- data/lib/pact_broker/webhooks/webhook.rb +5 -0
- data/public/stylesheets/index.css +5 -0
- data/script/data/auto-create-things-for-tags.rb +1 -0
- data/script/data/contract-published-requiring-verification.rb +0 -1
- data/spec/fixtures/invalid-publish-contract-body.json +38 -0
- data/spec/integration/webhooks/contract_publication_spec.rb +68 -0
- data/spec/integration/webhooks/contract_requiring_verification_published_spec.rb +67 -0
- data/spec/integration/webhooks/pact_publication_spec.rb +1 -1
- data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +2 -2
- data/spec/lib/pact_broker/api/contracts/publish_contracts_schema_spec.rb +13 -0
- data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +7 -6
- data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +18 -0
- data/spec/lib/pact_broker/api/resources/triggered_webhook_logs_spec.rb +6 -5
- data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +13 -0
- data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +4 -5
- data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +1 -1
- data/spec/lib/pact_broker/verifications/service_spec.rb +6 -6
- data/spec/lib/pact_broker/webhooks/render_spec.rb +3 -2
- data/tasks/db.rake +4 -1
- metadata +13 -3
@@ -2,11 +2,14 @@ require "pact_broker/deployments/environment"
|
|
2
2
|
require "securerandom"
|
3
3
|
require "pact_broker/pacticipants/generate_display_name"
|
4
4
|
require "pact_broker/string_refinements"
|
5
|
+
require "pact_broker/repositories/scopes"
|
5
6
|
|
6
7
|
module PactBroker
|
7
8
|
module Deployments
|
8
9
|
module EnvironmentService
|
9
10
|
using PactBroker::StringRefinements
|
11
|
+
extend PactBroker::Repositories::Scopes
|
12
|
+
|
10
13
|
extend self
|
11
14
|
|
12
15
|
def self.included(base)
|
@@ -34,7 +37,7 @@ module PactBroker
|
|
34
37
|
end
|
35
38
|
|
36
39
|
def find_all
|
37
|
-
PactBroker::Deployments::Environment.order(Sequel.function(:lower, :display_name)).all
|
40
|
+
scope_for(PactBroker::Deployments::Environment).order(Sequel.function(:lower, :display_name)).all
|
38
41
|
end
|
39
42
|
|
40
43
|
def find(uuid)
|
@@ -17,6 +17,7 @@ module PactBroker
|
|
17
17
|
"webhooks-webhooks" => "webhooks",
|
18
18
|
"webhook" => "webhooks",
|
19
19
|
"can-i-deploy-pacticipant-version-to-tag" => "can-i-deploy",
|
20
|
+
"can-i-deploy-pacticipant-version-to-environment" => "can-i-deploy",
|
20
21
|
"pacticipant" => "pacticipants"
|
21
22
|
}.freeze
|
22
23
|
|
@@ -10,7 +10,8 @@ A simplified resource that accepts the same parameters as the basic usage of the
|
|
10
10
|
* _version_: The version of the pacticipant (application) you want to deploy (required).
|
11
11
|
* _environment_: The name of the environment into which the pacticipant (application) is to be deployed.
|
12
12
|
* _to_: The tag used to identify the environment into which you wish to deploy the application (eg. `test` or `prod`). Deprecated - use the `environment=ENVIRONMENT` parameter in preference to the `to=TAG` parameter as deployments and environments are now explictly supported.
|
13
|
-
* _ignore[]_: The name of the pacticipant to ignore when determining if it is safe to deploy (optional). May be used multiple times.
|
13
|
+
* _ignore[]_: The name of the pacticipant to ignore when determining if it is safe to deploy (optional). May be used multiple times. eg `ignore[]=foo&ignore[]=bar`
|
14
|
+
* _ignore[][pacticipant]_ and _ignore[][version]_: When ignoring a specific pacticipant version, the name and version of the application to ignore may be specified using "nested" param names syntax. eg. `ignore[][pacticipant]=foo&ignore[][version]=2ac5a946&ignore[][pacticipant]=bar`
|
14
15
|
|
15
16
|
|
16
17
|
If you have an environment that you identify with the name `prod`, and each time you deployed an application to the prod environment you recorded the deployment of relevant application version in the Pact Broker using `record-deployment`, then calling `/can-i-deploy?pacticipant=Foo&version=734137278d&environment=prod` will check that version 734137278d of Foo has a successful verification result with each of the integrated application versions that are currently in prod. That is, it is safe to deploy.
|
@@ -4,11 +4,16 @@ Allowed methods: `POST`
|
|
4
4
|
|
5
5
|
Path: `/contracts/publish`
|
6
6
|
|
7
|
+
Index relation: `pb:publish-contracts`
|
8
|
+
|
9
|
+
Supported from: `v2.86.0`
|
10
|
+
|
7
11
|
This is the preferred endpoint with which to publish contracts (previously, contracts were published using multiple calls to different endpoints to create the tag and contract resources). To detect whether this endpoint exists in a particular version of the Pact Broker, make a request to the index resource, and locate the `pb:publish-contracts` relation. Do a `POST` to the href specified for that relation.
|
8
12
|
|
9
|
-
The previous tag and pact endpoints are still supported, however, future features that build on this endpoint may not be able to be backported into those endpoints
|
13
|
+
The previous tag and pact endpoints are still supported, however, future features that build on this endpoint may not be able to be backported into those endpoints.
|
10
14
|
|
11
15
|
## Parameters
|
16
|
+
|
12
17
|
* `pacticipantName`: the name of the application. Required.
|
13
18
|
* `pacticipantVersionNumber`: the version number of the application. Required. It is recommended that this should be or include the git SHA. See [http://docs.pact.io/versioning](http://docs.pact.io/versioning).
|
14
19
|
* `branch`: The git branch name. Optional but strongly recommended.
|
@@ -20,7 +25,31 @@ The previous tag and pact endpoints are still supported, however, future feature
|
|
20
25
|
* `specification`: currently, only contracts of type "pact" are supported, but this will be extended in the future. Required.
|
21
26
|
* `contentType`: currently, only contracts with a content type of "application/json" are supported. Required.
|
22
27
|
* `content`: the content of the contract. Must be Base64 encoded. Required.
|
23
|
-
|
28
|
+
|
29
|
+
## Responses
|
30
|
+
|
31
|
+
### Success
|
32
|
+
|
33
|
+
* `notices`
|
34
|
+
* `level`: one of `debug`, `info`, `warning`,`prompt`,`success`
|
35
|
+
* `text`: the text of the notice. This is designed to be displayed in the output of a CLI.
|
36
|
+
|
37
|
+
The `_links` section will contain links to all the resources created by the publication. The relations are:
|
38
|
+
|
39
|
+
* `pb:contracts` (array)
|
40
|
+
* `pb:pacticipant-version-tags` (array)
|
41
|
+
* `pb:pacticipant-version`
|
42
|
+
* `pb:pacticipant`
|
43
|
+
|
44
|
+
### Errors
|
45
|
+
|
46
|
+
Any validation errors will be returned in the standard Pact Broker format:
|
47
|
+
|
48
|
+
{
|
49
|
+
"errors": {
|
50
|
+
"<fieldName>": ["message 1", "message 2"]
|
51
|
+
}
|
52
|
+
}
|
24
53
|
|
25
54
|
## Example
|
26
55
|
|
@@ -37,30 +66,29 @@ The previous tag and pact endpoints are still supported, however, future feature
|
|
37
66
|
"providerName": "Bar",
|
38
67
|
"specification": "pact",
|
39
68
|
"contentType": "application/json",
|
40
|
-
"content": "<base64 encoded JSON pact>"
|
41
|
-
"onConflict": "overwrite"
|
69
|
+
"content": "<base64 encoded JSON pact>"
|
42
70
|
}
|
43
71
|
]
|
44
72
|
}
|
45
73
|
|
46
74
|
{
|
47
75
|
{
|
48
|
-
"
|
76
|
+
"notices": [
|
49
77
|
{
|
50
78
|
"level": "debug",
|
51
|
-
"
|
79
|
+
"text": "Created Foo version dc5eb529230038a4673b8c971395bd2922d8b240 with branch main and tags main"
|
52
80
|
},
|
53
81
|
{
|
54
82
|
"level": "info",
|
55
|
-
"
|
83
|
+
"text": "Pact published for Foo version dc5eb529230038a4673b8c971395bd2922d8b240 and provider Bar."
|
56
84
|
},
|
57
85
|
{
|
58
86
|
"level": "debug",
|
59
|
-
"
|
87
|
+
"text": " Events detected: contract_published, contract_content_changed (first time any pact published for this consumer with consumer version tagged main)"
|
60
88
|
},
|
61
89
|
{
|
62
90
|
"level": "debug",
|
63
|
-
"
|
91
|
+
"text": " Webhook \"foo webhook\" triggered for event contract_content_changed.\n See logs at http://example.org/triggered-webhooks/1234/logs\""
|
64
92
|
}
|
65
93
|
],
|
66
94
|
"_embedded": {
|
@@ -118,3 +146,4 @@ The previous tag and pact endpoints are still supported, however, future feature
|
|
118
146
|
}
|
119
147
|
}
|
120
148
|
}
|
149
|
+
|
@@ -74,6 +74,10 @@ module PactBroker
|
|
74
74
|
consumer_version.branch_heads.collect(&:branch_name)
|
75
75
|
end
|
76
76
|
|
77
|
+
def consumer_version_branch_heads
|
78
|
+
consumer_version.branch_heads
|
79
|
+
end
|
80
|
+
|
77
81
|
def consumer_version_environment_names
|
78
82
|
(consumer_version.current_deployed_versions.collect(&:environment).collect(&:name) + consumer_version.current_supported_released_versions.collect(&:environment).collect(&:name)).uniq
|
79
83
|
end
|
@@ -90,6 +94,11 @@ module PactBroker
|
|
90
94
|
@latest_verification ? @latest_verification.provider_version_number : nil
|
91
95
|
end
|
92
96
|
|
97
|
+
def provider_version_branch_heads
|
98
|
+
provider_version&.branch_heads || []
|
99
|
+
end
|
100
|
+
|
101
|
+
|
93
102
|
def provider_version_branches
|
94
103
|
provider_version&.branch_heads&.collect(&:branch_name) || []
|
95
104
|
end
|
@@ -258,6 +258,9 @@ end
|
|
258
258
|
# wip | boolean | NOT NULL DEFAULT false
|
259
259
|
# consumer_version_selector_hashes | text |
|
260
260
|
# tag_names | text |
|
261
|
+
# pact_pending | boolean |
|
262
|
+
# verified_by_implementation | text |
|
263
|
+
# verified_by_version | text |
|
261
264
|
# Indexes:
|
262
265
|
# verifications_pkey | PRIMARY KEY btree (id)
|
263
266
|
# verifications_pact_version_id_number_index | UNIQUE btree (pact_version_id, number)
|
@@ -138,8 +138,8 @@ module PactBroker
|
|
138
138
|
pact_publications = head_pact_publications(consumer_name: consumer_name, provider_name: provider_name, tags: true, page_number: page_number, page_size: page_size)
|
139
139
|
.eager(:consumer)
|
140
140
|
.eager(:provider)
|
141
|
-
.eager(pact_version: { latest_verification: { provider_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, :
|
142
|
-
.eager(consumer_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, :
|
141
|
+
.eager(pact_version: { latest_verification: { provider_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, { branch_heads: :branch_version }, { tags: :head_tag }]} })
|
142
|
+
.eager(consumer_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, { branch_heads: :branch_version }, { tags: :head_tag }])
|
143
143
|
.eager(:head_pact_publications_for_tags)
|
144
144
|
|
145
145
|
pact_publications.all.collect do | pact_publication |
|
@@ -34,16 +34,18 @@ en:
|
|
34
34
|
consumerVersionTags: The list of tag names for the most recent consumer version associated with the pact content, separated by ", "
|
35
35
|
consumerVersionBranch: The repository branch associated with the consumer version
|
36
36
|
providerVersionTags: The list of tag names for the provider version associated with the verification result, separated by ", ".
|
37
|
+
providerVersionDescriptions: The descriptions of the provider version(s) for which the contract_requiring_verification_published webhook has been triggered.
|
37
38
|
providerVersionBranch: The repository branch associated with the provider version
|
38
39
|
consumerLabels: The list of labels for the consumer associated with the pact content, separated by ", ".
|
39
40
|
providerLabels: The list of labels for the provider associated with the pact content, separated by ", ".
|
40
|
-
pactUrl: The "permalink" URL to the newly published pact (
|
41
|
+
pactUrl: The "permalink" URL to the newly published pact content (using the pact version SHA).
|
41
42
|
verificationResultUrl: The URL to the relevant verification result.
|
42
43
|
githubVerificationStatus: The verification status using the correct keywords for posting to the Github commit status API. See https://developer.github.com/v3/repos/statuses
|
43
44
|
bitbucketVerificationStatus: The verification status using the correct keywords for posting to the Bitbucket commit status API. See https://developer.atlassian.com/server/bitbucket/how-tos/updating-build-status-for-commits/
|
44
45
|
azureDevOpsVerificationStatus: The verification status using the correct keywords for posting to the Azure DevOps GitStatusState API. See https://docs.microsoft.com/en-us/rest/api/azure/devops/git/statuses/create?view=azure-devops-rest-6.0
|
45
46
|
gitlabVerificationStatus: The verification status using the correct keywords for posting to the Gitlab Commits API. See https://docs.gitlab.com/ee/api/commits.html#post-the-build-status-to-a-commit
|
46
47
|
eventName: The name of the event that triggered the webhook
|
48
|
+
buildUrl: The URL of the build that published the resources that have triggered the webhook (currently only supported for contracts published using the 'all in one' endpoint).
|
47
49
|
currentlyDeployedProviderVersionNumber: The version number of the currently deployed provider version (when used in a template, the webhook will be triggered once for each currently deployed provider version)
|
48
50
|
no_webhooks_enabled_for_event: No enabled webhooks found for the detected events
|
49
51
|
webhook_triggered_for_event: Webhook %{webhook_description} triggered for event %{event_name}.
|
@@ -29,9 +29,11 @@ module PactBroker
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if params[:ignore].is_a?(Array)
|
32
|
-
options[:ignore_selectors] = params[:ignore].collect do |
|
33
|
-
if
|
34
|
-
PactBroker::Matrix::UnresolvedSelector.new(pacticipant_name:
|
32
|
+
options[:ignore_selectors] = params[:ignore].collect do | param |
|
33
|
+
if param.is_a?(String)
|
34
|
+
PactBroker::Matrix::UnresolvedSelector.new(pacticipant_name: param)
|
35
|
+
elsif param.is_a?(Hash) && param.key?(:pacticipant)
|
36
|
+
PactBroker::Matrix::UnresolvedSelector.new({ pacticipant_name: param[:pacticipant], pacticipant_version_number: param[:version] }.compact)
|
35
37
|
end
|
36
38
|
end.compact
|
37
39
|
else
|
@@ -95,7 +95,7 @@ module PactBroker
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def search_by_name(pacticipant_name)
|
98
|
-
terms = pacticipant_name.split.map { |v| v.gsub("_",
|
98
|
+
terms = pacticipant_name.split.map { |v| v.gsub("_", "\\_") }
|
99
99
|
string_match_query = Sequel.|( *terms.map { |term| Sequel.ilike(Sequel[:pacticipants][:name], "%#{term}%") })
|
100
100
|
PactBroker::Domain::Pacticipant.where(string_match_query)
|
101
101
|
end
|
@@ -5,7 +5,7 @@ module PactBroker
|
|
5
5
|
|
6
6
|
MAPPINGS = [
|
7
7
|
[:consumer_version_tags, "cvt"],
|
8
|
-
[:consumer_version_number, "cvn"], # for old urls
|
8
|
+
[:consumer_version_number, "cvn"], # for old urls and build_metadata_for_consumer_version_number
|
9
9
|
[:consumer_version_id, "cv"],
|
10
10
|
[:wip, "w"],
|
11
11
|
[:pending, "p"],
|
@@ -33,6 +33,12 @@ module PactBroker
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def build_metadata_for_consumer_version_number(consumer_version_number)
|
37
|
+
{
|
38
|
+
"cvn" => consumer_version_number
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
36
42
|
# When a pact is published, and a webhook is triggered, this stores
|
37
43
|
# the current tags and consumer version number in the metadata parameter of the
|
38
44
|
# pact version URL that is made available in the webhook template
|
@@ -132,6 +132,7 @@ module PactBroker
|
|
132
132
|
selectors = selector_for_latest_main_version_or_overall_latest(provider)
|
133
133
|
selectors << Selector.for_currently_deployed
|
134
134
|
selectors << Selector.for_currently_supported
|
135
|
+
logger.debug("Default selectors", payload: selectors)
|
135
136
|
selectors
|
136
137
|
end
|
137
138
|
|
@@ -140,9 +141,9 @@ module PactBroker
|
|
140
141
|
consumers = integration_service.find_for_provider(provider).collect(&:consumer)
|
141
142
|
|
142
143
|
consumers.collect do | consumer |
|
143
|
-
if consumer.main_branch && PactBroker::Domain::Version.for_selector(PactBroker::Matrix::UnresolvedSelector.new(branch: consumer.main_branch, latest: true)).any?
|
144
|
+
if consumer.main_branch && PactBroker::Domain::Version.for_selector(PactBroker::Matrix::UnresolvedSelector.new(branch: consumer.main_branch, pacticipant_name: consumer.name, latest: true)).any?
|
144
145
|
selectors << Selector.for_main_branch.for_consumer(consumer.name)
|
145
|
-
elsif consumer.main_branch && PactBroker::Domain::Version.for_selector(PactBroker::Matrix::UnresolvedSelector.new(tag: consumer.main_branch, latest: true)).any?
|
146
|
+
elsif consumer.main_branch && PactBroker::Domain::Version.for_selector(PactBroker::Matrix::UnresolvedSelector.new(tag: consumer.main_branch, pacticipant_name: consumer.name, latest: true)).any?
|
146
147
|
selectors << Selector.latest_for_tag(consumer.main_branch).for_consumer(consumer.name)
|
147
148
|
else
|
148
149
|
selectors << Selector.overall_latest.for_consumer(consumer.name)
|
@@ -56,7 +56,7 @@ module PactBroker
|
|
56
56
|
existing_pact = pact_repository.find_by_version_and_provider(consumer_version.id, provider.id)
|
57
57
|
|
58
58
|
if existing_pact
|
59
|
-
|
59
|
+
create_pact_revision params, existing_pact
|
60
60
|
else
|
61
61
|
create_pact params, consumer_version, provider
|
62
62
|
end
|
@@ -72,7 +72,7 @@ module PactBroker
|
|
72
72
|
existing_pact.json_content, params[:json_content]
|
73
73
|
)
|
74
74
|
|
75
|
-
|
75
|
+
create_pact_revision params, existing_pact
|
76
76
|
end
|
77
77
|
|
78
78
|
def find_all_pact_versions_between consumer, options
|
@@ -155,7 +155,7 @@ module PactBroker
|
|
155
155
|
end
|
156
156
|
|
157
157
|
# Overwriting an existing pact with the same consumer/provider/consumer version number
|
158
|
-
def
|
158
|
+
def create_pact_revision params, existing_pact
|
159
159
|
logger.info "Updating existing pact publication with params #{params.reject{ |k, _v| k == :json_content}}"
|
160
160
|
logger.debug "Content #{params[:json_content]}"
|
161
161
|
pact_version_sha = generate_sha(params[:json_content])
|
@@ -177,12 +177,12 @@ module PactBroker
|
|
177
177
|
updated_pact
|
178
178
|
end
|
179
179
|
|
180
|
+
private :create_pact_revision
|
181
|
+
|
180
182
|
def disallowed_modification?(existing_pact, new_json_content)
|
181
183
|
!PactBroker.configuration.allow_dangerous_contract_modification && existing_pact && existing_pact.pact_version_sha != generate_sha(new_json_content)
|
182
184
|
end
|
183
185
|
|
184
|
-
private :update_pact
|
185
|
-
|
186
186
|
# When no publication for the given consumer/provider/consumer version number exists
|
187
187
|
def create_pact params, version, provider
|
188
188
|
logger.info "Creating new pact publication with params #{params.reject{ |k, _v| k == :json_content}}"
|
@@ -20,6 +20,7 @@ module PactBroker
|
|
20
20
|
logger.filter(/(Authorization: ).*/,'\1[REMOVED]')
|
21
21
|
end
|
22
22
|
end
|
23
|
+
faraday.basic_auth(auth[:username], auth[:password]) if auth[:username]
|
23
24
|
faraday.headers["Authorization"] = "Bearer #{auth[:token]}" if auth[:token]
|
24
25
|
faraday.adapter Faraday.default_adapter
|
25
26
|
end
|
@@ -229,6 +230,7 @@ module PactBroker
|
|
229
230
|
"providerVersionBranch" => "${pactbroker.providerVersionBranch}",
|
230
231
|
"providerName" => "${pactbroker.providerName}",
|
231
232
|
"providerVersionNumber" => "${pactbroker.providerVersionNumber}",
|
233
|
+
"providerVersionDescriptions" => "${pactbroker.providerVersionDescriptions}",
|
232
234
|
"consumerVersionBranch" => "${pactbroker.consumerVersionBranch}",
|
233
235
|
}
|
234
236
|
request_body = {
|
@@ -18,6 +18,18 @@ module PactBroker
|
|
18
18
|
def matrix_url consumer_name, provider_name, base_url = ""
|
19
19
|
"#{base_url}/matrix/provider/#{ERB::Util.url_encode(provider_name)}/consumer/#{ERB::Util.url_encode(consumer_name)}"
|
20
20
|
end
|
21
|
+
|
22
|
+
def matrix_url_for_consumer_version consumer_name, consumer_version_number, provider_name, base_url = ""
|
23
|
+
query = {
|
24
|
+
q:
|
25
|
+
[
|
26
|
+
{ pacticipant: consumer_name, version: consumer_version_number },
|
27
|
+
{ pacticipant: provider_name }
|
28
|
+
],
|
29
|
+
latestby: "cvpv"
|
30
|
+
}
|
31
|
+
"#{base_url}/matrix?" + Rack::Utils.build_nested_query(query)
|
32
|
+
end
|
21
33
|
end
|
22
34
|
end
|
23
35
|
end
|
@@ -3,6 +3,8 @@ require "pact_broker/ui/helpers/url_helper"
|
|
3
3
|
require "pact_broker/date_helper"
|
4
4
|
require "pact_broker/versions/abbreviate_number"
|
5
5
|
require "pact_broker/configuration"
|
6
|
+
require "pact_broker/ui/view_models/index_item_branch_head"
|
7
|
+
require "pact_broker/ui/view_models/index_item_provider_branch_head"
|
6
8
|
require "forwardable"
|
7
9
|
|
8
10
|
module PactBroker
|
@@ -66,6 +68,12 @@ module PactBroker
|
|
66
68
|
@relationship.latest?
|
67
69
|
end
|
68
70
|
|
71
|
+
def consumer_version_branch_heads
|
72
|
+
@relationship.consumer_version_branch_heads.collect do | branch_head |
|
73
|
+
IndexItemBranchHead.new(branch_head, consumer_name)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
69
77
|
def consumer_version_latest_tag_names
|
70
78
|
@relationship.tag_names
|
71
79
|
end
|
@@ -74,6 +82,12 @@ module PactBroker
|
|
74
82
|
@relationship.latest_verification_latest_tags.collect(&:name)
|
75
83
|
end
|
76
84
|
|
85
|
+
def provider_version_branch_heads
|
86
|
+
@relationship.provider_version_branch_heads.collect do | branch_head |
|
87
|
+
IndexItemProviderBranchHead.new(branch_head, provider_name)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
77
91
|
def consumer_group_url
|
78
92
|
Helpers::URLHelper.group_url(consumer_name, base_url)
|
79
93
|
end
|
@@ -95,7 +109,7 @@ module PactBroker
|
|
95
109
|
end
|
96
110
|
|
97
111
|
def pact_matrix_url
|
98
|
-
Helpers::URLHelper.
|
112
|
+
Helpers::URLHelper.matrix_url_for_consumer_version(consumer_name, consumer_version_number, provider_name, base_url)
|
99
113
|
end
|
100
114
|
|
101
115
|
def any_webhooks?
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "pact_broker/api/pact_broker_urls"
|
2
|
+
require "pact_broker/ui/helpers/url_helper"
|
3
|
+
require "pact_broker/date_helper"
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
module UI
|
7
|
+
module ViewDomain
|
8
|
+
class IndexItemBranchHead
|
9
|
+
|
10
|
+
include PactBroker::Api::PactBrokerUrls
|
11
|
+
|
12
|
+
def initialize branch_head, pacticipant_name
|
13
|
+
@branch_head = branch_head
|
14
|
+
@pacticipant_name = pacticipant_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def branch_name
|
18
|
+
branch_head.branch_name
|
19
|
+
end
|
20
|
+
|
21
|
+
def tooltip
|
22
|
+
if branch_head.branch_version.auto_created
|
23
|
+
"This is the latest pact from branch \"#{branch_name}\". This branch was automatically inferred from the first tag because the Pact Broker configuration setting `use_first_tag_as_branch` was true."
|
24
|
+
else
|
25
|
+
"This is the latest pact from branch \"#{branch_name}\"."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def latest?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :branch_head, :pacticipant_name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "pact_broker/api/pact_broker_urls"
|
2
|
+
require "pact_broker/ui/helpers/url_helper"
|
3
|
+
require "pact_broker/date_helper"
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
module UI
|
7
|
+
module ViewDomain
|
8
|
+
class IndexItemProviderBranchHead
|
9
|
+
|
10
|
+
include PactBroker::Api::PactBrokerUrls
|
11
|
+
|
12
|
+
def initialize branch_head, pacticipant_name
|
13
|
+
@branch_head = branch_head
|
14
|
+
@pacticipant_name = pacticipant_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def branch_name
|
18
|
+
branch_head.branch_name
|
19
|
+
end
|
20
|
+
|
21
|
+
def tooltip
|
22
|
+
if branch_head.branch_version.auto_created
|
23
|
+
"The latest verification is from branch \"#{branch_name}\". This branch was automatically inferred from the first tag because the Pact Broker configuration setting `use_first_tag_as_branch` was true."
|
24
|
+
else
|
25
|
+
"The latest verification is from branch \"#{branch_name}\"."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def latest?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :branch_head, :pacticipant_name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -85,9 +85,9 @@
|
|
85
85
|
%button.clippy.invisible{ title: "Copy to clipboard" }
|
86
86
|
%span.copy-icon
|
87
87
|
- if view == "branch" || view == "all"
|
88
|
-
- index_item.
|
89
|
-
%div{"class": "tag badge badge-dark"}
|
90
|
-
= "branch: " + branch_name
|
88
|
+
- index_item.consumer_version_branch_heads.each do | branch_head |
|
89
|
+
%div{"class": "tag badge badge-dark", "title": branch_head.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
|
90
|
+
= "branch: " + branch_head.branch_name
|
91
91
|
- if view == "tag" || view == "all"
|
92
92
|
- index_item.consumer_version_latest_tag_names.each do | tag_name |
|
93
93
|
.tag.badge.badge-primary
|
@@ -106,9 +106,9 @@
|
|
106
106
|
%button.clippy.invisible{ title: "Copy to clipboard" }
|
107
107
|
%span.copy-icon
|
108
108
|
- if view == "branch" || view == "all"
|
109
|
-
- index_item.
|
110
|
-
%div{"class": "tag badge badge-dark"}
|
111
|
-
= "branch: " + branch_name
|
109
|
+
- index_item.provider_version_branch_heads.each do | branch_head |
|
110
|
+
%div{"class": "tag badge badge-dark", "title": branch_head.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
|
111
|
+
= "branch: " + branch_head.branch_name
|
112
112
|
- if view == "tag" || view == "all"
|
113
113
|
- index_item.provider_version_latest_tag_names.each do | tag_name |
|
114
114
|
.tag.badge.badge-primary
|
@@ -159,8 +159,15 @@
|
|
159
159
|
$('td[data-toggle="tooltip"]').each(function(index, td){
|
160
160
|
//appended tooltip div screws up table if it's appended after a
|
161
161
|
//td, so need to append it to a div
|
162
|
-
$(td).tooltip({container: $(td).first()});
|
162
|
+
$(td).tooltip({ container: $(td).first() });
|
163
163
|
});
|
164
|
+
|
165
|
+
// https://www.w3schools.com/bootstrap/bootstrap_ref_js_tooltip.asp
|
166
|
+
|
167
|
+
$('div[data-toggle="tooltip"]').each(function(index, div){
|
168
|
+
$(div).tooltip()
|
169
|
+
});
|
170
|
+
|
164
171
|
});
|
165
172
|
|
166
173
|
$(".reset-search").on("click", function() {
|
@@ -138,7 +138,7 @@ module PactBroker
|
|
138
138
|
latest_version_from_main_branch = [version_service.find_latest_version_from_main_branch(pact_version.provider)].compact
|
139
139
|
|
140
140
|
latest_version_from_main_branch.collect do | main_branch_version |
|
141
|
-
identify_required_verification(pact_version, main_branch_version, "latest
|
141
|
+
identify_required_verification(pact_version, main_branch_version, "latest from main branch")
|
142
142
|
end.compact
|
143
143
|
end
|
144
144
|
private :required_verifications_for_main_branch
|
@@ -148,7 +148,7 @@ module PactBroker
|
|
148
148
|
unscoped_service.find_currently_deployed_versions_for_pacticipant(pact_version.provider)
|
149
149
|
end
|
150
150
|
deployed_versions.collect do | deployed_version |
|
151
|
-
identify_required_verification(pact_version, deployed_version.version, "
|
151
|
+
identify_required_verification(pact_version, deployed_version.version, "deployed in #{deployed_version.environment_name}")
|
152
152
|
end.compact
|
153
153
|
end
|
154
154
|
private :required_verifications_for_deployed_versions
|
@@ -158,7 +158,7 @@ module PactBroker
|
|
158
158
|
unscoped_service.find_currently_supported_versions_for_pacticipant(pact_version.provider)
|
159
159
|
end
|
160
160
|
released_versions.collect do | released_version |
|
161
|
-
identify_required_verification(pact_version, released_version.version, "
|
161
|
+
identify_required_verification(pact_version, released_version.version, "released in #{released_version.environment_name}")
|
162
162
|
end.compact
|
163
163
|
end
|
164
164
|
private :required_verifications_for_released_versions
|
data/lib/pact_broker/version.rb
CHANGED
@@ -28,14 +28,12 @@ end
|
|
28
28
|
|
29
29
|
# Table: branch_heads
|
30
30
|
# Columns:
|
31
|
-
# id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
|
32
31
|
# branch_id | integer | NOT NULL
|
33
32
|
# branch_version_id | integer | NOT NULL
|
34
33
|
# version_id | integer | NOT NULL
|
35
34
|
# pacticipant_id | integer | NOT NULL
|
36
35
|
# branch_name | text | NOT NULL
|
37
36
|
# Indexes:
|
38
|
-
# branch_heads_pkey | PRIMARY KEY btree (id)
|
39
37
|
# branch_heads_branch_id_index | UNIQUE btree (branch_id)
|
40
38
|
# branch_heads_branch_name_index | btree (branch_name)
|
41
39
|
# branch_heads_pacticipant_id_index | btree (pacticipant_id)
|
@@ -51,6 +51,7 @@ end
|
|
51
51
|
# branch_name | text | NOT NULL
|
52
52
|
# created_at | timestamp without time zone | NOT NULL
|
53
53
|
# updated_at | timestamp without time zone | NOT NULL
|
54
|
+
# auto_created | boolean | DEFAULT false
|
54
55
|
# Indexes:
|
55
56
|
# branch_versions_pkey | PRIMARY KEY btree (id)
|
56
57
|
# branch_versions_branch_id_version_id_index | UNIQUE btree (branch_id, version_id)
|
@@ -53,7 +53,6 @@ module PactBroker
|
|
53
53
|
|
54
54
|
# There may be a race condition if two simultaneous requests come in to create the same version
|
55
55
|
def create(args)
|
56
|
-
logger.info "Upserting version #{args[:number]} for pacticipant_id=#{args[:pacticipant_id]}"
|
57
56
|
version_params = {
|
58
57
|
number: args[:number],
|
59
58
|
pacticipant_id: args[:pacticipant_id],
|