Commit 29a88277 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Improve deploy environment chatops slash command

We now match deployment actions better. If there is more than one
deployment action matched, we check if there is an action which name
equals to environment name, instead of raising an error about too many
actions defined.
parent 3f1b7b88
...@@ -21,29 +21,34 @@ module Gitlab ...@@ -21,29 +21,34 @@ module Gitlab
from = match[:from] from = match[:from]
to = match[:to] to = match[:to]
actions = find_actions(from, to) action = find_action(from, to)
if actions.none? if action.nil?
Gitlab::SlashCommands::Presenters::Deploy.new(nil).no_actions Gitlab::SlashCommands::Presenters::Deploy
elsif actions.one? .new(action).action_not_found
action = play!(from, to, actions.first)
Gitlab::SlashCommands::Presenters::Deploy.new(action).present(from, to)
else else
Gitlab::SlashCommands::Presenters::Deploy.new(actions).too_many_actions deployment = action.play(current_user)
Gitlab::SlashCommands::Presenters::Deploy
.new(deployment).present(from, to)
end end
end end
private private
def play!(from, to, action) def find_action(from, to)
action.play(current_user)
end
def find_actions(from, to)
environment = project.environments.find_by(name: from) environment = project.environments.find_by(name: from)
return [] unless environment return unless environment
environment.actions_for(to).select(&:starts_environment?) actions = environment.actions_for(to).select do |action|
action.starts_environment?
end
if actions.many?
actions.find { |action| action.name == to.to_s }
else
actions.first
end
end end
end end
end end
......
...@@ -3,17 +3,14 @@ module Gitlab ...@@ -3,17 +3,14 @@ module Gitlab
module Presenters module Presenters
class Deploy < Presenters::Base class Deploy < Presenters::Base
def present(from, to) def present(from, to)
message = "Deployment started from #{from} to #{to}. [Follow its progress](#{resource_url})." message = "Deployment started from #{from} to #{to}. " \
"[Follow its progress](#{resource_url})."
in_channel_response(text: message) in_channel_response(text: message)
end end
def no_actions def action_not_found
ephemeral_response(text: "No action found to be executed") ephemeral_response(text: "Couldn't find a deployment action.")
end
def too_many_actions
ephemeral_response(text: "Too many actions defined")
end end
end end
end end
......
...@@ -22,7 +22,7 @@ describe Gitlab::SlashCommands::Deploy do ...@@ -22,7 +22,7 @@ describe Gitlab::SlashCommands::Deploy do
context 'if no environment is defined' do context 'if no environment is defined' do
it 'does not execute an action' do it 'does not execute an action' do
expect(subject[:response_type]).to be(:ephemeral) expect(subject[:response_type]).to be(:ephemeral)
expect(subject[:text]).to eq("No action found to be executed") expect(subject[:text]).to eq "Couldn't find a deployment action."
end end
end end
...@@ -35,12 +35,12 @@ describe Gitlab::SlashCommands::Deploy do ...@@ -35,12 +35,12 @@ describe Gitlab::SlashCommands::Deploy do
context 'without actions' do context 'without actions' do
it 'does not execute an action' do it 'does not execute an action' do
expect(subject[:response_type]).to be(:ephemeral) expect(subject[:response_type]).to be(:ephemeral)
expect(subject[:text]).to eq("No action found to be executed") expect(subject[:text]).to eq "Couldn't find a deployment action."
end end
end end
context 'with action' do context 'when single action has been matched' do
let!(:manual1) do before do
create(:ci_build, :manual, pipeline: pipeline, create(:ci_build, :manual, pipeline: pipeline,
name: 'first', name: 'first',
environment: 'production') environment: 'production')
...@@ -48,31 +48,61 @@ describe Gitlab::SlashCommands::Deploy do ...@@ -48,31 +48,61 @@ describe Gitlab::SlashCommands::Deploy do
it 'returns success result' do it 'returns success result' do
expect(subject[:response_type]).to be(:in_channel) expect(subject[:response_type]).to be(:in_channel)
expect(subject[:text]).to start_with('Deployment started from staging to production') expect(subject[:text])
.to start_with('Deployment started from staging to production')
end end
end
context 'when more than one action has been matched' do
context 'when there is no specific actions with a environment name' do
before do
create(:ci_build, :manual, pipeline: pipeline,
name: 'first',
environment: 'production')
context 'when duplicate action exists' do
let!(:manual2) do
create(:ci_build, :manual, pipeline: pipeline, create(:ci_build, :manual, pipeline: pipeline,
name: 'second', name: 'second',
environment: 'production') environment: 'production')
end end
it 'returns error' do it 'returns error about too many actions defined' do
expect(subject[:text]).to eq("Couldn't find a deployment action.")
expect(subject[:response_type]).to be(:ephemeral) expect(subject[:response_type]).to be(:ephemeral)
expect(subject[:text]).to eq('Too many actions defined')
end end
end end
context 'when teardown action exists' do context 'when one of the actions is environement specific action' do
let!(:teardown) do before do
create(:ci_build, :manual, pipeline: pipeline,
name: 'first',
environment: 'production')
create(:ci_build, :manual, pipeline: pipeline,
name: 'production',
environment: 'production')
end
it 'deploys to production' do
expect(subject[:text])
.to start_with('Deployment started from staging to production')
expect(subject[:response_type]).to be(:in_channel)
end
end
context 'when one of the actions is a teardown action' do
before do
create(:ci_build, :manual, pipeline: pipeline,
name: 'first',
environment: 'production')
create(:ci_build, :manual, :teardown_environment, create(:ci_build, :manual, :teardown_environment,
pipeline: pipeline, name: 'teardown', environment: 'production') pipeline: pipeline, name: 'teardown', environment: 'production')
end end
it 'returns the success message' do it 'deploys to production' do
expect(subject[:text])
.to start_with('Deployment started from staging to production')
expect(subject[:response_type]).to be(:in_channel) expect(subject[:response_type]).to be(:in_channel)
expect(subject[:text]).to start_with('Deployment started from staging to production')
end end
end end
end end
......
...@@ -17,8 +17,8 @@ describe Gitlab::SlashCommands::Presenters::Deploy do ...@@ -17,8 +17,8 @@ describe Gitlab::SlashCommands::Presenters::Deploy do
end end
end end
describe '#no_actions' do describe '#action_not_found' do
subject { described_class.new(nil).no_actions } subject { described_class.new(nil).action_not_found }
it { is_expected.to have_key(:text) } it { is_expected.to have_key(:text) }
it { is_expected.to have_key(:response_type) } it { is_expected.to have_key(:response_type) }
...@@ -27,21 +27,7 @@ describe Gitlab::SlashCommands::Presenters::Deploy do ...@@ -27,21 +27,7 @@ describe Gitlab::SlashCommands::Presenters::Deploy do
it 'tells the user there is no action' do it 'tells the user there is no action' do
expect(subject[:response_type]).to be(:ephemeral) expect(subject[:response_type]).to be(:ephemeral)
expect(subject[:text]).to eq("No action found to be executed") expect(subject[:text]).to eq "Couldn't find a deployment action."
end
end
describe '#too_many_actions' do
subject { described_class.new([]).too_many_actions }
it { is_expected.to have_key(:text) }
it { is_expected.to have_key(:response_type) }
it { is_expected.to have_key(:status) }
it { is_expected.not_to have_key(:attachments) }
it 'tells the user there is no action' do
expect(subject[:response_type]).to be(:ephemeral)
expect(subject[:text]).to eq("Too many actions defined")
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment