summaryrefslogtreecommitdiff
path: root/lib/gitlab/email
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 15:44:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 15:44:42 +0000
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /lib/gitlab/email
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
downloadgitlab-ce-4555e1b21c365ed8303ffb7a3325d773c9b8bf31.tar.gz
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'lib/gitlab/email')
-rw-r--r--lib/gitlab/email/handler/create_issue_handler.rb10
-rw-r--r--lib/gitlab/email/handler/create_merge_request_handler.rb4
-rw-r--r--lib/gitlab/email/handler/reply_processing.rb2
-rw-r--r--lib/gitlab/email/handler/service_desk_handler.rb20
-rw-r--r--lib/gitlab/email/message/in_product_marketing.rb19
-rw-r--r--lib/gitlab/email/message/in_product_marketing/base.rb154
-rw-r--r--lib/gitlab/email/message/in_product_marketing/create.rb101
-rw-r--r--lib/gitlab/email/message/in_product_marketing/helper.rb44
-rw-r--r--lib/gitlab/email/message/in_product_marketing/team.rb80
-rw-r--r--lib/gitlab/email/message/in_product_marketing/trial.rb75
-rw-r--r--lib/gitlab/email/message/in_product_marketing/verify.rb93
-rw-r--r--lib/gitlab/email/receiver.rb84
-rw-r--r--lib/gitlab/email/reply_parser.rb2
-rw-r--r--lib/gitlab/email/service_desk_receiver.rb15
14 files changed, 655 insertions, 48 deletions
diff --git a/lib/gitlab/email/handler/create_issue_handler.rb b/lib/gitlab/email/handler/create_issue_handler.rb
index 22fc8addcd9..e927a5641e5 100644
--- a/lib/gitlab/email/handler/create_issue_handler.rb
+++ b/lib/gitlab/email/handler/create_issue_handler.rb
@@ -56,10 +56,12 @@ module Gitlab
def create_issue
Issues::CreateService.new(
- project,
- author,
- title: mail.subject,
- description: message_including_reply
+ project: project,
+ current_user: author,
+ params: {
+ title: mail.subject,
+ description: message_including_reply
+ }
).execute
end
diff --git a/lib/gitlab/email/handler/create_merge_request_handler.rb b/lib/gitlab/email/handler/create_merge_request_handler.rb
index e8071bcafd0..df12aea1988 100644
--- a/lib/gitlab/email/handler/create_merge_request_handler.rb
+++ b/lib/gitlab/email/handler/create_merge_request_handler.rb
@@ -61,7 +61,7 @@ module Gitlab
private
def build_merge_request
- MergeRequests::BuildService.new(project, author, merge_request_params).execute
+ MergeRequests::BuildService.new(project: project, current_user: author, params: merge_request_params).execute
end
def create_merge_request
@@ -78,7 +78,7 @@ module Gitlab
if merge_request.errors.any?
merge_request
else
- MergeRequests::CreateService.new(project, author).create(merge_request)
+ MergeRequests::CreateService.new(project: project, current_user: author).create(merge_request)
end
end
diff --git a/lib/gitlab/email/handler/reply_processing.rb b/lib/gitlab/email/handler/reply_processing.rb
index 9e476dd4e2b..63334169c8e 100644
--- a/lib/gitlab/email/handler/reply_processing.rb
+++ b/lib/gitlab/email/handler/reply_processing.rb
@@ -100,4 +100,4 @@ module Gitlab
end
end
-Gitlab::Email::Handler::ReplyProcessing.prepend_if_ee('::EE::Gitlab::Email::Handler::ReplyProcessing')
+Gitlab::Email::Handler::ReplyProcessing.prepend_mod_with('Gitlab::Email::Handler::ReplyProcessing')
diff --git a/lib/gitlab/email/handler/service_desk_handler.rb b/lib/gitlab/email/handler/service_desk_handler.rb
index 80e8b726099..cab3538a447 100644
--- a/lib/gitlab/email/handler/service_desk_handler.rb
+++ b/lib/gitlab/email/handler/service_desk_handler.rb
@@ -38,7 +38,7 @@ module Gitlab
if from_address
add_email_participant
- send_thank_you_email!
+ send_thank_you_email
end
end
@@ -77,12 +77,14 @@ module Gitlab
def create_issue!
@issue = Issues::CreateService.new(
- project,
- User.support_bot,
- title: mail.subject,
- description: message_including_template,
- confidential: true,
- external_author: from_address
+ project: project,
+ current_user: User.support_bot,
+ params: {
+ title: mail.subject,
+ description: message_including_template,
+ confidential: true,
+ external_author: from_address
+ }
).execute
raise InvalidIssueError unless @issue.persisted?
@@ -92,8 +94,8 @@ module Gitlab
end
end
- def send_thank_you_email!
- Notify.service_desk_thank_you_email(@issue.id).deliver_later!
+ def send_thank_you_email
+ Notify.service_desk_thank_you_email(@issue.id).deliver_later
end
def message_including_template
diff --git a/lib/gitlab/email/message/in_product_marketing.rb b/lib/gitlab/email/message/in_product_marketing.rb
new file mode 100644
index 00000000000..d538238f26f
--- /dev/null
+++ b/lib/gitlab/email/message/in_product_marketing.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module Message
+ module InProductMarketing
+ UnknownTrackError = Class.new(StandardError)
+
+ TRACKS = [:create, :verify, :team, :trial].freeze
+
+ def self.for(track)
+ raise UnknownTrackError unless TRACKS.include?(track)
+
+ "Gitlab::Email::Message::InProductMarketing::#{track.to_s.classify}".constantize
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/message/in_product_marketing/base.rb b/lib/gitlab/email/message/in_product_marketing/base.rb
new file mode 100644
index 00000000000..6341a7c7596
--- /dev/null
+++ b/lib/gitlab/email/message/in_product_marketing/base.rb
@@ -0,0 +1,154 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module Message
+ module InProductMarketing
+ class Base
+ include Gitlab::Email::Message::InProductMarketing::Helper
+ include Gitlab::Routing
+
+ attr_accessor :format
+
+ def initialize(group:, series:, format: :html)
+ raise ArgumentError, "Only #{total_series} series available for this track." unless series.between?(0, total_series - 1)
+
+ @group = group
+ @series = series
+ @format = format
+ end
+
+ def subject_line
+ raise NotImplementedError
+ end
+
+ def tagline
+ raise NotImplementedError
+ end
+
+ def title
+ raise NotImplementedError
+ end
+
+ def subtitle
+ raise NotImplementedError
+ end
+
+ def body_line1
+ raise NotImplementedError
+ end
+
+ def body_line2
+ raise NotImplementedError
+ end
+
+ def cta_text
+ raise NotImplementedError
+ end
+
+ def cta_link
+ case format
+ when :html
+ link_to cta_text, group_email_campaigns_url(group, track: track, series: series), target: '_blank', rel: 'noopener noreferrer'
+ else
+ [cta_text, group_email_campaigns_url(group, track: track, series: series)].join(' >> ')
+ end
+ end
+
+ def unsubscribe
+ parts = Gitlab.com? ? unsubscribe_com : unsubscribe_self_managed(track, series)
+
+ case format
+ when :html
+ parts.join(' ')
+ else
+ parts.join("\n" + ' ' * 16)
+ end
+ end
+
+ def progress
+ if Gitlab.com?
+ s_('InProductMarketing|This is email %{current_series} of %{total_series} in the %{track} series.') % { current_series: series + 1, total_series: total_series, track: track.to_s.humanize }
+ else
+ s_('InProductMarketing|This is email %{current_series} of %{total_series} in the %{track} series. To disable notification emails sent by your local GitLab instance, either contact your administrator or %{unsubscribe_link}.') % { current_series: series + 1, total_series: total_series, track: track.to_s.humanize, unsubscribe_link: unsubscribe_link }
+ end
+ end
+
+ def address
+ s_('InProductMarketing|%{strong_start}GitLab Inc.%{strong_end} 268 Bush Street, #350, San Francisco, CA 94104, USA').html_safe % strong_options
+ end
+
+ def footer_links
+ links = [
+ [s_('InProductMarketing|Blog'), 'https://about.gitlab.com/blog'],
+ [s_('InProductMarketing|Twitter'), 'https://twitter.com/gitlab'],
+ [s_('InProductMarketing|Facebook'), 'https://www.facebook.com/gitlab'],
+ [s_('InProductMarketing|YouTube'), 'https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg']
+ ]
+ case format
+ when :html
+ links.map do |text, link|
+ link_to(text, link)
+ end
+ else
+ '| ' + links.map do |text, link|
+ [text, link].join(' ')
+ end.join("\n| ")
+ end
+ end
+
+ def logo_path
+ ["mailers/in_product_marketing", "#{track}-#{series}.png"].join('/')
+ end
+
+ protected
+
+ attr_reader :group, :series
+
+ def total_series
+ 3
+ end
+
+ private
+
+ def track
+ self.class.name.demodulize.downcase.to_sym
+ end
+
+ def unsubscribe_com
+ [
+ s_('InProductMarketing|If you no longer wish to receive marketing emails from us,'),
+ s_('InProductMarketing|you may %{unsubscribe_link} at any time.') % { unsubscribe_link: unsubscribe_link }
+ ]
+ end
+
+ def unsubscribe_self_managed(track, series)
+ [
+ s_('InProductMarketing|To opt out of these onboarding emails, %{unsubscribe_link}.') % { unsubscribe_link: unsubscribe_link },
+ s_("InProductMarketing|If you don't want to receive marketing emails directly from GitLab, %{marketing_preference_link}.") % { marketing_preference_link: marketing_preference_link(track, series) }
+ ]
+ end
+
+ def unsubscribe_link
+ unsubscribe_url = Gitlab.com? ? '%tag_unsubscribe_url%' : profile_notifications_url
+
+ link(s_('InProductMarketing|unsubscribe'), unsubscribe_url)
+ end
+
+ def marketing_preference_link(track, series)
+ params = {
+ utm_source: 'SM',
+ utm_medium: 'email',
+ utm_campaign: 'onboarding',
+ utm_term: "#{track}_#{series}"
+ }
+
+ preference_link = "https://about.gitlab.com/company/preference-center/?#{params.to_query}"
+
+ link(s_('InProductMarketing|update your preferences'), preference_link)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/message/in_product_marketing/create.rb b/lib/gitlab/email/message/in_product_marketing/create.rb
new file mode 100644
index 00000000000..5d3cac0a121
--- /dev/null
+++ b/lib/gitlab/email/message/in_product_marketing/create.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module Message
+ module InProductMarketing
+ class Create < Base
+ def subject_line
+ [
+ s_('InProductMarketing|Create a project in GitLab in 5 minutes'),
+ s_('InProductMarketing|Import your project and code from GitHub, Bitbucket and others'),
+ s_('InProductMarketing|Understand repository mirroring')
+ ][series]
+ end
+
+ def tagline
+ [
+ s_('InProductMarketing|Get started today'),
+ s_('InProductMarketing|Get our import guides'),
+ s_('InProductMarketing|Need an alternative to importing?')
+ ][series]
+ end
+
+ def title
+ [
+ s_('InProductMarketing|Take your first steps with GitLab'),
+ s_('InProductMarketing|Start by importing your projects'),
+ s_('InProductMarketing|How (and why) mirroring makes sense')
+ ][series]
+ end
+
+ def subtitle
+ [
+ s_('InProductMarketing|Dig in and create a project and a repo'),
+ s_("InProductMarketing|Here's what you need to know"),
+ s_('InProductMarketing|Try it out')
+ ][series]
+ end
+
+ def body_line1
+ [
+ s_("InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}.") % { project_link: project_link, repo_link: repo_link },
+ s_("InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}.") % { github_link: github_link, bitbucket_link: bitbucket_link },
+ s_("InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool.") % { mirroring_link: mirroring_link }
+ ][series]
+ end
+
+ def body_line2
+ [
+ s_("InProductMarketing|That's all it takes to get going with GitLab, but if you're new to working with Git, check out our %{basics_link} for helpful tips and tricks for getting started.") % { basics_link: basics_link },
+ s_("InProductMarketing|Have a different instance you'd like to import? Here's our %{import_link}.") % { import_link: import_link },
+ s_("InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD.") % { external_repo_link: external_repo_link }
+ ][series]
+ end
+
+ def cta_text
+ [
+ s_('InProductMarketing|Create your first project!'),
+ s_('InProductMarketing|Master the art of importing!'),
+ s_('InProductMarketing|Understand your project options')
+ ][series]
+ end
+
+ private
+
+ def project_link
+ link(s_('InProductMarketing|create a project'), help_page_url('gitlab-basics/create-project'))
+ end
+
+ def repo_link
+ link(s_('InProductMarketing|set up a repo'), help_page_url('user/project/repository/index', anchor: 'create-a-repository'))
+ end
+
+ def github_link
+ link(s_('InProductMarketing|GitHub Enterprise projects to GitLab'), help_page_url('integration/github'))
+ end
+
+ def bitbucket_link
+ link(s_('InProductMarketing|from Bitbucket'), help_page_url('user/project/import/bitbucket_server'))
+ end
+
+ def mirroring_link
+ link(s_('InProductMarketing|repository mirroring'), help_page_url('user/project/repository/repository_mirroring'))
+ end
+
+ def basics_link
+ link(s_('InProductMarketing|Git basics'), help_page_url('gitlab-basics/README'))
+ end
+
+ def import_link
+ link(s_('InProductMarketing|comprehensive guide'), help_page_url('user/project/import/index'))
+ end
+
+ def external_repo_link
+ link(s_('InProductMarketing|connect an external repository'), new_project_url(anchor: 'cicd_for_external_repo'))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/message/in_product_marketing/helper.rb b/lib/gitlab/email/message/in_product_marketing/helper.rb
new file mode 100644
index 00000000000..4780e08322a
--- /dev/null
+++ b/lib/gitlab/email/message/in_product_marketing/helper.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module Message
+ module InProductMarketing
+ module Helper
+ include ActionView::Context
+ include ActionView::Helpers::TagHelper
+ include ActionView::Helpers::UrlHelper
+
+ private
+
+ def list(array)
+ case format
+ when :html
+ tag.ul { array.map { |item| tag.li item} }
+ else
+ '- ' + array.join("\n- ")
+ end
+ end
+
+ def strong_options
+ case format
+ when :html
+ { strong_start: '<b>'.html_safe, strong_end: '</b>'.html_safe }
+ else
+ { strong_start: '', strong_end: '' }
+ end
+ end
+
+ def link(text, link)
+ case format
+ when :html
+ link_to text, link
+ else
+ "#{text} (#{link})"
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/message/in_product_marketing/team.rb b/lib/gitlab/email/message/in_product_marketing/team.rb
new file mode 100644
index 00000000000..46c2797e534
--- /dev/null
+++ b/lib/gitlab/email/message/in_product_marketing/team.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module Message
+ module InProductMarketing
+ class Team < Base
+ def subject_line
+ [
+ s_('InProductMarketing|Working in GitLab = more efficient'),
+ s_("InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"),
+ s_('InProductMarketing|Your teams can be more efficient')
+ ][series]
+ end
+
+ def tagline
+ [
+ s_('InProductMarketing|Invite your colleagues to join in less than one minute'),
+ s_('InProductMarketing|Get your team set up on GitLab'),
+ nil
+ ][series]
+ end
+
+ def title
+ [
+ s_('InProductMarketing|Team work makes the dream work'),
+ s_('InProductMarketing|*GitLab*, noun: a synonym for efficient teams'),
+ s_('InProductMarketing|Find out how your teams are really doing')
+ ][series]
+ end
+
+ def subtitle
+ [
+ s_('InProductMarketing|Actually, GitLab makes the team work (better)'),
+ s_('InProductMarketing|Our tool brings all the things together'),
+ s_("InProductMarketing|It's all in the stats")
+ ][series]
+ end
+
+ def body_line1
+ [
+ [
+ s_('InProductMarketing|Did you know teams that use GitLab are far more efficient?'),
+ list([
+ s_('InProductMarketing|Goldman Sachs went from 1 build every two weeks to thousands of builds a day'),
+ s_('InProductMarketing|Ticketmaster decreased their CI build time by 15X')
+ ])
+ ].join("\n"),
+ s_("InProductMarketing|We know a thing or two about efficiency and we don't want to keep that to ourselves. Sign up for a free trial of GitLab Ultimate and your teams will be on it from day one."),
+ [
+ s_('InProductMarketing|Stop wondering and use GitLab to answer questions like:'),
+ list([
+ s_('InProductMarketing|How long does it take us to close issues/MRs by types like feature requests, bugs, tech debt, security?'),
+ s_('InProductMarketing|How many days does it take our team to complete various tasks?'),
+ s_('InProductMarketing|What does our value stream timeline look like from product to development to review and production?')
+ ])
+ ].join("\n")
+ ][series]
+ end
+
+ def body_line2
+ [
+ s_('InProductMarketing|Invite your colleagues and start shipping code faster.'),
+ s_("InProductMarketing|Streamline code review, know at a glance who's unavailable, communicate in comments or in email and integrate with Slack so everyone's on the same page."),
+ s_('InProductMarketing|When your team is on GitLab these answers are a click away.')
+ ][series]
+ end
+
+ def cta_text
+ [
+ s_('InProductMarketing|Invite your colleagues today'),
+ s_('InProductMarketing|Invite your team in less than 60 seconds'),
+ s_('InProductMarketing|Invite your team now')
+ ][series]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/message/in_product_marketing/trial.rb b/lib/gitlab/email/message/in_product_marketing/trial.rb
new file mode 100644
index 00000000000..d87dc5c1b81
--- /dev/null
+++ b/lib/gitlab/email/message/in_product_marketing/trial.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module Message
+ module InProductMarketing
+ class Trial < Base
+ def subject_line
+ [
+ s_('InProductMarketing|Go farther with GitLab'),
+ s_('InProductMarketing|Automated security scans directly within GitLab'),
+ s_('InProductMarketing|Take your source code management to the next level')
+ ][series]
+ end
+
+ def tagline
+ [
+ s_('InProductMarketing|Start a free trial of GitLab Ultimate – no CC required'),
+ s_('InProductMarketing|Improve app security with a 30-day trial'),
+ s_('InProductMarketing|Start with a GitLab Ultimate free trial')
+ ][series]
+ end
+
+ def title
+ [
+ s_('InProductMarketing|Give us one minute...'),
+ s_("InProductMarketing|Security that's integrated into your development lifecycle"),
+ s_('InProductMarketing|Improve code quality and streamline reviews')
+ ][series]
+ end
+
+ def subtitle
+ [
+ s_('InProductMarketing|...and you can get a free trial of GitLab Ultimate'),
+ s_('InProductMarketing|Try GitLab Ultimate for free'),
+ s_('InProductMarketing|Better code in less time')
+ ][series]
+ end
+
+ def body_line1
+ [
+ [
+ s_("InProductMarketing|GitLab's premium tiers are designed to make you, your team and your application more efficient and more secure with features including but not limited to:"),
+ list([
+ s_('InProductMarketing|%{strong_start}Company wide portfolio management%{strong_end} — including multi-level epics, scoped labels').html_safe % strong_options,
+ s_('InProductMarketing|%{strong_start}Multiple approval roles%{strong_end} — including code owners and required merge approvals').html_safe % strong_options,
+ s_('InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection').html_safe % strong_options,
+ s_('InProductMarketing|%{strong_start}Executive level insights%{strong_end} — including reporting on productivity, tasks by type, days to completion, value stream').html_safe % strong_options
+ ])
+ ].join("\n"),
+ s_('InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance.'),
+ s_('InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process.')
+ ][series]
+ end
+
+ def body_line2
+ [
+ s_('InProductMarketing|Start a GitLab Ultimate trial today in less than one minute, no credit card required.'),
+ s_('InProductMarketing|Get started today with a 30-day GitLab Ultimate trial, no credit card required.'),
+ s_('InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required.')
+ ][series]
+ end
+
+ def cta_text
+ [
+ s_('InProductMarketing|Start a trial'),
+ s_('InProductMarketing|Beef up your security'),
+ s_('InProductMarketing|Start your trial now!')
+ ][series]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/message/in_product_marketing/verify.rb b/lib/gitlab/email/message/in_product_marketing/verify.rb
new file mode 100644
index 00000000000..d563de6c77e
--- /dev/null
+++ b/lib/gitlab/email/message/in_product_marketing/verify.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ module Message
+ module InProductMarketing
+ class Verify < Base
+ def subject_line
+ [
+ s_('InProductMarketing|Feel the need for speed?'),
+ s_('InProductMarketing|3 ways to dive into GitLab CI/CD'),
+ s_('InProductMarketing|Explore the power of GitLab CI/CD')
+ ][series]
+ end
+
+ def tagline
+ [
+ s_('InProductMarketing|Use GitLab CI/CD'),
+ s_('InProductMarketing|Test, create, deploy'),
+ s_('InProductMarketing|Are your runners ready?')
+ ][series]
+ end
+
+ def title
+ [
+ s_('InProductMarketing|Rapid development, simplified'),
+ s_('InProductMarketing|Get started with GitLab CI/CD'),
+ s_('InProductMarketing|Launch GitLab CI/CD in 20 minutes or less')
+ ][series]
+ end
+
+ def subtitle
+ [
+ s_('InProductMarketing|How to build and test faster'),
+ s_('InProductMarketing|Explore the options'),
+ s_('InProductMarketing|Follow our steps')
+ ][series]
+ end
+
+ def body_line1
+ [
+ s_("InProductMarketing|Tired of wrestling with disparate tool chains, information silos and inefficient processes? GitLab's CI/CD is built on a DevOps platform with source code management, planning, monitoring and more ready to go. Find out %{ci_link}.") % { ci_link: ci_link },
+ s_("InProductMarketing|GitLab's CI/CD makes software development easier. Don't believe us? Here are three ways you can take it for a fast (and satisfying) test drive:"),
+ s_("InProductMarketing|Get going with CI/CD quickly using our %{quick_start_link}. Start with an available runner and then create a CI .yml file – it's really that easy.") % { quick_start_link: quick_start_link }
+ ][series]
+ end
+
+ def body_line2
+ [
+ nil,
+ list([
+ s_('InProductMarketing|Start by %{performance_link}').html_safe % { performance_link: performance_link },
+ s_('InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}').html_safe % { ci_template_link: ci_template_link },
+ s_('InProductMarketing|And finally %{deploy_link} a Python application.').html_safe % { deploy_link: deploy_link }
+ ]),
+ nil
+ ][series]
+ end
+
+ def cta_text
+ [
+ s_('InProductMarketing|Get to know GitLab CI/CD'),
+ s_('InProductMarketing|Try it yourself'),
+ s_('InProductMarketing|Explore GitLab CI/CD')
+ ][series]
+ end
+
+ private
+
+ def ci_link
+ link(s_('InProductMarketing|how easy it is to get started'), help_page_url('ci/README'))
+ end
+
+ def quick_start_link
+ link(s_('InProductMarketing|quick start guide'), help_page_url('ci/quick_start/README'))
+ end
+
+ def performance_link
+ link(s_('InProductMarketing|testing browser performance'), help_page_url('user/project/merge_requests/browser_performance_testing'))
+ end
+
+ def ci_template_link
+ link(s_('InProductMarketing|using a CI/CD template'), help_page_url('user/project/pages/getting_started/pages_ci_cd_template'))
+ end
+
+ def deploy_link
+ link(s_('InProductMarketing|test and deploy'), help_page_url('ci/examples/test-and-deploy-python-application-to-heroku'))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb
index f5e47b43a9a..71db8ab6067 100644
--- a/lib/gitlab/email/receiver.rb
+++ b/lib/gitlab/email/receiver.rb
@@ -6,6 +6,8 @@ require_dependency 'gitlab/email/handler'
module Gitlab
module Email
class Receiver
+ include Gitlab::Utils::StrongMemoize
+
def initialize(raw)
@raw = raw
end
@@ -13,11 +15,7 @@ module Gitlab
def execute
raise EmptyEmailError if @raw.blank?
- mail = build_mail
-
- ignore_auto_reply!(mail)
-
- handler = find_handler(mail)
+ ignore_auto_reply!
raise UnknownIncomingEmail unless handler
@@ -26,13 +24,33 @@ module Gitlab
end
end
+ def mail_metadata
+ {
+ mail_uid: mail.message_id,
+ from_address: mail.from,
+ to_address: mail.to,
+ mail_key: mail_key,
+ references: Array(mail.references),
+ delivered_to: delivered_to.map(&:value),
+ envelope_to: envelope_to.map(&:value),
+ x_envelope_to: x_envelope_to.map(&:value)
+ }
+ end
+
private
- def find_handler(mail)
- mail_key = extract_mail_key(mail)
+ def handler
+ strong_memoize(:handler) { find_handler }
+ end
+
+ def find_handler
Handler.for(mail, mail_key)
end
+ def mail
+ strong_memoize(:mail) { build_mail }
+ end
+
def build_mail
Mail::Message.new(@raw)
rescue Encoding::UndefinedConversionError,
@@ -40,22 +58,24 @@ module Gitlab
raise EmailUnparsableError, e
end
- def extract_mail_key(mail)
- key_from_to_header(mail) || key_from_additional_headers(mail)
+ def mail_key
+ strong_memoize(:mail_key) do
+ key_from_to_header || key_from_additional_headers
+ end
end
- def key_from_to_header(mail)
+ def key_from_to_header
mail.to.find do |address|
key = Gitlab::IncomingEmail.key_from_address(address)
break key if key
end
end
- def key_from_additional_headers(mail)
- find_key_from_references(mail) ||
- find_key_from_delivered_to_header(mail) ||
- find_key_from_envelope_to_header(mail) ||
- find_key_from_x_envelope_to_header(mail)
+ def key_from_additional_headers
+ find_key_from_references ||
+ find_key_from_delivered_to_header ||
+ find_key_from_envelope_to_header ||
+ find_key_from_x_envelope_to_header
end
def ensure_references_array(references)
@@ -71,41 +91,53 @@ module Gitlab
end
end
- def find_key_from_references(mail)
+ def find_key_from_references
ensure_references_array(mail.references).find do |mail_id|
key = Gitlab::IncomingEmail.key_from_fallback_message_id(mail_id)
break key if key
end
end
- def find_key_from_delivered_to_header(mail)
- Array(mail[:delivered_to]).find do |header|
+ def delivered_to
+ Array(mail[:delivered_to])
+ end
+
+ def envelope_to
+ Array(mail[:envelope_to])
+ end
+
+ def x_envelope_to
+ Array(mail[:x_envelope_to])
+ end
+
+ def find_key_from_delivered_to_header
+ delivered_to.find do |header|
key = Gitlab::IncomingEmail.key_from_address(header.value)
break key if key
end
end
- def find_key_from_envelope_to_header(mail)
- Array(mail[:envelope_to]).find do |header|
+ def find_key_from_envelope_to_header
+ envelope_to.find do |header|
key = Gitlab::IncomingEmail.key_from_address(header.value)
break key if key
end
end
- def find_key_from_x_envelope_to_header(mail)
- Array(mail[:x_envelope_to]).find do |header|
+ def find_key_from_x_envelope_to_header
+ x_envelope_to.find do |header|
key = Gitlab::IncomingEmail.key_from_address(header.value)
break key if key
end
end
- def ignore_auto_reply!(mail)
- if auto_submitted?(mail) || auto_replied?(mail)
+ def ignore_auto_reply!
+ if auto_submitted? || auto_replied?
raise AutoGeneratedEmailError
end
end
- def auto_submitted?(mail)
+ def auto_submitted?
# Mail::Header#[] is case-insensitive
auto_submitted = mail.header['Auto-Submitted']&.value
@@ -114,7 +146,7 @@ module Gitlab
auto_submitted && auto_submitted != 'no'
end
- def auto_replied?(mail)
+ def auto_replied?
autoreply = mail.header['X-Autoreply']&.value
autoreply && autoreply == 'yes'
diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb
index dc44e9d7481..7579f3d8680 100644
--- a/lib/gitlab/email/reply_parser.rb
+++ b/lib/gitlab/email/reply_parser.rb
@@ -68,7 +68,7 @@ module Gitlab
else
object.body.to_s
end
- rescue
+ rescue StandardError
nil
end
end
diff --git a/lib/gitlab/email/service_desk_receiver.rb b/lib/gitlab/email/service_desk_receiver.rb
index 1ee5c10097b..133c4ee4b45 100644
--- a/lib/gitlab/email/service_desk_receiver.rb
+++ b/lib/gitlab/email/service_desk_receiver.rb
@@ -5,14 +5,19 @@ module Gitlab
class ServiceDeskReceiver < Receiver
private
- def find_handler(mail)
- key = service_desk_key(mail)
- return unless key
+ def find_handler
+ return unless service_desk_key
- Gitlab::Email::Handler::ServiceDeskHandler.new(mail, nil, service_desk_key: key)
+ Gitlab::Email::Handler::ServiceDeskHandler.new(mail, nil, service_desk_key: service_desk_key)
end
- def service_desk_key(mail)
+ def service_desk_key
+ strong_memoize(:service_desk_key) do
+ find_service_desk_key
+ end
+ end
+
+ def find_service_desk_key
mail.to.find do |address|
key = ::Gitlab::ServiceDeskEmail.key_from_address(address)
break key if key