Skip to content

Commit

Permalink
feat: add can-i-deploy endpoint to expose a simplified interface to t…
Browse files Browse the repository at this point in the history
…he /matrix resource that accepts the same parameters as the can-i-deploy CLI.
  • Loading branch information
bethesque committed Oct 3, 2019
1 parent fc73439 commit 02443f3
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/pact_broker/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ module PactBroker
add ['matrix', 'provider', :provider_name, 'consumer', :consumer_name], Api::Resources::MatrixForConsumerAndProvider, {resource_name: "matrix_consumer_provider"}
add ['matrix', 'provider', :provider_name, 'latest', :provider_tag, 'consumer', :consumer_name, 'latest', :tag, 'badge'], Api::Resources::MatrixBadge, {resource_name: "matrix_tag_badge"}
add ['matrix'], Api::Resources::Matrix, {resource_name: "matrix"}
add ['can-i-deploy'], Api::Resources::CanIDeploy, {resource_name: "can-i-deploy"}

add ['dashboard'], Api::Resources::Dashboard, {resource_name: "dashboard"}
add ['dashboard', 'provider', :provider_name, 'consumer', :consumer_name ], Api::Resources::Dashboard, {resource_name: "integration_dashboard"}
Expand Down
41 changes: 41 additions & 0 deletions lib/pact_broker/api/resources/can_i_deploy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'pact_broker/api/resources/matrix'
require 'pact_broker/matrix/can_i_deploy_query_schema'
require 'pact_broker/matrix/parse_can_i_deploy_query'

module PactBroker
module Api
module Resources
class CanIDeploy < Matrix
def initialize
@query_params = JSON.parse(Rack::Utils.parse_nested_query(request.uri.query).to_json, symbolize_names: true)
@selectors, @options = PactBroker::Matrix::ParseCanIDeployQuery.call(query_params)
end

def malformed_request?
if (errors = query_schema.call(query_params)).any?
set_json_validation_error_messages(errors)
true
else
false
end
end

private

attr_reader :query_params

def query_schema
PactBroker::Api::Contracts::CanIDeployQuerySchema
end

def selectors
@selectors
end

def options
@options
end
end
end
end
end
6 changes: 6 additions & 0 deletions lib/pact_broker/api/resources/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ def links
href: base_url + '/metrics',
title: "Get Pact Broker metrics",
},
'pb:can-i-deploy-pacticipant-version-to-tag' =>
{
href: base_url + '/can-i-deploy?pacticipant={pacticipant}&version={version}&to={tag}',
title: "Determine if an application can be safely deployed to an environment identified by the given tag",
templated: true
},
'curies' =>
[{
name: 'pb',
Expand Down
4 changes: 3 additions & 1 deletion lib/pact_broker/doc/controllers/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ class App < Padrino::Application

MAPPINGS = {
'webhooks-create' => 'webhooks',
'webhooks-webhooks' => 'webhooks'
'webhooks-webhooks' => 'webhooks',
'can-i-deploy-pacticipant-version-to-tag' => 'can-i-deploy',
'pacticipant' => 'pacticipants'
}.freeze

helpers do
Expand Down
25 changes: 25 additions & 0 deletions lib/pact_broker/matrix/can_i_deploy_query_schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'dry-validation'

module PactBroker
module Api
module Contracts
class CanIDeployQuerySchema
SCHEMA = Dry::Validation.Schema do
required(:pacticipant).filled(:str?)
required(:version).filled(:str?)
optional(:to).filled(:str?)
end

def self.call(params)
select_first_message(SCHEMA.call(params).messages(full: true))
end

def self.select_first_message(messages)
messages.each_with_object({}) do | (key, value), new_messages |
new_messages[key] = [value.first]
end
end
end
end
end
end
29 changes: 29 additions & 0 deletions lib/pact_broker/matrix/parse_can_i_deploy_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'rack/utils'

module PactBroker
module Matrix
class ParseCanIDeployQuery
def self.call params
selector = {}
options = {
latestby: 'cvp',
latest: true
}

if params[:pacticipant].is_a?(String)
selector[:pacticipant_name] = params[:pacticipant]
end

if params[:version].is_a?(String)
selector[:pacticipant_version_number] = params[:version]
end

if params[:to].is_a?(String)
options[:tag] = params[:to]
end

return [selector], options
end
end
end
end
31 changes: 31 additions & 0 deletions spec/features/can_i_deploy_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
RSpec.describe "can i deploy" do
before do
td.create_pact_with_hierarchy("Foo", "1.2.3", "Bar")
end

let(:query) do
{
pacticipant: "Foo",
version: "1.2.3",
to: "prod"
}
end

let(:response_body) { JSON.parse(subject.body, symbolize_names: true) }

subject { get("/can-i-deploy", query, { 'HTTP_ACCEPT' => 'application/hal+json'}) }

it "returns the matrix response" do
expect(subject).to be_a_hal_json_success_response
expect(response_body[:matrix]).to be_instance_of(Array)
end

context "with a validation error" do
let(:query) { {} }

it "returns an error response" do
expect(subject.status).to eq 400
expect(response_body[:errors]).to be_instance_of(Hash)
end
end
end

0 comments on commit 02443f3

Please sign in to comment.