diff --git a/app/models/integration.rb b/app/models/integration.rb index 4dd3e1a1785831e69b854f162868d4d27aed0279..0a1f61fd5400786c5edfb0e050d72f40127a1bce 100644 --- a/app/models/integration.rb +++ b/app/models/integration.rb @@ -14,7 +14,7 @@ class Integration < ApplicationRecord asana assembla bamboo bugzilla buildkite campfire confluence custom_issue_tracker datadog discord drone_ci emails_on_push ewm external_wiki flowdock hangouts_chat irker jira mattermost mattermost_slash_commands microsoft_teams packagist pipelines_email - pivotaltracker prometheus pushover redmine slack slack_slash_commands teamcity unify_circuit webex_teams youtrack zentao + pivotaltracker prometheus pushover redmine shimo slack slack_slash_commands teamcity unify_circuit webex_teams youtrack zentao ].freeze PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[ diff --git a/app/models/integrations/shimo.rb b/app/models/integrations/shimo.rb new file mode 100644 index 0000000000000000000000000000000000000000..4f42fda257758e5888c2b6413fb3b3957c83508f --- /dev/null +++ b/app/models/integrations/shimo.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Integrations + class Shimo < Integration + prop_accessor :external_wiki_url + validates :external_wiki_url, presence: true, public_url: true, if: :activated? + + def render? + valid? && activated? + end + + def title + s_('Shimo|Shimo') + end + + def description + s_('Shimo|Link to a Shimo Workspace from the sidebar.') + end + + def self.to_param + 'shimo' + end + + # support for `test` method + def execute(_data) + response = Gitlab::HTTP.get(properties['external_wiki_url'], verify: true, use_read_total_timeout: true) + response.body if response.code == 200 + rescue StandardError + nil + end + + def self.supported_events + %w() + end + + def fields + [ + { + type: 'text', + name: 'external_wiki_url', + title: s_('Shimo|Shimo Workspace URL'), + required: true + } + ] + end + end +end diff --git a/app/models/project.rb b/app/models/project.rb index f2c26f918069ee9c48984d55fe8fb573109d99b6..f7f8ae1f77c074e24c0047724c1ae0c3aa02e782 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -189,6 +189,7 @@ def self.integration_association_name(name) has_one :prometheus_integration, class_name: 'Integrations::Prometheus', inverse_of: :project has_one :pushover_integration, class_name: 'Integrations::Pushover' has_one :redmine_integration, class_name: 'Integrations::Redmine' + has_one :shimo_integration, class_name: 'Integrations::Shimo' has_one :slack_integration, class_name: 'Integrations::Slack' has_one :slack_slash_commands_integration, class_name: 'Integrations::SlackSlashCommands' has_one :teamcity_integration, class_name: 'Integrations::Teamcity' @@ -1453,7 +1454,7 @@ def find_or_initialize_integrations end def disabled_integrations - [] + [:shimo] end def find_or_initialize_integration(name) diff --git a/config/metrics/counts_all/20211028210001_projects_shimo_active.yml b/config/metrics/counts_all/20211028210001_projects_shimo_active.yml new file mode 100644 index 0000000000000000000000000000000000000000..b6b11407c6a71504c6546978b24d8deba04f4f6c --- /dev/null +++ b/config/metrics/counts_all/20211028210001_projects_shimo_active.yml @@ -0,0 +1,22 @@ +--- +key_path: counts.projects_shimo_active +name: count_all_projects_shimo_active +description: Count of projects with active Shimo integrations +product_section: dev +product_stage: ecosystem +product_group: group::integrations +product_category: integrations +value_type: number +status: active +milestone: "14.5" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 +time_frame: all +data_source: database +data_category: optional +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_all/20211028210002_groups_shimo_active.yml b/config/metrics/counts_all/20211028210002_groups_shimo_active.yml new file mode 100644 index 0000000000000000000000000000000000000000..3f2423f76966cb20f6151b457cb78a8eab507f50 --- /dev/null +++ b/config/metrics/counts_all/20211028210002_groups_shimo_active.yml @@ -0,0 +1,22 @@ +--- +key_path: counts.groups_shimo_active +name: count_all_groups_shimo_active +description: Count of groups with active Shimo integrations +product_section: dev +product_stage: ecosystem +product_group: group::integrations +product_category: integrations +value_type: number +status: active +milestone: "14.5" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 +time_frame: all +data_source: database +data_category: optional +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_all/20211028210003_instances_shimo_active.yml b/config/metrics/counts_all/20211028210003_instances_shimo_active.yml new file mode 100644 index 0000000000000000000000000000000000000000..2b835ef6d6c168f7e0e4853e2082b9f89dff7423 --- /dev/null +++ b/config/metrics/counts_all/20211028210003_instances_shimo_active.yml @@ -0,0 +1,22 @@ +--- +key_path: counts.instances_shimo_active +name: count_all_instances_shimo_active +description: Count of instances with active Shimo integrations +product_section: dev +product_stage: ecosystem +product_group: group::integrations +product_category: integrations +value_type: number +status: active +milestone: "14.5" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 +time_frame: all +data_source: database +data_category: optional +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_all/20211028210004_projects_inheriting_shimo_active.yml b/config/metrics/counts_all/20211028210004_projects_inheriting_shimo_active.yml new file mode 100644 index 0000000000000000000000000000000000000000..d7d231206d582f660a90b6ccd9639673b9556f98 --- /dev/null +++ b/config/metrics/counts_all/20211028210004_projects_inheriting_shimo_active.yml @@ -0,0 +1,22 @@ +--- +key_path: counts.projects_inheriting_shimo_active +name: count_all_projects_inheriting_shimo_active +description: Count of projects that inherit active Shimo integrations +product_section: dev +product_stage: ecosystem +product_group: group::integrations +product_category: integrations +value_type: number +status: active +milestone: "14.5" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 +time_frame: all +data_source: database +data_category: optional +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_all/20211028210005_groups_inheriting_shimo_active.yml b/config/metrics/counts_all/20211028210005_groups_inheriting_shimo_active.yml new file mode 100644 index 0000000000000000000000000000000000000000..d979e672f6067ca6927254089df5a379b39c80bd --- /dev/null +++ b/config/metrics/counts_all/20211028210005_groups_inheriting_shimo_active.yml @@ -0,0 +1,22 @@ +--- +key_path: counts.groups_inheriting_shimo_active +name: count_all_groups_inheriting_shimo_active +description: Count of groups that inherit active Shimo integrations +product_section: dev +product_stage: ecosystem +product_group: group::integrations +product_category: integrations +value_type: number +status: active +milestone: "14.5" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 +time_frame: all +data_source: database +data_category: optional +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 4b09907b9a87476089af6aa8a714a64ef111f7f7..0a835d7bbf77c887558d1dfe9b3f02f6a62d6361 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -16698,6 +16698,7 @@ State of a Sentry error. | `PROMETHEUS_SERVICE` | PrometheusService type. | | `PUSHOVER_SERVICE` | PushoverService type. | | `REDMINE_SERVICE` | RedmineService type. | +| `SHIMO_SERVICE` | ShimoService type. | | `SLACK_SERVICE` | SlackService type. | | `SLACK_SLASH_COMMANDS_SERVICE` | SlackSlashCommandsService type. | | `TEAMCITY_SERVICE` | TeamcityService type. | diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb index 7ae46abd0971c51630fbfd84d3b7cd6424cd7b9a..e7fdb6645a507f06537ae5dc70a4c3e59f1d11f6 100644 --- a/lib/api/helpers/integrations_helpers.rb +++ b/lib/api/helpers/integrations_helpers.rb @@ -530,6 +530,14 @@ def self.integrations desc: 'The Mattermost token' } ], + 'shimo' => [ + { + required: true, + name: :external_wiki_url, + type: String, + desc: 'Shimo workspace URL' + } + ], 'slack-slash-commands' => [ { required: true, diff --git a/lib/gitlab/integrations/sti_type.rb b/lib/gitlab/integrations/sti_type.rb index 91797a7b99bcafd911aa68a3eed1361f063e07b7..1350d75b2169a0b5b3dfd2f4c711a09ef0473bfa 100644 --- a/lib/gitlab/integrations/sti_type.rb +++ b/lib/gitlab/integrations/sti_type.rb @@ -7,7 +7,7 @@ class StiType < ActiveRecord::Type::String Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker - Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack Zentao + Prometheus Pushover Redmine Shimo Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack Zentao )).freeze def self.namespaced_integrations diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 766114b525521b9b1be92d254a3acee1c3952fd9..19da2e9b438b58e3d4eb5ed9a6c66a23dd91eb32 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -31638,6 +31638,15 @@ msgstr "" msgid "Sherlock Transactions" msgstr "" +msgid "Shimo|Link to a Shimo Workspace from the sidebar." +msgstr "" + +msgid "Shimo|Shimo" +msgstr "" + +msgid "Shimo|Shimo Workspace URL" +msgstr "" + msgid "Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you %{boldStart}will%{boldEnd} lose access to your account." msgstr "" diff --git a/spec/factories/integrations.rb b/spec/factories/integrations.rb index 63f85c04ac7a6bcc29ce8e7d7531bd280b27e8f0..7205a0c40f9781f7570035a4aea208a2dc88a973 100644 --- a/spec/factories/integrations.rb +++ b/spec/factories/integrations.rb @@ -111,6 +111,12 @@ end end + factory :shimo_integration, class: 'Integrations::Shimo' do + project + active { true } + external_wiki_url { 'https://shimo.example.com/desktop' } + end + factory :confluence_integration, class: 'Integrations::Confluence' do project active { true } diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 95217b43d1397e024e98e2073c9668f8b73bb69b..b474f5825fdf852e122c4b51ac47c8729df832f2 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -384,6 +384,7 @@ project: - emails_on_push_integration - pipelines_email_integration - mattermost_slash_commands_integration +- shimo_integration - slack_slash_commands_integration - irker_integration - packagist_integration diff --git a/spec/models/integrations/shimo_spec.rb b/spec/models/integrations/shimo_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..25df8d2b2498ef9314a551bece25486ad660aab1 --- /dev/null +++ b/spec/models/integrations/shimo_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Integrations::Shimo do + describe '#fields' do + let(:shimo_integration) { create(:shimo_integration) } + + it 'returns custom fields' do + expect(shimo_integration.fields.pluck(:name)).to eq(%w[external_wiki_url]) + end + end + + describe '#create' do + let(:project) { create(:project, :repository) } + let(:external_wiki_url) { 'https://shimo.example.com/desktop' } + let(:params) { { active: true, project: project, external_wiki_url: external_wiki_url } } + + context 'with valid params' do + it 'creates the Shimo integration' do + shimo = described_class.create!(params) + + expect(shimo.valid?).to be true + expect(shimo.render?).to be true + expect(shimo.external_wiki_url).to eq(external_wiki_url) + end + end + + context 'with invalid params' do + it 'cannot create the Shimo integration without external_wiki_url' do + params['external_wiki_url'] = nil + expect { described_class.create!(params) }.to raise_error(ActiveRecord::RecordInvalid) + end + + it 'cannot create the Shimo integration with invalid external_wiki_url' do + params['external_wiki_url'] = 'Fake Invalid URL' + expect { described_class.create!(params) }.to raise_error(ActiveRecord::RecordInvalid) + end + end + end +end