Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
a5ccaded
Commit
a5ccaded
authored
Dec 06, 2016
by
Felipe Artur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change SlackService to SlackNotificationsService
parent
141faaac
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
223 additions
and
168 deletions
+223
-168
app/models/project.rb
app/models/project.rb
+2
-2
app/models/project_services/chat_notification_service.rb
app/models/project_services/chat_notification_service.rb
+147
-0
app/models/project_services/chat_service.rb
app/models/project_services/chat_service.rb
+8
-135
app/models/project_services/mattermost_notification_service.rb
...odels/project_services/mattermost_notification_service.rb
+3
-3
app/models/project_services/mattermost_slash_commands_service.rb
...els/project_services/mattermost_slash_commands_service.rb
+1
-11
app/models/project_services/slack_notification_service.rb
app/models/project_services/slack_notification_service.rb
+2
-2
app/models/service.rb
app/models/service.rb
+2
-2
db/migrate/20141006143943_move_slack_service_to_webhook.rb
db/migrate/20141006143943_move_slack_service_to_webhook.rb
+5
-1
db/migrate/20161213172958_change_slack_service_to_slack_notification_service.rb
...958_change_slack_service_to_slack_notification_service.rb
+14
-0
db/schema.rb
db/schema.rb
+1
-1
lib/api/services.rb
lib/api/services.rb
+9
-1
spec/features/projects/import_export/test_project_export.tar.gz
...eatures/projects/import_export/test_project_export.tar.gz
+0
-0
spec/features/projects/services/slack_service_spec.rb
spec/features/projects/services/slack_service_spec.rb
+2
-2
spec/lib/gitlab/import_export/all_models.yml
spec/lib/gitlab/import_export/all_models.yml
+2
-2
spec/models/project_services/chat_notification_service_spec.rb
...models/project_services/chat_notification_service_spec.rb
+12
-0
spec/models/project_services/chat_service_spec.rb
spec/models/project_services/chat_service_spec.rb
+9
-2
spec/models/project_services/mattermost_notification_service_spec.rb
.../project_services/mattermost_notification_service_spec.rb
+1
-1
spec/models/project_services/slack_notification_service_spec.rb
...odels/project_services/slack_notification_service_spec.rb
+1
-1
spec/models/project_spec.rb
spec/models/project_spec.rb
+2
-2
No files found.
app/models/project.rb
View file @
a5ccaded
...
@@ -95,8 +95,8 @@ class Project < ActiveRecord::Base
...
@@ -95,8 +95,8 @@ class Project < ActiveRecord::Base
has_one
:asana_service
,
dependent: :destroy
has_one
:asana_service
,
dependent: :destroy
has_one
:gemnasium_service
,
dependent: :destroy
has_one
:gemnasium_service
,
dependent: :destroy
has_one
:mattermost_slash_commands_service
,
dependent: :destroy
has_one
:mattermost_slash_commands_service
,
dependent: :destroy
has_one
:mattermost_service
,
dependent: :destroy
has_one
:mattermost_
notification_
service
,
dependent: :destroy
has_one
:slack_service
,
dependent: :destroy
has_one
:slack_
notification_
service
,
dependent: :destroy
has_one
:buildkite_service
,
dependent: :destroy
has_one
:buildkite_service
,
dependent: :destroy
has_one
:bamboo_service
,
dependent: :destroy
has_one
:bamboo_service
,
dependent: :destroy
has_one
:teamcity_service
,
dependent: :destroy
has_one
:teamcity_service
,
dependent: :destroy
...
...
app/models/project_services/chat_notification_service.rb
0 → 100644
View file @
a5ccaded
# Base class for Chat notifications services
# This class is not meant to be used directly, but only to inherit from.
class
ChatNotificationService
<
Service
include
ChatMessage
default_value_for
:category
,
'chat'
prop_accessor
:webhook
,
:username
,
:channel
boolean_accessor
:notify_only_broken_builds
,
:notify_only_broken_pipelines
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
self
.
notify_only_broken_pipelines
=
true
end
end
def
can_test?
valid?
end
def
supported_events
%w[push issue confidential_issue merge_request note tag_push
build pipeline wiki_page]
end
def
execute
(
data
)
return
unless
supported_events
.
include?
(
data
[
:object_kind
])
return
unless
webhook
.
present?
object_kind
=
data
[
:object_kind
]
data
=
data
.
merge
(
project_url:
project_url
,
project_name:
project_name
)
# WebHook events often have an 'update' event that follows a 'open' or
# 'close' action. Ignore update events for now to prevent duplicate
# messages from arriving.
message
=
get_message
(
object_kind
,
data
)
return
false
unless
message
opt
=
{}
opt
[
:channel
]
=
get_channel_field
(
object_kind
).
presence
||
channel
||
default_channel
opt
[
:username
]
=
username
if
username
notifier
=
Slack
::
Notifier
.
new
(
webhook
,
opt
)
notifier
.
ping
(
message
.
pretext
,
attachments:
message
.
attachments
,
fallback:
message
.
fallback
)
true
end
def
event_channel_names
supported_events
.
map
{
|
event
|
event_channel_name
(
event
)
}
end
def
event_field
(
event
)
fields
.
find
{
|
field
|
field
[
:name
]
==
event_channel_name
(
event
)
}
end
def
global_fields
fields
.
reject
{
|
field
|
field
[
:name
].
end_with?
(
'channel'
)
}
end
def
default_channel
raise
NotImplementedError
end
private
def
get_message
(
object_kind
,
data
)
case
object_kind
when
"push"
,
"tag_push"
PushMessage
.
new
(
data
)
when
"issue"
IssueMessage
.
new
(
data
)
unless
is_update?
(
data
)
when
"merge_request"
MergeMessage
.
new
(
data
)
unless
is_update?
(
data
)
when
"note"
NoteMessage
.
new
(
data
)
when
"build"
BuildMessage
.
new
(
data
)
if
should_build_be_notified?
(
data
)
when
"pipeline"
PipelineMessage
.
new
(
data
)
if
should_pipeline_be_notified?
(
data
)
when
"wiki_page"
WikiPageMessage
.
new
(
data
)
end
end
def
get_channel_field
(
event
)
field_name
=
event_channel_name
(
event
)
self
.
public_send
(
field_name
)
end
def
build_event_channels
supported_events
.
reduce
([])
do
|
channels
,
event
|
channels
<<
{
type:
'text'
,
name:
event_channel_name
(
event
),
placeholder:
default_channel
}
end
end
def
event_channel_name
(
event
)
"
#{
event
}
_channel"
end
def
project_name
project
.
name_with_namespace
.
gsub
(
/\s/
,
''
)
end
def
project_url
project
.
web_url
end
def
is_update?
(
data
)
data
[
:object_attributes
][
:action
]
==
'update'
end
def
should_build_be_notified?
(
data
)
case
data
[
:commit
][
:status
]
when
'success'
!
notify_only_broken_builds?
when
'failed'
true
else
false
end
end
def
should_pipeline_be_notified?
(
data
)
case
data
[
:object_attributes
][
:status
]
when
'success'
!
notify_only_broken_pipelines?
when
'failed'
true
else
false
end
end
end
app/models/project_services/chat_service.rb
View file @
a5ccaded
# Base class for Chat services
# Base class for Chat services
# This class is not meant to be used directly, but only to inher
r
it from.
# This class is not meant to be used directly, but only to inherit from.
class
ChatService
<
Service
class
ChatService
<
Service
include
ChatMessage
default_value_for
:category
,
'chat'
default_value_for
:category
,
'chat'
prop_accessor
:webhook
,
:username
,
:channel
has_many
:chat_names
,
foreign_key: :service_id
boolean_accessor
:notify_only_broken_builds
,
:notify_only_broken_pipelines
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?
def
valid_token?
(
token
)
self
.
properties
=
{}
self
.
respond_to?
(
:token
)
&&
self
.
notify_only_broken_builds
=
true
self
.
token
.
present?
&&
self
.
notify_only_broken_pipelines
=
true
ActiveSupport
::
SecurityUtils
.
variable_size_secure_compare
(
token
,
self
.
token
)
end
end
def
can_test?
valid?
end
end
def
supported_events
def
supported_events
%w[push issue confidential_issue merge_request note tag_push
[]
build pipeline wiki_page]
end
end
def
execute
(
data
)
def
trigger
(
params
)
return
unless
supported_events
.
include?
(
data
[
:object_kind
])
return
unless
webhook
.
present?
object_kind
=
data
[
:object_kind
]
data
=
data
.
merge
(
project_url:
project_url
,
project_name:
project_name
)
# WebHook events often have an 'update' event that follows a 'open' or
# 'close' action. Ignore update events for now to prevent duplicate
# messages from arriving.
message
=
get_message
(
object_kind
,
data
)
return
false
unless
message
opt
=
{}
opt
[
:channel
]
=
get_channel_field
(
object_kind
).
presence
||
channel
||
default_channel
opt
[
:username
]
=
username
if
username
notifier
=
Slack
::
Notifier
.
new
(
webhook
,
opt
)
notifier
.
ping
(
message
.
pretext
,
attachments:
message
.
attachments
,
fallback:
message
.
fallback
)
true
end
def
event_channel_names
supported_events
.
map
{
|
event
|
event_channel_name
(
event
)
}
end
def
event_field
(
event
)
fields
.
find
{
|
field
|
field
[
:name
]
==
event_channel_name
(
event
)
}
end
def
global_fields
fields
.
reject
{
|
field
|
field
[
:name
].
end_with?
(
'channel'
)
}
end
def
default_channel
raise
NotImplementedError
raise
NotImplementedError
end
end
private
def
get_message
(
object_kind
,
data
)
case
object_kind
when
"push"
,
"tag_push"
PushMessage
.
new
(
data
)
when
"issue"
IssueMessage
.
new
(
data
)
unless
is_update?
(
data
)
when
"merge_request"
MergeMessage
.
new
(
data
)
unless
is_update?
(
data
)
when
"note"
NoteMessage
.
new
(
data
)
when
"build"
BuildMessage
.
new
(
data
)
if
should_build_be_notified?
(
data
)
when
"pipeline"
PipelineMessage
.
new
(
data
)
if
should_pipeline_be_notified?
(
data
)
when
"wiki_page"
WikiPageMessage
.
new
(
data
)
end
end
def
get_channel_field
(
event
)
field_name
=
event_channel_name
(
event
)
self
.
public_send
(
field_name
)
end
def
build_event_channels
supported_events
.
reduce
([])
do
|
channels
,
event
|
channels
<<
{
type:
'text'
,
name:
event_channel_name
(
event
),
placeholder:
default_channel
}
end
end
def
event_channel_name
(
event
)
"
#{
event
}
_channel"
end
def
project_name
project
.
name_with_namespace
.
gsub
(
/\s/
,
''
)
end
def
project_url
project
.
web_url
end
def
is_update?
(
data
)
data
[
:object_attributes
][
:action
]
==
'update'
end
def
should_build_be_notified?
(
data
)
case
data
[
:commit
][
:status
]
when
'success'
!
notify_only_broken_builds?
when
'failed'
true
else
false
end
end
def
should_pipeline_be_notified?
(
data
)
case
data
[
:object_attributes
][
:status
]
when
'success'
!
notify_only_broken_pipelines?
when
'failed'
true
else
false
end
end
end
end
app/models/project_services/mattermost_service.rb
→
app/models/project_services/mattermost_
notification_
service.rb
View file @
a5ccaded
class
Mattermost
Service
<
Chat
Service
class
Mattermost
NotificationService
<
ChatNotification
Service
def
title
def
title
'Mattermost notifications'
'Mattermost notifications'
end
end
...
@@ -8,7 +8,7 @@ class MattermostService < ChatService
...
@@ -8,7 +8,7 @@ class MattermostService < ChatService
end
end
def
to_param
def
to_param
'mattermost'
'mattermost
_notification
'
end
end
def
help
def
help
...
@@ -28,7 +28,7 @@ class MattermostService < ChatService
...
@@ -28,7 +28,7 @@ class MattermostService < ChatService
def
default_fields
def
default_fields
[
[
{
type:
'text'
,
name:
'webhook'
,
placeholder:
'http://mattermost_host/hooks/...'
},
{
type:
'text'
,
name:
'webhook'
,
placeholder:
'http://mattermost_host/hooks/...'
},
{
type:
'text'
,
name:
'username'
,
placeholder:
'username'
},
{
type:
'text'
,
name:
'username'
,
placeholder:
'username'
},
{
type:
'checkbox'
,
name:
'notify_only_broken_builds'
},
{
type:
'checkbox'
,
name:
'notify_only_broken_builds'
},
{
type:
'checkbox'
,
name:
'notify_only_broken_pipelines'
},
{
type:
'checkbox'
,
name:
'notify_only_broken_pipelines'
},
...
...
app/models/project_services/mattermost_slash_commands_service.rb
View file @
a5ccaded
class
MattermostSlashCommandsService
<
Service
class
MattermostSlashCommandsService
<
Chat
Service
include
TriggersHelper
include
TriggersHelper
prop_accessor
:token
prop_accessor
:token
def
valid_token?
(
token
)
self
.
respond_to?
(
:token
)
&&
self
.
token
.
present?
&&
ActiveSupport
::
SecurityUtils
.
variable_size_secure_compare
(
token
,
self
.
token
)
end
def
supported_events
[]
end
def
can_test?
def
can_test?
false
false
end
end
...
...
app/models/project_services/slack_service.rb
→
app/models/project_services/slack_
notification_
service.rb
View file @
a5ccaded
class
Slack
Service
<
Chat
Service
class
Slack
NotificationService
<
ChatNotification
Service
def
title
def
title
'Slack notifications'
'Slack notifications'
end
end
...
@@ -8,7 +8,7 @@ class SlackService < ChatService
...
@@ -8,7 +8,7 @@ class SlackService < ChatService
end
end
def
to_param
def
to_param
'slack'
'slack
_notification
'
end
end
def
help
def
help
...
...
app/models/service.rb
View file @
a5ccaded
...
@@ -220,8 +220,8 @@ class Service < ActiveRecord::Base
...
@@ -220,8 +220,8 @@ class Service < ActiveRecord::Base
pivotaltracker
pivotaltracker
pushover
pushover
redmine
redmine
mattermost
mattermost
_notification
slack
slack
_notification
teamcity
teamcity
]
]
end
end
...
...
db/migrate/20141006143943_move_slack_service_to_webhook.rb
View file @
a5ccaded
# rubocop:disable all
# rubocop:disable all
class
MoveSlackServiceToWebhook
<
ActiveRecord
::
Migration
class
MoveSlackServiceToWebhook
<
ActiveRecord
::
Migration
DOWNTIME
=
true
DOWNTIME_REASON
=
'Move old fields "token" and "subdomain" to one single field "webhook"'
def
change
def
change
SlackService
.
all
.
each
do
|
slack_service
|
Slack
Notification
Service
.
all
.
each
do
|
slack_service
|
if
[
"token"
,
"subdomain"
].
all?
{
|
property
|
slack_service
.
properties
.
key?
property
}
if
[
"token"
,
"subdomain"
].
all?
{
|
property
|
slack_service
.
properties
.
key?
property
}
token
=
slack_service
.
properties
[
'token'
]
token
=
slack_service
.
properties
[
'token'
]
subdomain
=
slack_service
.
properties
[
'subdomain'
]
subdomain
=
slack_service
.
properties
[
'subdomain'
]
...
...
db/migrate/20161213172958_change_slack_service_to_slack_notification_service.rb
0 → 100644
View file @
a5ccaded
class
ChangeSlackServiceToSlackNotificationService
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
true
DOWNTIME_REASON
=
'Rename SlackService to SlackNotificationService'
def
up
execute
(
"UPDATE services SET type = 'SlackNotificationService' WHERE type = 'SlackService'"
)
end
def
down
execute
(
"UPDATE services SET type = 'SlackService' WHERE type = 'SlackNotificationService'"
)
end
end
db/schema.rb
View file @
a5ccaded
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
#
#
# It's strongly recommended that you check this file into your version control system.
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
2016121
2142807
)
do
ActiveRecord
::
Schema
.
define
(
version:
2016121
3172958
)
do
# These are extensions that must be enabled in order to support this database
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
enable_extension
"plpgsql"
...
...
lib/api/services.rb
View file @
a5ccaded
...
@@ -473,7 +473,7 @@ module API
...
@@ -473,7 +473,7 @@ module API
desc:
'The description of the tracker'
desc:
'The description of the tracker'
}
}
],
],
'slack'
=>
[
'slack
-notification
'
=>
[
{
{
required:
true
,
required:
true
,
name: :webhook
,
name: :webhook
,
...
@@ -493,6 +493,14 @@ module API
...
@@ -493,6 +493,14 @@ module API
desc:
'The channel name'
desc:
'The channel name'
}
}
],
],
'mattermost-notification'
=>
[
{
required:
true
,
name: :webhook
,
type:
String
,
desc:
'The Mattermost webhook. e.g. http://mattermost_host/hooks/...'
}
],
'teamcity'
=>
[
'teamcity'
=>
[
{
{
required:
true
,
required:
true
,
...
...
spec/features/projects/import_export/test_project_export.tar.gz
View file @
a5ccaded
No preview for this file type
spec/features/projects/services/slack_service_spec.rb
View file @
a5ccaded
...
@@ -2,8 +2,8 @@ require 'spec_helper'
...
@@ -2,8 +2,8 @@ require 'spec_helper'
feature
'Projects > Slack service > Setup events'
,
feature:
true
do
feature
'Projects > Slack service > Setup events'
,
feature:
true
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:service
)
{
SlackService
.
new
}
let
(
:service
)
{
Slack
Notification
Service
.
new
}
let
(
:project
)
{
create
(
:project
,
slack_service:
service
)
}
let
(
:project
)
{
create
(
:project
,
slack_
notification_
service:
service
)
}
background
do
background
do
service
.
fields
service
.
fields
...
...
spec/lib/gitlab/import_export/all_models.yml
View file @
a5ccaded
...
@@ -136,8 +136,8 @@ project:
...
@@ -136,8 +136,8 @@ project:
-
assembla_service
-
assembla_service
-
asana_service
-
asana_service
-
gemnasium_service
-
gemnasium_service
-
slack_service
-
slack_
notification_
service
-
mattermost_service
-
mattermost_
notification_
service
-
buildkite_service
-
buildkite_service
-
bamboo_service
-
bamboo_service
-
teamcity_service
-
teamcity_service
...
...
spec/models/project_services/chat_notification_service_spec.rb
0 → 100644
View file @
a5ccaded
require
'spec_helper'
describe
ChatNotificationService
,
models:
true
do
describe
"Associations"
do
before
do
allow
(
subject
).
to
receive
(
:activated?
).
and_return
(
true
)
end
it
{
is_expected
.
to
validate_presence_of
:webhook
}
end
end
spec/models/project_services/chat_service_spec.rb
View file @
a5ccaded
...
@@ -2,7 +2,14 @@ require 'spec_helper'
...
@@ -2,7 +2,14 @@ require 'spec_helper'
describe
ChatService
,
models:
true
do
describe
ChatService
,
models:
true
do
describe
"Associations"
do
describe
"Associations"
do
before
{
allow
(
subject
).
to
receive
(
:activated?
).
and_return
(
true
)
}
it
{
is_expected
.
to
have_many
:chat_names
}
it
{
is_expected
.
to
validate_presence_of
:webhook
}
end
describe
'#valid_token?'
do
subject
{
described_class
.
new
}
it
'is false as it has no token'
do
expect
(
subject
.
valid_token?
(
'wer'
)).
to
be_falsey
end
end
end
end
end
spec/models/project_services/
slack
_service_spec.rb
→
spec/models/project_services/
mattermost_notification
_service_spec.rb
View file @
a5ccaded
require
'spec_helper'
require
'spec_helper'
describe
Slack
Service
,
models:
true
do
describe
MattermostNotification
Service
,
models:
true
do
it_behaves_like
"slack or mattermost"
it_behaves_like
"slack or mattermost"
end
end
spec/models/project_services/
mattermost
_service_spec.rb
→
spec/models/project_services/
slack_notification
_service_spec.rb
View file @
a5ccaded
require
'spec_helper'
require
'spec_helper'
describe
Mattermost
Service
,
models:
true
do
describe
SlackNotification
Service
,
models:
true
do
it_behaves_like
"slack or mattermost"
it_behaves_like
"slack or mattermost"
end
end
spec/models/project_spec.rb
View file @
a5ccaded
...
@@ -22,8 +22,8 @@ describe Project, models: true do
...
@@ -22,8 +22,8 @@ describe Project, models: true do
it
{
is_expected
.
to
have_many
(
:protected_branches
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:protected_branches
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:chat_services
)
}
it
{
is_expected
.
to
have_many
(
:chat_services
)
}
it
{
is_expected
.
to
have_one
(
:forked_project_link
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:forked_project_link
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:slack_service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:slack_
notification_
service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:mattermost_service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:mattermost_
notification_
service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:pushover_service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:pushover_service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:asana_service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_one
(
:asana_service
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:boards
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:boards
).
dependent
(
:destroy
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment