Skip to content

Commit

Permalink
feat: support version branch and build URL when publishing pacts
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Feb 13, 2021
1 parent 26f3535 commit a75f7df
Show file tree
Hide file tree
Showing 14 changed files with 825 additions and 78 deletions.
103 changes: 103 additions & 0 deletions doc/pacts/markdown/Pact Broker Client - Pact Broker.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

* [A request for the index resource](#a_request_for_the_index_resource_given_the_pb:latest-version_relation_exists_in_the_index_resource) given the pb:latest-version relation exists in the index resource

* [A request for the index resource](#a_request_for_the_index_resource_given_the_pb:pacticipant-version_relation_exists_in_the_index_resource) given the pb:pacticipant-version relation exists in the index resource

* [A request for the index resource with the webhook relation](#a_request_for_the_index_resource_with_the_webhook_relation)

* [A request for the list of the latest pacts from all consumers for the Pricing Service'](#a_request_for_the_list_of_the_latest_pacts_from_all_consumers_for_the_Pricing_Service'_given_a_latest_pact_between_Condor_and_the_Pricing_Service_exists) given a latest pact between Condor and the Pricing Service exists
Expand All @@ -42,6 +44,10 @@

* [A request to create a pacticipant](#a_request_to_create_a_pacticipant)

* [A request to create a pacticipant version](#a_request_to_create_a_pacticipant_version_given_version_26f353580936ad3b9baddb17b00e84f33c69e7cb_of_pacticipant_Foo_does_exist) given version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does exist

* [A request to create a pacticipant version](#a_request_to_create_a_pacticipant_version_given_version_26f353580936ad3b9baddb17b00e84f33c69e7cb_of_pacticipant_Foo_does_not_exist) given version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does not exist

* [A request to create a webhook for a consumer and provider](#a_request_to_create_a_webhook_for_a_consumer_and_provider_given_'Condor'_does_not_exist_in_the_pact-broker) given 'Condor' does not exist in the pact-broker

* [A request to create a webhook with a JSON body and a uuid](#a_request_to_create_a_webhook_with_a_JSON_body_and_a_uuid_given_the_'Pricing_Service'_and_'Condor'_already_exist_in_the_pact-broker) given the 'Pricing Service' and 'Condor' already exist in the pact-broker
Expand Down Expand Up @@ -646,6 +652,33 @@ Pact Broker will respond with:
}
}
```
<a name="a_request_for_the_index_resource_given_the_pb:pacticipant-version_relation_exists_in_the_index_resource"></a>
Given **the pb:pacticipant-version relation exists in the index resource**, upon receiving **a request for the index resource** from Pact Broker Client, with
```json
{
"method": "get",
"path": "/",
"headers": {
"Accept": "application/hal+json"
}
}
```
Pact Broker will respond with:
```json
{
"status": 200,
"headers": {
"Content-Type": "application/hal+json;charset=utf-8"
},
"body": {
"_links": {
"pb:pacticipant-version": {
"href": "http://localhost:1234/HAL-REL-PLACEHOLDER-INDEX-PB-PACTICIPANT-VERSION-{pacticipant}-{version}"
}
}
}
}
```
<a name="a_request_for_the_index_resource_with_the_webhook_relation"></a>
Upon receiving **a request for the index resource with the webhook relation** from Pact Broker Client, with
```json
Expand Down Expand Up @@ -898,6 +931,76 @@ Pact Broker will respond with:
}
}
```
<a name="a_request_to_create_a_pacticipant_version_given_version_26f353580936ad3b9baddb17b00e84f33c69e7cb_of_pacticipant_Foo_does_exist"></a>
Given **version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does exist**, upon receiving **a request to create a pacticipant version** from Pact Broker Client, with
```json
{
"method": "put",
"path": "/HAL-REL-PLACEHOLDER-INDEX-PB-PACTICIPANT-VERSION-Foo-26f353580936ad3b9baddb17b00e84f33c69e7cb",
"headers": {
"Content-Type": "application/json",
"Accept": "application/hal+json"
},
"body": {
"branch": "main",
"buildUrl": "http://my-ci/builds/1"
}
}
```
Pact Broker will respond with:
```json
{
"status": 200,
"headers": {
"Content-Type": "application/hal+json;charset=utf-8"
},
"body": {
"number": "26f353580936ad3b9baddb17b00e84f33c69e7cb",
"branch": "main",
"buildUrl": "http://my-ci/builds/1",
"_links": {
"self": {
"href": "http://localhost:1234/some-url"
}
}
}
}
```
<a name="a_request_to_create_a_pacticipant_version_given_version_26f353580936ad3b9baddb17b00e84f33c69e7cb_of_pacticipant_Foo_does_not_exist"></a>
Given **version 26f353580936ad3b9baddb17b00e84f33c69e7cb of pacticipant Foo does not exist**, upon receiving **a request to create a pacticipant version** from Pact Broker Client, with
```json
{
"method": "put",
"path": "/HAL-REL-PLACEHOLDER-INDEX-PB-PACTICIPANT-VERSION-Foo-26f353580936ad3b9baddb17b00e84f33c69e7cb",
"headers": {
"Content-Type": "application/json",
"Accept": "application/hal+json"
},
"body": {
"branch": "main",
"buildUrl": "http://my-ci/builds/1"
}
}
```
Pact Broker will respond with:
```json
{
"status": 201,
"headers": {
"Content-Type": "application/hal+json;charset=utf-8"
},
"body": {
"number": "26f353580936ad3b9baddb17b00e84f33c69e7cb",
"branch": "main",
"buildUrl": "http://my-ci/builds/1",
"_links": {
"self": {
"href": "http://localhost:1234/some-url"
}
}
}
}
```
<a name="a_request_to_create_a_webhook_for_a_consumer_and_provider_given_&#39;Condor&#39;_does_not_exist_in_the_pact-broker"></a>
Given **'Condor' does not exist in the pact-broker**, upon receiving **a request to create a webhook for a consumer and provider** from Pact Broker Client, with
```json
Expand Down
29 changes: 26 additions & 3 deletions lib/pact_broker/client/cli/broker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ def can_i_deploy(*ignored_but_necessary)
method_option :broker_username, aliases: "-u", desc: "Pact Broker basic auth username"
method_option :broker_password, aliases: "-p", desc: "Pact Broker basic auth password"
method_option :broker_token, aliases: "-k", desc: "Pact Broker bearer token"
method_option :branch, aliases: "-h", desc: "Repository branch of the consumer version"
method_option :auto_detect_branch, type: :boolean, default: true, desc: "Automatically detect the repository branch from known CI environment variables or git CLI."
method_option :tag, aliases: "-t", type: :array, banner: "TAG", desc: "Tag name for consumer version. Can be specified multiple times."
method_option :tag_with_git_branch, aliases: "-g", type: :boolean, default: false, required: false, desc: "Tag consumer version with the name of the current git branch. Default: false"
method_option :build_url, desc: "The build URL that created the pact"
method_option :merge, type: :boolean, default: false, require: false, desc: "If a pact already exists for this consumer version and provider, merge the contents. Useful when running Pact tests concurrently on different build nodes."
method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"

Expand Down Expand Up @@ -211,12 +214,18 @@ def validate_can_i_deploy_selectors selectors
def publish_pacts pact_files
require 'pact_broker/client/publish_pacts'
write_options = options[:merge] ? { write: :merge } : {}
consumer_version_params = {
number: options.consumer_app_version,
branch: branch,
tags: tags,
build_url: options.build_url,
version_required: (!!options.branch || !!options.build_url || explict_auto_detect_branch)
}.compact

PactBroker::Client::PublishPacts.call(
options.broker_base_url,
file_list(pact_files),
options.consumer_app_version,
tags,
consumer_version_params,
pact_broker_client_options.merge(write_options)
)
end
Expand All @@ -238,10 +247,24 @@ def tags
require 'pact_broker/client/git'

t = [*options.tag]
t << PactBroker::Client::Git.branch if options.tag_with_git_branch
t << PactBroker::Client::Git.branch(raise_error: true) if options.tag_with_git_branch
t.compact.uniq
end

def branch
require 'pact_broker/client/git'

if options.branch.nil? && options.auto_detect_branch
PactBroker::Client::Git.branch(raise_error: explict_auto_detect_branch)
else
options.branch
end
end

def explict_auto_detect_branch
@explict_auto_detect_branch ||= ARGV.include?("--auto-detect-branch")
end

def pact_broker_client_options
client_options = { verbose: options.verbose }
client_options[:token] = options.broker_token if options.broker_token
Expand Down
60 changes: 38 additions & 22 deletions lib/pact_broker/client/git.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@
=end

# Keep in sync with pact-provider-verifier/lib/pact/provider_verifier/git.rb

# `git name-rev --name-only HEAD` provides "tags/v1.35.0^0"
module PactBroker
module Client
module Git
COMMAND = 'git name-rev --name-only HEAD'.freeze
COMMAND = 'git rev-parse --abbrev-ref HEAD'.freeze
BRANCH_ENV_VAR_NAMES = %w{BUILDKITE_BRANCH CIRCLE_BRANCH TRAVIS_BRANCH GIT_BRANCH GIT_LOCAL_BRANCH APPVEYOR_REPO_BRANCH CI_COMMIT_REF_NAME BITBUCKET_BRANCH}.freeze
COMMIT_ENV_VAR_NAMES = %w{BUILDKITE_COMMIT CIRCLE_SHA1 TRAVIS_COMMIT GIT_COMMIT APPVEYOR_REPO_COMMIT CI_COMMIT_ID BITBUCKET_COMMIT}

def self.commit
find_commit_from_env_vars
end

def self.branch
find_branch_from_env_vars || branch_from_git_command
def self.branch(options)
find_branch_from_known_env_vars || find_branch_from_env_var_ending_with_branch || branch_from_git_command(options[:raise_error])
end

# private
Expand All @@ -37,10 +39,21 @@ def self.find_commit_from_env_vars
COMMIT_ENV_VAR_NAMES.collect { |env_var_name| value_from_env_var(env_var_name) }.compact.first
end

def self.find_branch_from_env_vars
def self.find_branch_from_known_env_vars
BRANCH_ENV_VAR_NAMES.collect { |env_var_name| value_from_env_var(env_var_name) }.compact.first
end

def self.find_branch_from_env_var_ending_with_branch
values = ENV.keys
.select{ |env_var_name| env_var_name.end_with?("_BRANCH") }
.collect{ |env_var_name| value_from_env_var(env_var_name) }.compact
if values.size == 1
values.first
else
nil
end
end

def self.value_from_env_var(env_var_name)
val = ENV[env_var_name]
if val && val.strip.size > 0
Expand All @@ -50,24 +63,10 @@ def self.value_from_env_var(env_var_name)
end
end

def self.branch_from_git_command
branch_names = nil
begin
branch_names = execute_git_command
.split("\n")
.collect(&:strip)
.reject(&:empty?)
.collect(&:split)
.collect(&:first)
.collect{ |line| line.gsub(/^origin\//, '') }
.reject{ |line| line == "HEAD" }

rescue StandardError => e
raise PactBroker::Client::Error, "Could not determine current git branch using command `#{COMMAND}`. #{e.class} #{e.message}"
end

validate_branch_names(branch_names)
branch_names[0]
def self.branch_from_git_command(raise_error)
branch_names = execute_and_parse_command(raise_error)
validate_branch_names(branch_names) if raise_error
branch_names.size == 1 ? branch_names[0] : nil
end

def self.validate_branch_names(branch_names)
Expand All @@ -83,6 +82,23 @@ def self.validate_branch_names(branch_names)
def self.execute_git_command
`#{COMMAND}`
end

def self.execute_and_parse_command(raise_error)
execute_git_command
.split("\n")
.collect(&:strip)
.reject(&:empty?)
.collect(&:split)
.collect(&:first)
.collect{ |line| line.gsub(/^origin\//, '') }
.reject{ |line| line == "HEAD" }
rescue StandardError => e
if raise_error
raise PactBroker::Client::Error, "Could not determine current git branch using command `#{COMMAND}`. #{e.class} #{e.message}"
else
return []
end
end
end
end
end
Loading

0 comments on commit a75f7df

Please sign in to comment.