Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/integrations')
-rw-r--r--app/models/integrations/asana.rb18
-rw-r--r--app/models/integrations/bamboo.rb37
-rw-r--r--app/models/integrations/base_chat_notification.rb20
-rw-r--r--app/models/integrations/base_slack_notification.rb3
-rw-r--r--app/models/integrations/chat_message/alert_message.rb4
-rw-r--r--app/models/integrations/chat_message/deployment_message.rb24
-rw-r--r--app/models/integrations/chat_message/issue_message.rb6
-rw-r--r--app/models/integrations/chat_message/pipeline_message.rb18
-rw-r--r--app/models/integrations/chat_message/push_message.rb8
-rw-r--r--app/models/integrations/discord.rb38
-rw-r--r--app/models/integrations/hangouts_chat.rb23
-rw-r--r--app/models/integrations/integration_list.rb29
-rw-r--r--app/models/integrations/jira.rb92
-rw-r--r--app/models/integrations/pipelines_email.rb4
-rw-r--r--app/models/integrations/pivotaltracker.rb4
-rw-r--r--app/models/integrations/prometheus.rb2
-rw-r--r--app/models/integrations/pushover.rb4
-rw-r--r--app/models/integrations/telegram.rb10
18 files changed, 239 insertions, 105 deletions
diff --git a/app/models/integrations/asana.rb b/app/models/integrations/asana.rb
index 859522670ef..77555996cd9 100644
--- a/app/models/integrations/asana.rb
+++ b/app/models/integrations/asana.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
-require 'asana'
-
module Integrations
class Asana < Integration
+ TASK_URL_TEMPLATE = 'https://app.asana.com/api/1.0/tasks/%{task_gid}'
+ STORY_URL_TEMPLATE = 'https://app.asana.com/api/1.0/tasks/%{task_gid}/stories'
+
validates :api_key, presence: true, if: :activated?
field :api_key,
@@ -40,12 +41,6 @@ module Integrations
%w[push]
end
- def client
- @_client ||= ::Asana::Client.new do |c|
- c.authentication :access_token, api_key
- end
- end
-
def execute(data)
return unless supported_events.include?(data[:object_kind])
@@ -78,11 +73,12 @@ module Integrations
taskid = tuple[2] || tuple[1]
begin
- task = ::Asana::Resources::Task.find_by_id(client, taskid)
- task.add_comment(text: "#{push_msg} #{message}")
+ story_on_task_url = format(STORY_URL_TEMPLATE, task_gid: taskid)
+ Gitlab::HTTP.post(story_on_task_url, headers: { "Authorization" => "Bearer #{api_key}" }, body: { text: "#{push_msg} #{message}" })
if tuple[0]
- task.update(completed: true)
+ task_url = format(TASK_URL_TEMPLATE, task_gid: taskid)
+ Gitlab::HTTP.put(task_url, headers: { "Authorization" => "Bearer #{api_key}" }, body: { completed: true })
end
rescue StandardError => e
log_error(e.message)
diff --git a/app/models/integrations/bamboo.rb b/app/models/integrations/bamboo.rb
index 0b8432136dd..9f15532a0b0 100644
--- a/app/models/integrations/bamboo.rb
+++ b/app/models/integrations/bamboo.rb
@@ -28,14 +28,13 @@ module Integrations
non_empty_password_title: -> { s_('ProjectService|Enter new password') },
non_empty_password_help: -> { s_('ProjectService|Leave blank to use your current password') }
- validates :bamboo_url, presence: true, public_url: true, if: :activated?
- validates :build_key, presence: true, if: :activated?
- validates :username,
- presence: true,
- if: ->(service) { service.activated? && service.password }
- validates :password,
- presence: true,
- if: ->(service) { service.activated? && service.username }
+ with_options if: :activated? do
+ validates :bamboo_url, presence: true, public_url: true
+ validates :build_key, presence: true
+ end
+
+ validates :username, presence: true, if: ->(integration) { integration.activated? && integration.password }
+ validates :password, presence: true, if: ->(integration) { integration.activated? && integration.username }
attr_accessor :response
@@ -48,8 +47,16 @@ module Integrations
end
def help
- docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bamboo'), target: '_blank', rel: 'noopener noreferrer'
- s_('BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
+ docs_link = ActionController::Base.helpers.link_to(
+ _('Learn more.'),
+ Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bamboo'),
+ target: '_blank',
+ rel: 'noopener noreferrer'
+ )
+ format(
+ s_('BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up automatic revision labeling and ' \
+ 'a repository trigger in Bamboo. %{docs_link}').html_safe,
+ docs_link: docs_link.html_safe)
end
def self.to_param
@@ -70,12 +77,18 @@ module Integrations
get_path("updateAndBuild.action", { buildKey: build_key })
end
- def calculate_reactive_cache(sha, ref)
+ def calculate_reactive_cache(sha, _ref)
response = try_get_path("rest/api/latest/result/byChangeset/#{sha}")
{ build_page: read_build_page(response), commit_status: read_commit_status(response) }
end
+ def avatar_url
+ ActionController::Base.helpers.image_path(
+ 'illustrations/third-party-logos/integrations-logos/atlassian-bamboo.svg'
+ )
+ end
+
private
def get_build_result(response)
@@ -112,7 +125,7 @@ module Integrations
if result.blank?
'Pending'
else
- result.dig('buildState')
+ result['buildState']
end
return :error unless status.present?
diff --git a/app/models/integrations/base_chat_notification.rb b/app/models/integrations/base_chat_notification.rb
index 2c929dc2cb3..b75801335bd 100644
--- a/app/models/integrations/base_chat_notification.rb
+++ b/app/models/integrations/base_chat_notification.rb
@@ -13,6 +13,8 @@ module Integrations
tag_push pipeline wiki_page deployment incident
].freeze
+ GROUP_ONLY_SUPPORTED_EVENTS = %w[group_mention group_confidential_mention].freeze
+
SUPPORTED_EVENTS_FOR_LABEL_FILTER = %w[issue confidential_issue merge_request note confidential_note].freeze
EVENT_CHANNEL = proc { |event| "#{event}_channel" }
@@ -26,12 +28,12 @@ module Integrations
attribute :category, default: 'chat'
- prop_accessor :webhook, :username, :channel, :branches_to_be_notified, :labels_to_be_notified, :labels_to_be_notified_behavior
+ prop_accessor :webhook, :username, :channel, :branches_to_be_notified, :labels_to_be_notified,
+ :labels_to_be_notified_behavior, :notify_only_default_branch
# Custom serialized properties initialization
prop_accessor(*SUPPORTED_EVENTS.map { |event| EVENT_CHANNEL[event] })
-
- boolean_accessor :notify_only_default_branch
+ prop_accessor(*GROUP_ONLY_SUPPORTED_EVENTS.map { |event| EVENT_CHANNEL[event] })
validates :webhook,
presence: true,
@@ -44,10 +46,10 @@ module Integrations
super
if properties.empty?
- self.notify_only_broken_pipelines = true if self.respond_to?(:notify_only_broken_pipelines)
+ self.notify_only_broken_pipelines = true if respond_to?(:notify_only_broken_pipelines)
self.branches_to_be_notified = "default"
self.labels_to_be_notified_behavior = MATCH_ANY_LABEL
- elsif !self.notify_only_default_branch.nil?
+ elsif !notify_only_default_branch.nil?
# In older versions, there was only a boolean property named
# `notify_only_default_branch`. Now we have a string property named
# `branches_to_be_notified`. Instead of doing a background migration, we
@@ -55,7 +57,7 @@ module Integrations
# users haven't specified one already. When users edit the integration and
# select a value for this new property, it will override everything.
- self.branches_to_be_notified ||= notify_only_default_branch? ? "default" : "all"
+ self.branches_to_be_notified ||= notify_only_default_branch == 'true' ? "default" : "all"
end
end
@@ -237,7 +239,7 @@ module Integrations
case object_kind
when "push", "tag_push"
Integrations::ChatMessage::PushMessage.new(data) if notify_for_ref?(data)
- when "issue"
+ when "issue", "incident"
Integrations::ChatMessage::IssueMessage.new(data) unless update?(data)
when "merge_request"
Integrations::ChatMessage::MergeMessage.new(data) unless update?(data)
@@ -249,8 +251,8 @@ 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)
+ when "group_mention"
+ Integrations::ChatMessage::GroupMentionMessage.new(data)
end
end
# rubocop:enable Metrics/CyclomaticComplexity
diff --git a/app/models/integrations/base_slack_notification.rb b/app/models/integrations/base_slack_notification.rb
index 65aec8b278f..09a0c9ba361 100644
--- a/app/models/integrations/base_slack_notification.rb
+++ b/app/models/integrations/base_slack_notification.rb
@@ -7,8 +7,6 @@ module Integrations
].freeze
prop_accessor EVENT_CHANNEL['alert']
- prop_accessor EVENT_CHANNEL['group_mention']
- prop_accessor EVENT_CHANNEL['group_confidential_mention']
override :default_channel_placeholder
def default_channel_placeholder
@@ -18,7 +16,6 @@ module Integrations
override :get_message
def get_message(object_kind, data)
return Integrations::ChatMessage::AlertMessage.new(data) if object_kind == 'alert'
- return Integrations::ChatMessage::GroupMentionMessage.new(data) if object_kind == 'group_mention'
super
end
diff --git a/app/models/integrations/chat_message/alert_message.rb b/app/models/integrations/chat_message/alert_message.rb
index e2c689f9435..6c7ea9aed7c 100644
--- a/app/models/integrations/chat_message/alert_message.rb
+++ b/app/models/integrations/chat_message/alert_message.rb
@@ -34,12 +34,12 @@ module Integrations
"Alert firing in #{strip_markup(project_name)}"
end
- private
-
def attachment_color
"#C95823"
end
+ private
+
def attachment_fields
[
{
diff --git a/app/models/integrations/chat_message/deployment_message.rb b/app/models/integrations/chat_message/deployment_message.rb
index 0367459dfcb..4d3e962d885 100644
--- a/app/models/integrations/chat_message/deployment_message.rb
+++ b/app/models/integrations/chat_message/deployment_message.rb
@@ -30,7 +30,7 @@ module Integrations
[{
text: format(description_message),
- color: color
+ color: attachment_color
}]
end
@@ -38,17 +38,7 @@ module Integrations
{}
end
- private
-
- def message
- if running?
- "Starting deploy to #{strip_markup(environment)}"
- else
- "Deploy to #{strip_markup(environment)} #{humanized_status}"
- end
- end
-
- def color
+ def attachment_color
case status
when 'success'
'good'
@@ -61,6 +51,16 @@ module Integrations
end
end
+ private
+
+ def message
+ if running?
+ "Starting deploy to #{strip_markup(environment)}"
+ else
+ "Deploy to #{strip_markup(environment)} #{humanized_status}"
+ end
+ end
+
def project_link
link(project_name, project_url)
end
diff --git a/app/models/integrations/chat_message/issue_message.rb b/app/models/integrations/chat_message/issue_message.rb
index dd516362491..4c144bc2f68 100644
--- a/app/models/integrations/chat_message/issue_message.rb
+++ b/app/models/integrations/chat_message/issue_message.rb
@@ -41,6 +41,10 @@ module Integrations
}
end
+ def attachment_color
+ '#C95823'
+ end
+
private
def message
@@ -56,7 +60,7 @@ module Integrations
title: issue_title,
title_link: issue_url,
text: format(SlackMarkdownSanitizer.sanitize_slack_link(description)),
- color: '#C95823'
+ color: attachment_color
}]
end
diff --git a/app/models/integrations/chat_message/pipeline_message.rb b/app/models/integrations/chat_message/pipeline_message.rb
index f8a634be336..2abe4a6e9c7 100644
--- a/app/models/integrations/chat_message/pipeline_message.rb
+++ b/app/models/integrations/chat_message/pipeline_message.rb
@@ -89,6 +89,15 @@ module Integrations
}
end
+ def attachment_color
+ case status
+ when 'success'
+ detailed_status == 'passed with warnings' ? 'warning' : 'good'
+ else
+ 'danger'
+ end
+ end
+
private
def actually_failed_jobs(builds)
@@ -180,15 +189,6 @@ module Integrations
end
end
- def attachment_color
- case status
- when 'success'
- detailed_status == 'passed with warnings' ? 'warning' : 'good'
- else
- 'danger'
- end
- end
-
def ref_url
if ref_type == 'tag'
"#{project_url}/-/tags/#{ref}"
diff --git a/app/models/integrations/chat_message/push_message.rb b/app/models/integrations/chat_message/push_message.rb
index b17e28bb6c6..ee44fc98791 100644
--- a/app/models/integrations/chat_message/push_message.rb
+++ b/app/models/integrations/chat_message/push_message.rb
@@ -35,6 +35,10 @@ module Integrations
}
end
+ def attachment_color
+ '#345'
+ end
+
private
def humanized_action(short: false)
@@ -111,10 +115,6 @@ module Integrations
['pushed to', ref_link, "of #{project_link} (#{compare_link})"]
end
end
-
- def attachment_color
- '#345'
- end
end
end
end
diff --git a/app/models/integrations/discord.rb b/app/models/integrations/discord.rb
index 815e3669d78..33b2b52fa62 100644
--- a/app/models/integrations/discord.rb
+++ b/app/models/integrations/discord.rb
@@ -42,8 +42,15 @@ module Integrations
s_('DiscordService|Override the default webhook (e.g. https://discord.com/api/webhooks/…)')
end
+ override :supported_events
+ def supported_events
+ additional = group_level? ? %w[group_mention group_confidential_mention] : []
+
+ (self.class.supported_events + additional).freeze
+ end
+
def self.supported_events
- %w[push issue confidential_issue merge_request note confidential_note tag_push pipeline wiki_page]
+ %w[push issue confidential_issue merge_request note confidential_note tag_push pipeline wiki_page deployment]
end
def configurable_channels?
@@ -68,7 +75,7 @@ module Integrations
builder.add_embed do |embed|
embed.author = Discordrb::Webhooks::EmbedAuthor.new(name: message.user_name, icon_url: message.user_avatar)
embed.description = (message.pretext + "\n" + Array.wrap(message.attachments).join("\n")).gsub(ATTACHMENT_REGEX, " \\k<entry> - \\k<name>\n")
- embed.colour = 16543014 # The hex "fc6d26" as an Integer
+ embed.colour = embed_color(message)
embed.timestamp = Time.now.utc
end
end
@@ -77,6 +84,33 @@ module Integrations
false
end
+ COLOR_OVERRIDES = {
+ 'good' => '#0d532a',
+ 'warning' => '#703800',
+ 'danger' => '#8d1300'
+ }.freeze
+
+ def embed_color(message)
+ return 'fc6d26'.hex unless message.respond_to?(:attachment_color)
+
+ color = message.attachment_color
+
+ color = COLOR_OVERRIDES[color] if COLOR_OVERRIDES.key?(color)
+
+ color = color.delete_prefix('#')
+
+ normalize_color(color).hex
+ end
+
+ # Expands the short notation to the full colorcode notation
+ # 123456 -> 123456
+ # 123 -> 112233
+ def normalize_color(color)
+ return (color[0, 1] * 2) + (color[1, 1] * 2) + (color[2, 1] * 2) if color.length == 3
+
+ color
+ end
+
def custom_data(data)
super(data).merge(markdown: true)
end
diff --git a/app/models/integrations/hangouts_chat.rb b/app/models/integrations/hangouts_chat.rb
index 680752c3d56..6e4753470a3 100644
--- a/app/models/integrations/hangouts_chat.rb
+++ b/app/models/integrations/hangouts_chat.rb
@@ -30,12 +30,15 @@ module Integrations
end
def help
- docs_link = ActionController::Base.helpers.link_to _('How do I set up a Google Chat webhook?'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/hangouts_chat'), target: '_blank', rel: 'noopener noreferrer'
- s_('Before enabling this integration, create a webhook for the room in Google Chat where you want to receive notifications from this project. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
+ docs_link = ActionController::Base.helpers.link_to(_('How do I set up a Google Chat webhook?'),
+ Rails.application.routes.url_helpers.help_page_url('user/project/integrations/hangouts_chat'),
+ target: '_blank', rel: 'noopener noreferrer')
+ format(
+ s_('Before enabling this integration, create a webhook for the room in Google Chat where you want to receive ' \
+ 'notifications from this project. %{docs_link}').html_safe, docs_link: docs_link.html_safe)
end
- def default_channel_placeholder
- end
+ def default_channel_placeholder; end
def self.supported_events
%w[push issue confidential_issue merge_request note confidential_note tag_push pipeline wiki_page]
@@ -43,14 +46,20 @@ module Integrations
private
- def notify(message, opts)
+ def notify(message, _opts)
url = webhook.dup
key = parse_thread_key(message)
url = Gitlab::Utils.add_url_parameters(url, { threadKey: key }) if key
- simple_text = parse_simple_text_message(message)
- ::HangoutsChat::Sender.new(url).simple(simple_text)
+ payload = { text: parse_simple_text_message(message) }
+
+ Gitlab::HTTP.post(
+ url,
+ body: payload.to_json,
+ headers: { 'Content-Type' => 'application/json' },
+ parse: nil
+ ).response
end
# Returns an appropriate key for threading messages in google chat
diff --git a/app/models/integrations/integration_list.rb b/app/models/integrations/integration_list.rb
new file mode 100644
index 00000000000..ab03e5c0e0a
--- /dev/null
+++ b/app/models/integrations/integration_list.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Integrations
+ class IntegrationList
+ def initialize(batch, integration_hash, association)
+ @batch = batch
+ @integration_hash = integration_hash
+ @association = association
+ end
+
+ def to_array
+ [Integration, columns, values]
+ end
+
+ private
+
+ attr_reader :batch, :integration_hash, :association
+
+ def columns
+ integration_hash.keys << "#{association}_id"
+ end
+
+ def values
+ batch.select(:id).map do |record|
+ integration_hash.values << record.id
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb
index d8d1f860e9a..f6e99454cb1 100644
--- a/app/models/integrations/jira.rb
+++ b/app/models/integrations/jira.rb
@@ -11,8 +11,12 @@ module Integrations
PROJECTS_PER_PAGE = 50
JIRA_CLOUD_HOST = '.atlassian.net'
- ATLASSIAN_REFERRER_GITLAB_COM = { atlOrigin: 'eyJpIjoiY2QyZTJiZDRkNGZhNGZlMWI3NzRkNTBmZmVlNzNiZTkiLCJwIjoianN3LWdpdGxhYi1pbnQifQ' }.freeze
- ATLASSIAN_REFERRER_SELF_MANAGED = { atlOrigin: 'eyJpIjoiYjM0MTA4MzUyYTYxNDVkY2IwMzVjOGQ3ZWQ3NzMwM2QiLCJwIjoianN3LWdpdGxhYlNNLWludCJ9' }.freeze
+ ATLASSIAN_REFERRER_GITLAB_COM = {
+ atlOrigin: 'eyJpIjoiY2QyZTJiZDRkNGZhNGZlMWI3NzRkNTBmZmVlNzNiZTkiLCJwIjoianN3LWdpdGxhYi1pbnQifQ'
+ }.freeze
+ ATLASSIAN_REFERRER_SELF_MANAGED = {
+ atlOrigin: 'eyJpIjoiYjM0MTA4MzUyYTYxNDVkY2IwMzVjOGQ3ZWQ3NzMwM2QiLCJwIjoianN3LWdpdGxhYlNNLWludCJ9'
+ }.freeze
API_ENDPOINTS = {
find_issue: "/rest/api/2/issue/%s",
@@ -28,11 +32,13 @@ module Integrations
AUTH_TYPE_BASIC = 0
AUTH_TYPE_PAT = 1
- SNOWPLOW_EVENT_CATEGORY = self.name
+ SNOWPLOW_EVENT_CATEGORY = name
validates :url, public_url: true, presence: true, if: :activated?
validates :api_url, public_url: true, allow_blank: true
- validates :username, presence: true, if: ->(object) { object.activated? && !object.personal_access_token_authorization? }
+ validates :username, presence: true, if: ->(object) {
+ object.activated? && !object.personal_access_token_authorization?
+ }
validates :password, presence: true, if: :activated?
validates :jira_auth_type, presence: true, inclusion: { in: [AUTH_TYPE_BASIC, AUTH_TYPE_PAT] }, if: :activated?
validates :jira_issue_prefix, untrusted_regexp: true, length: { maximum: 255 }, if: :activated?
@@ -130,7 +136,7 @@ module Integrations
end
# {PROJECT-KEY}-{NUMBER} Examples: JIRA-1, PROJECT-1
- def reference_pattern(only_long: true)
+ def reference_pattern(*)
@reference_pattern ||= jira_issue_match_regex
end
@@ -144,7 +150,7 @@ module Integrations
end
def data_fields
- jira_tracker_data || self.build_jira_tracker_data
+ jira_tracker_data || build_jira_tracker_data
end
def set_default_data
@@ -186,8 +192,13 @@ module Integrations
end
def help
- jira_doc_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('integration/jira/index') }
- s_("JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}") % { jira_doc_link_start: jira_doc_link_start, link_end: '</a>'.html_safe }
+ jira_doc_link_start = format('<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe,
+ url: help_page_path('integration/jira/index'))
+ format(
+ s_("JiraService|You must configure Jira before enabling this integration. " \
+ "%{jira_doc_link_start}Learn more.%{link_end}"),
+ jira_doc_link_start: jira_doc_link_start,
+ link_end: '</a>'.html_safe)
end
def title
@@ -212,7 +223,8 @@ module Integrations
{
type: SECTION_TYPE_JIRA_TRIGGER,
title: _('Trigger'),
- description: s_('JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created.')
+ description: s_('JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link ' \
+ 'and comment (if enabled) will be created.')
},
{
type: SECTION_TYPE_CONFIGURATION,
@@ -313,7 +325,8 @@ module Integrations
override :create_cross_reference_note
def create_cross_reference_note(external_issue, mentioned_in, author)
unless can_cross_reference?(mentioned_in)
- return s_("JiraService|Events for %{noteable_model_name} are disabled.") % { noteable_model_name: mentioned_in.model_name.plural.humanize(capitalize: false) }
+ return format(s_("JiraService|Events for %{noteable_model_name} are disabled."),
+ noteable_model_name: mentioned_in.model_name.plural.humanize(capitalize: false))
end
jira_issue = find_issue(external_issue.id)
@@ -381,6 +394,10 @@ module Integrations
jira_auth_type == AUTH_TYPE_PAT
end
+ def avatar_url
+ ActionController::Base.helpers.image_path('illustrations/third-party-logos/integrations-logos/jira.svg')
+ end
+
private
def jira_issue_match_regex
@@ -398,10 +415,9 @@ module Integrations
end
def server_info
- strong_memoize(:server_info) do
- client_url.present? ? jira_request(API_ENDPOINTS[:server_info]) { client.ServerInfo.all.attrs } : nil
- end
+ client_url.present? ? jira_request(API_ENDPOINTS[:server_info]) { client.ServerInfo.all.attrs } : nil
end
+ strong_memoize_attr :server_info
def can_cross_reference?(mentioned_in)
case mentioned_in
@@ -430,7 +446,8 @@ module Integrations
true
rescue StandardError => e
path = API_ENDPOINTS[:transition_issue] % issue.id
- log_exception(e, message: 'Issue transition failed', client_url: client_url, client_path: path, client_status: '400')
+ log_exception(e, message: 'Issue transition failed', client_url: client_url, client_path: path,
+ client_status: '400')
false
end
@@ -488,9 +505,9 @@ module Integrations
link_title = "#{entity_name.capitalize} - #{entity_title}"
link_props = build_remote_link_props(url: entity_url, title: link_title)
- unless comment_exists?(issue, message)
- send_message(issue, message, link_props)
- end
+ return if comment_exists?(issue, message)
+
+ send_message(issue, message, link_props)
end
def comment_message(data)
@@ -503,21 +520,22 @@ module Integrations
project_link = build_jira_link(project.full_name, Gitlab::Routing.url_helpers.project_url(project))
branch =
if entity[:branch].present?
- s_('JiraService| on branch %{branch_link}') % {
- branch_link: build_jira_link(entity[:branch], project_tree_url(project, entity[:branch]))
- }
+ format(s_('JiraService| on branch %{branch_link}'),
+ branch_link: build_jira_link(entity[:branch], project_tree_url(project, entity[:branch])))
end
entity_message = entity[:description].presence if all_details?
entity_message ||= entity[:title].chomp
- s_('JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}') % {
+ format(
+ s_('JiraService|%{user_link} mentioned this issue in %{entity_link} of ' \
+ '%{project_link}%{branch}:{quote}%{entity_message}{quote}'),
user_link: user_link,
entity_link: entity_link,
project_link: project_link,
branch: branch,
entity_message: entity_message
- }
+ )
end
def build_jira_link(title, url)
@@ -586,13 +604,13 @@ module Integrations
end
def resource_url(resource)
- "#{Settings.gitlab.base_url.chomp("/")}#{resource}"
+ "#{Settings.gitlab.base_url.chomp('/')}#{resource}"
end
def build_entity_url(entity_type, entity_id)
polymorphic_url(
[
- self.project,
+ project,
entity_type.to_sym
],
id: entity_id,
@@ -631,7 +649,8 @@ module Integrations
yield
rescue StandardError => e
@error = e
- log_exception(e, message: 'Error sending message', client_url: client_url, client_path: path, client_status: e.try(:code))
+ log_exception(e, message: 'Error sending message', client_url: client_url, client_path: path,
+ client_status: e.try(:code))
nil
end
@@ -648,7 +667,8 @@ module Integrations
results = server_info
unless results.present?
- Gitlab::AppLogger.warn(message: "Jira API returned no ServerInfo, setting deployment_type from URL", server_info: results, url: client_url)
+ Gitlab::AppLogger.warn(message: "Jira API returned no ServerInfo, setting deployment_type from URL",
+ server_info: results, url: client_url)
return set_deployment_type_from_url
end
@@ -681,13 +701,25 @@ module Integrations
end
def jira_issues_section_description
- jira_issues_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('integration/jira/issues') }
- description = s_('JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}') % { jira_issues_link_start: jira_issues_link_start, link_end: '</a>'.html_safe }
+ jira_issues_link_start = format('<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe,
+ url: help_page_path('integration/jira/issues'))
+ description = format(
+ s_('JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of ' \
+ 'your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}'),
+ jira_issues_link_start: jira_issues_link_start,
+ link_end: '</a>'.html_safe
+ )
if project&.issues_enabled?
- gitlab_issues_link_start = '<a href="%{url}">'.html_safe % { url: edit_project_path(project, anchor: 'js-shared-permissions') }
+ gitlab_issues_link_start = format('<a href="%{url}">'.html_safe, url: edit_project_path(project,
+ anchor: 'js-shared-permissions'))
description += '<br><br>'.html_safe
- description += s_("JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{gitlab_issues_link_start}disabling GitLab issues%{link_end} if they won't otherwise be used.") % { gitlab_issues_link_start: gitlab_issues_link_start, link_end: '</a>'.html_safe }
+ description += format(
+ s_("JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. " \
+ "Consider %{gitlab_issues_link_start}disabling GitLab issues%{link_end} if they won't otherwise be used."),
+ gitlab_issues_link_start: gitlab_issues_link_start,
+ link_end: '</a>'.html_safe
+ )
end
description
diff --git a/app/models/integrations/pipelines_email.rb b/app/models/integrations/pipelines_email.rb
index fa22bd1a73c..01efbc3e4a4 100644
--- a/app/models/integrations/pipelines_email.rb
+++ b/app/models/integrations/pipelines_email.rb
@@ -37,8 +37,8 @@ module Integrations
# `notify_only_default_branch`. Now we have a string property named
# `branches_to_be_notified`. Instead of doing a background migration, we
# opted to set a value for the new property based on the old one, if
- # users hasn't specified one already. When users edit the service and
- # selects a value for this new property, it will override everything.
+ # users haven't specified one already. When users edit the integration and
+ # select a value for this new property, it will override everything.
self.branches_to_be_notified ||= notify_only_default_branch? ? "default" : "all"
end
diff --git a/app/models/integrations/pivotaltracker.rb b/app/models/integrations/pivotaltracker.rb
index f42a872c49e..b3cbc988dd6 100644
--- a/app/models/integrations/pivotaltracker.rb
+++ b/app/models/integrations/pivotaltracker.rb
@@ -65,6 +65,10 @@ module Integrations
end
end
+ def avatar_url
+ ActionController::Base.helpers.image_path('illustrations/third-party-logos/integrations-logos/pivotal-tracker.svg')
+ end
+
private
def allowed_branch?(ref)
diff --git a/app/models/integrations/prometheus.rb b/app/models/integrations/prometheus.rb
index 8474a5b7adf..ff8d07a1b4c 100644
--- a/app/models/integrations/prometheus.rb
+++ b/app/models/integrations/prometheus.rb
@@ -185,7 +185,7 @@ module Integrations
# Remove in next required stop after %16.4
# https://gitlab.com/gitlab-org/gitlab/-/issues/338838
def sync_http_integration!
- return unless manual_configuration_changed?
+ return unless manual_configuration_changed? && !manual_configuration_was.nil?
project.alert_management_http_integrations
.for_endpoint_identifier('legacy-prometheus')
diff --git a/app/models/integrations/pushover.rb b/app/models/integrations/pushover.rb
index e97c7e5e738..2feae29f627 100644
--- a/app/models/integrations/pushover.rb
+++ b/app/models/integrations/pushover.rb
@@ -125,5 +125,9 @@ module Integrations
Gitlab::HTTP.post('/messages.json', base_uri: BASE_URI, body: pushover_data)
end
+
+ def avatar_url
+ ActionController::Base.helpers.image_path('illustrations/third-party-logos/integrations-logos/pushover.svg')
+ end
end
end
diff --git a/app/models/integrations/telegram.rb b/app/models/integrations/telegram.rb
index 7c196720386..71fe6f8d6ef 100644
--- a/app/models/integrations/telegram.rb
+++ b/app/models/integrations/telegram.rb
@@ -26,6 +26,12 @@ module Integrations
section: SECTION_TYPE_CONFIGURATION,
help: 'If selected, successful pipelines do not trigger a notification event.'
+ field :branches_to_be_notified,
+ type: :select,
+ section: SECTION_TYPE_CONFIGURATION,
+ title: -> { s_('Integrations|Branches for which notifications are to be sent') },
+ choices: -> { branch_choices }
+
with_options if: :activated? do
validates :token, :room, presence: true
end
@@ -60,6 +66,10 @@ module Integrations
super - ['deployment']
end
+ def avatar_url
+ ActionController::Base.helpers.image_path('illustrations/third-party-logos/integrations-logos/telegram.svg')
+ end
+
private
def set_webhook