Commit afd747d4 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'feature/email_on_push_service' of /home/git/repositories/gitlab/gitlabhq

parents 26c8b316 6ac73f45
...@@ -13,5 +13,15 @@ module Emails ...@@ -13,5 +13,15 @@ module Emails
mail(to: @user.email, mail(to: @user.email,
subject: subject("Project was moved")) subject: subject("Project was moved"))
end end
def repository_push_email(project_id, recipient, author_id, branch, compare)
@project = Project.find(project_id)
@author = User.find(author_id)
@commits = Commit.decorate(compare.commits)
@diffs = compare.diffs
@branch = branch
mail(to: recipient, subject: subject("New push to repository"))
end
end end
end end
...@@ -48,6 +48,7 @@ class Project < ActiveRecord::Base ...@@ -48,6 +48,7 @@ class Project < ActiveRecord::Base
has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id' has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id'
has_one :gitlab_ci_service, dependent: :destroy has_one :gitlab_ci_service, dependent: :destroy
has_one :campfire_service, dependent: :destroy has_one :campfire_service, dependent: :destroy
has_one :emails_on_push_service, dependent: :destroy
has_one :pivotaltracker_service, dependent: :destroy has_one :pivotaltracker_service, dependent: :destroy
has_one :hipchat_service, dependent: :destroy has_one :hipchat_service, dependent: :destroy
has_one :flowdock_service, dependent: :destroy has_one :flowdock_service, dependent: :destroy
...@@ -237,7 +238,7 @@ class Project < ActiveRecord::Base ...@@ -237,7 +238,7 @@ class Project < ActiveRecord::Base
end end
def available_services_names def available_services_names
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla) %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push)
end end
def gitlab_ci? def gitlab_ci?
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# token :string(255)
# project_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# active :boolean default(FALSE), not null
# project_url :string(255)
# subdomain :string(255)
# room :string(255)
#
class EmailsOnPushService < Service
attr_accessible :recipients
validates :recipients, presence: true, if: :activated?
def title
'Emails on push'
end
def description
'Email the commits and diff of each push to a list of recipients.'
end
def to_param
'emails_on_push'
end
def execute(push_data)
EmailsOnPushWorker.perform_async(project_id, recipients, push_data)
end
def fields
[
{ type: 'textarea', name: 'recipients', placeholder: 'Emails separated by whitespace' },
]
end
end
%h3 #{@author.name} pushed to #{@branch} at #{@project.name_with_namespace}
%h4 Commits:
%ul
- @commits.each do |commit|
%li
#{commit.short_id} - #{commit.title}
%h4 Diff:
- @diffs.each do |diff|
%li
%strong
- if diff.old_path == diff.new_path
= diff.new_path
- elsif diff.new_path && diff.old_path
#{diff.old_path} &rarr; #{diff.new_path}
- else
= diff.new_path || diff.old_path
%hr
%pre
= diff.diff
%br
#{@author.name} pushed to #{@branch} at #{@project.name_with_namespace}
\
Commits:
- @commits.each do |commit|
#{commit.short_id} - #{truncate(commit.title, length: 40)}
\
\
Diff:
- @diffs.each do |diff|
\
\=====================================
- if diff.old_path == diff.new_path
= diff.new_path
- elsif diff.new_path && diff.old_path
#{diff.old_path} &rarr; #{diff.new_path}
- else
= diff.new_path || diff.old_path
\=====================================
= diff.diff
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
.controls .controls
- if type == 'text' - if type == 'text'
= f.text_field name, class: "input-xlarge", placeholder: placeholder = f.text_field name, class: "input-xlarge", placeholder: placeholder
- elsif type == 'textarea'
= f.text_area name, rows: 5, class: "input-xxlarge", placeholder: placeholder
- elsif type == 'checkbox' - elsif type == 'checkbox'
= f.check_box name = f.check_box name
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
%hr %hr
%ul.bordered-list %ul.bordered-list
- @services.each do |service| - @services.sort_by(&:title).each do |service|
%li %li
%h4 %h4
= link_to edit_project_service_path(@project, service.to_param) do = link_to edit_project_service_path(@project, service.to_param) do
......
class EmailsOnPushWorker
include Sidekiq::Worker
def perform(project_id, recipients, push_data)
project = Project.find(project_id)
before_sha = push_data["before"]
after_sha = push_data["after"]
branch = push_data["ref"]
author_id = push_data["user_id"]
if before_sha =~ /^000000/ || after_sha =~ /^000000/
# skip if new branch was pushed or branch was removed
return true
end
compare = Gitlab::Git::Compare.new(project.repository.raw_repository, before_sha, after_sha)
# Do not send emails if git compare failed
return false unless compare && compare.commits.present?
recipients.split(" ").each do |recipient|
Notify.delay.repository_push_email(project_id, recipient, author_id, branch, compare)
end
end
end
...@@ -12,7 +12,7 @@ module Gitlab ...@@ -12,7 +12,7 @@ module Gitlab
# -- all .rb files in that directory are automatically loaded. # -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable. # Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/models/concerns) config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/models/concerns #{config.root}/app/models/project_services)
# Only load the plugins named here, in the order given (default is alphabetical). # Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named. # :all can be used as a placeholder for all plugins not explicitly named.
......
class AddRecipientsToService < ActiveRecord::Migration
def change
add_column :services, :recipients, :text
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20131214224427) do ActiveRecord::Schema.define(version: 20131217102743) do
create_table "broadcast_messages", force: true do |t| create_table "broadcast_messages", force: true do |t|
t.text "message", null: false t.text "message", null: false
...@@ -219,6 +219,7 @@ ActiveRecord::Schema.define(version: 20131214224427) do ...@@ -219,6 +219,7 @@ ActiveRecord::Schema.define(version: 20131214224427) do
t.string "project_url" t.string "project_url"
t.string "subdomain" t.string "subdomain"
t.string "room" t.string "room"
t.text "recipients"
end end
add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree
......
...@@ -36,3 +36,9 @@ Feature: Project Services ...@@ -36,3 +36,9 @@ Feature: Project Services
And I click Assembla service link And I click Assembla service link
And I fill Assembla settings And I fill Assembla settings
Then I should see Assembla service settings saved Then I should see Assembla service settings saved
Scenario: Activate email on push service
When I visit project "Shop" services page
And I click email on push service link
And I fill email on push settings
Then I should see email on push service settings saved
...@@ -3,11 +3,11 @@ class ProjectServices < Spinach::FeatureSteps ...@@ -3,11 +3,11 @@ class ProjectServices < Spinach::FeatureSteps
include SharedProject include SharedProject
include SharedPaths include SharedPaths
When 'I visit project "Shop" services page' do step 'I visit project "Shop" services page' do
visit project_services_path(@project) visit project_services_path(@project)
end end
Then 'I should see list of available services' do step 'I should see list of available services' do
page.should have_content 'Services' page.should have_content 'Services'
page.should have_content 'Campfire' page.should have_content 'Campfire'
page.should have_content 'Hipchat' page.should have_content 'Hipchat'
...@@ -15,76 +15,89 @@ class ProjectServices < Spinach::FeatureSteps ...@@ -15,76 +15,89 @@ class ProjectServices < Spinach::FeatureSteps
page.should have_content 'Assembla' page.should have_content 'Assembla'
end end
And 'I click gitlab-ci service link' do step 'I click gitlab-ci service link' do
click_link 'GitLab CI' click_link 'GitLab CI'
end end
And 'I fill gitlab-ci settings' do step 'I fill gitlab-ci settings' do
check 'Active' check 'Active'
fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3' fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3'
fill_in 'Token', with: 'verySecret' fill_in 'Token', with: 'verySecret'
click_button 'Save' click_button 'Save'
end end
Then 'I should see service settings saved' do step 'I should see service settings saved' do
find_field('Project url').value.should == 'http://ci.gitlab.org/projects/3' find_field('Project url').value.should == 'http://ci.gitlab.org/projects/3'
end end
And 'I click hipchat service link' do step 'I click hipchat service link' do
click_link 'Hipchat' click_link 'Hipchat'
end end
And 'I fill hipchat settings' do step 'I fill hipchat settings' do
check 'Active' check 'Active'
fill_in 'Room', with: 'gitlab' fill_in 'Room', with: 'gitlab'
fill_in 'Token', with: 'verySecret' fill_in 'Token', with: 'verySecret'
click_button 'Save' click_button 'Save'
end end
Then 'I should see hipchat service settings saved' do step 'I should see hipchat service settings saved' do
find_field('Room').value.should == 'gitlab' find_field('Room').value.should == 'gitlab'
end end
And 'I click pivotaltracker service link' do step 'I click pivotaltracker service link' do
click_link 'PivotalTracker' click_link 'PivotalTracker'
end end
And 'I fill pivotaltracker settings' do step 'I fill pivotaltracker settings' do
check 'Active' check 'Active'
fill_in 'Token', with: 'verySecret' fill_in 'Token', with: 'verySecret'
click_button 'Save' click_button 'Save'
end end
Then 'I should see pivotaltracker service settings saved' do step 'I should see pivotaltracker service settings saved' do
find_field('Token').value.should == 'verySecret' find_field('Token').value.should == 'verySecret'
end end
And 'I click Flowdock service link' do step 'I click Flowdock service link' do
click_link 'Flowdock' click_link 'Flowdock'
end end
And 'I fill Flowdock settings' do step 'I fill Flowdock settings' do
check 'Active' check 'Active'
fill_in 'Token', with: 'verySecret' fill_in 'Token', with: 'verySecret'
click_button 'Save' click_button 'Save'
end end
Then 'I should see Flowdock service settings saved' do step 'I should see Flowdock service settings saved' do
find_field('Token').value.should == 'verySecret' find_field('Token').value.should == 'verySecret'
end end
And 'I click Assembla service link' do step 'I click Assembla service link' do
click_link 'Assembla' click_link 'Assembla'
end end
And 'I fill Assembla settings' do step 'I fill Assembla settings' do
check 'Active' check 'Active'
fill_in 'Token', with: 'verySecret' fill_in 'Token', with: 'verySecret'
click_button 'Save' click_button 'Save'
end end
Then 'I should see Assembla service settings saved' do step 'I should see Assembla service settings saved' do
find_field('Token').value.should == 'verySecret' find_field('Token').value.should == 'verySecret'
end end
step 'I click email on push service link' do
click_link 'Emails on push'
end
step 'I fill email on push settings' do
fill_in 'Recipients', with: 'qa@company.name'
click_button 'Save'
end
step 'I should see email on push service settings saved' do
find_field('Recipients').value.should == 'qa@company.name'
end
end end
...@@ -391,4 +391,28 @@ describe Notify do ...@@ -391,4 +391,28 @@ describe Notify do
should have_body_text /#{example_site_path}/ should have_body_text /#{example_site_path}/
end end
end end
describe 'email on push' do
let(:example_site_path) { root_path }
let(:user) { create(:user) }
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, 'cd5c4bac', 'b1e6a9db') }
subject { Notify.repository_push_email(project.id, 'devs@company.name', user.id, 'master', compare) }
it 'is sent to recipient' do
should deliver_to 'devs@company.name'
end
it 'has the correct subject' do
should have_subject /New push to repository/
end
it 'includes commits list' do
should have_body_text /tree css fixes/
end
it 'includes diffs' do
should have_body_text /Checkout wiki pages for installation information/
end
end
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