From 8da43c2d8e281e97cb67235c1fd9a9025d9eea97 Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt Date: Fri, 4 Jan 2019 00:17:19 +0100 Subject: [PATCH] Revert "Merge branch 'blackst0ne-add-discord-service' into 'master'" This reverts commit ca3e9b975922339b25cc7ca902c7c46e24ed1170, reversing changes made to 89686b90939c7dc1d6c5376d711988efd7809f13. The way Discord integration is implemented causes dependency problems. --- Gemfile | 3 - Gemfile.lock | 3 - app/models/project.rb | 1 - .../project_services/discord_service.rb | 57 ---- app/models/service.rb | 1 - .../integrations/discord_notifications.md | 29 -- .../project/integrations/project_services.md | 1 - lib/api/services.rb | 9 - spec/lib/gitlab/import_export/all_models.yml | 1 - .../project_services/discord_service_spec.rb | 11 - .../hangouts_chat_service_spec.rb | 249 +++++++++++++++++- spec/models/project_spec.rb | 1 - .../models/chat_service_spec.rb | 242 ----------------- 13 files changed, 242 insertions(+), 366 deletions(-) delete mode 100644 app/models/project_services/discord_service.rb delete mode 100644 doc/user/project/integrations/discord_notifications.md delete mode 100644 spec/models/project_services/discord_service_spec.rb delete mode 100644 spec/support/shared_examples/models/chat_service_spec.rb diff --git a/Gemfile b/Gemfile index 1fd519d8be4..969584a9ccc 100644 --- a/Gemfile +++ b/Gemfile @@ -201,9 +201,6 @@ gem 'redis-rails', '~> 5.0.2' gem 'redis', '~> 3.2' gem 'connection_pool', '~> 2.0' -# Discord integration -gem 'discordrb-webhooks-blackst0ne', '~> 3.3', require: false - # HipChat integration gem 'hipchat', '~> 1.5.0' diff --git a/Gemfile.lock b/Gemfile.lock index 27a2821cedb..1d8bd06bb90 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -165,8 +165,6 @@ GEM rotp (~> 2.0) diff-lcs (1.3) diffy (3.1.0) - discordrb-webhooks-blackst0ne (3.3.0) - rest-client (~> 2.0) docile (1.1.5) domain_name (0.5.20180417) unf (>= 0.0.5, < 1.0.0) @@ -991,7 +989,6 @@ DEPENDENCIES devise (~> 4.4) devise-two-factor (~> 3.0.0) diffy (~> 3.1.0) - discordrb-webhooks-blackst0ne (~> 3.3) doorkeeper (~> 4.3) doorkeeper-openid_connect (~> 1.5) ed25519 (~> 1.2) diff --git a/app/models/project.rb b/app/models/project.rb index 1b1bcec413f..1eced48fbbc 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -141,7 +141,6 @@ class Project < ActiveRecord::Base # Project services has_one :campfire_service - has_one :discord_service has_one :drone_ci_service has_one :emails_on_push_service has_one :pipelines_email_service diff --git a/app/models/project_services/discord_service.rb b/app/models/project_services/discord_service.rb deleted file mode 100644 index 21afd14dbff..00000000000 --- a/app/models/project_services/discord_service.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require "discordrb/webhooks" - -class DiscordService < ChatNotificationService - def title - "Discord Notifications" - end - - def description - "Receive event notifications in Discord" - end - - def self.to_param - "discord" - end - - def help - "This service sends notifications about project events to Discord channels.
- To set up this service: -
    -
  1. Setup a custom Incoming Webhook.
  2. -
  3. Paste the Webhook URL into the field below.
  4. -
  5. Select events below to enable notifications.
  6. -
" - end - - def event_field(event) - # No-op. - end - - def default_channel_placeholder - # No-op. - end - - def default_fields - [ - { type: "text", name: "webhook", placeholder: "e.g. https://discordapp.com/api/webhooks/…" }, - { type: "checkbox", name: "notify_only_broken_pipelines" }, - { type: "checkbox", name: "notify_only_default_branch" } - ] - end - - private - - def notify(message, opts) - client = Discordrb::Webhooks::Client.new(url: webhook) - - client.execute do |builder| - builder.content = message.pretext - end - end - - def custom_data(data) - super(data).merge(markdown: true) - end -end diff --git a/app/models/service.rb b/app/models/service.rb index cdae99d7727..c7380719197 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -249,7 +249,6 @@ def self.available_services_names bugzilla campfire custom_issue_tracker - discord drone_ci emails_on_push external_wiki diff --git a/doc/user/project/integrations/discord_notifications.md b/doc/user/project/integrations/discord_notifications.md deleted file mode 100644 index cb98105e0c0..00000000000 --- a/doc/user/project/integrations/discord_notifications.md +++ /dev/null @@ -1,29 +0,0 @@ -# Discord Notifications service - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22684) in GitLab 11.6. - -The Discord Notifications service sends event notifications from GitLab to the channel for which the webhook was created. - -To send GitLab event notifications to a Discord channel, create a webhook in Discord and configure it in GitLab. - -## Create webhook - -1. Open the Discord channel you want to receive GitLab event notifications. -1. From the channel menu, select **Edit channel**. -1. Click on **Webhooks** menu item. -1. Click the **Create Webhook** button and fill in the name of the bot that will post the messages. Optionally, edit the avatar. -1. Note the URL from the **WEBHOOK URL** field. -1. Click the **Save** button. - -## Configure created webhook in GitLab - -With the webhook URL created in the Discord channel, you can set up the Discord Notifications service in GitLab. - -1. Navigate to the [Integrations page](project_services.md#accessing-the-project-services) in your project's settings. That is, **Project > Settings > Integrations**. -1. Select the **Discord Notifications** project service to configure it. -1. Check the **Active** checkbox to turn on the service. -1. Check the checkboxes corresponding to the GitLab events for which you want to send notifications to Discord. -1. Paste the webhook URL that you copied from the create Discord webhook step. -1. Configure the remaining options and click the **Save changes** button. - -The Discord channel you created the webhook for will now receive notification of the GitLab events that were configured. diff --git a/doc/user/project/integrations/project_services.md b/doc/user/project/integrations/project_services.md index 42c7824a125..026c29ad9f5 100644 --- a/doc/user/project/integrations/project_services.md +++ b/doc/user/project/integrations/project_services.md @@ -30,7 +30,6 @@ Click on the service links to see further configuration instructions and details | [Bugzilla](bugzilla.md) | Bugzilla issue tracker | | Campfire | Simple web-based real-time group chat | | Custom Issue Tracker | Custom issue tracker | -| [Discord Notifications](discord_notifications.md) | Receive event notifications in Discord | | Drone CI | Continuous Integration platform built on Docker, written in Go | | [Emails on push](emails_on_push.md) | Email the commits and diff of each push to a list of recipients | | External Wiki | Replaces the link to the internal wiki with a link to an external wiki | diff --git a/lib/api/services.rb b/lib/api/services.rb index f52bd8c2622..b27647ee264 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -299,14 +299,6 @@ class Services < Grape::API desc: 'Title' } ], - 'discord' => [ - { - required: true, - name: :webhook, - type: String, - desc: 'Discord webhook. e.g. https://discordapp.com/api/webhooks/…' - } - ], 'drone-ci' => [ { required: true, @@ -707,7 +699,6 @@ class Services < Grape::API BuildkiteService, CampfireService, CustomIssueTrackerService, - DiscordService, DroneCiService, EmailsOnPushService, ExternalWikiService, diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 017624d7b55..98f46578ae7 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -210,7 +210,6 @@ project: - last_event - services - campfire_service -- discord_service - drone_ci_service - emails_on_push_service - pipelines_email_service diff --git a/spec/models/project_services/discord_service_spec.rb b/spec/models/project_services/discord_service_spec.rb deleted file mode 100644 index be82f223478..00000000000 --- a/spec/models/project_services/discord_service_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -describe DiscordService do - it_behaves_like "chat service", "Discord notifications" do - let(:client) { Discordrb::Webhooks::Client } - let(:client_arguments) { { url: webhook_url } } - let(:content_key) { :content } - end -end diff --git a/spec/models/project_services/hangouts_chat_service_spec.rb b/spec/models/project_services/hangouts_chat_service_spec.rb index 0505ac9b49c..cfa55188a64 100644 --- a/spec/models/project_services/hangouts_chat_service_spec.rb +++ b/spec/models/project_services/hangouts_chat_service_spec.rb @@ -1,11 +1,246 @@ -# frozen_string_literal: true - -require "spec_helper" +require 'spec_helper' describe HangoutsChatService do - it_behaves_like "chat service", "Hangouts Chat" do - let(:client) { HangoutsChat::Sender } - let(:client_arguments) { webhook_url } - let(:content_key) { :text } + describe 'Associations' do + it { is_expected.to belong_to :project } + it { is_expected.to have_one :service_hook } + end + + describe 'Validations' do + context 'when service is active' do + before do + subject.active = true + end + + it { is_expected.to validate_presence_of(:webhook) } + it_behaves_like 'issue tracker service URL attribute', :webhook + end + + context 'when service is inactive' do + before do + subject.active = false + end + + it { is_expected.not_to validate_presence_of(:webhook) } + end + end + + describe '#execute' do + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + let(:webhook_url) { 'https://example.gitlab.com/' } + + before do + allow(subject).to receive_messages( + project: project, + project_id: project.id, + service_hook: true, + webhook: webhook_url + ) + + WebMock.stub_request(:post, webhook_url) + end + + shared_examples 'Hangouts Chat service' do + it 'calls Hangouts Chat API' do + subject.execute(sample_data) + + expect(WebMock) + .to have_requested(:post, webhook_url) + .with { |req| req.body =~ /\A{"text":.+}\Z/ } + .once + end + end + + context 'with push events' do + let(:sample_data) do + Gitlab::DataBuilder::Push.build_sample(project, user) + end + + it_behaves_like 'Hangouts Chat service' + + it 'specifies the webhook when it is configured' do + expect(HangoutsChat::Sender).to receive(:new).with(webhook_url).and_return(double(:hangouts_chat_service).as_null_object) + + subject.execute(sample_data) + end + + context 'with not default branch' do + let(:sample_data) do + Gitlab::DataBuilder::Push.build(project, user, nil, nil, 'not-the-default-branch') + end + + context 'when notify_only_default_branch enabled' do + before do + subject.notify_only_default_branch = true + end + + it 'does not call the Hangouts Chat API' do + result = subject.execute(sample_data) + + expect(result).to be_falsy + end + end + + context 'when notify_only_default_branch disabled' do + before do + subject.notify_only_default_branch = false + end + + it_behaves_like 'Hangouts Chat service' + end + end + end + + context 'with issue events' do + let(:opts) { { title: 'Awesome issue', description: 'please fix' } } + let(:sample_data) do + service = Issues::CreateService.new(project, user, opts) + issue = service.execute + service.hook_data(issue, 'open') + end + + it_behaves_like 'Hangouts Chat service' + end + + context 'with merge events' do + let(:opts) do + { + title: 'Awesome merge_request', + description: 'please fix', + source_branch: 'feature', + target_branch: 'master' + } + end + + let(:sample_data) do + service = MergeRequests::CreateService.new(project, user, opts) + merge_request = service.execute + service.hook_data(merge_request, 'open') + end + + before do + project.add_developer(user) + end + + it_behaves_like 'Hangouts Chat service' + end + + context 'with wiki page events' do + let(:opts) do + { + title: 'Awesome wiki_page', + content: 'Some text describing some thing or another', + format: 'md', + message: 'user created page: Awesome wiki_page' + } + end + let(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: opts) } + let(:sample_data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') } + + it_behaves_like 'Hangouts Chat service' + end + + context 'with note events' do + let(:sample_data) { Gitlab::DataBuilder::Note.build(note, user) } + + context 'with commit comment' do + let(:note) do + create(:note_on_commit, author: user, + project: project, + commit_id: project.repository.commit.id, + note: 'a comment on a commit') + end + + it_behaves_like 'Hangouts Chat service' + end + + context 'with merge request comment' do + let(:note) do + create(:note_on_merge_request, project: project, + note: 'merge request note') + end + + it_behaves_like 'Hangouts Chat service' + end + + context 'with issue comment' do + let(:note) do + create(:note_on_issue, project: project, note: 'issue note') + end + + it_behaves_like 'Hangouts Chat service' + end + + context 'with snippet comment' do + let(:note) do + create(:note_on_project_snippet, project: project, + note: 'snippet note') + end + + it_behaves_like 'Hangouts Chat service' + end + end + + context 'with pipeline events' do + let(:pipeline) do + create(:ci_pipeline, + project: project, status: status, + sha: project.commit.sha, ref: project.default_branch) + end + let(:sample_data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } + + context 'with failed pipeline' do + let(:status) { 'failed' } + + it_behaves_like 'Hangouts Chat service' + end + + context 'with succeeded pipeline' do + let(:status) { 'success' } + + context 'with default notify_only_broken_pipelines' do + it 'does not call Hangouts Chat API' do + result = subject.execute(sample_data) + + expect(result).to be_falsy + end + end + + context 'when notify_only_broken_pipelines is false' do + before do + subject.notify_only_broken_pipelines = false + end + + it_behaves_like 'Hangouts Chat service' + end + end + + context 'with not default branch' do + let(:pipeline) do + create(:ci_pipeline, project: project, status: 'failed', ref: 'not-the-default-branch') + end + + context 'when notify_only_default_branch enabled' do + before do + subject.notify_only_default_branch = true + end + + it 'does not call the Hangouts Chat API' do + result = subject.execute(sample_data) + + expect(result).to be_falsy + end + end + + context 'when notify_only_default_branch disabled' do + before do + subject.notify_only_default_branch = false + end + + it_behaves_like 'Hangouts Chat service' + end + end + end end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index a91fb1775ce..89714523a8b 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -35,7 +35,6 @@ it { is_expected.to have_one(:asana_service) } it { is_expected.to have_many(:boards) } it { is_expected.to have_one(:campfire_service) } - it { is_expected.to have_one(:discord_service) } it { is_expected.to have_one(:drone_ci_service) } it { is_expected.to have_one(:emails_on_push_service) } it { is_expected.to have_one(:pipelines_email_service) } diff --git a/spec/support/shared_examples/models/chat_service_spec.rb b/spec/support/shared_examples/models/chat_service_spec.rb deleted file mode 100644 index cf1d52a9616..00000000000 --- a/spec/support/shared_examples/models/chat_service_spec.rb +++ /dev/null @@ -1,242 +0,0 @@ -require "spec_helper" - -shared_examples_for "chat service" do |service_name| - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Validations" do - context "when service is active" do - before do - subject.active = true - end - - it { is_expected.to validate_presence_of(:webhook) } - it_behaves_like "issue tracker service URL attribute", :webhook - end - - context "when service is inactive" do - before do - subject.active = false - end - - it { is_expected.not_to validate_presence_of(:webhook) } - end - end - - describe "#execute" do - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } - let(:webhook_url) { "https://example.gitlab.com/" } - - before do - allow(subject).to receive_messages( - project: project, - project_id: project.id, - service_hook: true, - webhook: webhook_url - ) - - WebMock.stub_request(:post, webhook_url) - end - - shared_examples "#{service_name} service" do - it "calls #{service_name} API" do - subject.execute(sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).with { |req| req.body =~ /\A{"#{content_key}":.+}\Z/ }.once - end - end - - context "with push events" do - let(:sample_data) do - Gitlab::DataBuilder::Push.build_sample(project, user) - end - - it_behaves_like "#{service_name} service" - - it "specifies the webhook when it is configured" do - expect(client).to receive(:new).with(client_arguments).and_return(double(:chat_service).as_null_object) - - subject.execute(sample_data) - end - - context "with not default branch" do - let(:sample_data) do - Gitlab::DataBuilder::Push.build(project, user, nil, nil, "not-the-default-branch") - end - - context "when notify_only_default_branch enabled" do - before do - subject.notify_only_default_branch = true - end - - it "does not call the Discord Webhooks API" do - result = subject.execute(sample_data) - - expect(result).to be_falsy - end - end - - context "when notify_only_default_branch disabled" do - before do - subject.notify_only_default_branch = false - end - - it_behaves_like "#{service_name} service" - end - end - end - - context "with issue events" do - let(:opts) { { title: "Awesome issue", description: "please fix" } } - let(:sample_data) do - service = Issues::CreateService.new(project, user, opts) - issue = service.execute - service.hook_data(issue, "open") - end - - it_behaves_like "#{service_name} service" - end - - context "with merge events" do - let(:opts) do - { - title: "Awesome merge_request", - description: "please fix", - source_branch: "feature", - target_branch: "master" - } - end - - let(:sample_data) do - service = MergeRequests::CreateService.new(project, user, opts) - merge_request = service.execute - service.hook_data(merge_request, "open") - end - - before do - project.add_developer(user) - end - - it_behaves_like "#{service_name} service" - end - - context "with wiki page events" do - let(:opts) do - { - title: "Awesome wiki_page", - content: "Some text describing some thing or another", - format: "md", - message: "user created page: Awesome wiki_page" - } - end - let(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: opts) } - let(:sample_data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, "create") } - - it_behaves_like "#{service_name} service" - end - - context "with note events" do - let(:sample_data) { Gitlab::DataBuilder::Note.build(note, user) } - - context "with commit comment" do - let(:note) do - create(:note_on_commit, - author: user, - project: project, - commit_id: project.repository.commit.id, - note: "a comment on a commit") - end - - it_behaves_like "#{service_name} service" - end - - context "with merge request comment" do - let(:note) do - create(:note_on_merge_request, project: project, note: "merge request note") - end - - it_behaves_like "#{service_name} service" - end - - context "with issue comment" do - let(:note) do - create(:note_on_issue, project: project, note: "issue note") - end - - it_behaves_like "#{service_name} service" - end - - context "with snippet comment" do - let(:note) do - create(:note_on_project_snippet, project: project, note: "snippet note") - end - - it_behaves_like "#{service_name} service" - end - end - - context "with pipeline events" do - let(:pipeline) do - create(:ci_pipeline, - project: project, status: status, - sha: project.commit.sha, ref: project.default_branch) - end - let(:sample_data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } - - context "with failed pipeline" do - let(:status) { "failed" } - - it_behaves_like "#{service_name} service" - end - - context "with succeeded pipeline" do - let(:status) { "success" } - - context "with default notify_only_broken_pipelines" do - it "does not call Discord Webhooks API" do - result = subject.execute(sample_data) - - expect(result).to be_falsy - end - end - - context "when notify_only_broken_pipelines is false" do - before do - subject.notify_only_broken_pipelines = false - end - - it_behaves_like "#{service_name} service" - end - end - - context "with not default branch" do - let(:pipeline) do - create(:ci_pipeline, project: project, status: "failed", ref: "not-the-default-branch") - end - - context "when notify_only_default_branch enabled" do - before do - subject.notify_only_default_branch = true - end - - it "does not call the Discord Webhooks API" do - result = subject.execute(sample_data) - - expect(result).to be_falsy - end - end - - context "when notify_only_default_branch disabled" do - before do - subject.notify_only_default_branch = false - end - - it_behaves_like "#{service_name} service" - end - end - end - end -end -- GitLab