diff options
Diffstat (limited to 'app/models/integrations')
-rw-r--r-- | app/models/integrations/apple_app_store.rb | 111 | ||||
-rw-r--r-- | app/models/integrations/base_chat_notification.rb | 16 | ||||
-rw-r--r-- | app/models/integrations/base_slash_commands.rb | 2 | ||||
-rw-r--r-- | app/models/integrations/chat_message/issue_message.rb | 10 | ||||
-rw-r--r-- | app/models/integrations/chat_message/pipeline_message.rb | 2 | ||||
-rw-r--r-- | app/models/integrations/field.rb | 7 | ||||
-rw-r--r-- | app/models/integrations/flowdock.rb | 20 |
7 files changed, 139 insertions, 29 deletions
diff --git a/app/models/integrations/apple_app_store.rb b/app/models/integrations/apple_app_store.rb new file mode 100644 index 00000000000..84185542939 --- /dev/null +++ b/app/models/integrations/apple_app_store.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +require 'app_store_connect' + +module Integrations + class AppleAppStore < Integration + ISSUER_ID_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/.freeze + KEY_ID_REGEX = /\A(?=.*[A-Z])(?=.*[0-9])[A-Z0-9]+\z/.freeze + + with_options if: :activated? do + validates :app_store_issuer_id, presence: true, format: { with: ISSUER_ID_REGEX } + validates :app_store_key_id, presence: true, format: { with: KEY_ID_REGEX } + validates :app_store_private_key, presence: true, certificate_key: true + end + + field :app_store_issuer_id, + section: SECTION_TYPE_CONNECTION, + required: true, + title: -> { s_('AppleAppStore|The Apple App Store Connect Issuer ID.') } + + field :app_store_key_id, + section: SECTION_TYPE_CONNECTION, + required: true, + title: -> { s_('AppleAppStore|The Apple App Store Connect Key ID.') }, + is_secret: false + + field :app_store_private_key, + section: SECTION_TYPE_CONNECTION, + required: true, + type: 'textarea', + title: -> { s_('AppleAppStore|The Apple App Store Connect Private Key.') }, + is_secret: false + + def title + 'Apple App Store Connect' + end + + def description + s_('AppleAppStore|Use GitLab to build and release an app in the Apple App Store.') + end + + def help + variable_list = [ + '<code>APP_STORE_CONNECT_API_KEY_ISSUER_ID</code>', + '<code>APP_STORE_CONNECT_API_KEY_KEY_ID</code>', + '<code>APP_STORE_CONNECT_API_KEY_KEY</code>' + ] + + # rubocop:disable Layout/LineLength + texts = [ + s_("Use the Apple App Store Connect integration to easily connect to the Apple App Store with Fastlane in CI/CD pipelines."), + s_("After the Apple App Store Connect integration is activated, the following protected variables will be created for CI/CD use."), + variable_list.join('<br>'), + s_(format("To get started, see the <a href='%{url}' target='_blank'>integration documentation</a> for instructions on how to generate App Store Connect credentials, and how to use this integration.", url: "https://docs.gitlab.com/ee/integration/apple_app_store.html")).html_safe + ] + # rubocop:enable Layout/LineLength + + texts.join('<br><br>'.html_safe) + end + + def self.to_param + 'apple_app_store' + end + + def self.supported_events + [] + end + + def sections + [ + { + type: SECTION_TYPE_CONNECTION, + title: s_('Integrations|Integration details'), + description: help + } + ] + end + + def test(*_args) + response = client.apps + if response.has_key?(:errors) + { success: false, message: response[:errors].first[:title] } + else + { success: true } + end + end + + def ci_variables + return [] unless activated? + + [ + { key: 'APP_STORE_CONNECT_API_KEY_ISSUER_ID', value: app_store_issuer_id, masked: true, public: false }, + { key: 'APP_STORE_CONNECT_API_KEY_KEY', value: Base64.encode64(app_store_private_key), masked: true, + public: false }, + { key: 'APP_STORE_CONNECT_API_KEY_KEY_ID', value: app_store_key_id, masked: true, public: false } + ] + end + + private + + def client + config = { + issuer_id: app_store_issuer_id, + key_id: app_store_key_id, + private_key: app_store_private_key + } + + AppStoreConnect::Client.new(config) + end + end +end diff --git a/app/models/integrations/base_chat_notification.rb b/app/models/integrations/base_chat_notification.rb index f2a707c2214..8700b673370 100644 --- a/app/models/integrations/base_chat_notification.rb +++ b/app/models/integrations/base_chat_notification.rb @@ -10,7 +10,7 @@ module Integrations SUPPORTED_EVENTS = %w[ push issue confidential_issue merge_request note confidential_note - tag_push pipeline wiki_page deployment + tag_push pipeline wiki_page deployment incident ].freeze SUPPORTED_EVENTS_FOR_LABEL_FILTER = %w[issue confidential_issue merge_request note confidential_note].freeze @@ -76,21 +76,29 @@ module Integrations def default_fields [ - { type: 'checkbox', name: 'notify_only_broken_pipelines', help: 'Do not send notifications for successful pipelines.' }.freeze, + { + type: 'checkbox', + section: SECTION_TYPE_CONFIGURATION, + name: 'notify_only_broken_pipelines', + help: 'Do not send notifications for successful pipelines.' + }.freeze, { type: 'select', + section: SECTION_TYPE_CONFIGURATION, name: 'branches_to_be_notified', title: s_('Integrations|Branches for which notifications are to be sent'), choices: self.class.branch_choices }.freeze, { type: 'text', + section: SECTION_TYPE_CONFIGURATION, name: 'labels_to_be_notified', placeholder: '~backend,~frontend', help: 'Send notifications for issue, merge request, and comment events with the listed labels only. Leave blank to receive notifications for all events.' }.freeze, { type: 'select', + section: SECTION_TYPE_CONFIGURATION, name: 'labels_to_be_notified_behavior', choices: [ ['Match any of the labels', MATCH_ANY_LABEL], @@ -224,6 +232,7 @@ module Integrations data.merge(project_url: project_url, project_name: project_name).with_indifferent_access end + # rubocop:disable Metrics/CyclomaticComplexity def get_message(object_kind, data) case object_kind when "push", "tag_push" @@ -240,8 +249,11 @@ module Integrations Integrations::ChatMessage::WikiPageMessage.new(data) when "deployment" Integrations::ChatMessage::DeploymentMessage.new(data) if notify_for_ref?(data) + when "incident" + Integrations::ChatMessage::IssueMessage.new(data) unless update?(data) end end + # rubocop:enable Metrics/CyclomaticComplexity def build_event_channels event_channel_names.map do |channel_field| diff --git a/app/models/integrations/base_slash_commands.rb b/app/models/integrations/base_slash_commands.rb index 11ff7547325..619579a543a 100644 --- a/app/models/integrations/base_slash_commands.rb +++ b/app/models/integrations/base_slash_commands.rb @@ -66,7 +66,7 @@ module Integrations # rubocop: disable CodeReuse/ServiceClass def authorize_chat_name_url(params) - ChatNames::AuthorizeUserService.new(self, params).execute + ChatNames::AuthorizeUserService.new(params).execute end # rubocop: enable CodeReuse/ServiceClass end diff --git a/app/models/integrations/chat_message/issue_message.rb b/app/models/integrations/chat_message/issue_message.rb index ca8ef670e67..1c234630370 100644 --- a/app/models/integrations/chat_message/issue_message.rb +++ b/app/models/integrations/chat_message/issue_message.rb @@ -9,6 +9,7 @@ module Integrations attr_reader :action attr_reader :state attr_reader :description + attr_reader :object_kind def initialize(params) super @@ -21,6 +22,7 @@ module Integrations @action = obj_attr[:action] @state = obj_attr[:state] @description = obj_attr[:description] || '' + @object_kind = params[:object_kind] end def attachments @@ -32,7 +34,7 @@ module Integrations def activity { - title: "Issue #{state} by #{strip_markup(user_combined_name)}", + title: "#{issue_type} #{state} by #{strip_markup(user_combined_name)}", subtitle: "in #{project_link}", text: issue_link, image: user_avatar @@ -42,7 +44,7 @@ module Integrations private def message - "[#{project_link}] Issue #{issue_link} #{state} by #{strip_markup(user_combined_name)}" + "[#{project_link}] #{issue_type} #{issue_link} #{state} by #{strip_markup(user_combined_name)}" end def opened_issue? @@ -69,6 +71,10 @@ module Integrations def issue_title "#{Issue.reference_prefix}#{issue_iid} #{strip_markup(title)}" end + + def issue_type + @issue_type ||= object_kind == 'incident' ? 'Incident' : 'Issue' + end end end end diff --git a/app/models/integrations/chat_message/pipeline_message.rb b/app/models/integrations/chat_message/pipeline_message.rb index 88db40bea7f..f8a634be336 100644 --- a/app/models/integrations/chat_message/pipeline_message.rb +++ b/app/models/integrations/chat_message/pipeline_message.rb @@ -151,7 +151,7 @@ module Integrations fields << failed_stages_field if failed_stages.any? fields << failed_jobs_field if failed_jobs.any? fields << yaml_error_field if pipeline.has_yaml_errors? - fields << pipeline_name_field if Feature.enabled?(:pipeline_name, project) && pipeline.name.present? + fields << pipeline_name_field if pipeline.name.present? fields end diff --git a/app/models/integrations/field.rb b/app/models/integrations/field.rb index 53c8f5f623e..329c046075f 100644 --- a/app/models/integrations/field.rb +++ b/app/models/integrations/field.rb @@ -4,7 +4,7 @@ module Integrations class Field SECRET_NAME = %r/token|key|password|passphrase|secret/.freeze - BOOLEAN_ATTRIBUTES = %i[required api_only exposes_secrets].freeze + BOOLEAN_ATTRIBUTES = %i[required api_only is_secret exposes_secrets].freeze ATTRIBUTES = %i[ section type placeholder choices value checkbox_label @@ -17,12 +17,13 @@ module Integrations attr_reader :name, :integration_class - def initialize(name:, integration_class:, type: 'text', api_only: false, **attributes) + def initialize(name:, integration_class:, type: 'text', is_secret: true, api_only: false, **attributes) @name = name.to_s.freeze @integration_class = integration_class - attributes[:type] = SECRET_NAME.match?(@name) ? 'password' : type + attributes[:type] = SECRET_NAME.match?(@name) && is_secret ? 'password' : type attributes[:api_only] = api_only + attributes[:is_secret] = is_secret @attributes = attributes.freeze invalid_attributes = attributes.keys - ATTRIBUTES diff --git a/app/models/integrations/flowdock.rb b/app/models/integrations/flowdock.rb deleted file mode 100644 index d7625cfb3d2..00000000000 --- a/app/models/integrations/flowdock.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -# This integration is scheduled for removal. -# All records must be deleted before the class can be removed. -# https://gitlab.com/gitlab-org/gitlab/-/issues/379197 -module Integrations - class Flowdock < Integration - def readonly? - true - end - - def self.to_param - 'flowdock' - end - - def self.supported_events - %w[] - end - end -end |