diff --git a/README.md b/README.md index 2557b943..76f3d714 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ PactBroker::Client::PublicationTask.new do | task | require 'my_consumer/version' task.consumer_version = MyConsumer::VERSION task.pact_broker_base_url = "http://pact-broker.my.org" - task.tag = "dev" # optional + task.tags = ["dev"] # optional task.pact_broker_basic_auth = { username: 'basic_auth_user', password: 'basic_auth_pass'} #optional task.write_method = :merge # optional, this will merge the published pact into an existing pact rather than overwriting it if one exists. Not recommended, as it makes a mulch of the workflow on the broker. end diff --git a/lib/pact_broker/client/publish_pacts.rb b/lib/pact_broker/client/publish_pacts.rb index b6971427..3eed82a7 100644 --- a/lib/pact_broker/client/publish_pacts.rb +++ b/lib/pact_broker/client/publish_pacts.rb @@ -6,31 +6,34 @@ module PactBroker module Client class PublishPacts - def initialize pact_broker_base_url, pact_files, consumer_version, tag, pact_broker_client_options={} + def initialize pact_broker_base_url, pact_files, consumer_version, tags, pact_broker_client_options={} @pact_broker_base_url = pact_broker_base_url @pact_files = pact_files @consumer_version = consumer_version - @tag = tag + @tags = tags @pact_broker_client_options = pact_broker_client_options end def call validate $stdout.puts("") - result = pact_files.collect{ | pact_file | publish_pact pact_file }.all? - result = result && tag_consumer_version + result = apply_tags && publish_pacts $stdout.puts("") result end private - attr_reader :pact_broker_base_url, :pact_files, :consumer_version, :tag, :pact_broker_client_options + attr_reader :pact_broker_base_url, :pact_files, :consumer_version, :tags, :pact_broker_client_options def pact_broker_client @pact_broker_client ||= PactBroker::Client::PactBrokerClient.new(base_url: pact_broker_base_url, client_options: pact_broker_client_options) end + def publish_pacts + pact_files.collect{ | pact_file | publish_pact pact_file }.all? + end + def publish_pact pact_file begin $stdout.puts ">> Publishing #{pact_file} to pact broker at #{pact_broker_base_url}" @@ -41,12 +44,19 @@ def publish_pact pact_file end end - def tag_consumer_version - return true unless tag + def apply_tags + return true if tags.nil? || tags.empty? + tags.all? do | tag | + tag_consumer_version tag + end + end + + def tag_consumer_version tag versions = pact_broker_client.pacticipants.versions Retry.until_true do $stdout.puts "Tagging version #{consumer_version} of #{consumer_name} as #{tag.inspect}" versions.tag(pacticipant: consumer_name, version: consumer_version, tag: tag) + true end rescue => e $stderr.puts "Failed to tag version #{consumer_version} of #{consumer_name} due to error: #{e.to_s}\n#{e.backtrace.join("\n")}" diff --git a/lib/pact_broker/client/tasks/publication_task.rb b/lib/pact_broker/client/tasks/publication_task.rb index 496335b3..f29eccee 100644 --- a/lib/pact_broker/client/tasks/publication_task.rb +++ b/lib/pact_broker/client/tasks/publication_task.rb @@ -17,6 +17,7 @@ module Client class PublicationTask < ::Rake::TaskLib attr_accessor :pattern, :pact_broker_base_url, :consumer_version, :tag, :write_method, :pact_broker_basic_auth + alias_method :tags, :tag def initialize name = nil, &block @name = name @@ -35,7 +36,7 @@ def rake_task &block require 'pact_broker/client/publish_pacts' basic_auth_client_options = pact_broker_basic_auth ? {basic_auth: pact_broker_basic_auth} : {} pact_broker_client_options = basic_auth_client_options.merge(write_method ? {write: write_method} : {}) - success = PactBroker::Client::PublishPacts.new(pact_broker_base_url, FileList[pattern], consumer_version, tag, pact_broker_client_options).call + success = PactBroker::Client::PublishPacts.new(pact_broker_base_url, FileList[pattern], consumer_version, [*tags], pact_broker_client_options).call raise "One or more pacts failed to be published" unless success end end diff --git a/spec/lib/pact_broker/client/publish_pacts_spec.rb b/spec/lib/pact_broker/client/publish_pacts_spec.rb index 637644ed..defaac85 100644 --- a/spec/lib/pact_broker/client/publish_pacts_spec.rb +++ b/spec/lib/pact_broker/client/publish_pacts_spec.rb @@ -22,7 +22,7 @@ module Client let(:pact_broker_client) { double("PactBroker::Client")} let(:pact_files) { ['spec/pacts/consumer-provider.json']} let(:consumer_version) { "1.2.3" } - let(:tag) { nil } + let(:tags) { nil } let(:pact_hash) { {consumer: {name: 'Consumer'}, provider: {name: 'Provider'}, interactions: [] } } let(:pacts_client) { instance_double("PactBroker::ClientSupport::Pacts")} let(:pact_versions_client) { instance_double("PactBroker::Client::Versions", tag: false) } @@ -36,7 +36,7 @@ module Client } end - subject { PublishPacts.new(pact_broker_base_url, pact_files, consumer_version, tag, pact_broker_client_options) } + subject { PublishPacts.new(pact_broker_base_url, pact_files, consumer_version, tags, pact_broker_client_options) } before do FileUtils.mkdir_p "spec/pacts" @@ -109,10 +109,16 @@ module Client end context "when a tag is provided" do - let(:tag) { "dev" } + let(:tags) { ["dev"] } it "tags the consumer version" do - expect(pact_versions_client).to receive(:tag).with({pacticipant: "Consumer", version: consumer_version, tag: tag}) + expect(pact_versions_client).to receive(:tag).with({pacticipant: "Consumer", version: consumer_version, tag: "dev"}) + subject.call + end + + it "tags the version before publishing the pact so that there aren't timing issues retrieving pacts by tag" do + expect(pact_versions_client).to receive(:tag).ordered + expect(pacts_client).to receive(:publish).ordered subject.call end diff --git a/spec/lib/pact_broker/client/tasks/publication_task_spec.rb b/spec/lib/pact_broker/client/tasks/publication_task_spec.rb index aa0aa33c..ed6cdf55 100644 --- a/spec/lib/pact_broker/client/tasks/publication_task_spec.rb +++ b/spec/lib/pact_broker/client/tasks/publication_task_spec.rb @@ -14,8 +14,8 @@ module PactBroker::Client let(:pact_file_list) { ['spec/pact/consumer-provider.json'] } before do - PactBroker::Client::PublishPacts.stub(:new).and_return(publish_pacts) - FileList.stub(:[]).with(pattern).and_return(pact_file_list) + allow(PactBroker::Client::PublishPacts).to receive(:new).and_return(publish_pacts) + allow(FileList).to receive(:[]).with(pattern).and_return(pact_file_list) end let(:pattern) { "spec/pacts/*.json" } @@ -30,15 +30,15 @@ module PactBroker::Client context "when pacts are succesfully published" do it "invokes PublishPacts with the default values" do - PactBroker::Client::PublishPacts.should_receive(:new).with('http://pact-broker', pact_file_list, '1.2.3', nil, {}).and_return(publish_pacts) - publish_pacts.should_receive(:call).and_return(true) + expect(PactBroker::Client::PublishPacts).to receive(:new).with('http://pact-broker', pact_file_list, '1.2.3', [], {}).and_return(publish_pacts) + expect(publish_pacts).to receive(:call).and_return(true) Rake::Task['pact:publish'].execute end end context "when a pact fails to be published" do it "raises an error" do - publish_pacts.should_receive(:call).and_return(false) + expect(publish_pacts).to receive(:call).and_return(false) expect { Rake::Task['pact:publish'].execute }.to raise_error("One or more pacts failed to be published") end end @@ -53,8 +53,8 @@ module PactBroker::Client end it "invokes PublishPacts with the write method set" do - PactBroker::Client::PublishPacts.should_receive(:new).with('http://pact-broker', pact_file_list, '1.2.3', nil, {write: :merge}).and_return(publish_pacts) - publish_pacts.should_receive(:call).and_return(true) + expect(PactBroker::Client::PublishPacts).to receive(:new).with('http://pact-broker', pact_file_list, '1.2.3', [], {write: :merge}).and_return(publish_pacts) + expect(publish_pacts).to receive(:call).and_return(true) Rake::Task['pact:publish:merge'].execute end end @@ -78,8 +78,8 @@ module PactBroker::Client let(:pattern) { @pattern } it "invokes PublishPacts with the customised values" do - PactBroker::Client::PublishPacts.should_receive(:new).with(@pact_broker_base_url, pact_file_list, '1.2.3', @tag, {basic_auth: @pact_broker_basic_auth}) - publish_pacts.should_receive(:call).and_return(true) + expect(PactBroker::Client::PublishPacts).to receive(:new).with(@pact_broker_base_url, pact_file_list, '1.2.3', [@tag], {basic_auth: @pact_broker_basic_auth}) + expect(publish_pacts).to receive(:call).and_return(true) Rake::Task['pact:publish:custom'].execute end end