Merge branch 'issue_22269' into 'master'
Mattermost Notifications Service ## What does this MR do? closes #22269 ## Screenshots ![mattermost](/uploads/de71c121f544a91305b6dfa6dc4c5738/mattermost.png) ![slack](/uploads/081d75d49239319d94332abda214fb98/slack.png) ## Does this MR meet the acceptance criteria? - [x] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added - [x] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md) - [x] API support added - Tests - [x] Added for this feature/bug - [x] All builds are passing - [x] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html) - [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides) - [x] Branch has no merge conflicts with `master` (if it does - rebase it please) - [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) See merge request !7764
This commit is contained in:
commit
bdb5e67718
|
@ -95,7 +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 :slack_service, dependent: :destroy
|
has_one :mattermost_notification_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
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'slack-notifier'
|
require 'slack-notifier'
|
||||||
|
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class BaseMessage
|
class BaseMessage
|
||||||
def initialize(params)
|
def initialize(params)
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
|
@ -1,4 +1,4 @@
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class BuildMessage < BaseMessage
|
class BuildMessage < BaseMessage
|
||||||
attr_reader :sha
|
attr_reader :sha
|
||||||
attr_reader :ref_type
|
attr_reader :ref_type
|
|
@ -1,4 +1,4 @@
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class IssueMessage < BaseMessage
|
class IssueMessage < BaseMessage
|
||||||
attr_reader :user_name
|
attr_reader :user_name
|
||||||
attr_reader :title
|
attr_reader :title
|
|
@ -1,4 +1,4 @@
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class MergeMessage < BaseMessage
|
class MergeMessage < BaseMessage
|
||||||
attr_reader :user_name
|
attr_reader :user_name
|
||||||
attr_reader :project_name
|
attr_reader :project_name
|
|
@ -1,4 +1,4 @@
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class NoteMessage < BaseMessage
|
class NoteMessage < BaseMessage
|
||||||
attr_reader :message
|
attr_reader :message
|
||||||
attr_reader :user_name
|
attr_reader :user_name
|
|
@ -1,4 +1,4 @@
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class PipelineMessage < BaseMessage
|
class PipelineMessage < BaseMessage
|
||||||
attr_reader :ref_type, :ref, :status, :project_name, :project_url,
|
attr_reader :ref_type, :ref, :status, :project_name, :project_url,
|
||||||
:user_name, :duration, :pipeline_id
|
:user_name, :duration, :pipeline_id
|
|
@ -1,4 +1,4 @@
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class PushMessage < BaseMessage
|
class PushMessage < BaseMessage
|
||||||
attr_reader :after
|
attr_reader :after
|
||||||
attr_reader :before
|
attr_reader :before
|
|
@ -1,4 +1,4 @@
|
||||||
class SlackService
|
module ChatMessage
|
||||||
class WikiPageMessage < BaseMessage
|
class WikiPageMessage < BaseMessage
|
||||||
attr_reader :user_name
|
attr_reader :user_name
|
||||||
attr_reader :title
|
attr_reader :title
|
|
@ -1,6 +1,13 @@
|
||||||
class SlackService < Service
|
# 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
|
prop_accessor :webhook, :username, :channel
|
||||||
boolean_accessor :notify_only_broken_builds, :notify_only_broken_pipelines
|
boolean_accessor :notify_only_broken_builds, :notify_only_broken_pipelines
|
||||||
|
|
||||||
validates :webhook, presence: true, url: true, if: :activated?
|
validates :webhook, presence: true, url: true, if: :activated?
|
||||||
|
|
||||||
def initialize_properties
|
def initialize_properties
|
||||||
|
@ -14,35 +21,8 @@ class SlackService < Service
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def title
|
def can_test?
|
||||||
'Slack'
|
valid?
|
||||||
end
|
|
||||||
|
|
||||||
def description
|
|
||||||
'A team communication tool for the 21st century'
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_param
|
|
||||||
'slack'
|
|
||||||
end
|
|
||||||
|
|
||||||
def help
|
|
||||||
'This service sends notifications to your Slack channel.<br/>
|
|
||||||
To setup this Service you need to create a new <b>"Incoming webhook"</b> in your Slack integration panel,
|
|
||||||
and enter the Webhook URL below.'
|
|
||||||
end
|
|
||||||
|
|
||||||
def fields
|
|
||||||
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' },
|
|
||||||
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
|
|
||||||
]
|
|
||||||
|
|
||||||
default_fields + build_event_channels
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def supported_events
|
def supported_events
|
||||||
|
@ -67,21 +47,16 @@ class SlackService < Service
|
||||||
|
|
||||||
message = get_message(object_kind, data)
|
message = get_message(object_kind, data)
|
||||||
|
|
||||||
if message
|
return false unless message
|
||||||
opt = {}
|
|
||||||
|
|
||||||
event_channel = get_channel_field(object_kind) || channel
|
opt = {}
|
||||||
|
|
||||||
opt[:channel] = event_channel if event_channel
|
opt[:channel] = get_channel_field(object_kind).presence || channel || default_channel
|
||||||
opt[:username] = username if username
|
opt[:username] = username if username
|
||||||
|
notifier = Slack::Notifier.new(webhook, opt)
|
||||||
|
notifier.ping(message.pretext, attachments: message.attachments, fallback: message.fallback)
|
||||||
|
|
||||||
notifier = Slack::Notifier.new(webhook, opt)
|
true
|
||||||
notifier.ping(message.pretext, attachments: message.attachments, fallback: message.fallback)
|
|
||||||
|
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def event_channel_names
|
def event_channel_names
|
||||||
|
@ -96,6 +71,10 @@ class SlackService < Service
|
||||||
fields.reject { |field| field[:name].end_with?('channel') }
|
fields.reject { |field| field[:name].end_with?('channel') }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_channel
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_message(object_kind, data)
|
def get_message(object_kind, data)
|
||||||
|
@ -124,7 +103,7 @@ class SlackService < Service
|
||||||
|
|
||||||
def build_event_channels
|
def build_event_channels
|
||||||
supported_events.reduce([]) do |channels, event|
|
supported_events.reduce([]) do |channels, event|
|
||||||
channels << { type: 'text', name: event_channel_name(event), placeholder: "#general" }
|
channels << { type: 'text', name: event_channel_name(event), placeholder: default_channel }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -166,11 +145,3 @@ class SlackService < Service
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require "slack_service/issue_message"
|
|
||||||
require "slack_service/push_message"
|
|
||||||
require "slack_service/merge_message"
|
|
||||||
require "slack_service/note_message"
|
|
||||||
require "slack_service/build_message"
|
|
||||||
require "slack_service/pipeline_message"
|
|
||||||
require "slack_service/wiki_page_message"
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Base class for Chat services
|
# Base class for Chat services
|
||||||
# This class is not meant to be used directly, but only to inherrit from.
|
# This class is not meant to be used directly, but only to inherit from.
|
||||||
class ChatService < Service
|
class ChatService < Service
|
||||||
default_value_for :category, 'chat'
|
default_value_for :category, 'chat'
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
class MattermostNotificationService < ChatNotificationService
|
||||||
|
def title
|
||||||
|
'Mattermost notifications'
|
||||||
|
end
|
||||||
|
|
||||||
|
def description
|
||||||
|
'Receive event notifications in Mattermost'
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
'mattermost_notification'
|
||||||
|
end
|
||||||
|
|
||||||
|
def help
|
||||||
|
'This service sends notifications about projects events to Mattermost channels.<br />
|
||||||
|
To set up this service:
|
||||||
|
<ol>
|
||||||
|
<li><a href="https://docs.mattermost.com/developer/webhooks-incoming.html#enabling-incoming-webhooks">Enable incoming webhooks</a> in your Mattermost installation. </li>
|
||||||
|
<li><a href="https://docs.mattermost.com/developer/webhooks-incoming.html#creating-integrations-using-incoming-webhooks">Add an incoming webhook</a> in your Mattermost team. The default channel can be overridden for each event. </li>
|
||||||
|
<li>Paste the webhook <strong>URL</strong> into the field bellow. </li>
|
||||||
|
<li>Select events below to enable notifications. The channel and username are optional. </li>
|
||||||
|
</ol>'
|
||||||
|
end
|
||||||
|
|
||||||
|
def fields
|
||||||
|
default_fields + build_event_channels
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_fields
|
||||||
|
[
|
||||||
|
{ type: 'text', name: 'webhook', placeholder: 'http://mattermost_host/hooks/...' },
|
||||||
|
{ type: 'text', name: 'username', placeholder: 'username' },
|
||||||
|
{ type: 'checkbox', name: 'notify_only_broken_builds' },
|
||||||
|
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_channel
|
||||||
|
"#town-square"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,40 @@
|
||||||
|
class SlackNotificationService < ChatNotificationService
|
||||||
|
def title
|
||||||
|
'Slack notifications'
|
||||||
|
end
|
||||||
|
|
||||||
|
def description
|
||||||
|
'Receive event notifications in Slack'
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
'slack_notification'
|
||||||
|
end
|
||||||
|
|
||||||
|
def help
|
||||||
|
'This service sends notifications about projects events to Slack channels.<br />
|
||||||
|
To setup this service:
|
||||||
|
<ol>
|
||||||
|
<li><a href="https://slack.com/apps/A0F7XDUAZ-incoming-webhooks">Add an incoming webhook</a> in your Slack team. The default channel can be overridden for each event. </li>
|
||||||
|
<li>Paste the <strong>Webhook URL</strong> into the field below. </li>
|
||||||
|
<li>Select events below to enable notifications. The channel and username are optional. </li>
|
||||||
|
</ol>'
|
||||||
|
end
|
||||||
|
|
||||||
|
def fields
|
||||||
|
default_fields + build_event_channels
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_fields
|
||||||
|
[
|
||||||
|
{ type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' },
|
||||||
|
{ type: 'text', name: 'username', placeholder: 'username' },
|
||||||
|
{ type: 'checkbox', name: 'notify_only_broken_builds' },
|
||||||
|
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_channel
|
||||||
|
"#general"
|
||||||
|
end
|
||||||
|
end
|
|
@ -220,7 +220,8 @@ class Service < ActiveRecord::Base
|
||||||
pivotaltracker
|
pivotaltracker
|
||||||
pushover
|
pushover
|
||||||
redmine
|
redmine
|
||||||
slack
|
mattermost_notification
|
||||||
|
slack_notification
|
||||||
teamcity
|
teamcity
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
title: Create mattermost service
|
||||||
|
merge_request:
|
||||||
|
author:
|
|
@ -1,7 +1,11 @@
|
||||||
# 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|
|
SlackNotificationService.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']
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
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
|
|
@ -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: 20161212142807) do
|
ActiveRecord::Schema.define(version: 20161213172958) 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"
|
||||||
|
|
|
@ -703,9 +703,9 @@ Get Redmine service settings for a project.
|
||||||
GET /projects/:id/services/redmine
|
GET /projects/:id/services/redmine
|
||||||
```
|
```
|
||||||
|
|
||||||
## Slack
|
## Slack notifications
|
||||||
|
|
||||||
A team communication tool for the 21st century
|
Receive event notifications in Slack
|
||||||
|
|
||||||
### Create/Edit Slack service
|
### Create/Edit Slack service
|
||||||
|
|
||||||
|
@ -737,6 +737,40 @@ Get Slack service settings for a project.
|
||||||
GET /projects/:id/services/slack
|
GET /projects/:id/services/slack
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Mattermost notifications
|
||||||
|
|
||||||
|
Receive event notifications in Mattermost
|
||||||
|
|
||||||
|
### Create/Edit Mattermost notifications service
|
||||||
|
|
||||||
|
Set Mattermost service for a project.
|
||||||
|
|
||||||
|
```
|
||||||
|
PUT /projects/:id/services/mattermost
|
||||||
|
```
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- `webhook` (**required**) - https://mattermost.example/hooks/1298aff...
|
||||||
|
- `username` (optional) - username
|
||||||
|
- `channel` (optional) - #channel
|
||||||
|
|
||||||
|
### Delete Mattermost notifications service
|
||||||
|
|
||||||
|
Delete Mattermost Notifications service for a project.
|
||||||
|
|
||||||
|
```
|
||||||
|
DELETE /projects/:id/services/mattermost
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get Mattermost notifications service settings
|
||||||
|
|
||||||
|
Get Mattermost notifications service settings for a project.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /projects/:id/services/mattermost
|
||||||
|
```
|
||||||
|
|
||||||
## JetBrains TeamCity CI
|
## JetBrains TeamCity CI
|
||||||
|
|
||||||
A continuous integration and build server
|
A continuous integration and build server
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
|
@ -0,0 +1,45 @@
|
||||||
|
# Mattermost Notifications Service
|
||||||
|
|
||||||
|
## On Mattermost
|
||||||
|
|
||||||
|
To enable Mattermost integration you must create an incoming webhook integration:
|
||||||
|
|
||||||
|
1. Sign in to your Mattermost instance
|
||||||
|
1. Visit incoming webhooks, that will be something like: https://mattermost.example/your_team_name/integrations/incoming_webhooks/add
|
||||||
|
1. Choose a display name, description and channel, those can be overridden on GitLab
|
||||||
|
1. Save it, copy the **Webhook URL**, we'll need this later for GitLab.
|
||||||
|
|
||||||
|
There might be some cases that Incoming Webhooks are blocked by admin, ask your mattermost admin to enable
|
||||||
|
it on https://mattermost.example/admin_console/integrations/custom.
|
||||||
|
|
||||||
|
Display name override is not enabled by default, you need to ask your admin to enable it on that same section.
|
||||||
|
|
||||||
|
## On GitLab
|
||||||
|
|
||||||
|
After you set up Mattermost, it's time to set up GitLab.
|
||||||
|
|
||||||
|
Go to your project's **Settings > Services > Mattermost Notifications** and you will see a
|
||||||
|
checkbox with the following events that can be triggered:
|
||||||
|
|
||||||
|
- Push
|
||||||
|
- Issue
|
||||||
|
- Merge request
|
||||||
|
- Note
|
||||||
|
- Tag push
|
||||||
|
- Build
|
||||||
|
- Wiki page
|
||||||
|
|
||||||
|
Bellow each of these event checkboxes, you will have an input field to insert
|
||||||
|
which Mattermost channel you want to send that event message, with `#town-square`
|
||||||
|
being the default. The hash sign is optional.
|
||||||
|
|
||||||
|
At the end, fill in your Mattermost details:
|
||||||
|
|
||||||
|
| Field | Description |
|
||||||
|
| ----- | ----------- |
|
||||||
|
| **Webhook** | The incoming webhooks which you have to setup on Mattermost, it will be something like: http://mattermost.example/hooks/5xo... |
|
||||||
|
| **Username** | Optional username which can be on messages sent to Mattermost. Fill this in if you want to change the username of the bot. |
|
||||||
|
| **Notify only broken builds** | If you choose to enable the **Build** event and you want to be only notified about failed builds. |
|
||||||
|
|
||||||
|
|
||||||
|
![Mattermost configuration](img/mattermost_configuration.png)
|
|
@ -44,10 +44,11 @@ further configuration instructions and details. Contributions are welcome.
|
||||||
| JetBrains TeamCity CI | A continuous integration and build server |
|
| JetBrains TeamCity CI | A continuous integration and build server |
|
||||||
| [Kubernetes](kubernetes.md) | A containerized deployment service |
|
| [Kubernetes](kubernetes.md) | A containerized deployment service |
|
||||||
| [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands |
|
| [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands |
|
||||||
|
| [Mattermost Notifications](mattermost.md) | Receive event notifications in Mattermost |
|
||||||
|
| [Slack Notifications](slack.md) | Receive event notifications in Slack |
|
||||||
| PivotalTracker | Project Management Software (Source Commits Endpoint) |
|
| PivotalTracker | Project Management Software (Source Commits Endpoint) |
|
||||||
| Pushover | Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop |
|
| Pushover | Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop |
|
||||||
| [Redmine](redmine.md) | Redmine issue tracker |
|
| [Redmine](redmine.md) | Redmine issue tracker |
|
||||||
| [Slack](slack.md) | A team communication tool for the 21st century |
|
|
||||||
|
|
||||||
## Services Templates
|
## Services Templates
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Slack Service
|
# Slack Notifications Service
|
||||||
|
|
||||||
## On Slack
|
## On Slack
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ Slack:
|
||||||
|
|
||||||
After you set up Slack, it's time to set up GitLab.
|
After you set up Slack, it's time to set up GitLab.
|
||||||
|
|
||||||
Go to your project's **Settings > Services > Slack** and you will see a
|
Go to your project's **Settings > Services > Slack Notifications** and you will see a
|
||||||
checkbox with the following events that can be triggered:
|
checkbox with the following events that can be triggered:
|
||||||
|
|
||||||
- Push
|
- Push
|
||||||
|
|
|
@ -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
|
||||||
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,
|
||||||
|
|
Binary file not shown.
|
@ -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) { SlackNotificationService.new }
|
||||||
let(:project) { create(:project, slack_service: service) }
|
let(:project) { create(:project, slack_notification_service: service) }
|
||||||
|
|
||||||
background do
|
background do
|
||||||
service.fields
|
service.fields
|
||||||
|
|
|
@ -136,7 +136,8 @@ project:
|
||||||
- assembla_service
|
- assembla_service
|
||||||
- asana_service
|
- asana_service
|
||||||
- gemnasium_service
|
- gemnasium_service
|
||||||
- slack_service
|
- slack_notification_service
|
||||||
|
- mattermost_notification_service
|
||||||
- buildkite_service
|
- buildkite_service
|
||||||
- bamboo_service
|
- bamboo_service
|
||||||
- teamcity_service
|
- teamcity_service
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe SlackService::BuildMessage do
|
describe ChatMessage::BuildMessage do
|
||||||
subject { SlackService::BuildMessage.new(args) }
|
subject { described_class.new(args) }
|
||||||
|
|
||||||
let(:args) do
|
let(:args) do
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe SlackService::IssueMessage, models: true do
|
describe ChatMessage::IssueMessage, models: true do
|
||||||
subject { SlackService::IssueMessage.new(args) }
|
subject { described_class.new(args) }
|
||||||
|
|
||||||
let(:args) do
|
let(:args) do
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe SlackService::MergeMessage, models: true do
|
describe ChatMessage::MergeMessage, models: true do
|
||||||
subject { SlackService::MergeMessage.new(args) }
|
subject { described_class.new(args) }
|
||||||
|
|
||||||
let(:args) do
|
let(:args) do
|
||||||
{
|
{
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe SlackService::NoteMessage, models: true do
|
describe ChatMessage::NoteMessage, models: true do
|
||||||
let(:color) { '#345' }
|
let(:color) { '#345' }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
@ -36,7 +36,7 @@ describe SlackService::NoteMessage, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a message regarding notes on commits' do
|
it 'returns a message regarding notes on commits' do
|
||||||
message = SlackService::NoteMessage.new(@args)
|
message = described_class.new(@args)
|
||||||
expect(message.pretext).to eq("test.user <url|commented on " \
|
expect(message.pretext).to eq("test.user <url|commented on " \
|
||||||
"commit 5f163b2b> in <somewhere.com|project_name>: " \
|
"commit 5f163b2b> in <somewhere.com|project_name>: " \
|
||||||
"*Added a commit message*")
|
"*Added a commit message*")
|
||||||
|
@ -62,7 +62,7 @@ describe SlackService::NoteMessage, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a message regarding notes on a merge request' do
|
it 'returns a message regarding notes on a merge request' do
|
||||||
message = SlackService::NoteMessage.new(@args)
|
message = described_class.new(@args)
|
||||||
expect(message.pretext).to eq("test.user <url|commented on " \
|
expect(message.pretext).to eq("test.user <url|commented on " \
|
||||||
"merge request !30> in <somewhere.com|project_name>: " \
|
"merge request !30> in <somewhere.com|project_name>: " \
|
||||||
"*merge request title*")
|
"*merge request title*")
|
||||||
|
@ -88,7 +88,7 @@ describe SlackService::NoteMessage, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a message regarding notes on an issue' do
|
it 'returns a message regarding notes on an issue' do
|
||||||
message = SlackService::NoteMessage.new(@args)
|
message = described_class.new(@args)
|
||||||
expect(message.pretext).to eq(
|
expect(message.pretext).to eq(
|
||||||
"test.user <url|commented on " \
|
"test.user <url|commented on " \
|
||||||
"issue #20> in <somewhere.com|project_name>: " \
|
"issue #20> in <somewhere.com|project_name>: " \
|
||||||
|
@ -114,7 +114,7 @@ describe SlackService::NoteMessage, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a message regarding notes on a project snippet' do
|
it 'returns a message regarding notes on a project snippet' do
|
||||||
message = SlackService::NoteMessage.new(@args)
|
message = described_class.new(@args)
|
||||||
expect(message.pretext).to eq("test.user <url|commented on " \
|
expect(message.pretext).to eq("test.user <url|commented on " \
|
||||||
"snippet #5> in <somewhere.com|project_name>: " \
|
"snippet #5> in <somewhere.com|project_name>: " \
|
||||||
"*snippet title*")
|
"*snippet title*")
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe SlackService::PipelineMessage do
|
describe ChatMessage::PipelineMessage do
|
||||||
subject { SlackService::PipelineMessage.new(args) }
|
subject { described_class.new(args) }
|
||||||
let(:user) { { name: 'hacker' } }
|
let(:user) { { name: 'hacker' } }
|
||||||
|
|
||||||
let(:args) do
|
let(:args) do
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe SlackService::PushMessage, models: true do
|
describe ChatMessage::PushMessage, models: true do
|
||||||
subject { SlackService::PushMessage.new(args) }
|
subject { described_class.new(args) }
|
||||||
|
|
||||||
let(:args) do
|
let(:args) do
|
||||||
{
|
{
|
|
@ -1,6 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe SlackService::WikiPageMessage, models: true do
|
describe ChatMessage::WikiPageMessage, models: true do
|
||||||
subject { described_class.new(args) }
|
subject { described_class.new(args) }
|
||||||
|
|
||||||
let(:args) do
|
let(:args) do
|
|
@ -0,0 +1,11 @@
|
||||||
|
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
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe MattermostNotificationService, models: true do
|
||||||
|
it_behaves_like "slack or mattermost"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe SlackNotificationService, models: true do
|
||||||
|
it_behaves_like "slack or mattermost"
|
||||||
|
end
|
|
@ -22,7 +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_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) }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'spec_helper'
|
Dir[Rails.root.join("app/models/project_services/chat_message/*.rb")].each { |f| require f }
|
||||||
|
|
||||||
describe SlackService, models: true do
|
RSpec.shared_examples 'slack or mattermost' do
|
||||||
let(:slack) { SlackService.new }
|
let(:chat_service) { described_class.new }
|
||||||
let(:webhook_url) { 'https://example.gitlab.com/' }
|
let(:webhook_url) { 'https://example.gitlab.com/' }
|
||||||
|
|
||||||
describe "Associations" do
|
describe "Associations" do
|
||||||
|
@ -24,7 +24,7 @@ describe SlackService, models: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Execute" do
|
describe "#execute" do
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:username) { 'slack_username' }
|
let(:username) { 'slack_username' }
|
||||||
|
@ -35,7 +35,7 @@ describe SlackService, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(slack).to receive_messages(
|
allow(chat_service).to receive_messages(
|
||||||
project: project,
|
project: project,
|
||||||
project_id: project.id,
|
project_id: project.id,
|
||||||
service_hook: true,
|
service_hook: true,
|
||||||
|
@ -77,54 +77,55 @@ describe SlackService, models: true do
|
||||||
@wiki_page_sample_data = wiki_page_service.hook_data(@wiki_page, 'create')
|
@wiki_page_sample_data = wiki_page_service.hook_data(@wiki_page, 'create')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls Slack API for push events" do
|
it "calls Slack/Mattermost API for push events" do
|
||||||
slack.execute(push_sample_data)
|
chat_service.execute(push_sample_data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls Slack API for issue events" do
|
it "calls Slack/Mattermost API for issue events" do
|
||||||
slack.execute(@issues_sample_data)
|
chat_service.execute(@issues_sample_data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls Slack API for merge requests events" do
|
it "calls Slack/Mattermost API for merge requests events" do
|
||||||
slack.execute(@merge_sample_data)
|
chat_service.execute(@merge_sample_data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls Slack API for wiki page events" do
|
it "calls Slack/Mattermost API for wiki page events" do
|
||||||
slack.execute(@wiki_page_sample_data)
|
chat_service.execute(@wiki_page_sample_data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'uses the username as an option for slack when configured' do
|
it 'uses the username as an option for slack when configured' do
|
||||||
allow(slack).to receive(:username).and_return(username)
|
allow(chat_service).to receive(:username).and_return(username)
|
||||||
|
|
||||||
expect(Slack::Notifier).to receive(:new).
|
expect(Slack::Notifier).to receive(:new).
|
||||||
with(webhook_url, username: username).
|
with(webhook_url, username: username, channel: chat_service.default_channel).
|
||||||
and_return(
|
and_return(
|
||||||
double(:slack_service).as_null_object
|
double(:slack_service).as_null_object
|
||||||
)
|
)
|
||||||
|
|
||||||
slack.execute(push_sample_data)
|
chat_service.execute(push_sample_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'uses the channel as an option when it is configured' do
|
it 'uses the channel as an option when it is configured' do
|
||||||
allow(slack).to receive(:channel).and_return(channel)
|
allow(chat_service).to receive(:channel).and_return(channel)
|
||||||
expect(Slack::Notifier).to receive(:new).
|
expect(Slack::Notifier).to receive(:new).
|
||||||
with(webhook_url, channel: channel).
|
with(webhook_url, channel: channel).
|
||||||
and_return(
|
and_return(
|
||||||
double(:slack_service).as_null_object
|
double(:slack_service).as_null_object
|
||||||
)
|
)
|
||||||
slack.execute(push_sample_data)
|
chat_service.execute(push_sample_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "event channels" do
|
context "event channels" do
|
||||||
it "uses the right channel for push event" do
|
it "uses the right channel for push event" do
|
||||||
slack.update_attributes(push_channel: "random")
|
chat_service.update_attributes(push_channel: "random")
|
||||||
|
|
||||||
expect(Slack::Notifier).to receive(:new).
|
expect(Slack::Notifier).to receive(:new).
|
||||||
with(webhook_url, channel: "random").
|
with(webhook_url, channel: "random").
|
||||||
|
@ -132,11 +133,11 @@ describe SlackService, models: true do
|
||||||
double(:slack_service).as_null_object
|
double(:slack_service).as_null_object
|
||||||
)
|
)
|
||||||
|
|
||||||
slack.execute(push_sample_data)
|
chat_service.execute(push_sample_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "uses the right channel for merge request event" do
|
it "uses the right channel for merge request event" do
|
||||||
slack.update_attributes(merge_request_channel: "random")
|
chat_service.update_attributes(merge_request_channel: "random")
|
||||||
|
|
||||||
expect(Slack::Notifier).to receive(:new).
|
expect(Slack::Notifier).to receive(:new).
|
||||||
with(webhook_url, channel: "random").
|
with(webhook_url, channel: "random").
|
||||||
|
@ -144,11 +145,11 @@ describe SlackService, models: true do
|
||||||
double(:slack_service).as_null_object
|
double(:slack_service).as_null_object
|
||||||
)
|
)
|
||||||
|
|
||||||
slack.execute(@merge_sample_data)
|
chat_service.execute(@merge_sample_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "uses the right channel for issue event" do
|
it "uses the right channel for issue event" do
|
||||||
slack.update_attributes(issue_channel: "random")
|
chat_service.update_attributes(issue_channel: "random")
|
||||||
|
|
||||||
expect(Slack::Notifier).to receive(:new).
|
expect(Slack::Notifier).to receive(:new).
|
||||||
with(webhook_url, channel: "random").
|
with(webhook_url, channel: "random").
|
||||||
|
@ -156,11 +157,11 @@ describe SlackService, models: true do
|
||||||
double(:slack_service).as_null_object
|
double(:slack_service).as_null_object
|
||||||
)
|
)
|
||||||
|
|
||||||
slack.execute(@issues_sample_data)
|
chat_service.execute(@issues_sample_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "uses the right channel for wiki event" do
|
it "uses the right channel for wiki event" do
|
||||||
slack.update_attributes(wiki_page_channel: "random")
|
chat_service.update_attributes(wiki_page_channel: "random")
|
||||||
|
|
||||||
expect(Slack::Notifier).to receive(:new).
|
expect(Slack::Notifier).to receive(:new).
|
||||||
with(webhook_url, channel: "random").
|
with(webhook_url, channel: "random").
|
||||||
|
@ -168,7 +169,7 @@ describe SlackService, models: true do
|
||||||
double(:slack_service).as_null_object
|
double(:slack_service).as_null_object
|
||||||
)
|
)
|
||||||
|
|
||||||
slack.execute(@wiki_page_sample_data)
|
chat_service.execute(@wiki_page_sample_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "note event" do
|
context "note event" do
|
||||||
|
@ -177,7 +178,7 @@ describe SlackService, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "uses the right channel" do
|
it "uses the right channel" do
|
||||||
slack.update_attributes(note_channel: "random")
|
chat_service.update_attributes(note_channel: "random")
|
||||||
|
|
||||||
note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
|
note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
|
||||||
|
|
||||||
|
@ -187,7 +188,7 @@ describe SlackService, models: true do
|
||||||
double(:slack_service).as_null_object
|
double(:slack_service).as_null_object
|
||||||
)
|
)
|
||||||
|
|
||||||
slack.execute(note_data)
|
chat_service.execute(note_data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -198,7 +199,7 @@ describe SlackService, models: true do
|
||||||
let(:project) { create(:project, creator_id: user.id) }
|
let(:project) { create(:project, creator_id: user.id) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(slack).to receive_messages(
|
allow(chat_service).to receive_messages(
|
||||||
project: project,
|
project: project,
|
||||||
project_id: project.id,
|
project_id: project.id,
|
||||||
service_hook: true,
|
service_hook: true,
|
||||||
|
@ -216,9 +217,9 @@ describe SlackService, models: true do
|
||||||
note: 'a comment on a commit')
|
note: 'a comment on a commit')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls Slack API for commit comment events" do
|
it "calls Slack/Mattermost API for commit comment events" do
|
||||||
data = Gitlab::DataBuilder::Note.build(commit_note, user)
|
data = Gitlab::DataBuilder::Note.build(commit_note, user)
|
||||||
slack.execute(data)
|
chat_service.execute(data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
@ -232,7 +233,7 @@ describe SlackService, models: true do
|
||||||
|
|
||||||
it "calls Slack API for merge request comment events" do
|
it "calls Slack API for merge request comment events" do
|
||||||
data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
|
data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
|
||||||
slack.execute(data)
|
chat_service.execute(data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
@ -245,7 +246,7 @@ describe SlackService, models: true do
|
||||||
|
|
||||||
it "calls Slack API for issue comment events" do
|
it "calls Slack API for issue comment events" do
|
||||||
data = Gitlab::DataBuilder::Note.build(issue_note, user)
|
data = Gitlab::DataBuilder::Note.build(issue_note, user)
|
||||||
slack.execute(data)
|
chat_service.execute(data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
@ -259,7 +260,7 @@ describe SlackService, models: true do
|
||||||
|
|
||||||
it "calls Slack API for snippet comment events" do
|
it "calls Slack API for snippet comment events" do
|
||||||
data = Gitlab::DataBuilder::Note.build(snippet_note, user)
|
data = Gitlab::DataBuilder::Note.build(snippet_note, user)
|
||||||
slack.execute(data)
|
chat_service.execute(data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
@ -277,21 +278,21 @@ describe SlackService, models: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(slack).to receive_messages(
|
allow(chat_service).to receive_messages(
|
||||||
project: project,
|
project: project,
|
||||||
service_hook: true,
|
service_hook: true,
|
||||||
webhook: webhook_url
|
webhook: webhook_url
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'call Slack API' do
|
shared_examples 'call Slack/Mattermost API' do
|
||||||
before do
|
before do
|
||||||
WebMock.stub_request(:post, webhook_url)
|
WebMock.stub_request(:post, webhook_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'calls Slack API for pipeline events' do
|
it 'calls Slack/Mattermost API for pipeline events' do
|
||||||
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
|
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
|
||||||
slack.execute(data)
|
chat_service.execute(data)
|
||||||
|
|
||||||
expect(WebMock).to have_requested(:post, webhook_url).once
|
expect(WebMock).to have_requested(:post, webhook_url).once
|
||||||
end
|
end
|
||||||
|
@ -300,16 +301,16 @@ describe SlackService, models: true do
|
||||||
context 'with failed pipeline' do
|
context 'with failed pipeline' do
|
||||||
let(:status) { 'failed' }
|
let(:status) { 'failed' }
|
||||||
|
|
||||||
it_behaves_like 'call Slack API'
|
it_behaves_like 'call Slack/Mattermost API'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with succeeded pipeline' do
|
context 'with succeeded pipeline' do
|
||||||
let(:status) { 'success' }
|
let(:status) { 'success' }
|
||||||
|
|
||||||
context 'with default to notify_only_broken_pipelines' do
|
context 'with default to notify_only_broken_pipelines' do
|
||||||
it 'does not call Slack API for pipeline events' do
|
it 'does not call Slack/Mattermost API for pipeline events' do
|
||||||
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
|
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
|
||||||
result = slack.execute(data)
|
result = chat_service.execute(data)
|
||||||
|
|
||||||
expect(result).to be_falsy
|
expect(result).to be_falsy
|
||||||
end
|
end
|
||||||
|
@ -317,10 +318,10 @@ describe SlackService, models: true do
|
||||||
|
|
||||||
context 'with setting notify_only_broken_pipelines to false' do
|
context 'with setting notify_only_broken_pipelines to false' do
|
||||||
before do
|
before do
|
||||||
slack.notify_only_broken_pipelines = false
|
chat_service.notify_only_broken_pipelines = false
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'call Slack API'
|
it_behaves_like 'call Slack/Mattermost API'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Reference in New Issue