summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/integrations/chat_message/alert_message.rb76
-rw-r--r--app/models/integrations/chat_message/base_message.rb88
-rw-r--r--app/models/integrations/chat_message/deployment_message.rb87
-rw-r--r--app/models/integrations/chat_message/issue_message.rb74
-rw-r--r--app/models/integrations/chat_message/merge_message.rb83
-rw-r--r--app/models/integrations/chat_message/note_message.rb86
-rw-r--r--app/models/integrations/chat_message/pipeline_message.rb267
-rw-r--r--app/models/integrations/chat_message/push_message.rb120
-rw-r--r--app/models/integrations/chat_message/wiki_page_message.rb63
-rw-r--r--app/models/packages/package.rb5
-rw-r--r--app/models/pages/lookup_path.rb9
-rw-r--r--app/models/pages/virtual_domain.rb4
-rw-r--r--app/models/project_services/chat_message/alert_message.rb74
-rw-r--r--app/models/project_services/chat_message/base_message.rb86
-rw-r--r--app/models/project_services/chat_message/deployment_message.rb85
-rw-r--r--app/models/project_services/chat_message/issue_message.rb72
-rw-r--r--app/models/project_services/chat_message/merge_message.rb81
-rw-r--r--app/models/project_services/chat_message/note_message.rb84
-rw-r--r--app/models/project_services/chat_message/pipeline_message.rb265
-rw-r--r--app/models/project_services/chat_message/push_message.rb118
-rw-r--r--app/models/project_services/chat_message/wiki_page_message.rb61
-rw-r--r--app/models/project_services/chat_notification_service.rb14
-rw-r--r--app/models/project_services/slack_service.rb2
23 files changed, 957 insertions, 947 deletions
diff --git a/app/models/integrations/chat_message/alert_message.rb b/app/models/integrations/chat_message/alert_message.rb
new file mode 100644
index 00000000000..ef0579124fe
--- /dev/null
+++ b/app/models/integrations/chat_message/alert_message.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class AlertMessage < BaseMessage
+ attr_reader :title
+ attr_reader :alert_url
+ attr_reader :severity
+ attr_reader :events
+ attr_reader :status
+ attr_reader :started_at
+
+ def initialize(params)
+ @project_name = params[:project_name] || params.dig(:project, :path_with_namespace)
+ @project_url = params.dig(:project, :web_url) || params[:project_url]
+ @title = params.dig(:object_attributes, :title)
+ @alert_url = params.dig(:object_attributes, :url)
+ @severity = params.dig(:object_attributes, :severity)
+ @events = params.dig(:object_attributes, :events)
+ @status = params.dig(:object_attributes, :status)
+ @started_at = params.dig(:object_attributes, :started_at)
+ end
+
+ def attachments
+ [{
+ title: title,
+ title_link: alert_url,
+ color: attachment_color,
+ fields: attachment_fields
+ }]
+ end
+
+ def message
+ "Alert firing in #{project_name}"
+ end
+
+ private
+
+ def attachment_color
+ "#C95823"
+ end
+
+ def attachment_fields
+ [
+ {
+ title: "Severity",
+ value: severity.to_s.humanize,
+ short: true
+ },
+ {
+ title: "Events",
+ value: events,
+ short: true
+ },
+ {
+ title: "Status",
+ value: status.to_s.humanize,
+ short: true
+ },
+ {
+ title: "Start time",
+ value: format_time(started_at),
+ short: true
+ }
+ ]
+ end
+
+ # This formats time into the following format
+ # April 23rd, 2020 1:06AM UTC
+ def format_time(time)
+ time = Time.zone.parse(time.to_s)
+ time.strftime("%B #{time.day.ordinalize}, %Y %l:%M%p %Z")
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/chat_message/base_message.rb b/app/models/integrations/chat_message/base_message.rb
new file mode 100644
index 00000000000..2f70384d3b9
--- /dev/null
+++ b/app/models/integrations/chat_message/base_message.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class BaseMessage
+ RELATIVE_LINK_REGEX = %r{!\[[^\]]*\]\((/uploads/[^\)]*)\)}.freeze
+
+ attr_reader :markdown
+ attr_reader :user_full_name
+ attr_reader :user_name
+ attr_reader :user_avatar
+ attr_reader :project_name
+ attr_reader :project_url
+
+ def initialize(params)
+ @markdown = params[:markdown] || false
+ @project_name = params[:project_name] || params.dig(:project, :path_with_namespace)
+ @project_url = params.dig(:project, :web_url) || params[:project_url]
+ @user_full_name = params.dig(:user, :name) || params[:user_full_name]
+ @user_name = params.dig(:user, :username) || params[:user_name]
+ @user_avatar = params.dig(:user, :avatar_url) || params[:user_avatar]
+ end
+
+ def user_combined_name
+ if user_full_name.present?
+ "#{user_full_name} (#{user_name})"
+ else
+ user_name
+ end
+ end
+
+ def summary
+ return message if markdown
+
+ format(message)
+ end
+
+ def pretext
+ summary
+ end
+
+ def fallback
+ format(message)
+ end
+
+ def attachments
+ raise NotImplementedError
+ end
+
+ def activity
+ raise NotImplementedError
+ end
+
+ private
+
+ def message
+ raise NotImplementedError
+ end
+
+ def format(string)
+ Slack::Messenger::Util::LinkFormatter.format(format_relative_links(string))
+ end
+
+ def format_relative_links(string)
+ string.gsub(RELATIVE_LINK_REGEX, "#{project_url}\\1")
+ end
+
+ def attachment_color
+ '#345'
+ end
+
+ def link(text, url)
+ "[#{text}](#{url})"
+ end
+
+ def pretty_duration(seconds)
+ parse_string =
+ if duration < 1.hour
+ '%M:%S'
+ else
+ '%H:%M:%S'
+ end
+
+ Time.at(seconds).utc.strftime(parse_string)
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/chat_message/deployment_message.rb b/app/models/integrations/chat_message/deployment_message.rb
new file mode 100644
index 00000000000..c4f3bf9610d
--- /dev/null
+++ b/app/models/integrations/chat_message/deployment_message.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class DeploymentMessage < BaseMessage
+ attr_reader :commit_title
+ attr_reader :commit_url
+ attr_reader :deployable_id
+ attr_reader :deployable_url
+ attr_reader :environment
+ attr_reader :short_sha
+ attr_reader :status
+ attr_reader :user_url
+
+ def initialize(data)
+ super
+
+ @commit_title = data[:commit_title]
+ @commit_url = data[:commit_url]
+ @deployable_id = data[:deployable_id]
+ @deployable_url = data[:deployable_url]
+ @environment = data[:environment]
+ @short_sha = data[:short_sha]
+ @status = data[:status]
+ @user_url = data[:user_url]
+ end
+
+ def attachments
+ [{
+ text: "#{project_link} with job #{deployment_link} by #{user_link}\n#{commit_link}: #{commit_title}",
+ color: color
+ }]
+ end
+
+ def activity
+ {}
+ end
+
+ private
+
+ def message
+ if running?
+ "Starting deploy to #{environment}"
+ else
+ "Deploy to #{environment} #{humanized_status}"
+ end
+ end
+
+ def color
+ case status
+ when 'success'
+ 'good'
+ when 'canceled'
+ 'warning'
+ when 'failed'
+ 'danger'
+ else
+ '#334455'
+ end
+ end
+
+ def project_link
+ link(project_name, project_url)
+ end
+
+ def deployment_link
+ link("##{deployable_id}", deployable_url)
+ end
+
+ def user_link
+ link(user_combined_name, user_url)
+ end
+
+ def commit_link
+ link(short_sha, commit_url)
+ end
+
+ def humanized_status
+ status == 'success' ? 'succeeded' : status
+ end
+
+ def running?
+ status == 'running'
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/chat_message/issue_message.rb b/app/models/integrations/chat_message/issue_message.rb
new file mode 100644
index 00000000000..5fa6bd4090f
--- /dev/null
+++ b/app/models/integrations/chat_message/issue_message.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class IssueMessage < BaseMessage
+ attr_reader :title
+ attr_reader :issue_iid
+ attr_reader :issue_url
+ attr_reader :action
+ attr_reader :state
+ attr_reader :description
+
+ def initialize(params)
+ super
+
+ obj_attr = params[:object_attributes]
+ obj_attr = HashWithIndifferentAccess.new(obj_attr)
+ @title = obj_attr[:title]
+ @issue_iid = obj_attr[:iid]
+ @issue_url = obj_attr[:url]
+ @action = obj_attr[:action]
+ @state = obj_attr[:state]
+ @description = obj_attr[:description] || ''
+ end
+
+ def attachments
+ return [] unless opened_issue?
+ return description if markdown
+
+ description_message
+ end
+
+ def activity
+ {
+ title: "Issue #{state} by #{user_combined_name}",
+ subtitle: "in #{project_link}",
+ text: issue_link,
+ image: user_avatar
+ }
+ end
+
+ private
+
+ def message
+ "[#{project_link}] Issue #{issue_link} #{state} by #{user_combined_name}"
+ end
+
+ def opened_issue?
+ action == 'open'
+ end
+
+ def description_message
+ [{
+ title: issue_title,
+ title_link: issue_url,
+ text: format(description),
+ color: '#C95823'
+ }]
+ end
+
+ def project_link
+ link(project_name, project_url)
+ end
+
+ def issue_link
+ link(issue_title, issue_url)
+ end
+
+ def issue_title
+ "#{Issue.reference_prefix}#{issue_iid} #{title}"
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/chat_message/merge_message.rb b/app/models/integrations/chat_message/merge_message.rb
new file mode 100644
index 00000000000..d2f48699f50
--- /dev/null
+++ b/app/models/integrations/chat_message/merge_message.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class MergeMessage < BaseMessage
+ attr_reader :merge_request_iid
+ attr_reader :source_branch
+ attr_reader :target_branch
+ attr_reader :action
+ attr_reader :state
+ attr_reader :title
+
+ def initialize(params)
+ super
+
+ obj_attr = params[:object_attributes]
+ obj_attr = HashWithIndifferentAccess.new(obj_attr)
+ @merge_request_iid = obj_attr[:iid]
+ @source_branch = obj_attr[:source_branch]
+ @target_branch = obj_attr[:target_branch]
+ @action = obj_attr[:action]
+ @state = obj_attr[:state]
+ @title = format_title(obj_attr[:title])
+ end
+
+ def attachments
+ []
+ end
+
+ def activity
+ {
+ title: "Merge request #{state_or_action_text} by #{user_combined_name}",
+ subtitle: "in #{project_link}",
+ text: merge_request_link,
+ image: user_avatar
+ }
+ end
+
+ private
+
+ def format_title(title)
+ '*' + title.lines.first.chomp + '*'
+ end
+
+ def message
+ merge_request_message
+ end
+
+ def project_link
+ link(project_name, project_url)
+ end
+
+ def merge_request_message
+ "#{user_combined_name} #{state_or_action_text} merge request #{merge_request_link} in #{project_link}"
+ end
+
+ def merge_request_link
+ link(merge_request_title, merge_request_url)
+ end
+
+ def merge_request_title
+ "#{MergeRequest.reference_prefix}#{merge_request_iid} #{title}"
+ end
+
+ def merge_request_url
+ "#{project_url}/-/merge_requests/#{merge_request_iid}"
+ end
+
+ def state_or_action_text
+ case action
+ when 'approved', 'unapproved'
+ action
+ when 'approval'
+ 'added their approval to'
+ when 'unapproval'
+ 'removed their approval from'
+ else
+ state
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/chat_message/note_message.rb b/app/models/integrations/chat_message/note_message.rb
new file mode 100644
index 00000000000..96675d2b27c
--- /dev/null
+++ b/app/models/integrations/chat_message/note_message.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class NoteMessage < BaseMessage
+ attr_reader :note
+ attr_reader :note_url
+ attr_reader :title
+ attr_reader :target
+
+ def initialize(params)
+ super
+
+ params = HashWithIndifferentAccess.new(params)
+ obj_attr = params[:object_attributes]
+ @note = obj_attr[:note]
+ @note_url = obj_attr[:url]
+ @target, @title = case obj_attr[:noteable_type]
+ when "Commit"
+ create_commit_note(params[:commit])
+ when "Issue"
+ create_issue_note(params[:issue])
+ when "MergeRequest"
+ create_merge_note(params[:merge_request])
+ when "Snippet"
+ create_snippet_note(params[:snippet])
+ end
+ end
+
+ def attachments
+ return note if markdown
+
+ description_message
+ end
+
+ def activity
+ {
+ title: "#{user_combined_name} #{link('commented on ' + target, note_url)}",
+ subtitle: "in #{project_link}",
+ text: formatted_title,
+ image: user_avatar
+ }
+ end
+
+ private
+
+ def message
+ "#{user_combined_name} #{link('commented on ' + target, note_url)} in #{project_link}: *#{formatted_title}*"
+ end
+
+ def format_title(title)
+ title.lines.first.chomp
+ end
+
+ def formatted_title
+ format_title(title)
+ end
+
+ def create_issue_note(issue)
+ ["issue #{Issue.reference_prefix}#{issue[:iid]}", issue[:title]]
+ end
+
+ def create_commit_note(commit)
+ commit_sha = Commit.truncate_sha(commit[:id])
+
+ ["commit #{commit_sha}", commit[:message]]
+ end
+
+ def create_merge_note(merge_request)
+ ["merge request #{MergeRequest.reference_prefix}#{merge_request[:iid]}", merge_request[:title]]
+ end
+
+ def create_snippet_note(snippet)
+ ["snippet #{Snippet.reference_prefix}#{snippet[:id]}", snippet[:title]]
+ end
+
+ def description_message
+ [{ text: format(note), color: attachment_color }]
+ end
+
+ def project_link
+ link(project_name, project_url)
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/chat_message/pipeline_message.rb b/app/models/integrations/chat_message/pipeline_message.rb
new file mode 100644
index 00000000000..a0f6f582e4c
--- /dev/null
+++ b/app/models/integrations/chat_message/pipeline_message.rb
@@ -0,0 +1,267 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class PipelineMessage < BaseMessage
+ MAX_VISIBLE_JOBS = 10
+
+ attr_reader :user
+ attr_reader :ref_type
+ attr_reader :ref
+ attr_reader :status
+ attr_reader :detailed_status
+ attr_reader :duration
+ attr_reader :finished_at
+ attr_reader :pipeline_id
+ attr_reader :failed_stages
+ attr_reader :failed_jobs
+
+ attr_reader :project
+ attr_reader :commit
+ attr_reader :committer
+ attr_reader :pipeline
+
+ def initialize(data)
+ super
+
+ @user = data[:user]
+ @user_name = data.dig(:user, :username) || 'API'
+
+ pipeline_attributes = data[:object_attributes]
+ @ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch'
+ @ref = pipeline_attributes[:ref]
+ @status = pipeline_attributes[:status]
+ @detailed_status = pipeline_attributes[:detailed_status]
+ @duration = pipeline_attributes[:duration].to_i
+ @finished_at = pipeline_attributes[:finished_at] ? Time.parse(pipeline_attributes[:finished_at]).to_i : nil
+ @pipeline_id = pipeline_attributes[:id]
+
+ # Get list of jobs that have actually failed (after exhausting all retries)
+ @failed_jobs = actually_failed_jobs(Array(data[:builds]))
+ @failed_stages = @failed_jobs.map { |j| j[:stage] }.uniq
+
+ @project = Project.find(data[:project][:id])
+ @commit = project.commit_by(oid: data[:commit][:id])
+ @committer = commit.committer
+ @pipeline = Ci::Pipeline.find(pipeline_id)
+ end
+
+ def pretext
+ ''
+ end
+
+ def attachments
+ return message if markdown
+
+ [{
+ fallback: format(message),
+ color: attachment_color,
+ author_name: user_combined_name,
+ author_icon: user_avatar,
+ author_link: author_url,
+ title: s_("ChatMessage|Pipeline #%{pipeline_id} %{humanized_status} in %{duration}") %
+ {
+ pipeline_id: pipeline_id,
+ humanized_status: humanized_status,
+ duration: pretty_duration(duration)
+ },
+ title_link: pipeline_url,
+ fields: attachments_fields,
+ footer: project.name,
+ footer_icon: project.avatar_url(only_path: false),
+ ts: finished_at
+ }]
+ end
+
+ def activity
+ {
+ title: s_("ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status}") %
+ {
+ pipeline_link: pipeline_link,
+ ref_type: ref_type,
+ ref_link: ref_link,
+ user_combined_name: user_combined_name,
+ humanized_status: humanized_status
+ },
+ subtitle: s_("ChatMessage|in %{project_link}") % { project_link: project_link },
+ text: s_("ChatMessage|in %{duration}") % { duration: pretty_duration(duration) },
+ image: user_avatar || ''
+ }
+ end
+
+ private
+
+ def actually_failed_jobs(builds)
+ succeeded_job_names = builds.map { |b| b[:name] if b[:status] == 'success' }.compact.uniq
+
+ failed_jobs = builds.select do |build|
+ # Select jobs which doesn't have a successful retry
+ build[:status] == 'failed' && !succeeded_job_names.include?(build[:name])
+ end
+
+ failed_jobs.uniq { |job| job[:name] }.reverse
+ end
+
+ def failed_stages_field
+ {
+ title: s_("ChatMessage|Failed stage").pluralize(failed_stages.length),
+ value: Slack::Messenger::Util::LinkFormatter.format(failed_stages_links),
+ short: true
+ }
+ end
+
+ def failed_jobs_field
+ {
+ title: s_("ChatMessage|Failed job").pluralize(failed_jobs.length),
+ value: Slack::Messenger::Util::LinkFormatter.format(failed_jobs_links),
+ short: true
+ }
+ end
+
+ def yaml_error_field
+ {
+ title: s_("ChatMessage|Invalid CI config YAML file"),
+ value: pipeline.yaml_errors,
+ short: false
+ }
+ end
+
+ def attachments_fields
+ fields = [
+ {
+ title: ref_type == "tag" ? s_("ChatMessage|Tag") : s_("ChatMessage|Branch"),
+ value: Slack::Messenger::Util::LinkFormatter.format(ref_link),
+ short: true
+ },
+ {
+ title: s_("ChatMessage|Commit"),
+ value: Slack::Messenger::Util::LinkFormatter.format(commit_link),
+ short: true
+ }
+ ]
+
+ 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
+ end
+
+ def message
+ s_("ChatMessage|%{project_link}: Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status} in %{duration}") %
+ {
+ project_link: project_link,
+ pipeline_link: pipeline_link,
+ ref_type: ref_type,
+ ref_link: ref_link,
+ user_combined_name: user_combined_name,
+ humanized_status: humanized_status,
+ duration: pretty_duration(duration)
+ }
+ end
+
+ def humanized_status
+ case status
+ when 'success'
+ detailed_status == "passed with warnings" ? s_("ChatMessage|has passed with warnings") : s_("ChatMessage|has passed")
+ when 'failed'
+ s_("ChatMessage|has failed")
+ else
+ status
+ 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}"
+ else
+ "#{project_url}/-/commits/#{ref}"
+ end
+ end
+
+ def ref_link
+ "[#{ref}](#{ref_url})"
+ end
+
+ def project_url
+ project.web_url
+ end
+
+ def project_link
+ "[#{project.name}](#{project_url})"
+ end
+
+ def pipeline_failed_jobs_url
+ "#{project_url}/-/pipelines/#{pipeline_id}/failures"
+ end
+
+ def pipeline_url
+ if failed_jobs.any?
+ pipeline_failed_jobs_url
+ else
+ "#{project_url}/-/pipelines/#{pipeline_id}"
+ end
+ end
+
+ def pipeline_link
+ "[##{pipeline_id}](#{pipeline_url})"
+ end
+
+ def job_url(job)
+ "#{project_url}/-/jobs/#{job[:id]}"
+ end
+
+ def job_link(job)
+ "[#{job[:name]}](#{job_url(job)})"
+ end
+
+ def failed_jobs_links
+ failed = failed_jobs.slice(0, MAX_VISIBLE_JOBS)
+ truncated = failed_jobs.slice(MAX_VISIBLE_JOBS, failed_jobs.size)
+
+ failed_links = failed.map { |job| job_link(job) }
+
+ unless truncated.blank?
+ failed_links << s_("ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})") % {
+ count: truncated.size,
+ pipeline_failed_jobs_url: pipeline_failed_jobs_url
+ }
+ end
+
+ failed_links.join(I18n.t(:'support.array.words_connector'))
+ end
+
+ def stage_link(stage)
+ # All stages link to the pipeline page
+ "[#{stage}](#{pipeline_url})"
+ end
+
+ def failed_stages_links
+ failed_stages.map { |s| stage_link(s) }.join(I18n.t(:'support.array.words_connector'))
+ end
+
+ def commit_url
+ Gitlab::UrlBuilder.build(commit)
+ end
+
+ def commit_link
+ "[#{commit.title}](#{commit_url})"
+ end
+
+ def author_url
+ return unless user && committer
+
+ Gitlab::UrlBuilder.build(committer)
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/chat_message/push_message.rb b/app/models/integrations/chat_message/push_message.rb
new file mode 100644
index 00000000000..0952986e923
--- /dev/null
+++ b/app/models/integrations/chat_message/push_message.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class PushMessage < BaseMessage
+ attr_reader :after
+ attr_reader :before
+ attr_reader :commits
+ attr_reader :ref
+ attr_reader :ref_type
+
+ def initialize(params)
+ super
+
+ @after = params[:after]
+ @before = params[:before]
+ @commits = params.fetch(:commits, [])
+ @ref_type = Gitlab::Git.tag_ref?(params[:ref]) ? 'tag' : 'branch'
+ @ref = Gitlab::Git.ref_name(params[:ref])
+ end
+
+ def attachments
+ return [] if new_branch? || removed_branch?
+ return commit_messages if markdown
+
+ commit_message_attachments
+ end
+
+ def activity
+ {
+ title: humanized_action(short: true),
+ subtitle: "in #{project_link}",
+ text: compare_link,
+ image: user_avatar
+ }
+ end
+
+ private
+
+ def humanized_action(short: false)
+ action, ref_link, target_link = compose_action_details
+ text = [user_combined_name, action, ref_type, ref_link]
+ text << target_link unless short
+ text.join(' ')
+ end
+
+ def message
+ humanized_action
+ end
+
+ def format(string)
+ Slack::Messenger::Util::LinkFormatter.format(string)
+ end
+
+ def commit_messages
+ commits.map { |commit| compose_commit_message(commit) }.join("\n\n")
+ end
+
+ def commit_message_attachments
+ [{ text: format(commit_messages), color: attachment_color }]
+ end
+
+ def compose_commit_message(commit)
+ author = commit[:author][:name]
+ id = Commit.truncate_sha(commit[:id])
+ title = commit[:title]
+
+ url = commit[:url]
+
+ "[#{id}](#{url}): #{title} - #{author}"
+ end
+
+ def new_branch?
+ Gitlab::Git.blank_ref?(before)
+ end
+
+ def removed_branch?
+ Gitlab::Git.blank_ref?(after)
+ end
+
+ def ref_url
+ if ref_type == 'tag'
+ "#{project_url}/-/tags/#{ref}"
+ else
+ "#{project_url}/commits/#{ref}"
+ end
+ end
+
+ def compare_url
+ "#{project_url}/compare/#{before}...#{after}"
+ end
+
+ def ref_link
+ "[#{ref}](#{ref_url})"
+ end
+
+ def project_link
+ "[#{project_name}](#{project_url})"
+ end
+
+ def compare_link
+ "[Compare changes](#{compare_url})"
+ end
+
+ def compose_action_details
+ if new_branch?
+ ['pushed new', ref_link, "to #{project_link}"]
+ elsif removed_branch?
+ ['removed', ref, "from #{project_link}"]
+ else
+ ['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/chat_message/wiki_page_message.rb b/app/models/integrations/chat_message/wiki_page_message.rb
new file mode 100644
index 00000000000..9b5275b8c03
--- /dev/null
+++ b/app/models/integrations/chat_message/wiki_page_message.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class WikiPageMessage < BaseMessage
+ attr_reader :title
+ attr_reader :wiki_page_url
+ attr_reader :action
+ attr_reader :description
+
+ def initialize(params)
+ super
+
+ obj_attr = params[:object_attributes]
+ obj_attr = HashWithIndifferentAccess.new(obj_attr)
+ @title = obj_attr[:title]
+ @wiki_page_url = obj_attr[:url]
+ @description = obj_attr[:message]
+
+ @action =
+ case obj_attr[:action]
+ when "create"
+ "created"
+ when "update"
+ "edited"
+ end
+ end
+
+ def attachments
+ return description if markdown
+
+ description_message
+ end
+
+ def activity
+ {
+ title: "#{user_combined_name} #{action} #{wiki_page_link}",
+ subtitle: "in #{project_link}",
+ text: title,
+ image: user_avatar
+ }
+ end
+
+ private
+
+ def message
+ "#{user_combined_name} #{action} #{wiki_page_link} in #{project_link}: *#{title}*"
+ end
+
+ def description_message
+ [{ text: format(@description), color: attachment_color }]
+ end
+
+ def project_link
+ "[#{project_name}](#{project_url})"
+ end
+
+ def wiki_page_link
+ "[wiki page](#{wiki_page_url})"
+ end
+ end
+ end
+end
diff --git a/app/models/packages/package.rb b/app/models/packages/package.rb
index fa7921afcbf..36edf646658 100644
--- a/app/models/packages/package.rb
+++ b/app/models/packages/package.rb
@@ -117,11 +117,6 @@ class Packages::Package < ApplicationRecord
scope :without_nuget_temporary_name, -> { where.not(name: Packages::Nuget::TEMPORARY_PACKAGE_NAME) }
scope :has_version, -> { where.not(version: nil) }
- scope :processed, -> do
- where.not(package_type: :nuget).or(
- where.not(name: Packages::Nuget::TEMPORARY_PACKAGE_NAME)
- )
- end
scope :preload_files, -> { preload(:package_files) }
scope :last_of_each_version, -> { where(id: all.select('MAX(id) AS id').group(:version)) }
scope :limit_recent, ->(limit) { order_created_desc.limit(limit) }
diff --git a/app/models/pages/lookup_path.rb b/app/models/pages/lookup_path.rb
index bd4b232849f..17131cd736d 100644
--- a/app/models/pages/lookup_path.rb
+++ b/app/models/pages/lookup_path.rb
@@ -62,17 +62,16 @@ module Pages
}
end
+ # TODO: remove support for legacy storage in 14.3 https://gitlab.com/gitlab-org/gitlab/-/issues/328712
+ # we support this till 14.3 to allow people to still use legacy storage if something goes very wrong
+ # on self-hosted installations, and we'll need some time to fix it
def legacy_source
- raise LegacyStorageDisabledError unless Feature.enabled?(:pages_serve_from_legacy_storage, default_enabled: true)
+ return unless ::Settings.pages.local_store.enabled
{
type: 'file',
path: File.join(project.full_path, 'public/')
}
- rescue LegacyStorageDisabledError => e
- Gitlab::ErrorTracking.track_exception(e, project_id: project.id)
-
- nil
end
end
end
diff --git a/app/models/pages/virtual_domain.rb b/app/models/pages/virtual_domain.rb
index 90cb8253b52..497f67993ae 100644
--- a/app/models/pages/virtual_domain.rb
+++ b/app/models/pages/virtual_domain.rb
@@ -21,9 +21,7 @@ module Pages
project.pages_lookup_path(trim_prefix: trim_prefix, domain: domain)
end
- # TODO: remove in https://gitlab.com/gitlab-org/gitlab/-/issues/297524
- # source can only be nil if pages_serve_from_legacy_storage FF is disabled
- # we can remove this filtering once we remove legacy storage
+ # TODO: remove in https://gitlab.com/gitlab-org/gitlab/-/issues/328715
paths = paths.select(&:source)
paths.sort_by(&:prefix).reverse
diff --git a/app/models/project_services/chat_message/alert_message.rb b/app/models/project_services/chat_message/alert_message.rb
deleted file mode 100644
index c8913775843..00000000000
--- a/app/models/project_services/chat_message/alert_message.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class AlertMessage < BaseMessage
- attr_reader :title
- attr_reader :alert_url
- attr_reader :severity
- attr_reader :events
- attr_reader :status
- attr_reader :started_at
-
- def initialize(params)
- @project_name = params[:project_name] || params.dig(:project, :path_with_namespace)
- @project_url = params.dig(:project, :web_url) || params[:project_url]
- @title = params.dig(:object_attributes, :title)
- @alert_url = params.dig(:object_attributes, :url)
- @severity = params.dig(:object_attributes, :severity)
- @events = params.dig(:object_attributes, :events)
- @status = params.dig(:object_attributes, :status)
- @started_at = params.dig(:object_attributes, :started_at)
- end
-
- def attachments
- [{
- title: title,
- title_link: alert_url,
- color: attachment_color,
- fields: attachment_fields
- }]
- end
-
- def message
- "Alert firing in #{project_name}"
- end
-
- private
-
- def attachment_color
- "#C95823"
- end
-
- def attachment_fields
- [
- {
- title: "Severity",
- value: severity.to_s.humanize,
- short: true
- },
- {
- title: "Events",
- value: events,
- short: true
- },
- {
- title: "Status",
- value: status.to_s.humanize,
- short: true
- },
- {
- title: "Start time",
- value: format_time(started_at),
- short: true
- }
- ]
- end
-
- # This formats time into the following format
- # April 23rd, 2020 1:06AM UTC
- def format_time(time)
- time = Time.zone.parse(time.to_s)
- time.strftime("%B #{time.day.ordinalize}, %Y %l:%M%p %Z")
- end
- end
-end
diff --git a/app/models/project_services/chat_message/base_message.rb b/app/models/project_services/chat_message/base_message.rb
deleted file mode 100644
index bdd77a919e3..00000000000
--- a/app/models/project_services/chat_message/base_message.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class BaseMessage
- RELATIVE_LINK_REGEX = /!\[[^\]]*\]\((\/uploads\/[^\)]*)\)/.freeze
-
- attr_reader :markdown
- attr_reader :user_full_name
- attr_reader :user_name
- attr_reader :user_avatar
- attr_reader :project_name
- attr_reader :project_url
-
- def initialize(params)
- @markdown = params[:markdown] || false
- @project_name = params[:project_name] || params.dig(:project, :path_with_namespace)
- @project_url = params.dig(:project, :web_url) || params[:project_url]
- @user_full_name = params.dig(:user, :name) || params[:user_full_name]
- @user_name = params.dig(:user, :username) || params[:user_name]
- @user_avatar = params.dig(:user, :avatar_url) || params[:user_avatar]
- end
-
- def user_combined_name
- if user_full_name.present?
- "#{user_full_name} (#{user_name})"
- else
- user_name
- end
- end
-
- def summary
- return message if markdown
-
- format(message)
- end
-
- def pretext
- summary
- end
-
- def fallback
- format(message)
- end
-
- def attachments
- raise NotImplementedError
- end
-
- def activity
- raise NotImplementedError
- end
-
- private
-
- def message
- raise NotImplementedError
- end
-
- def format(string)
- Slack::Messenger::Util::LinkFormatter.format(format_relative_links(string))
- end
-
- def format_relative_links(string)
- string.gsub(RELATIVE_LINK_REGEX, "#{project_url}\\1")
- end
-
- def attachment_color
- '#345'
- end
-
- def link(text, url)
- "[#{text}](#{url})"
- end
-
- def pretty_duration(seconds)
- parse_string =
- if duration < 1.hour
- '%M:%S'
- else
- '%H:%M:%S'
- end
-
- Time.at(seconds).utc.strftime(parse_string)
- end
- end
-end
diff --git a/app/models/project_services/chat_message/deployment_message.rb b/app/models/project_services/chat_message/deployment_message.rb
deleted file mode 100644
index 5deb757e60f..00000000000
--- a/app/models/project_services/chat_message/deployment_message.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class DeploymentMessage < BaseMessage
- attr_reader :commit_title
- attr_reader :commit_url
- attr_reader :deployable_id
- attr_reader :deployable_url
- attr_reader :environment
- attr_reader :short_sha
- attr_reader :status
- attr_reader :user_url
-
- def initialize(data)
- super
-
- @commit_title = data[:commit_title]
- @commit_url = data[:commit_url]
- @deployable_id = data[:deployable_id]
- @deployable_url = data[:deployable_url]
- @environment = data[:environment]
- @short_sha = data[:short_sha]
- @status = data[:status]
- @user_url = data[:user_url]
- end
-
- def attachments
- [{
- text: "#{project_link} with job #{deployment_link} by #{user_link}\n#{commit_link}: #{commit_title}",
- color: color
- }]
- end
-
- def activity
- {}
- end
-
- private
-
- def message
- if running?
- "Starting deploy to #{environment}"
- else
- "Deploy to #{environment} #{humanized_status}"
- end
- end
-
- def color
- case status
- when 'success'
- 'good'
- when 'canceled'
- 'warning'
- when 'failed'
- 'danger'
- else
- '#334455'
- end
- end
-
- def project_link
- link(project_name, project_url)
- end
-
- def deployment_link
- link("##{deployable_id}", deployable_url)
- end
-
- def user_link
- link(user_combined_name, user_url)
- end
-
- def commit_link
- link(short_sha, commit_url)
- end
-
- def humanized_status
- status == 'success' ? 'succeeded' : status
- end
-
- def running?
- status == 'running'
- end
- end
-end
diff --git a/app/models/project_services/chat_message/issue_message.rb b/app/models/project_services/chat_message/issue_message.rb
deleted file mode 100644
index c8e90b66bae..00000000000
--- a/app/models/project_services/chat_message/issue_message.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class IssueMessage < BaseMessage
- attr_reader :title
- attr_reader :issue_iid
- attr_reader :issue_url
- attr_reader :action
- attr_reader :state
- attr_reader :description
-
- def initialize(params)
- super
-
- obj_attr = params[:object_attributes]
- obj_attr = HashWithIndifferentAccess.new(obj_attr)
- @title = obj_attr[:title]
- @issue_iid = obj_attr[:iid]
- @issue_url = obj_attr[:url]
- @action = obj_attr[:action]
- @state = obj_attr[:state]
- @description = obj_attr[:description] || ''
- end
-
- def attachments
- return [] unless opened_issue?
- return description if markdown
-
- description_message
- end
-
- def activity
- {
- title: "Issue #{state} by #{user_combined_name}",
- subtitle: "in #{project_link}",
- text: issue_link,
- image: user_avatar
- }
- end
-
- private
-
- def message
- "[#{project_link}] Issue #{issue_link} #{state} by #{user_combined_name}"
- end
-
- def opened_issue?
- action == 'open'
- end
-
- def description_message
- [{
- title: issue_title,
- title_link: issue_url,
- text: format(description),
- color: '#C95823'
- }]
- end
-
- def project_link
- link(project_name, project_url)
- end
-
- def issue_link
- link(issue_title, issue_url)
- end
-
- def issue_title
- "#{Issue.reference_prefix}#{issue_iid} #{title}"
- end
- end
-end
diff --git a/app/models/project_services/chat_message/merge_message.rb b/app/models/project_services/chat_message/merge_message.rb
deleted file mode 100644
index e45bb9b8ce1..00000000000
--- a/app/models/project_services/chat_message/merge_message.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class MergeMessage < BaseMessage
- attr_reader :merge_request_iid
- attr_reader :source_branch
- attr_reader :target_branch
- attr_reader :action
- attr_reader :state
- attr_reader :title
-
- def initialize(params)
- super
-
- obj_attr = params[:object_attributes]
- obj_attr = HashWithIndifferentAccess.new(obj_attr)
- @merge_request_iid = obj_attr[:iid]
- @source_branch = obj_attr[:source_branch]
- @target_branch = obj_attr[:target_branch]
- @action = obj_attr[:action]
- @state = obj_attr[:state]
- @title = format_title(obj_attr[:title])
- end
-
- def attachments
- []
- end
-
- def activity
- {
- title: "Merge request #{state_or_action_text} by #{user_combined_name}",
- subtitle: "in #{project_link}",
- text: merge_request_link,
- image: user_avatar
- }
- end
-
- private
-
- def format_title(title)
- '*' + title.lines.first.chomp + '*'
- end
-
- def message
- merge_request_message
- end
-
- def project_link
- link(project_name, project_url)
- end
-
- def merge_request_message
- "#{user_combined_name} #{state_or_action_text} merge request #{merge_request_link} in #{project_link}"
- end
-
- def merge_request_link
- link(merge_request_title, merge_request_url)
- end
-
- def merge_request_title
- "#{MergeRequest.reference_prefix}#{merge_request_iid} #{title}"
- end
-
- def merge_request_url
- "#{project_url}/-/merge_requests/#{merge_request_iid}"
- end
-
- def state_or_action_text
- case action
- when 'approved', 'unapproved'
- action
- when 'approval'
- 'added their approval to'
- when 'unapproval'
- 'removed their approval from'
- else
- state
- end
- end
- end
-end
diff --git a/app/models/project_services/chat_message/note_message.rb b/app/models/project_services/chat_message/note_message.rb
deleted file mode 100644
index 741474fb27b..00000000000
--- a/app/models/project_services/chat_message/note_message.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class NoteMessage < BaseMessage
- attr_reader :note
- attr_reader :note_url
- attr_reader :title
- attr_reader :target
-
- def initialize(params)
- super
-
- params = HashWithIndifferentAccess.new(params)
- obj_attr = params[:object_attributes]
- @note = obj_attr[:note]
- @note_url = obj_attr[:url]
- @target, @title = case obj_attr[:noteable_type]
- when "Commit"
- create_commit_note(params[:commit])
- when "Issue"
- create_issue_note(params[:issue])
- when "MergeRequest"
- create_merge_note(params[:merge_request])
- when "Snippet"
- create_snippet_note(params[:snippet])
- end
- end
-
- def attachments
- return note if markdown
-
- description_message
- end
-
- def activity
- {
- title: "#{user_combined_name} #{link('commented on ' + target, note_url)}",
- subtitle: "in #{project_link}",
- text: formatted_title,
- image: user_avatar
- }
- end
-
- private
-
- def message
- "#{user_combined_name} #{link('commented on ' + target, note_url)} in #{project_link}: *#{formatted_title}*"
- end
-
- def format_title(title)
- title.lines.first.chomp
- end
-
- def formatted_title
- format_title(title)
- end
-
- def create_issue_note(issue)
- ["issue #{Issue.reference_prefix}#{issue[:iid]}", issue[:title]]
- end
-
- def create_commit_note(commit)
- commit_sha = Commit.truncate_sha(commit[:id])
-
- ["commit #{commit_sha}", commit[:message]]
- end
-
- def create_merge_note(merge_request)
- ["merge request #{MergeRequest.reference_prefix}#{merge_request[:iid]}", merge_request[:title]]
- end
-
- def create_snippet_note(snippet)
- ["snippet #{Snippet.reference_prefix}#{snippet[:id]}", snippet[:title]]
- end
-
- def description_message
- [{ text: format(note), color: attachment_color }]
- end
-
- def project_link
- link(project_name, project_url)
- end
- end
-end
diff --git a/app/models/project_services/chat_message/pipeline_message.rb b/app/models/project_services/chat_message/pipeline_message.rb
deleted file mode 100644
index f4c6938fa78..00000000000
--- a/app/models/project_services/chat_message/pipeline_message.rb
+++ /dev/null
@@ -1,265 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class PipelineMessage < BaseMessage
- MAX_VISIBLE_JOBS = 10
-
- attr_reader :user
- attr_reader :ref_type
- attr_reader :ref
- attr_reader :status
- attr_reader :detailed_status
- attr_reader :duration
- attr_reader :finished_at
- attr_reader :pipeline_id
- attr_reader :failed_stages
- attr_reader :failed_jobs
-
- attr_reader :project
- attr_reader :commit
- attr_reader :committer
- attr_reader :pipeline
-
- def initialize(data)
- super
-
- @user = data[:user]
- @user_name = data.dig(:user, :username) || 'API'
-
- pipeline_attributes = data[:object_attributes]
- @ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch'
- @ref = pipeline_attributes[:ref]
- @status = pipeline_attributes[:status]
- @detailed_status = pipeline_attributes[:detailed_status]
- @duration = pipeline_attributes[:duration].to_i
- @finished_at = pipeline_attributes[:finished_at] ? Time.parse(pipeline_attributes[:finished_at]).to_i : nil
- @pipeline_id = pipeline_attributes[:id]
-
- # Get list of jobs that have actually failed (after exhausting all retries)
- @failed_jobs = actually_failed_jobs(Array(data[:builds]))
- @failed_stages = @failed_jobs.map { |j| j[:stage] }.uniq
-
- @project = Project.find(data[:project][:id])
- @commit = project.commit_by(oid: data[:commit][:id])
- @committer = commit.committer
- @pipeline = Ci::Pipeline.find(pipeline_id)
- end
-
- def pretext
- ''
- end
-
- def attachments
- return message if markdown
-
- [{
- fallback: format(message),
- color: attachment_color,
- author_name: user_combined_name,
- author_icon: user_avatar,
- author_link: author_url,
- title: s_("ChatMessage|Pipeline #%{pipeline_id} %{humanized_status} in %{duration}") %
- {
- pipeline_id: pipeline_id,
- humanized_status: humanized_status,
- duration: pretty_duration(duration)
- },
- title_link: pipeline_url,
- fields: attachments_fields,
- footer: project.name,
- footer_icon: project.avatar_url(only_path: false),
- ts: finished_at
- }]
- end
-
- def activity
- {
- title: s_("ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status}") %
- {
- pipeline_link: pipeline_link,
- ref_type: ref_type,
- ref_link: ref_link,
- user_combined_name: user_combined_name,
- humanized_status: humanized_status
- },
- subtitle: s_("ChatMessage|in %{project_link}") % { project_link: project_link },
- text: s_("ChatMessage|in %{duration}") % { duration: pretty_duration(duration) },
- image: user_avatar || ''
- }
- end
-
- private
-
- def actually_failed_jobs(builds)
- succeeded_job_names = builds.map { |b| b[:name] if b[:status] == 'success' }.compact.uniq
-
- failed_jobs = builds.select do |build|
- # Select jobs which doesn't have a successful retry
- build[:status] == 'failed' && !succeeded_job_names.include?(build[:name])
- end
-
- failed_jobs.uniq { |job| job[:name] }.reverse
- end
-
- def failed_stages_field
- {
- title: s_("ChatMessage|Failed stage").pluralize(failed_stages.length),
- value: Slack::Messenger::Util::LinkFormatter.format(failed_stages_links),
- short: true
- }
- end
-
- def failed_jobs_field
- {
- title: s_("ChatMessage|Failed job").pluralize(failed_jobs.length),
- value: Slack::Messenger::Util::LinkFormatter.format(failed_jobs_links),
- short: true
- }
- end
-
- def yaml_error_field
- {
- title: s_("ChatMessage|Invalid CI config YAML file"),
- value: pipeline.yaml_errors,
- short: false
- }
- end
-
- def attachments_fields
- fields = [
- {
- title: ref_type == "tag" ? s_("ChatMessage|Tag") : s_("ChatMessage|Branch"),
- value: Slack::Messenger::Util::LinkFormatter.format(ref_link),
- short: true
- },
- {
- title: s_("ChatMessage|Commit"),
- value: Slack::Messenger::Util::LinkFormatter.format(commit_link),
- short: true
- }
- ]
-
- 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
- end
-
- def message
- s_("ChatMessage|%{project_link}: Pipeline %{pipeline_link} of %{ref_type} %{ref_link} by %{user_combined_name} %{humanized_status} in %{duration}") %
- {
- project_link: project_link,
- pipeline_link: pipeline_link,
- ref_type: ref_type,
- ref_link: ref_link,
- user_combined_name: user_combined_name,
- humanized_status: humanized_status,
- duration: pretty_duration(duration)
- }
- end
-
- def humanized_status
- case status
- when 'success'
- detailed_status == "passed with warnings" ? s_("ChatMessage|has passed with warnings") : s_("ChatMessage|has passed")
- when 'failed'
- s_("ChatMessage|has failed")
- else
- status
- 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}"
- else
- "#{project_url}/-/commits/#{ref}"
- end
- end
-
- def ref_link
- "[#{ref}](#{ref_url})"
- end
-
- def project_url
- project.web_url
- end
-
- def project_link
- "[#{project.name}](#{project_url})"
- end
-
- def pipeline_failed_jobs_url
- "#{project_url}/-/pipelines/#{pipeline_id}/failures"
- end
-
- def pipeline_url
- if failed_jobs.any?
- pipeline_failed_jobs_url
- else
- "#{project_url}/-/pipelines/#{pipeline_id}"
- end
- end
-
- def pipeline_link
- "[##{pipeline_id}](#{pipeline_url})"
- end
-
- def job_url(job)
- "#{project_url}/-/jobs/#{job[:id]}"
- end
-
- def job_link(job)
- "[#{job[:name]}](#{job_url(job)})"
- end
-
- def failed_jobs_links
- failed = failed_jobs.slice(0, MAX_VISIBLE_JOBS)
- truncated = failed_jobs.slice(MAX_VISIBLE_JOBS, failed_jobs.size)
-
- failed_links = failed.map { |job| job_link(job) }
-
- unless truncated.blank?
- failed_links << s_("ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})") % {
- count: truncated.size,
- pipeline_failed_jobs_url: pipeline_failed_jobs_url
- }
- end
-
- failed_links.join(I18n.translate(:'support.array.words_connector'))
- end
-
- def stage_link(stage)
- # All stages link to the pipeline page
- "[#{stage}](#{pipeline_url})"
- end
-
- def failed_stages_links
- failed_stages.map { |s| stage_link(s) }.join(I18n.translate(:'support.array.words_connector'))
- end
-
- def commit_url
- Gitlab::UrlBuilder.build(commit)
- end
-
- def commit_link
- "[#{commit.title}](#{commit_url})"
- end
-
- def author_url
- return unless user && committer
-
- Gitlab::UrlBuilder.build(committer)
- end
- end
-end
diff --git a/app/models/project_services/chat_message/push_message.rb b/app/models/project_services/chat_message/push_message.rb
deleted file mode 100644
index c8e70a69c88..00000000000
--- a/app/models/project_services/chat_message/push_message.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class PushMessage < BaseMessage
- attr_reader :after
- attr_reader :before
- attr_reader :commits
- attr_reader :ref
- attr_reader :ref_type
-
- def initialize(params)
- super
-
- @after = params[:after]
- @before = params[:before]
- @commits = params.fetch(:commits, [])
- @ref_type = Gitlab::Git.tag_ref?(params[:ref]) ? 'tag' : 'branch'
- @ref = Gitlab::Git.ref_name(params[:ref])
- end
-
- def attachments
- return [] if new_branch? || removed_branch?
- return commit_messages if markdown
-
- commit_message_attachments
- end
-
- def activity
- {
- title: humanized_action(short: true),
- subtitle: "in #{project_link}",
- text: compare_link,
- image: user_avatar
- }
- end
-
- private
-
- def humanized_action(short: false)
- action, ref_link, target_link = compose_action_details
- text = [user_combined_name, action, ref_type, ref_link]
- text << target_link unless short
- text.join(' ')
- end
-
- def message
- humanized_action
- end
-
- def format(string)
- Slack::Messenger::Util::LinkFormatter.format(string)
- end
-
- def commit_messages
- commits.map { |commit| compose_commit_message(commit) }.join("\n\n")
- end
-
- def commit_message_attachments
- [{ text: format(commit_messages), color: attachment_color }]
- end
-
- def compose_commit_message(commit)
- author = commit[:author][:name]
- id = Commit.truncate_sha(commit[:id])
- title = commit[:title]
-
- url = commit[:url]
-
- "[#{id}](#{url}): #{title} - #{author}"
- end
-
- def new_branch?
- Gitlab::Git.blank_ref?(before)
- end
-
- def removed_branch?
- Gitlab::Git.blank_ref?(after)
- end
-
- def ref_url
- if ref_type == 'tag'
- "#{project_url}/-/tags/#{ref}"
- else
- "#{project_url}/commits/#{ref}"
- end
- end
-
- def compare_url
- "#{project_url}/compare/#{before}...#{after}"
- end
-
- def ref_link
- "[#{ref}](#{ref_url})"
- end
-
- def project_link
- "[#{project_name}](#{project_url})"
- end
-
- def compare_link
- "[Compare changes](#{compare_url})"
- end
-
- def compose_action_details
- if new_branch?
- ['pushed new', ref_link, "to #{project_link}"]
- elsif removed_branch?
- ['removed', ref, "from #{project_link}"]
- else
- ['pushed to', ref_link, "of #{project_link} (#{compare_link})"]
- end
- end
-
- def attachment_color
- '#345'
- end
- end
-end
diff --git a/app/models/project_services/chat_message/wiki_page_message.rb b/app/models/project_services/chat_message/wiki_page_message.rb
deleted file mode 100644
index ebe7abb379f..00000000000
--- a/app/models/project_services/chat_message/wiki_page_message.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-module ChatMessage
- class WikiPageMessage < BaseMessage
- attr_reader :title
- attr_reader :wiki_page_url
- attr_reader :action
- attr_reader :description
-
- def initialize(params)
- super
-
- obj_attr = params[:object_attributes]
- obj_attr = HashWithIndifferentAccess.new(obj_attr)
- @title = obj_attr[:title]
- @wiki_page_url = obj_attr[:url]
- @description = obj_attr[:message]
-
- @action =
- case obj_attr[:action]
- when "create"
- "created"
- when "update"
- "edited"
- end
- end
-
- def attachments
- return description if markdown
-
- description_message
- end
-
- def activity
- {
- title: "#{user_combined_name} #{action} #{wiki_page_link}",
- subtitle: "in #{project_link}",
- text: title,
- image: user_avatar
- }
- end
-
- private
-
- def message
- "#{user_combined_name} #{action} #{wiki_page_link} in #{project_link}: *#{title}*"
- end
-
- def description_message
- [{ text: format(@description), color: attachment_color }]
- end
-
- def project_link
- "[#{project_name}](#{project_url})"
- end
-
- def wiki_page_link
- "[wiki page](#{wiki_page_url})"
- end
- end
-end
diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb
index c95a5d4e6cb..2f841bf903e 100644
--- a/app/models/project_services/chat_notification_service.rb
+++ b/app/models/project_services/chat_notification_service.rb
@@ -185,19 +185,19 @@ class ChatNotificationService < Integration
def get_message(object_kind, data)
case object_kind
when "push", "tag_push"
- ChatMessage::PushMessage.new(data) if notify_for_ref?(data)
+ Integrations::ChatMessage::PushMessage.new(data) if notify_for_ref?(data)
when "issue"
- ChatMessage::IssueMessage.new(data) unless update?(data)
+ Integrations::ChatMessage::IssueMessage.new(data) unless update?(data)
when "merge_request"
- ChatMessage::MergeMessage.new(data) unless update?(data)
+ Integrations::ChatMessage::MergeMessage.new(data) unless update?(data)
when "note"
- ChatMessage::NoteMessage.new(data)
+ Integrations::ChatMessage::NoteMessage.new(data)
when "pipeline"
- ChatMessage::PipelineMessage.new(data) if should_pipeline_be_notified?(data)
+ Integrations::ChatMessage::PipelineMessage.new(data) if should_pipeline_be_notified?(data)
when "wiki_page"
- ChatMessage::WikiPageMessage.new(data)
+ Integrations::ChatMessage::WikiPageMessage.new(data)
when "deployment"
- ChatMessage::DeploymentMessage.new(data)
+ Integrations::ChatMessage::DeploymentMessage.new(data)
end
end
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index 7badcc24870..92a46f8d01f 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -39,7 +39,7 @@ class SlackService < ChatNotificationService
end
def get_message(object_kind, data)
- return ChatMessage::AlertMessage.new(data) if object_kind == 'alert'
+ return Integrations::ChatMessage::AlertMessage.new(data) if object_kind == 'alert'
super
end