Commit 74a6b4b6 authored by Robert Speicher's avatar Robert Speicher Committed by Robert Speicher

Merge branch 'add_email_headers' into 'master'

Added X-GitLab-... headers to emails from CI and Email On Push services

Fixes #2098

This adds the 'X-GitLab-Project', 'X-GitLab-Project-Id' and
'X-GitLab-Project-Path' headers to emails from CI and Email On Push in a way
that it is done currently for merge requests and issues emails.

Additionally, CI emails will have 'X-GitLab-Build-Status' header with either
'fail' or 'success'.

Emails from Email On Push will include 'X-Gitlab-Author' header containing the
username of user who did the push.

See merge request !2159
parent 91af0864
...@@ -67,6 +67,7 @@ v 8.4.0 (unreleased) ...@@ -67,6 +67,7 @@ v 8.4.0 (unreleased)
- Increase default size of `data` column in `events` table when using MySQL - Increase default size of `data` column in `events` table when using MySQL
- Expose button to CI Lint tool on project builds page - Expose button to CI Lint tool on project builds page
- Fix: Creator should be added as a master of the project on creation - Fix: Creator should be added as a master of the project on creation
- Added X-GitLab-... headers to emails from CI and Email On Push services
v 8.3.4 v 8.3.4
- Use gitlab-workhorse 0.5.4 (fixes API routing bug) - Use gitlab-workhorse 0.5.4 (fixes API routing bug)
......
...@@ -3,13 +3,26 @@ module Emails ...@@ -3,13 +3,26 @@ module Emails
def build_fail_email(build_id, to) def build_fail_email(build_id, to)
@build = Ci::Build.find(build_id) @build = Ci::Build.find(build_id)
@project = @build.project @project = @build.project
add_project_headers
add_build_headers
headers['X-GitLab-Build-Status'] = "failed"
mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha)) mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha))
end end
def build_success_email(build_id, to) def build_success_email(build_id, to)
@build = Ci::Build.find(build_id) @build = Ci::Build.find(build_id)
@project = @build.project @project = @build.project
add_project_headers
add_build_headers
headers['X-GitLab-Build-Status'] = "success"
mail(to: to, subject: subject("Build success for #{@project.name}", @build.short_sha)) mail(to: to, subject: subject("Build success for #{@project.name}", @build.short_sha))
end end
private
def add_build_headers
headers['X-GitLab-Build-Id'] = @build.id
headers['X-GitLab-Build-Ref'] = @build.ref
end
end end
end end
...@@ -65,6 +65,10 @@ module Emails ...@@ -65,6 +65,10 @@ module Emails
# used in notify layout # used in notify layout
@target_url = @message.target_url @target_url = @message.target_url
@project = Project.find project_id
add_project_headers
headers['X-GitLab-Author'] = @message.author_username
mail(from: sender(@message.author_id, @message.send_from_committer_email?), mail(from: sender(@message.author_id, @message.send_from_committer_email?),
reply_to: @message.reply_to, reply_to: @message.reply_to,
......
...@@ -100,12 +100,7 @@ class Notify < BaseMailer ...@@ -100,12 +100,7 @@ class Notify < BaseMailer
end end
def mail_thread(model, headers = {}) def mail_thread(model, headers = {})
if @project add_project_headers
headers['X-GitLab-Project'] = @project.name
headers['X-GitLab-Project-Id'] = @project.id
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
end
headers["X-GitLab-#{model.class.name}-ID"] = model.id headers["X-GitLab-#{model.class.name}-ID"] = model.id
headers['X-GitLab-Reply-Key'] = reply_key headers['X-GitLab-Reply-Key'] = reply_key
...@@ -152,4 +147,12 @@ class Notify < BaseMailer ...@@ -152,4 +147,12 @@ class Notify < BaseMailer
def reply_key def reply_key
@reply_key ||= SentNotification.reply_key @reply_key ||= SentNotification.reply_key
end end
def add_project_headers
return unless @project
headers['X-GitLab-Project'] = @project.name
headers['X-GitLab-Project-Id'] = @project.id
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
end
end end
...@@ -9,6 +9,7 @@ module Gitlab ...@@ -9,6 +9,7 @@ module Gitlab
delegate :namespace, :name_with_namespace, to: :project, prefix: :project delegate :namespace, :name_with_namespace, to: :project, prefix: :project
delegate :name, to: :author, prefix: :author delegate :name, to: :author, prefix: :author
delegate :username, to: :author, prefix: :author
def initialize(notify, project_id, recipient, opts = {}) def initialize(notify, project_id, recipient, opts = {})
raise ArgumentError, 'Missing options: author_id, ref, action' unless raise ArgumentError, 'Missing options: author_id, ref, action' unless
......
...@@ -40,14 +40,38 @@ describe Notify do ...@@ -40,14 +40,38 @@ describe Notify do
end end
end end
shared_examples 'an email with X-GitLab headers containing project details' do
it 'has X-GitLab-Project* headers' do
is_expected.to have_header 'X-GitLab-Project', /#{project.name}/
is_expected.to have_header 'X-GitLab-Project-Id', /#{project.id}/
is_expected.to have_header 'X-GitLab-Project-Path', /#{project.path_with_namespace}/
end
end
shared_examples 'an email with X-GitLab headers containing build details' do
it 'has X-GitLab-Build* headers' do
is_expected.to have_header 'X-GitLab-Build-Id', /#{build.id}/
is_expected.to have_header 'X-GitLab-Build-Ref', /#{build.ref}/
end
end
shared_examples 'an email that contains a header with author username' do
it 'has X-GitLab-Author header containing author\'s username' do
is_expected.to have_header 'X-GitLab-Author', user.username
end
end
shared_examples 'an email starting a new thread' do |message_id_prefix| shared_examples 'an email starting a new thread' do |message_id_prefix|
include_examples 'an email with X-GitLab headers containing project details'
it 'has a discussion identifier' do it 'has a discussion identifier' do
is_expected.to have_header 'Message-ID', /<#{message_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/ is_expected.to have_header 'Message-ID', /<#{message_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'X-GitLab-Project', /#{project.name}/
end end
end end
shared_examples 'an answer to an existing thread' do |thread_id_prefix| shared_examples 'an answer to an existing thread' do |thread_id_prefix|
include_examples 'an email with X-GitLab headers containing project details'
it 'has a subject that begins with Re: ' do it 'has a subject that begins with Re: ' do
is_expected.to have_subject /^Re: / is_expected.to have_subject /^Re: /
end end
...@@ -56,7 +80,6 @@ describe Notify do ...@@ -56,7 +80,6 @@ describe Notify do
is_expected.to have_header 'Message-ID', /<(.*)@#{Gitlab.config.gitlab.host}>/ is_expected.to have_header 'Message-ID', /<(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'References', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/ is_expected.to have_header 'References', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'In-Reply-To', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/ is_expected.to have_header 'In-Reply-To', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'X-GitLab-Project', /#{project.name}/
end end
end end
...@@ -656,6 +679,8 @@ describe Notify do ...@@ -656,6 +679,8 @@ describe Notify do
it_behaves_like 'it should not have Gmail Actions links' it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
it 'is sent as the author' do it 'is sent as the author' do
sender = subject.header[:from].addrs[0] sender = subject.header[:from].addrs[0]
...@@ -685,6 +710,8 @@ describe Notify do ...@@ -685,6 +710,8 @@ describe Notify do
it_behaves_like 'it should not have Gmail Actions links' it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
it 'is sent as the author' do it 'is sent as the author' do
sender = subject.header[:from].addrs[0] sender = subject.header[:from].addrs[0]
...@@ -713,6 +740,8 @@ describe Notify do ...@@ -713,6 +740,8 @@ describe Notify do
it_behaves_like 'it should not have Gmail Actions links' it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
it 'is sent as the author' do it 'is sent as the author' do
sender = subject.header[:from].addrs[0] sender = subject.header[:from].addrs[0]
...@@ -737,6 +766,8 @@ describe Notify do ...@@ -737,6 +766,8 @@ describe Notify do
it_behaves_like 'it should not have Gmail Actions links' it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
it 'is sent as the author' do it 'is sent as the author' do
sender = subject.header[:from].addrs[0] sender = subject.header[:from].addrs[0]
...@@ -765,6 +796,8 @@ describe Notify do ...@@ -765,6 +796,8 @@ describe Notify do
it_behaves_like 'it should not have Gmail Actions links' it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
it 'is sent as the author' do it 'is sent as the author' do
sender = subject.header[:from].addrs[0] sender = subject.header[:from].addrs[0]
...@@ -871,6 +904,8 @@ describe Notify do ...@@ -871,6 +904,8 @@ describe Notify do
it_behaves_like 'it should show Gmail Actions View Commit link' it_behaves_like 'it should show Gmail Actions View Commit link'
it_behaves_like "a user cannot unsubscribe through footer link" it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'an email with X-GitLab headers containing project details'
it_behaves_like 'an email that contains a header with author username'
it 'is sent as the author' do it 'is sent as the author' do
sender = subject.header[:from].addrs[0] sender = subject.header[:from].addrs[0]
...@@ -904,6 +939,15 @@ describe Notify do ...@@ -904,6 +939,15 @@ describe Notify do
subject { Notify.build_success_email(build.id, 'wow@example.com') } subject { Notify.build_success_email(build.id, 'wow@example.com') }
it_behaves_like 'an email with X-GitLab headers containing build details'
it_behaves_like 'an email with X-GitLab headers containing project details' do
let(:project) { build.project }
end
it 'has header indicating build status' do
is_expected.to have_header 'X-GitLab-Build-Status', 'success'
end
it 'has the correct subject' do it 'has the correct subject' do
should have_subject /Build success for/ should have_subject /Build success for/
end end
...@@ -918,6 +962,15 @@ describe Notify do ...@@ -918,6 +962,15 @@ describe Notify do
subject { Notify.build_fail_email(build.id, 'wow@example.com') } subject { Notify.build_fail_email(build.id, 'wow@example.com') }
it_behaves_like 'an email with X-GitLab headers containing build details'
it_behaves_like 'an email with X-GitLab headers containing project details' do
let(:project) { build.project }
end
it 'has header indicating build status' do
is_expected.to have_header 'X-GitLab-Build-Status', 'failed'
end
it 'has the correct subject' do it 'has the correct subject' do
should have_subject /Build failed for/ should have_subject /Build failed for/
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment