Skip to content
Snippets Groups Projects
Commit 8bd520d7 authored by Felipe Artur's avatar Felipe Artur
Browse files

Allow slack service to send messages on different channels

parent b9ed9d65
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -101,6 +101,7 @@ v 8.10.0 (unreleased)
- Don't render discussion notes when requesting diff tab through AJAX
- Add basic system information like memory and disk usage to the admin panel
- Don't garbage collect commits that have related DB records like comments
- Allow to setup event by channel on slack service
- More descriptive message for git hooks and file locks
- Aliases of award emoji should be stored as original name. !5060 (dixpac)
- Handle custom Git hook result in GitLab UI
Loading
Loading
Loading
Loading
@@ -39,11 +39,14 @@ class Admin::ServicesController < Admin::ApplicationController
end
 
def application_services_params
dynamic_params = []
dynamic_params.concat(@service.event_channel_names) if @service.is_a?(SlackService)
application_services_params = params.permit(:id,
service: Projects::ServicesController::ALLOWED_PARAMS)
service: Projects::ServicesController::ALLOWED_PARAMS + dynamic_params)
if application_services_params[:service].is_a?(Hash)
Projects::ServicesController::FILTER_BLANK_PARAMS.each do |param|
application_services_params[:service].delete(param) if application_services_params[:service][param].blank?
application_services_params[:service].delete(param) if application_services_params[:service][param].blank?
end
end
application_services_params
Loading
Loading
Loading
Loading
@@ -66,10 +66,15 @@ class Projects::ServicesController < Projects::ApplicationController
end
 
def service_params
service_params = params.require(:service).permit(ALLOWED_PARAMS)
dynamic_params = []
dynamic_params.concat(@service.event_channel_names) if @service.is_a?(SlackService)
service_params = params.require(:service).permit(ALLOWED_PARAMS + dynamic_params)
FILTER_BLANK_PARAMS.each do |param|
service_params.delete(param) if service_params[param].blank?
end
service_params
end
end
module ServicesHelper
def service_event_description(event)
case event
when "push"
"Webhook will triggered by a push to the repository"
when "tag_push"
"Webhook will be triggered when a new tag is pushed to the repository"
when "note"
"Webhook will be triggered when someone adds a comment"
when "issue"
"Webhook will be triggered when an issue is created/updated/merged"
when "merge_request"
"Webhook will be triggered when a merge request is created/updated/merged"
when "build"
"Webhook will be triggered when a build status changes"
when "wiki_page"
"Webhook will be triggered when a wiki page is created/updated"
end
end
def service_event_field_name(event)
event = event.pluralize if %w(merge_request issue).include?(event)
"#{event}_events"
end
end
Loading
Loading
@@ -4,6 +4,9 @@ class SlackService < Service
validates :webhook, presence: true, url: true, if: :activated?
 
def initialize_properties
# Custom serialized properties initialization
self.supported_events.each { |event| self.class.prop_accessor event_channel_name(event) }
if properties.nil?
self.properties = {}
self.notify_only_broken_builds = true
Loading
Loading
@@ -29,13 +32,15 @@ class SlackService < Service
end
 
def fields
[
{ type: 'text', name: 'webhook',
placeholder: 'https://hooks.slack.com/services/...' },
{ type: 'text', name: 'username', placeholder: 'username' },
{ type: 'text', name: 'channel', placeholder: '#channel' },
{ type: 'checkbox', name: 'notify_only_broken_builds' },
]
default_fields =
[
{ type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' },
{ type: 'text', name: 'username', placeholder: 'username' },
{ type: 'text', name: 'channel', placeholder: "#General" },
{ type: 'checkbox', name: 'notify_only_broken_builds' },
]
default_fields + build_event_channels
end
 
def supported_events
Loading
Loading
@@ -74,7 +79,10 @@ class SlackService < Service
end
 
opt = {}
opt[:channel] = channel if channel
event_channel = get_channel_field(object_kind) || channel
opt[:channel] = event_channel if event_channel
opt[:username] = username if username
 
if message
Loading
Loading
@@ -83,8 +91,32 @@ class SlackService < Service
end
end
 
def event_channel_names
supported_events.map { |event| event_channel_name(event) }
end
private
 
def get_channel_field(event)
field_name = event_channel_name(event)
self.send(field_name)
end
def build_event_channels
channels = []
supported_events.each do |event|
channel_name = event_channel_name(event)
channels << { type: 'text', name: channel_name, placeholder: "#General" }
end
channels
end
def event_channel_name(event)
"#{event}_channel"
end
def project_name
project.name_with_namespace.gsub(/\s/, '')
end
Loading
Loading
Loading
Loading
@@ -4,7 +4,10 @@
%p #{@service.description} template
 
= form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'form-horizontal fieldset-form' } do |form|
= render 'shared/service_settings', form: form
- if @service.is_a?(SlackService)
= render 'projects/services/slack/service_settings', form: form
- else
= render 'shared/service_settings', form: form
 
.form-actions
= form.submit 'Save', class: 'btn btn-save'
Loading
Loading
@@ -7,7 +7,11 @@
%p= @service.description
.col-lg-9
= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form|
= render 'shared/service_settings', form: form
- if @service.is_a?(SlackService)
= render 'projects/services/slack/service_settings', form: form
- else
= render 'shared/service_settings', form: form
= form.submit 'Save changes', class: 'btn btn-save'
&nbsp;
- if @service.valid? && @service.activated?
Loading
Loading
= form_errors(@service)
- if @service.help.present?
.well
= preserve do
= markdown @service.help
.form-group
= form.label :active, "Active", class: "control-label"
.col-sm-10
= form.check_box :active
.form-group
= form.label :url, "Trigger", class: 'control-label'
.col-sm-10
- @service.supported_events.each do |event|
%div
= form.check_box service_event_field_name(event), class: 'pull-left'
.prepend-left-20
= form.label service_event_field_name(event), class: 'list-label' do
%strong
= event.humanize
%p
- field = @service.fields.select{ |field| field[:name] == "#{event}_channel"}.first
= form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
%p.light
= service_event_description(event)
- @service.fields.each do |field|
- if %w(webhook username notify_only_broken_builds).include?(field[:name])
= render 'shared/field', form: form, field: field
Loading
Loading
@@ -27,19 +27,19 @@ class Spinach::Features::AdminSettings < Spinach::FeatureSteps
 
step 'I check all events and submit form' do
page.check('Active')
page.check('Push events')
page.check('Tag push events')
page.check('Comments')
page.check('Issues events')
page.check('Merge Request events')
page.check('Build events')
page.check('Push')
page.check('Tag push')
page.check('Note')
page.check('Issue')
page.check('Merge request')
page.check('Build')
click_on 'Save'
end
 
step 'I fill out Slack settings' do
fill_in 'Webhook', with: 'http://localhost'
fill_in 'Username', with: 'test_user'
fill_in 'Channel', with: '#test_channel'
fill_in 'service_push_channel', with: '#test_channel'
page.check('Notify only broken builds')
end
 
Loading
Loading
@@ -56,6 +56,6 @@ class Spinach::Features::AdminSettings < Spinach::FeatureSteps
step 'I should see Slack settings saved' do
expect(find_field('Webhook').value).to eq 'http://localhost'
expect(find_field('Username').value).to eq 'test_user'
expect(find_field('Channel').value).to eq '#test_channel'
expect(find('#service_push_channel').value).to eq '#test_channel'
end
end
Loading
Loading
@@ -124,6 +124,7 @@ describe SlackService, models: true do
and_return(
double(:slack_service).as_null_object
)
slack.execute(push_sample_data)
end
 
Loading
Loading
@@ -136,6 +137,76 @@ describe SlackService, models: true do
)
slack.execute(push_sample_data)
end
context "event channels" do
it "should user the right channel for push event" do
slack.update_attributes(push_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
and_return(
double(:slack_service).as_null_object
)
slack.execute(push_sample_data)
end
it "should use the right channel for merge request event" do
slack.update_attributes(merge_request_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
and_return(
double(:slack_service).as_null_object
)
slack.execute(@merge_sample_data)
end
it "should use the right channel for issue event" do
slack.update_attributes(issue_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
and_return(
double(:slack_service).as_null_object
)
slack.execute(@issues_sample_data)
end
it "should use the right channel for wiki event" do
slack.update_attributes(wiki_page_channel: "random")
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
and_return(
double(:slack_service).as_null_object
)
slack.execute(@wiki_page_sample_data)
end
context "note event" do
let(:issue_note) do
create(:note_on_issue, project: project, note: "issue note")
end
it "should use the right channel" do
slack.update_attributes(note_channel: "random")
note_data = Gitlab::NoteDataBuilder.build(issue_note, user)
expect(Slack::Notifier).to receive(:new).
with(webhook_url, channel: "random").
and_return(
double(:slack_service).as_null_object
)
slack.execute(note_data)
end
end
end
end
 
describe "Note events" do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment