Commit 54661d3d authored by Sebastian Klier's avatar Sebastian Klier

add slack notifications for wiki pages

update changelog
parent 9617c274
...@@ -274,6 +274,7 @@ v 8.5.3 ...@@ -274,6 +274,7 @@ v 8.5.3
- Show commit message in JIRA mention comment - Show commit message in JIRA mention comment
- Makes issue page and merge request page usable on mobile browsers. - Makes issue page and merge request page usable on mobile browsers.
- Improved UI for profile settings - Improved UI for profile settings
- Add Slack notifications when Wiki is edited (Sebastian Klier)
v 8.5.2 v 8.5.2
- Fix sidebar overlapping content when screen width was below 1200px - Fix sidebar overlapping content when screen width was below 1200px
......
...@@ -6,7 +6,7 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -6,7 +6,7 @@ class Projects::ServicesController < Projects::ApplicationController
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel, :description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
:colorize_messages, :channels, :colorize_messages, :channels,
:push_events, :issues_events, :merge_requests_events, :tag_push_events, :push_events, :issues_events, :merge_requests_events, :tag_push_events,
:note_events, :build_events, :note_events, :build_events, :wiki_page_events,
:notify_only_broken_builds, :add_pusher, :notify_only_broken_builds, :add_pusher,
:send_from_committer_email, :disable_diffs, :external_wiki_url, :send_from_committer_email, :disable_diffs, :external_wiki_url,
:notify, :color, :notify, :color,
......
...@@ -44,7 +44,7 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -44,7 +44,7 @@ class Projects::WikisController < Projects::ApplicationController
return render('empty') unless can?(current_user, :create_wiki, @project) return render('empty') unless can?(current_user, :create_wiki, @project)
if @page.update(content, format, message) if @page = WikiPages::UpdateService.new(@project, current_user, wiki_params).execute(@page)
redirect_to( redirect_to(
namespace_project_wiki_path(@project.namespace, @project, @page), namespace_project_wiki_path(@project.namespace, @project, @page),
notice: 'Wiki was successfully updated.' notice: 'Wiki was successfully updated.'
...@@ -55,9 +55,9 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -55,9 +55,9 @@ class Projects::WikisController < Projects::ApplicationController
end end
def create def create
@page = WikiPage.new(@project_wiki) @page = WikiPages::CreateService.new(@project, current_user, wiki_params).execute
if @page.create(wiki_params) if @page
redirect_to( redirect_to(
namespace_project_wiki_path(@project.namespace, @project, @page), namespace_project_wiki_path(@project.namespace, @project, @page),
notice: 'Wiki was successfully updated.' notice: 'Wiki was successfully updated.'
......
...@@ -25,4 +25,5 @@ class ProjectHook < WebHook ...@@ -25,4 +25,5 @@ class ProjectHook < WebHook
scope :note_hooks, -> { where(note_events: true) } scope :note_hooks, -> { where(note_events: true) }
scope :merge_request_hooks, -> { where(merge_requests_events: true) } scope :merge_request_hooks, -> { where(merge_requests_events: true) }
scope :build_hooks, -> { where(build_events: true) } scope :build_hooks, -> { where(build_events: true) }
scope :wiki_page_hooks, -> { where(wiki_page_events: true) }
end end
...@@ -60,7 +60,7 @@ class SlackService < Service ...@@ -60,7 +60,7 @@ class SlackService < Service
end end
def supported_events def supported_events
%w(push issue merge_request note tag_push build) %w(push issue merge_request note tag_push build wiki_page)
end end
def execute(data) def execute(data)
...@@ -90,6 +90,8 @@ class SlackService < Service ...@@ -90,6 +90,8 @@ class SlackService < Service
NoteMessage.new(data) NoteMessage.new(data)
when "build" when "build"
BuildMessage.new(data) if should_build_be_notified?(data) BuildMessage.new(data) if should_build_be_notified?(data)
when "wiki_page"
WikiPageMessage.new(data)
end end
opt = {} opt = {}
...@@ -133,3 +135,4 @@ require "slack_service/push_message" ...@@ -133,3 +135,4 @@ require "slack_service/push_message"
require "slack_service/merge_message" require "slack_service/merge_message"
require "slack_service/note_message" require "slack_service/note_message"
require "slack_service/build_message" require "slack_service/build_message"
require "slack_service/wiki_page_message"
class SlackService
class WikiPageMessage < BaseMessage
attr_reader :user_name
attr_reader :title
attr_reader :project_name
attr_reader :project_url
attr_reader :wiki_page_url
attr_reader :action
attr_reader :description
def initialize(params)
@user_name = params[:user][:name]
@project_name = params[:project_name]
@project_url = params[:project_url]
obj_attr = params[:object_attributes]
obj_attr = HashWithIndifferentAccess.new(obj_attr)
@title = obj_attr[:title]
@wiki_page_url = obj_attr[:url]
@description = obj_attr[:content]
@action = \
case obj_attr[:action]
when "create"
"created"
when "update"
"edited"
end
end
def attachments
description_message
end
private
def message
"#{user_name} #{action} #{wiki_page_link} in #{project_link}: *#{title}*"
end
def description_message
[{ text: format(@description), color: attachment_color }]
end
def project_link
"[#{project_name}](#{project_url})"
end
def wiki_page_link
"[wiki page](#{wiki_page_url})"
end
end
end
...@@ -32,6 +32,7 @@ class Service < ActiveRecord::Base ...@@ -32,6 +32,7 @@ class Service < ActiveRecord::Base
default_value_for :tag_push_events, true default_value_for :tag_push_events, true
default_value_for :note_events, true default_value_for :note_events, true
default_value_for :build_events, true default_value_for :build_events, true
default_value_for :wiki_page_events, true
after_initialize :initialize_properties after_initialize :initialize_properties
...@@ -53,6 +54,7 @@ class Service < ActiveRecord::Base ...@@ -53,6 +54,7 @@ class Service < ActiveRecord::Base
scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) } scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) }
scope :note_hooks, -> { where(note_events: true, active: true) } scope :note_hooks, -> { where(note_events: true, active: true) }
scope :build_hooks, -> { where(build_events: true, active: true) } scope :build_hooks, -> { where(build_events: true, active: true) }
scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
default_value_for :category, 'common' default_value_for :category, 'common'
...@@ -94,7 +96,7 @@ class Service < ActiveRecord::Base ...@@ -94,7 +96,7 @@ class Service < ActiveRecord::Base
end end
def supported_events def supported_events
%w(push tag_push issue merge_request) %w(push tag_push issue merge_request wiki_page)
end end
def execute(data) def execute(data)
......
...@@ -29,6 +29,10 @@ class WikiPage ...@@ -29,6 +29,10 @@ class WikiPage
# new Page values before writing to the Gollum repository. # new Page values before writing to the Gollum repository.
attr_accessor :attributes attr_accessor :attributes
def hook_attrs
attributes
end
def initialize(wiki, page = nil, persisted = false) def initialize(wiki, page = nil, persisted = false)
@wiki = wiki @wiki = wiki
@page = page @page = page
......
module WikiPages
class BaseService < ::BaseService
def hook_data(page, action)
hook_data = {
object_kind: page.class.name.underscore,
user: current_user.hook_attrs,
project: @project.hook_attrs,
object_attributes: page.hook_attrs,
# DEPRECATED
repository: @project.hook_attrs.slice(:name, :url, :description, :homepage)
}
page_url = "#{Gitlab.config.gitlab.url}#{@project.wiki.wiki_base_path}/#{page.slug}"
hook_data[:object_attributes].merge!(url: page_url, action: action)
hook_data
end
private
def execute_hooks(page, action = 'create')
page_data = hook_data(page, action)
@project.execute_hooks(page_data, :wiki_page_hooks)
@project.execute_services(page_data, :wiki_page_hooks)
end
end
end
module WikiPages
class CreateService < WikiPages::BaseService
def execute
page = WikiPage.new(@project.wiki)
if page.create(@params)
execute_hooks(page, 'create')
end
page
end
end
end
module WikiPages
class UpdateService < WikiPages::BaseService
def execute(page)
if page.update(@params[:content], @params[:format], @params[:message])
execute_hooks(page, 'update')
end
page
end
end
end
...@@ -62,6 +62,14 @@ ...@@ -62,6 +62,14 @@
%strong Build events %strong Build events
%p.light %p.light
This url will be triggered when a build status changes This url will be triggered when a build status changes
- if @service.supported_events.include?("wiki_page")
%div
= form.check_box :wiki_page_events, class: 'pull-left'
.prepend-left-20
= form.label :wiki_page_events, class: 'list-label' do
%strong Wiki Page events
%p.light
This url will be triggered when a wiki page is created/updated
- @service.fields.each do |field| - @service.fields.each do |field|
......
class AddEventFieldForWebHook < ActiveRecord::Migration
def change
add_column :web_hooks, :wiki_page_events, :boolean, default: false, null: false
end
end
class AddEventToServices < ActiveRecord::Migration
def change
add_column :services, :wiki_page_events, :boolean, :default => true
end
end
...@@ -820,6 +820,7 @@ ActiveRecord::Schema.define(version: 20160419120017) do ...@@ -820,6 +820,7 @@ ActiveRecord::Schema.define(version: 20160419120017) do
t.boolean "build_events", default: false, null: false t.boolean "build_events", default: false, null: false
t.string "category", default: "common", null: false t.string "category", default: "common", null: false
t.boolean "default", default: false t.boolean "default", default: false
t.boolean "wiki_page_events", default: true
end end
add_index "services", ["category"], name: "index_services_on_category", using: :btree add_index "services", ["category"], name: "index_services_on_category", using: :btree
...@@ -1014,6 +1015,7 @@ ActiveRecord::Schema.define(version: 20160419120017) do ...@@ -1014,6 +1015,7 @@ ActiveRecord::Schema.define(version: 20160419120017) do
t.boolean "note_events", default: false, null: false t.boolean "note_events", default: false, null: false
t.boolean "enable_ssl_verification", default: true t.boolean "enable_ssl_verification", default: true
t.boolean "build_events", default: false, null: false t.boolean "build_events", default: false, null: false
t.boolean "wiki_page_events", default: false, null: false
end end
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
......
require 'spec_helper'
describe SlackService::WikiPageMessage, models: true do
subject { SlackService::WikiPageMessage.new(args) }
let(:args) do
{
user: {
name: 'Test User',
username: 'Test User'
},
project_name: 'project_name',
project_url: 'somewhere.com',
object_attributes: {
title: 'Wiki page title',
url: 'url',
action: 'create',
content: 'Wiki page description'
}
}
end
let(:color) { '#345' }
context 'create' do
it 'returns a message regarding creation of pages' do
expect(subject.pretext).to eq(
'Test User created <url|wiki page> in <somewhere.com|project_name>: '\
'*Wiki page title*')
expect(subject.attachments).to eq([
{
text: "Wiki page description",
color: color,
}
])
end
end
context 'update' do
before do
args[:object_attributes][:action] = 'update'
end
it 'returns a message regarding updating of pages' do
expect(subject.pretext). to eq(
'Test User edited <url|wiki page> in <somewhere.com|project_name>: '\
'*Wiki page title*')
expect(subject.attachments).to eq([
{
text: "Wiki page description",
color: color,
}
])
end
end
end
...@@ -75,6 +75,17 @@ describe SlackService, models: true do ...@@ -75,6 +75,17 @@ describe SlackService, models: true do
@merge_request = merge_service.execute @merge_request = merge_service.execute
@merge_sample_data = merge_service.hook_data(@merge_request, @merge_sample_data = merge_service.hook_data(@merge_request,
'open') 'open')
opts = {
title: "Awesome wiki_page",
content: "Some text describing some thing or another",
format: "md",
message: "user created page: Awesome wiki_page"
}
wiki_page_service = WikiPages::CreateService.new(project, user, opts)
@wiki_page = wiki_page_service.execute
@wiki_page_sample_data = wiki_page_service.hook_data(@wiki_page, 'create')
end end
it "should call Slack API for push events" do it "should call Slack API for push events" do
...@@ -95,6 +106,12 @@ describe SlackService, models: true do ...@@ -95,6 +106,12 @@ describe SlackService, models: true do
expect(WebMock).to have_requested(:post, webhook_url).once expect(WebMock).to have_requested(:post, webhook_url).once
end end
it "should call Slack API for wiki page events" do
slack.execute(@wiki_page_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
it 'should use the username as an option for slack when configured' do it 'should use the username as an option for slack when configured' do
allow(slack).to receive(:username).and_return(username) allow(slack).to receive(:username).and_return(username)
expect(Slack::Notifier).to receive(:new). expect(Slack::Notifier).to receive(:new).
......
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