Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for delete-branch command #151

Merged
merged 5 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,38 @@ Options:

Test the execution of a webhook

### Branches

#### delete-branch

```
Usage:
pact-broker delete-branch --branch=BRANCH -a, --pacticipant=PACTICIPANT -b, --broker-base-url=BROKER_BASE_URL

Options:
-a, --pacticipant=PACTICIPANT
# The name of the pacticipant that the branch belongs to.
--branch=BRANCH
# The pacticipant branch name.
[--error-when-not-found], [--no-error-when-not-found]
# Raise an error if the branch that is to be deleted is not
found.
# Default: true
-b, --broker-base-url=BROKER_BASE_URL
# The base URL of the Pact Broker
-u, [--broker-username=BROKER_USERNAME]
# Pact Broker basic auth username
-p, [--broker-password=BROKER_PASSWORD]
# Pact Broker basic auth password
-k, [--broker-token=BROKER_TOKEN]
# Pact Broker bearer token
-v, [--verbose], [--no-verbose]
# Verbose output.
# Default: false
```

Deletes a pacticipant branch.

### Tags

#### create-version-tag
Expand Down
45 changes: 45 additions & 0 deletions doc/pacts/markdown/Pact Broker Client - Pact Broker.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,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-branch_relation_exists_in_the_index_resource) given the pb:pacticipant-branch relation exists in the index resource

* [A request for the index resource](#a_request_for_the_index_resource_given_the_pb:pacticipant-version_and_pb:environments_relations_exist_in_the_index_resource) given the pb:pacticipant-version and pb:environments relations exist in the index resource

* [A request for the index resource](#a_request_for_the_index_resource_given_the_pb:publish-contracts_relations_exists_in_the_index_resource) given the pb:publish-contracts relations exists in the index resource
Expand Down Expand Up @@ -76,6 +78,8 @@

* [A request to create a webhook with every possible event type](#a_request_to_create_a_webhook_with_every_possible_event_type_given_the_'Pricing_Service'_and_'Condor'_already_exist_in_the_pact-broker) given the 'Pricing Service' and 'Condor' already exist in the pact-broker

* [A request to delete a pacticipant branch](#a_request_to_delete_a_pacticipant_branch_given_a_branch_named_main_exists_for_pacticipant_Foo) given a branch named main exists for pacticipant Foo

* [A request to determine if Bar can be deployed with all Foo tagged prod, ignoring the verification for Foo version 3.4.5](#a_request_to_determine_if_Bar_can_be_deployed_with_all_Foo_tagged_prod,_ignoring_the_verification_for_Foo_version_3.4.5_given_provider_Bar_version_4.5.6_has_a_successful_verification_for_Foo_version_1.2.3_tagged_prod_and_a_failed_verification_for_version_3.4.5_tagged_prod) given provider Bar version 4.5.6 has a successful verification for Foo version 1.2.3 tagged prod and a failed verification for version 3.4.5 tagged prod

* [A request to get the Pricing Service](#a_request_to_get_the_Pricing_Service_given_the_'Pricing_Service'_already_exists_in_the_pact-broker) given the 'Pricing Service' already exists in the pact-broker
Expand Down Expand Up @@ -827,6 +831,33 @@ Pact Broker will respond with:
}
}
```
<a name="a_request_for_the_index_resource_given_the_pb:pacticipant-branch_relation_exists_in_the_index_resource"></a>
Given **the pb:pacticipant-branch 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-branch": {
"href": "http://localhost:1234/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-BRANCH-{pacticipant}-{branch}"
}
}
}
}
```
<a name="a_request_for_the_index_resource_given_the_pb:pacticipant-version_and_pb:environments_relations_exist_in_the_index_resource"></a>
Given **the pb:pacticipant-version and pb:environments relations exist in the index resource**, upon receiving **a request for the index resource** from Pact Broker Client, with
```json
Expand Down Expand Up @@ -1766,6 +1797,20 @@ Pact Broker will respond with:
}
}
```
<a name="a_request_to_delete_a_pacticipant_branch_given_a_branch_named_main_exists_for_pacticipant_Foo"></a>
Given **a branch named main exists for pacticipant Foo**, upon receiving **a request to delete a pacticipant branch** from Pact Broker Client, with
```json
{
"method": "DELETE",
"path": "/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-BRANCH-Foo-main"
}
```
Pact Broker will respond with:
```json
{
"status": 204
}
```
<a name="a_request_to_determine_if_Bar_can_be_deployed_with_all_Foo_tagged_prod,_ignoring_the_verification_for_Foo_version_3.4.5_given_provider_Bar_version_4.5.6_has_a_successful_verification_for_Foo_version_1.2.3_tagged_prod_and_a_failed_verification_for_version_3.4.5_tagged_prod"></a>
Given **provider Bar version 4.5.6 has a successful verification for Foo version 1.2.3 tagged prod and a failed verification for version 3.4.5 tagged prod**, upon receiving **a request to determine if Bar can be deployed with all Foo tagged prod, ignoring the verification for Foo version 3.4.5** from Pact Broker Client, with
```json
Expand Down
64 changes: 64 additions & 0 deletions lib/pact_broker/client/branches/delete_branch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require "pact_broker/client/base_command"

module PactBroker
module Client
module Branches
class DeleteBranch < PactBroker::Client::BaseCommand

NOT_SUPPORTED_MESSAGE_PACT_BROKER = "This version of the Pact Broker does not support deleting branches. Please upgrade to version 2.108.0 or later."
NOT_SUPPORTED_MESSAGE_PACTFLOW = "This version of PactFlow does not support deleting branches. Please upgrade to the latest version."

def initialize(params, options, pact_broker_client_options)
super
@pacticipant_name = params.fetch(:pacticipant)
@branch_name = params.fetch(:branch)
@error_when_not_found = params.fetch(:error_when_not_found)
end

def do_call
check_if_command_supported
@deleted_resource = branch_link.delete
PactBroker::Client::CommandResult.new(success?, result_message)
end

private

attr_reader :pacticipant_name, :branch_name, :error_when_not_found, :deleted_resource

def branch_link
index_resource._link("pb:pacticipant-branch").expand(pacticipant: pacticipant_name, branch: branch_name)
end

def check_if_command_supported
unless index_resource.can?("pb:pacticipant-branch")
raise PactBroker::Client::Error.new(is_pactflow? ? NOT_SUPPORTED_MESSAGE_PACTFLOW : NOT_SUPPORTED_MESSAGE_PACT_BROKER)
end
end

def success?
if deleted_resource.success?
true
elsif deleted_resource.response.status == 404 && !error_when_not_found
true
else
false
end
end

def result_message
if deleted_resource.success?
green("Successfully deleted branch #{branch_name} of pacticipant #{pacticipant_name}")
elsif deleted_resource.response.status == 404
if error_when_not_found
red("Could not delete branch #{branch_name} of pacticipant #{pacticipant_name} as it was not found")
else
green("Branch #{branch_name} of pacticipant #{pacticipant_name} not found")
end
else
red(deleted_resource.response.raw_body)
end
end
end
end
end
end
39 changes: 39 additions & 0 deletions lib/pact_broker/client/cli/branch_commands.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module PactBroker
module Client
module CLI
module BranchCommands
def self.included(thor)
thor.class_eval do
method_option :pacticipant, required: true, aliases: "-a", desc: "The name of the pacticipant that the branch belongs to."
method_option :branch, required: true, desc: "The pacticipant branch name."
method_option :error_when_not_found, type: :boolean, default: true, desc: "Raise an error if the branch that is to be deleted is not found."
shared_authentication_options

desc "delete-branch", "Deletes a pacticipant branch."
def delete_branch
require "pact_broker/client/branches/delete_branch"

validate_credentials
params = {
pacticipant: options.pacticipant,
branch: options.branch,
error_when_not_found: options.error_when_not_found
}

result = PactBroker::Client::Branches::DeleteBranch.call(params, {}, pact_broker_client_options)
$stdout.puts result.message
exit(1) unless result.success
end

no_commands do
def validate_delete_branch_params
raise ::Thor::RequiredArgumentMissingError, "Pacticipant name cannot be blank" if options.pacticipant.strip.size == 0
raise ::Thor::RequiredArgumentMissingError, "Pacticipant branch name cannot be blank" if options.branch.strip.size == 0
end
end
end
end
end
end
end
end
3 changes: 2 additions & 1 deletion lib/pact_broker/client/cli/broker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
require "pact_broker/client/cli/version_commands"
require "pact_broker/client/cli/webhook_commands"
require "pact_broker/client/cli/matrix_commands"

require "pact_broker/client/cli/branch_commands"
module PactBroker
module Client
module CLI
Expand All @@ -19,6 +19,7 @@ class Broker < CustomThor
include PactBroker::Client::CLI::MatrixCommands
include PactBroker::Client::CLI::PacticipantCommands
include PactBroker::Client::CLI::VersionCommands
include PactBroker::Client::CLI::BranchCommands
include PactBroker::Client::CLI::WebhookCommands

ignored_and_hidden_potential_options_from_environment_variables
Expand Down
1 change: 1 addition & 0 deletions script/update-cli-usage-in-readme.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
[PactBroker::Client::CLI::Broker, "Matrix", %w[can-i-deploy can-i-merge]],
[PactBroker::Client::CLI::Broker, "Pacticipants", %w[create-or-update-pacticipant describe-pacticipant list-pacticipants]],
[PactBroker::Client::CLI::Broker, "Webhooks", %w[create-webhook create-or-update-webhook test-webhook]],
[PactBroker::Client::CLI::Broker, "Branches", %w[delete-branch]],
[PactBroker::Client::CLI::Broker, "Tags", %w[create-version-tag]],
[PactBroker::Client::CLI::Broker, "Versions", %w[describe-version create-or-update-version]],
[PactBroker::Client::CLI::Broker, "Miscellaneous", %w[generate-uuid]]
Expand Down
103 changes: 103 additions & 0 deletions spec/lib/pact_broker/client/branches/delete_branch_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
require "pact_broker/client/branches/delete_branch"

module PactBroker
module Client
module Branches
describe DeleteBranch do
before do
allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:sleep)
allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:default_max_tries).and_return(1)
end

let(:params) do
{
pacticipant: "Foo",
branch: "main",
error_when_not_found: error_when_not_found
}
end
let(:options) do
{
verbose: verbose
}
end
let(:error_when_not_found) { true }
let(:pact_broker_base_url) { "http://example.org" }
let(:pact_broker_client_options) { { pact_broker_base_url: pact_broker_base_url } }
let(:response_headers) { { "Content-Type" => "application/hal+json"} }
let(:verbose) { false }

before do
stub_request(:get, "http://example.org/").to_return(status: 200, body: index_response_body, headers: response_headers)
stub_request(:delete, "http://example.org/pacticipants/Foo/branches/main").to_return(status: delete_response_status, body: delete_response_body, headers: response_headers)
end
let(:delete_response_status) { 200 }

let(:index_response_body) do
{
"_links" => {
"pb:pacticipant-branch" => {
"href" => "http://example.org/pacticipants/{pacticipant}/branches/{branch}"
}
}
}.to_json
end

let(:delete_response_body) do
{ "some" => "error message" }.to_json
end

subject { DeleteBranch.call(params, options, pact_broker_client_options) }

context "when the branch is deleted" do
it "returns a success result" do
expect(subject.success).to be true
expect(subject.message).to include "Successfully deleted branch main of pacticipant Foo"
end
end

context "when there is a non-404 error" do
let(:delete_response_status) { 403 }

it "returns an error result with the response body" do
expect(subject.success).to be false
expect(subject.message).to include "error message"
end
end

context "when the branch is not found" do
let(:delete_response_status) { 404 }

context "when error_when_not_found is true" do
it "returns an error" do
expect(subject.success).to be false
expect(subject.message).to include "Could not delete branch main of pacticipant Foo as it was not found"
end
end

context "when error_when_not_found is false" do
let(:error_when_not_found) { false }

it "return a success" do
expect(subject.success).to be true
expect(subject.message).to include "Branch main of pacticipant Foo not found"
end
end
end

context "when deleting branches is not supported" do
let(:index_response_body) do
{
_links: {}
}.to_json
end

it "returns an error" do
expect(subject.success).to be false
expect(subject.message).to include "not support"
end
end
end
end
end
end
43 changes: 43 additions & 0 deletions spec/pacts/pact_broker_client-pact_broker.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,49 @@
"name": "Pact Broker"
},
"interactions": [
{
"description": "a request for the index resource",
"providerState": "the pb:pacticipant-branch relation exists in the index resource",
"request": {
"method": "GET",
"path": "/",
"headers": {
"Accept": "application/hal+json"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/hal+json;charset=utf-8"
},
"body": {
"_links": {
"pb:pacticipant-branch": {
"href": "http://localhost:1234/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-BRANCH-{pacticipant}-{branch}"
}
}
},
"matchingRules": {
"$.body._links.pb:pacticipant-branch.href": {
"match": "regex",
"regex": "http:\\/\\/.*{pacticipant}.*{branch}"
}
}
}
},
{
"description": "a request to delete a pacticipant branch",
"providerState": "a branch named main exists for pacticipant Foo",
"request": {
"method": "DELETE",
"path": "/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-BRANCH-Foo-main"
},
"response": {
"status": 204,
"headers": {
}
}
},
{
"description": "a request to list the latest pacts",
"providerState": "a pact between Condor and the Pricing Service exists",
Expand Down
Loading