summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelogs/unreleased/fix-gb-fix-chatops-deploy-multiple-actions-matching.yml4
-rw-r--r--doc/integration/slash_commands.md21
-rw-r--r--lib/gitlab/slash_commands/deploy.rb33
-rw-r--r--lib/gitlab/slash_commands/presenters/deploy.rb11
-rw-r--r--spec/lib/gitlab/slash_commands/command_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/deploy_spec.rb56
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb20
7 files changed, 94 insertions, 53 deletions
diff --git a/changelogs/unreleased/fix-gb-fix-chatops-deploy-multiple-actions-matching.yml b/changelogs/unreleased/fix-gb-fix-chatops-deploy-multiple-actions-matching.yml
new file mode 100644
index 00000000000..62488a0a2e3
--- /dev/null
+++ b/changelogs/unreleased/fix-gb-fix-chatops-deploy-multiple-actions-matching.yml
@@ -0,0 +1,4 @@
+---
+title: Improve deploy environment chatops slash command
+merge_request: 13150
+author:
diff --git a/doc/integration/slash_commands.md b/doc/integration/slash_commands.md
index 5d880ba785c..aa52b5415cf 100644
--- a/doc/integration/slash_commands.md
+++ b/doc/integration/slash_commands.md
@@ -2,7 +2,11 @@
Slash commands in Mattermost and Slack allow you to control GitLab and view GitLab content right inside your chat client, without having to leave it. For Slack, this requires a [project service configuration](../user/project/integrations/slack_slash_commands.md). Simply type the command as a message in your chat client to activate it.
-Commands are scoped to a project, with a trigger term that is specified during configuration. (We suggest you use the project name as the trigger term for simplicty and clarity.) Taking the trigger term as `project-name`, the commands are:
+Commands are scoped to a project, with a trigger term that is specified during configuration.
+
+We suggest you use the project name as the trigger term for simplicity and clarity.
+
+Taking the trigger term as `project-name`, the commands are:
| Command | Effect |
@@ -12,3 +16,18 @@ Commands are scoped to a project, with a trigger term that is specified during c
| `/project-name issue show <id>` | Shows the issue with id `<id>` |
| `/project-name issue search <query>` | Shows up to 5 issues matching `<query>` |
| `/project-name deploy <from> to <to>` | Deploy from the `<from>` environment to the `<to>` environment |
+
+## Issue commands
+
+It is possible to create new issue, display issue details and search up to 5 issues.
+
+## Deploy command
+
+In order to deploy to an environment, GitLab will try to find a deployment
+manual action in the pipeline.
+
+If there is only one action for a given environment, it is going to be triggered.
+If there is more than one action defined, GitLab will try to find an action
+which name equals the environment name we want to deploy to.
+
+Command will return an error when no matching action has been found.
diff --git a/lib/gitlab/slash_commands/deploy.rb b/lib/gitlab/slash_commands/deploy.rb
index e71eb15d604..93e00ab75a1 100644
--- a/lib/gitlab/slash_commands/deploy.rb
+++ b/lib/gitlab/slash_commands/deploy.rb
@@ -21,29 +21,34 @@ module Gitlab
from = match[:from]
to = match[:to]
- actions = find_actions(from, to)
+ action = find_action(from, to)
- if actions.none?
- Gitlab::SlashCommands::Presenters::Deploy.new(nil).no_actions
- elsif actions.one?
- action = play!(from, to, actions.first)
- Gitlab::SlashCommands::Presenters::Deploy.new(action).present(from, to)
+ if action.nil?
+ Gitlab::SlashCommands::Presenters::Deploy
+ .new(action).action_not_found
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
private
- def play!(from, to, action)
- action.play(current_user)
- end
-
- def find_actions(from, to)
+ def find_action(from, to)
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
diff --git a/lib/gitlab/slash_commands/presenters/deploy.rb b/lib/gitlab/slash_commands/presenters/deploy.rb
index b8dc77bd37b..ebae0f57f9b 100644
--- a/lib/gitlab/slash_commands/presenters/deploy.rb
+++ b/lib/gitlab/slash_commands/presenters/deploy.rb
@@ -3,17 +3,14 @@ module Gitlab
module Presenters
class Deploy < Presenters::Base
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)
end
- def no_actions
- ephemeral_response(text: "No action found to be executed")
- end
-
- def too_many_actions
- ephemeral_response(text: "Too many actions defined")
+ def action_not_found
+ ephemeral_response(text: "Couldn't find a deployment manual action.")
end
end
end
diff --git a/spec/lib/gitlab/slash_commands/command_spec.rb b/spec/lib/gitlab/slash_commands/command_spec.rb
index f0ecf59406a..88f73bf90cd 100644
--- a/spec/lib/gitlab/slash_commands/command_spec.rb
+++ b/spec/lib/gitlab/slash_commands/command_spec.rb
@@ -80,7 +80,7 @@ describe Gitlab::SlashCommands::Command do
it 'returns error' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to include('Too many actions defined')
+ expect(subject[:text]).to include("Couldn't find a deployment manual action.")
end
end
end
diff --git a/spec/lib/gitlab/slash_commands/deploy_spec.rb b/spec/lib/gitlab/slash_commands/deploy_spec.rb
index e52aaed7328..c3fb7d5adea 100644
--- a/spec/lib/gitlab/slash_commands/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/deploy_spec.rb
@@ -22,7 +22,7 @@ describe Gitlab::SlashCommands::Deploy do
context 'if no environment is defined' do
it 'does not execute an action' do
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 manual action."
end
end
@@ -35,12 +35,12 @@ describe Gitlab::SlashCommands::Deploy do
context 'without actions' do
it 'does not execute an action' do
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 manual action."
end
end
- context 'with action' do
- let!(:manual1) do
+ context 'when single action has been matched' do
+ before do
create(:ci_build, :manual, pipeline: pipeline,
name: 'first',
environment: 'production')
@@ -48,31 +48,61 @@ describe Gitlab::SlashCommands::Deploy do
it 'returns success result' do
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
+
+ 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,
name: 'second',
environment: 'production')
end
- it 'returns error' do
+ it 'returns error about too many actions defined' do
+ expect(subject[:text]).to eq("Couldn't find a deployment manual action.")
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to eq('Too many actions defined')
end
end
- context 'when teardown action exists' do
- let!(:teardown) do
+ context 'when one of the actions is environement specific action' 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,
pipeline: pipeline, name: 'teardown', environment: 'production')
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[:text]).to start_with('Deployment started from staging to production')
end
end
end
diff --git a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
index dee3c77db27..d16d122c64e 100644
--- a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
@@ -17,8 +17,8 @@ describe Gitlab::SlashCommands::Presenters::Deploy do
end
end
- describe '#no_actions' do
- subject { described_class.new(nil).no_actions }
+ describe '#action_not_found' do
+ subject { described_class.new(nil).action_not_found }
it { is_expected.to have_key(:text) }
it { is_expected.to have_key(:response_type) }
@@ -27,21 +27,7 @@ describe Gitlab::SlashCommands::Presenters::Deploy do
it 'tells the user there is no action' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to eq("No action found to be executed")
- 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")
+ expect(subject[:text]).to eq "Couldn't find a deployment manual action."
end
end
end