Skip to content

Commit

Permalink
feat: support publishing verification results with a version branch
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Sep 1, 2021
1 parent c5b8c6d commit da2facf
Show file tree
Hide file tree
Showing 16 changed files with 113 additions and 37 deletions.
2 changes: 1 addition & 1 deletion lib/pact/hal/http_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def create_request uri, http_method, body = nil, headers = {}
def perform_request request, uri
response = Retry.until_true do
http = Net::HTTP.new(uri.host, uri.port, :ENV)
http.set_debug_output(output_stream) if verbose
http.set_debug_output(output_stream) if verbose || ENV['VERBOSE'] == 'true'
http.use_ssl = (uri.scheme == 'https')
http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && ENV['SSL_CERT_FILE'] != ''
http.ca_path = ENV['SSL_CERT_DIR'] if ENV['SSL_CERT_DIR'] && ENV['SSL_CERT_DIR'] != ''
Expand Down
10 changes: 6 additions & 4 deletions lib/pact/pact_broker/fetch_pact_uris_for_verification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Pact
module PactBroker
class FetchPactURIsForVerification
include PactSelectionDescription
attr_reader :provider, :consumer_version_selectors, :provider_version_tags, :broker_base_url, :http_client_options, :http_client, :options
attr_reader :provider, :consumer_version_selectors, :provider_version_branch, :provider_version_tags, :broker_base_url, :http_client_options, :http_client, :options

PACTS_FOR_VERIFICATION_RELATION = 'pb:provider-pacts-for-verification'.freeze
PACTS_FOR_VERIFICATION_RELATION_BETA = 'beta:provider-pacts-for-verification'.freeze
Expand All @@ -20,18 +20,19 @@ class FetchPactURIsForVerification
SELF = 'self'.freeze
EMBEDDED = '_embedded'.freeze

def initialize(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options = {})
def initialize(provider, consumer_version_selectors, provider_version_branch, provider_version_tags, broker_base_url, http_client_options, options = {})
@provider = provider
@consumer_version_selectors = consumer_version_selectors || []
@provider_version_branch = provider_version_branch
@provider_version_tags = [*provider_version_tags]
@http_client_options = http_client_options
@broker_base_url = broker_base_url
@http_client = Pact::Hal::HttpClient.new(http_client_options)
@options = options
end

def self.call(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options = {})
new(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options, options).call
def self.call(provider, consumer_version_selectors, provider_version_branch, provider_version_tags, broker_base_url, http_client_options, options = {})
new(provider, consumer_version_selectors, provider_version_branch, provider_version_tags, broker_base_url, http_client_options, options).call
end

def call
Expand Down Expand Up @@ -76,6 +77,7 @@ def query
q["includePendingStatus"] = true if options[:include_pending_status]
q["consumerVersionSelectors"] = consumer_version_selectors if consumer_version_selectors.any?
q["providerVersionTags"] = provider_version_tags if provider_version_tags.any?
q["providerVersionBranch"] = provider_version_branch if provider_version_branch
q["includeWipPactsSince"] = options[:include_wip_pacts_since] if options[:include_wip_pacts_since]
q
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ class PactVerificationFromBroker
# in parent scope, it will clash with these ones,
# so put an underscore in front of the name to be safer.

attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose, :_consumer_version_selectors
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_branch, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose, :_consumer_version_selectors

def initialize(provider_name, provider_version_tags)
def initialize(provider_name, provider_version_branch, provider_version_tags)
@_provider_name = provider_name
@_provider_version_branch = provider_version_branch
@_provider_version_tags = provider_version_tags
@_consumer_version_tags = []
@_consumer_version_selectors = []
Expand Down Expand Up @@ -69,6 +70,7 @@ def create_pact_verification
fetch_pacts = Pact::PactBroker::FetchPactURIsForVerification.new(
_provider_name,
consumer_version_selectors,
_provider_version_branch,
_provider_version_tags,
_pact_broker_base_url,
_basic_auth_options.merge(verbose: _verbose),
Expand Down
4 changes: 3 additions & 1 deletion lib/pact/provider/configuration/service_provider_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ module Configuration
class ServiceProviderConfig

attr_accessor :application_version
attr_reader :branch

def initialize application_version, tags, publish_verification_results, &app_block
def initialize application_version, branch, tags, publish_verification_results, &app_block
@application_version = application_version
@branch = branch
@tags = [*tags]
@publish_verification_results = publish_verification_results
@app_block = app_block
Expand Down
10 changes: 7 additions & 3 deletions lib/pact/provider/configuration/service_provider_dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ServiceProviderDSL

extend Pact::DSL

attr_accessor :name, :app_block, :application_version, :tags, :publish_verification_results
attr_accessor :name, :app_block, :application_version, :branch, :tags, :publish_verification_results

CONFIG_RU_APP = lambda {
unless File.exist? Pact.configuration.config_ru_path
Expand Down Expand Up @@ -44,6 +44,10 @@ def app_version_tags tags
self.tags = tags
end

def app_version_branch branch
self.branch = branch
end

def publish_verification_results publish_verification_results
self.publish_verification_results = publish_verification_results
Pact::RSpec.with_rspec_2 do
Expand All @@ -65,7 +69,7 @@ def create_pact_verification consumer_name, options, &block
end

def create_pact_verification_from_broker(&block)
PactVerificationFromBroker.build(name, tags, &block)
PactVerificationFromBroker.build(name, branch, tags, &block)
end

def finalize
Expand All @@ -85,7 +89,7 @@ def application_version_blank?
end

def create_service_provider
Pact.configuration.provider = ServiceProviderConfig.new(application_version, tags, publish_verification_results, &@app_block)
Pact.configuration.provider = ServiceProviderConfig.new(application_version, branch, tags, publish_verification_results, &@app_block)
end
end
end
Expand Down
28 changes: 27 additions & 1 deletion lib/pact/provider/verification_results/publish.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Publish
PUBLISH_RELATION = 'pb:publish-verification-results'.freeze
PROVIDER_RELATION = 'pb:provider'.freeze
VERSION_TAG_RELATION = 'pb:version-tag'.freeze
BRANCH_VERSION_RELATION = 'pb:branch-version'.freeze

def self.call pact_source, verification_result, options = {}
new(pact_source, verification_result, options).call
Expand All @@ -31,6 +32,7 @@ def initialize pact_source, verification_result, options = {}

def call
if can_publish_verification_results?
create_branch_version_if_configured
tag_versions_if_configured
publish_verification_results
true
Expand Down Expand Up @@ -72,8 +74,28 @@ def tag_versions_if_configured
end
end

def create_branch_version_if_configured
if Pact.configuration.provider.branch
branch_version_link = provider_entity._link(BRANCH_VERSION_RELATION)
if branch_version_link
version_number = Pact.configuration.provider.application_version
branch = Pact.configuration.provider.branch

Pact.configuration.output_stream.puts "INFO: Creating #{provider_name} version #{version_number} with branch \"#{branch}\""
branch_entity = branch_version_link.expand(
version: version_number,
branch: branch
).put
unless branch_entity.success?
raise PublicationError.new("Error returned from tagging request: status=#{branch_entity.response.code} body=#{branch_entity.response.body}")
end
else
raise PublicationError.new("This version of the Pact Broker does not support version branches. Please update to version 2.58.0 or later.")
end
end
end

def tag_versions
provider_entity = pact_entity.get(PROVIDER_RELATION)
tag_link = provider_entity._link(VERSION_TAG_RELATION) || hacky_tag_url(provider_entity)
provider_application_version = Pact.configuration.provider.application_version

Expand Down Expand Up @@ -111,6 +133,10 @@ def consumer_name
def provider_name
pact_source.pact_hash['provider']['name']
end

def provider_entity
@provider_entity ||= pact_entity.get(PROVIDER_RELATION)
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions spec/integration/publish_verification_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
double('provider_configuration',
application_version: '1.2.3',
publish_verification_results?: true,
branch: nil,
tags: [])
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ module PactBroker
let(:broker_base_url) { "http://broker.org" }
let(:http_client_options) { {} }
let(:consumer_version_selectors) { [{ tag: "cmaster", latest: true, fallbackTag: 'blah' }] }
let(:provider_version_branch) { "pbranch" }
let(:provider_version_tags) { ["pmaster"] }

subject { FetchPactURIsForVerification.call(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options)}
subject { FetchPactURIsForVerification.call(provider, consumer_version_selectors, provider_version_branch, provider_version_tags, broker_base_url, http_client_options)}

context "when there is an error retrieving the index resource" do
before do
Expand All @@ -39,7 +40,7 @@ module PactBroker

let(:provider_version_tags) { "pmaster" }

subject { FetchPactURIsForVerification.new(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options)}
subject { FetchPactURIsForVerification.new(provider, consumer_version_selectors, provider_version_branch, provider_version_tags, broker_base_url, http_client_options)}

it "wraps an array around it" do
expect(subject.provider_version_tags).to eq ["pmaster"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ module Configuration
end

it "builds a PactVerificationFromBroker" do
expect(PactVerificationFromBroker).to receive(:build).with("some-provider", ["dev"])
expect(PactVerificationFromBroker).to receive(:build).with("some-provider", nil, ["dev"])
subject
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Configuration
describe PactVerificationFromBroker do
describe 'build' do
let(:provider_name) {'provider-name'}
let(:provider_version_branch) { 'main' }
let(:provider_version_tags) { ['master'] }
let(:base_url) { "http://broker.org" }
let(:since) { "2020-01-01" }
Expand All @@ -25,7 +26,7 @@ module Configuration

context "with valid values" do
subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do
pact_broker_base_url base_url, basic_auth_options
consumer_version_tags tags
enable_pending true
Expand All @@ -43,6 +44,7 @@ module Configuration
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(
provider_name,
consumer_version_selectors,
provider_version_branch,
provider_version_tags,
base_url,
basic_auth_opts,
Expand All @@ -66,6 +68,7 @@ module Configuration
anything,
anything,
anything,
anything,
{
include_pending_status: true,
include_wip_pacts_since: since.xmlschema
Expand All @@ -78,7 +81,7 @@ module Configuration

context "with a missing base url" do
subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do

end
end
Expand All @@ -90,27 +93,27 @@ module Configuration

context "with a non array object for consumer_version_tags" do
subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do
pact_broker_base_url base_url
consumer_version_tags "master"
end
end

it "coerces the value into an array" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "master", latest: true}], anything, anything, anything, anything)
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "master", latest: true}], anything, anything, anything, anything, anything)
subject
end
end

context "when no consumer_version_tags are provided" do
subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do
pact_broker_base_url base_url
end
end

it "creates an instance of FetchPacts with an emtpy array for the consumer_version_tags" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [], anything, anything, anything, anything)
it "creates an instance of FetchPacts with an empty array for the consumer_version_tags" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [], anything, anything, anything, anything, anything)
subject
end
end
Expand All @@ -119,14 +122,14 @@ module Configuration
let(:tags) { [{ name: 'main', all: true, fallback: 'fallback' }] }

subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do
pact_broker_base_url base_url
consumer_version_tags tags
end
end

it "converts them to selectors" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "main", latest: false, fallbackTag: 'fallback'}], anything, anything, anything, anything)
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "main", latest: false, fallbackTag: 'fallback'}], anything, anything, anything, anything, anything)
subject
end
end
Expand All @@ -135,7 +138,7 @@ module Configuration
let(:tags) { [true] }

subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do
pact_broker_base_url base_url
consumer_version_tags tags
end
Expand All @@ -150,27 +153,27 @@ module Configuration
let(:tags) { [{ tag: 'main', latest: true, fallback_tag: 'fallback' }] }

subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do
pact_broker_base_url base_url
consumer_version_selectors tags
end
end

it "converts the casing of the key names" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "main", latest: true, fallbackTag: 'fallback'}], anything, anything, anything, anything)
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "main", latest: true, fallbackTag: 'fallback'}], anything, anything, anything, anything, anything)
subject
end
end

context "when no verbose flag is provided" do
subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
PactVerificationFromBroker.build(provider_name, provider_version_branch, provider_version_tags) do
pact_broker_base_url base_url
end
end

it "creates an instance of FetchPactURIsForVerification with verbose: false" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, anything, anything, anything, hash_including(verbose: false), anything)
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, anything, anything, anything, anything, hash_including(verbose: false), anything)
subject
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
require 'spec_helper'
require 'pact/provider/configuration/service_provider_config'

module Pact
module Provider
module Configuration
describe ServiceProviderConfig do

describe "app" do

let(:app_block) { ->{ Object.new } }

subject { ServiceProviderConfig.new("1.2.3'", [], true, &app_block) }
subject { ServiceProviderConfig.new("1.2.3'", "main", [], true, &app_block) }

it "should execute the app_block each time" do
expect(subject.app.object_id).to_not equal(subject.app.object_id)
end

end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,15 @@ module Configuration
subject do
ServiceProviderDSL.build 'some-provider' do
app {}
app_version_branch 'main'
app_version_tags ['dev']
honours_pacts_from_pact_broker do
end
end
end

it 'builds a PactVerificationFromBroker' do
expect(PactVerificationFromBroker).to receive(:build).with('some-provider', ['dev'])
expect(PactVerificationFromBroker).to receive(:build).with('some-provider', 'main', ['dev'])
subject
end
end
Expand Down
Loading

0 comments on commit da2facf

Please sign in to comment.