From 1349bd03b101f6297e64e43fb31ceca514b837b6 Mon Sep 17 00:00:00 2001 From: Stan Vodetskyi Date: Tue, 8 Oct 2024 21:18:03 -0700 Subject: [PATCH 1/3] feat: support --ignore flag in can-i-merge command --- README.md | 7 +++++ ...ow.md => Pact Broker Client - PactFlow.md} | 0 lib/pact_broker/client/cli/matrix_commands.rb | 9 ++++-- spec/integration/can_i_merge_spec.rb | 29 ++++++++++++++----- 4 files changed, 35 insertions(+), 10 deletions(-) rename doc/pacts/markdown/{Pact Broker Client - Pactflow.md => Pact Broker Client - PactFlow.md} (100%) diff --git a/README.md b/README.md index f249969..7a17b33 100644 --- a/README.md +++ b/README.md @@ -572,6 +572,13 @@ Options: -e, [--version=VERSION] # The pacticipant version. Must be entered after the --pacticipant that it relates to. + [--ignore=PACTICIPANT] + # The pacticipant name to ignore. Use once for each pacticipant + being ignored. A specific version can be ignored by also + specifying a --version after the pacticipant name option. The + environment variable PACT_BROKER_CAN_I_MERGE_IGNORE may also be + used to specify a pacticipant name to ignore, with commas to + separate multiple pacticipant names if necessary. -o, [--output=OUTPUT] # json or table # Default: table diff --git a/doc/pacts/markdown/Pact Broker Client - Pactflow.md b/doc/pacts/markdown/Pact Broker Client - PactFlow.md similarity index 100% rename from doc/pacts/markdown/Pact Broker Client - Pactflow.md rename to doc/pacts/markdown/Pact Broker Client - PactFlow.md diff --git a/lib/pact_broker/client/cli/matrix_commands.rb b/lib/pact_broker/client/cli/matrix_commands.rb index 332c228..29dbd9e 100644 --- a/lib/pact_broker/client/cli/matrix_commands.rb +++ b/lib/pact_broker/client/cli/matrix_commands.rb @@ -48,6 +48,7 @@ def can_i_deploy(*ignored_but_necessary) long_desc "Checks if the specified pacticipant version is compatible with the configured main branch of each of the pacticipants with which it is integrated." method_option :pacticipant, required: true, aliases: "-a", desc: "The pacticipant name. Use once for each pacticipant being checked." method_option :version, required: false, aliases: "-e", desc: "The pacticipant version. Must be entered after the --pacticipant that it relates to." + method_option :ignore, required: false, banner: "PACTICIPANT", desc: "The pacticipant name to ignore. Use once for each pacticipant being ignored. A specific version can be ignored by also specifying a --version after the pacticipant name option. The environment variable PACT_BROKER_CAN_I_MERGE_IGNORE may also be used to specify a pacticipant name to ignore, with commas to separate multiple pacticipant names if necessary." method_option :output, aliases: "-o", desc: "json or table", default: "table" method_option :retry_while_unknown, banner: "TIMES", type: :numeric, default: 0, required: false, desc: "The number of times to retry while there is an unknown verification result (ie. the provider verification is likely still running)" method_option :retry_interval, banner: "SECONDS", type: :numeric, default: 10, required: false, desc: "The time between retries in seconds. Use in conjuction with --retry-while-unknown" @@ -59,11 +60,12 @@ def can_i_merge(*ignored_but_necessary) require "pact_broker/client/can_i_deploy" validate_credentials - selectors = VersionSelectorOptionsParser.call(ARGV) + selectors = VersionSelectorOptionsParser.call(ARGV).select { |s| !s[:ignore] } + ignore_selectors = VersionSelectorOptionsParser.call(ARGV).select { |s| s[:ignore] } + ignore_merge_selectors_from_environment_variable validate_can_i_deploy_selectors(selectors) dry_run = options.dry_run || ENV["PACT_BROKER_CAN_I_MERGE_DRY_RUN"] == "true" can_i_merge_options = { output: options.output, retry_while_unknown: options.retry_while_unknown, retry_interval: options.retry_interval, dry_run: dry_run, verbose: options.verbose } - result = CanIDeploy.call(selectors, { with_main_branches: true }, can_i_merge_options, pact_broker_client_options) + result = CanIDeploy.call(selectors, { with_main_branches: true, ignore_selectors: ignore_selectors}, can_i_merge_options, pact_broker_client_options) $stdout.puts result.message $stdout.flush exit(1) unless result.success @@ -121,6 +123,9 @@ def validate_can_i_deploy_options def ignore_selectors_from_environment_variable ENV.fetch("PACT_BROKER_CAN_I_DEPLOY_IGNORE", "").split(",").collect(&:strip).collect{ |i| { pacticipant: i } } end + def ignore_merge_selectors_from_environment_variable + ENV.fetch("PACT_BROKER_CAN_I_MERGE_IGNORE", "").split(",").collect(&:strip).collect{ |i| { pacticipant: i } } + end end end end diff --git a/spec/integration/can_i_merge_spec.rb b/spec/integration/can_i_merge_spec.rb index eef51a0..b887375 100644 --- a/spec/integration/can_i_merge_spec.rb +++ b/spec/integration/can_i_merge_spec.rb @@ -10,14 +10,6 @@ module CLI allow($stdout).to receive(:puts) allow($stderr).to receive(:puts) allow(Retry).to receive(:sleep) - - stub_const("ARGV", %w[--pacticipant Foo --version 1]) - stub_request(:get, "http://pact-broker/matrix?latest=true&latestby=cvp&mainBranch=true&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1"). - with( - headers: { - 'Accept'=>'application/hal+json', - }). - to_return(status: 200, body: File.read("spec/support/matrix.json"), headers: { "Content-Type" => "application/hal+json" }) end let(:minimum_valid_options) do @@ -35,6 +27,27 @@ module CLI let(:invoke_can_i_merge) { subject.can_i_merge } it "sends a matrix query" do + stub_request(:get, "http://pact-broker/matrix?latest=true&latestby=cvp&mainBranch=true&q%5B%5D%5Bpacticipant%5D=Foo&q%5B%5D%5Bversion%5D=1"). + with( + headers: { + 'Accept'=>'application/hal+json', + }). + to_return(status: 200, body: File.read("spec/support/matrix.json"), headers: { "Content-Type" => "application/hal+json" }) + + stub_const("ARGV", %w[--pacticipant Foo --version 1]) + expect($stdout).to receive(:puts).with(/Computer says yes/) + invoke_can_i_merge + end + + + it "ignores pacticipant if --ignore flag is provided" do + stub_request(:get, "http://pact-broker/matrix?latest=true&latestby=cvp&mainBranch=true&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=3.4.5&ignore%5B%5D%5Bpacticipant%5D=Foo"). + with( + headers: { + 'Accept'=>'application/hal+json', + }). + to_return(status: 200, body: File.read("spec/support/matrix.json"), headers: { "Content-Type" => "application/hal+json" }) + stub_const("ARGV", %w[--pacticipant Bar --version 3.4.5 --ignore Foo]) expect($stdout).to receive(:puts).with(/Computer says yes/) invoke_can_i_merge end From 12ee63f9362782c466bc0640233a88be02e908f3 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Wed, 23 Oct 2024 21:14:13 +0100 Subject: [PATCH 2/3] test: test ignored app allows deployable result can-i-merge --- spec/integration/can_i_merge_spec.rb | 8 +-- spec/support/matrix_with_ignored_failure.json | 62 +++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 spec/support/matrix_with_ignored_failure.json diff --git a/spec/integration/can_i_merge_spec.rb b/spec/integration/can_i_merge_spec.rb index b887375..3623f79 100644 --- a/spec/integration/can_i_merge_spec.rb +++ b/spec/integration/can_i_merge_spec.rb @@ -41,14 +41,14 @@ module CLI it "ignores pacticipant if --ignore flag is provided" do - stub_request(:get, "http://pact-broker/matrix?latest=true&latestby=cvp&mainBranch=true&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=3.4.5&ignore%5B%5D%5Bpacticipant%5D=Foo"). + stub_request(:get, "http://pact-broker/matrix?latest=true&latestby=cvp&mainBranch=true&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=5&ignore%5B%5D%5Bpacticipant%5D=Foo"). with( headers: { 'Accept'=>'application/hal+json', }). - to_return(status: 200, body: File.read("spec/support/matrix.json"), headers: { "Content-Type" => "application/hal+json" }) - stub_const("ARGV", %w[--pacticipant Bar --version 3.4.5 --ignore Foo]) - expect($stdout).to receive(:puts).with(/Computer says yes/) + to_return(status: 200, body: File.read("spec/support/matrix_with_ignored_failure.json"), headers: { "Content-Type" => "application/hal+json" }) + stub_const("ARGV", %w[--pacticipant Bar --version 5 --ignore Foo]) + expect($stdout).to receive(:puts).with(/Computer says yes.*false \[ignored\]/m) invoke_can_i_merge end end diff --git a/spec/support/matrix_with_ignored_failure.json b/spec/support/matrix_with_ignored_failure.json new file mode 100644 index 0000000..e7d4893 --- /dev/null +++ b/spec/support/matrix_with_ignored_failure.json @@ -0,0 +1,62 @@ +{ + "summary": { + "deployable": true, + "ignored": 1, + "unknown": 0 + }, + "matrix": [ + { + "consumer": { + "name": "Baz", + "version": { + "number": "4" + } + }, + "provider": { + "name": "Bar", + "version": { + "number": "5" + } + }, + "verificationResult": { + "verifiedAt": "2017-10-10T12:49:04+11:00", + "success": true, + "_links": { + "self": { + "href": "http://result" + } + } + }, + "pact": { + "createdAt": "2017-10-10T12:49:04+11:00" + } + }, + { + "consumer": { + "name": "Foo", + "version": { + "number": "4" + } + }, + "provider": { + "name": "Bar", + "version": { + "number": "5" + } + }, + "verificationResult": { + "verifiedAt": "2017-10-10T12:49:04+11:00", + "success": false, + "_links": { + "self": { + "href": "http://result" + } + } + }, + "ignored": true, + "pact": { + "createdAt": "2017-10-10T12:49:04+11:00" + } + } + ] +} From f77bfae9c2768b84820d4ca6f1850e71c8a2dc3e Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Wed, 23 Oct 2024 21:22:53 +0100 Subject: [PATCH 3/3] test: test can-i-merge exits with failure if one app has failing result --- spec/integration/can_i_merge_spec.rb | 11 +++++ spec/support/matrix_with_failure.json | 61 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 spec/support/matrix_with_failure.json diff --git a/spec/integration/can_i_merge_spec.rb b/spec/integration/can_i_merge_spec.rb index 3623f79..13226bf 100644 --- a/spec/integration/can_i_merge_spec.rb +++ b/spec/integration/can_i_merge_spec.rb @@ -39,6 +39,17 @@ module CLI invoke_can_i_merge end + it "exits with failure if one pacticipant has a failing result" do + stub_request(:get, "http://pact-broker/matrix?latest=true&latestby=cvp&mainBranch=true&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=5"). + with( + headers: { + 'Accept'=>'application/hal+json', + }). + to_return(status: 200, body: File.read("spec/support/matrix_with_failure.json"), headers: { "Content-Type" => "application/hal+json" }) + stub_const("ARGV", %w[--pacticipant Bar --version 5]) + expect($stdout).to receive(:puts).with(/Computer says no.*(success).*(failure)/m) + expect { invoke_can_i_merge }.to raise_error(SystemExit) + end it "ignores pacticipant if --ignore flag is provided" do stub_request(:get, "http://pact-broker/matrix?latest=true&latestby=cvp&mainBranch=true&q%5B%5D%5Bpacticipant%5D=Bar&q%5B%5D%5Bversion%5D=5&ignore%5B%5D%5Bpacticipant%5D=Foo"). diff --git a/spec/support/matrix_with_failure.json b/spec/support/matrix_with_failure.json new file mode 100644 index 0000000..f73c9a5 --- /dev/null +++ b/spec/support/matrix_with_failure.json @@ -0,0 +1,61 @@ +{ + "summary": { + "deployable": false, + "ignored": 0, + "unknown": 0 + }, + "matrix": [ + { + "consumer": { + "name": "Baz", + "version": { + "number": "4" + } + }, + "provider": { + "name": "Bar", + "version": { + "number": "5" + } + }, + "verificationResult": { + "verifiedAt": "2017-10-10T12:49:04+11:00", + "success": true, + "_links": { + "self": { + "href": "http://result" + } + } + }, + "pact": { + "createdAt": "2017-10-10T12:49:04+11:00" + } + }, + { + "consumer": { + "name": "Foo", + "version": { + "number": "4" + } + }, + "provider": { + "name": "Bar", + "version": { + "number": "5" + } + }, + "verificationResult": { + "verifiedAt": "2017-10-10T12:49:04+11:00", + "success": false, + "_links": { + "self": { + "href": "http://result" + } + } + }, + "pact": { + "createdAt": "2017-10-10T12:49:04+11:00" + } + } + ] +}