Commit efb17e05 authored by Stan Hu's avatar Stan Hu

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce

parents 91083d9e 8ceb7c05
...@@ -32,6 +32,7 @@ v 7.14.0 (unreleased) ...@@ -32,6 +32,7 @@ v 7.14.0 (unreleased)
- Fix bug causing Bitbucket importer to crash when OAuth application had been removed. - Fix bug causing Bitbucket importer to crash when OAuth application had been removed.
- Add fetch command to the MR page. - Add fetch command to the MR page.
- Show who last edited a comment if it wasn't the original author - Show who last edited a comment if it wasn't the original author
- Send notification to all participants when MR is merged.
- Add ability to manage user email addresses via the API. - Add ability to manage user email addresses via the API.
- Show buttons to add license, changelog and contribution guide if they're missing. - Show buttons to add license, changelog and contribution guide if they're missing.
- Tweak project page buttons. - Tweak project page buttons.
...@@ -42,6 +43,7 @@ v 7.14.0 (unreleased) ...@@ -42,6 +43,7 @@ v 7.14.0 (unreleased)
- Fetch code from forks to refs/merge-requests/:id/head when merge request created - Fetch code from forks to refs/merge-requests/:id/head when merge request created
- Remove satellites - Remove satellites
- Remove comments and email addresses when publicly exposing ssh keys (Zeger-Jan van de Weg) - Remove comments and email addresses when publicly exposing ssh keys (Zeger-Jan van de Weg)
- Cache all events
v 7.13.3 v 7.13.3
- Fix bug causing Bitbucket importer to crash when OAuth application had been removed. - Fix bug causing Bitbucket importer to crash when OAuth application had been removed.
......
...@@ -70,12 +70,6 @@ class NotificationService ...@@ -70,12 +70,6 @@ class NotificationService
reassign_resource_email(merge_request, merge_request.target_project, current_user, 'reassigned_merge_request_email') reassign_resource_email(merge_request, merge_request.target_project, current_user, 'reassigned_merge_request_email')
end end
# When we close a merge request we should send next emails:
#
# * merge_request author if their notification level is not Disabled
# * merge_request assignee if their notification level is not Disabled
# * project team members with notification level higher then Participating
#
def close_mr(merge_request, current_user) def close_mr(merge_request, current_user)
close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email') close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email')
end end
...@@ -84,26 +78,8 @@ class NotificationService ...@@ -84,26 +78,8 @@ class NotificationService
reopen_resource_email(issue, issue.project, current_user, 'issue_status_changed_email', 'reopened') reopen_resource_email(issue, issue.project, current_user, 'issue_status_changed_email', 'reopened')
end end
# When we merge a merge request we should send next emails:
#
# * merge_request author if their notification level is not Disabled
# * merge_request assignee if their notification level is not Disabled
# * project team members with notification level higher then Participating
#
def merge_mr(merge_request, current_user) def merge_mr(merge_request, current_user)
recipients = [merge_request.author, merge_request.assignee] close_resource_email(merge_request, merge_request.target_project, current_user, 'merged_merge_request_email')
recipients = add_project_watchers(recipients, merge_request.target_project)
recipients = reject_muted_users(recipients, merge_request.target_project)
recipients = add_subscribed_users(recipients, merge_request)
recipients = reject_unsubscribed_users(recipients, merge_request)
recipients.delete(current_user)
recipients.each do |recipient|
mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user.id)
end
end end
def reopen_mr(merge_request, current_user) def reopen_mr(merge_request, current_user)
...@@ -364,8 +340,7 @@ class NotificationService ...@@ -364,8 +340,7 @@ class NotificationService
end end
def new_resource_email(target, project, method) def new_resource_email(target, project, method)
recipients = build_recipients(target, project) recipients = build_recipients(target, project, target.author)
recipients.delete(target.author)
recipients.each do |recipient| recipients.each do |recipient|
mailer.send(method, recipient.id, target.id) mailer.send(method, recipient.id, target.id)
...@@ -373,8 +348,7 @@ class NotificationService ...@@ -373,8 +348,7 @@ class NotificationService
end end
def close_resource_email(target, project, current_user, method) def close_resource_email(target, project, current_user, method)
recipients = build_recipients(target, project) recipients = build_recipients(target, project, current_user)
recipients.delete(current_user)
recipients.each do |recipient| recipients.each do |recipient|
mailer.send(method, recipient.id, target.id, current_user.id) mailer.send(method, recipient.id, target.id, current_user.id)
...@@ -383,8 +357,7 @@ class NotificationService ...@@ -383,8 +357,7 @@ class NotificationService
def reassign_resource_email(target, project, current_user, method) def reassign_resource_email(target, project, current_user, method)
assignee_id_was = previous_record(target, "assignee_id") assignee_id_was = previous_record(target, "assignee_id")
recipients = build_recipients(target, project) recipients = build_recipients(target, project, current_user)
recipients.delete(current_user)
recipients.each do |recipient| recipients.each do |recipient|
mailer.send(method, recipient.id, target.id, assignee_id_was, current_user.id) mailer.send(method, recipient.id, target.id, assignee_id_was, current_user.id)
...@@ -392,21 +365,15 @@ class NotificationService ...@@ -392,21 +365,15 @@ class NotificationService
end end
def reopen_resource_email(target, project, current_user, method, status) def reopen_resource_email(target, project, current_user, method, status)
recipients = build_recipients(target, project) recipients = build_recipients(target, project, current_user)
recipients.delete(current_user)
recipients.each do |recipient| recipients.each do |recipient|
mailer.send(method, recipient.id, target.id, status, current_user.id) mailer.send(method, recipient.id, target.id, status, current_user.id)
end end
end end
def build_recipients(target, project) def build_recipients(target, project, current_user)
recipients = recipients = target.participants(current_user)
if target.respond_to?(:participants)
target.participants
else
[target.author, target.assignee]
end
recipients = add_project_watchers(recipients, project) recipients = add_project_watchers(recipients, project)
recipients = reject_mention_users(recipients, project) recipients = reject_mention_users(recipients, project)
...@@ -415,6 +382,8 @@ class NotificationService ...@@ -415,6 +382,8 @@ class NotificationService
recipients = add_subscribed_users(recipients, target) recipients = add_subscribed_users(recipients, target)
recipients = reject_unsubscribed_users(recipients, target) recipients = reject_unsubscribed_users(recipients, target)
recipients.delete(current_user)
recipients recipients
end end
......
...@@ -3,13 +3,11 @@ ...@@ -3,13 +3,11 @@
.event-item-timestamp .event-item-timestamp
#{time_ago_with_tooltip(event.created_at)} #{time_ago_with_tooltip(event.created_at)}
- if event.created_project? = cache event, "v1" do
= cache [event, current_user] do
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
= render "events/event/created_project", event: event
- else
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:'' = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- if event.push? - if event.created_project?
= render "events/event/created_project", event: event
- elsif event.push?
= render "events/event/push", event: event = render "events/event/push", event: event
- elsif event.commented? - elsif event.commented?
= render "events/event/note", event: event = render "events/event/note", event: event
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
- else - else
= event.project_name = event.project_name
- if current_user == event.author && !event.project.private? && twitter_sharing_enabled? - if !event.project.private? && twitter_sharing_enabled?
.event-body .event-body{"data-user-is" => event.author_id}
.event-note .event-note
.md .md
%p %p
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
- few_commits.each do |commit| - few_commits.each do |commit|
= render "events/commit", commit: commit, project: project = render "events/commit", commit: commit, project: project
- create_mr = current_user == event.author && event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project) - create_mr = event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project)
- if event.commits_count > 1 - if event.commits_count > 1
%li.commits-stat %li.commits-stat
- if event.commits_count > 2 - if event.commits_count > 2
...@@ -34,10 +34,11 @@ ...@@ -34,10 +34,11 @@
Compare #{from_label}...#{truncate_sha(event.commit_to)} Compare #{from_label}...#{truncate_sha(event.commit_to)}
- if create_mr - if create_mr
or %span{"data-user-is" => event.author_id, "data-display" => "inline"}
= link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do or
create a merge request = link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do
create a merge request
- elsif create_mr - elsif create_mr
%li.commits-stat %li.commits-stat{"data-user-is" => event.author_id}
= link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do = link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do
Create Merge Request Create Merge Request
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
= favicon_link_tag 'touch-icon-ipad-retina.png', rel: 'apple-touch-icon', sizes: '152x152' = favicon_link_tag 'touch-icon-ipad-retina.png', rel: 'apple-touch-icon', sizes: '152x152'
-# Windows 8 pinned site tile -# Windows 8 pinned site tile
%meta{name: 'msapplication-TileImage', content: image_url('msapplication-tile.png')} %meta{name: 'msapplication-TileImage', content: image_path('msapplication-tile.png')}
%meta{name: 'msapplication-TileColor', content: '#30353E'} %meta{name: 'msapplication-TileColor', content: '#30353E'}
= yield :meta_tags = yield :meta_tags
...@@ -35,3 +35,5 @@ ...@@ -35,3 +35,5 @@
= render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id') = render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id')
= render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id') = render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id')
= render 'layouts/bootlint' if Rails.env.development? = render 'layouts/bootlint' if Rails.env.development?
= render 'layouts/user_styles'
:css
[data-user-is] {
display: none !important;
}
[data-user-is="#{current_user.try(:id)}"] {
display: block !important;
}
[data-user-is="#{current_user.try(:id)}"][data-display="inline"] {
display: inline !important;
}
[data-user-is-not] {
display: block !important;
}
[data-user-is-not][data-display="inline"] {
display: inline !important;
}
[data-user-is-not="#{current_user.try(:id)}"] {
display: none !important;
}
...@@ -22,6 +22,7 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ...@@ -22,6 +22,7 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```bash ```bash
cd /home/git/gitlab cd /home/git/gitlab
sudo -u git -H git fetch --all sudo -u git -H git fetch --all
sudo -u git -H git checkout -- Gemfile.lock db/schema.rb
sudo -u git -H git checkout LATEST_TAG sudo -u git -H git checkout LATEST_TAG
``` ```
......
...@@ -52,18 +52,35 @@ Below is the table of events users can be notified of: ...@@ -52,18 +52,35 @@ Below is the table of events users can be notified of:
| New SSH key added | User | Security email, always sent. | | New SSH key added | User | Security email, always sent. |
| New email added | User | Security email, always sent. | | New email added | User | Security email, always sent. |
| New user created | User | Sent on user creation, except for omniauth (LDAP)| | New user created | User | Sent on user creation, except for omniauth (LDAP)|
| New issue created | Issue assignee [1], project members [2] | [1] not disabled, [2] higher than participating |
| User added to project | User | Sent when user is added to project | | User added to project | User | Sent when user is added to project |
| Project access level changed | User | Sent when user project access level is changed | | Project access level changed | User | Sent when user project access level is changed |
| User added to group | User | Sent when user is added to group | | User added to group | User | Sent when user is added to group |
| Project moved | Project members [1] | [1] not disabled |
| Group access level changed | User | Sent when user group access level is changed | | Group access level changed | User | Sent when user group access level is changed |
| Close issue | Issue author [1], issue assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating | | Project moved | Project members [1] | [1] not disabled |
| Reassign issue | New issue assignee [1], old issue assignee [2] | [1] [2] not disabled |
| Reopen issue | Project members [1] | [1] higher than participating | ### Issue / Merge Request events
| New merge request | MR assignee [1] | [1] not disabled |
| Reassign merge request | New MR assignee [1], old MR assignee [2] | [1] [2] not disabled | In all of the below cases, the notification will be sent to:
| Close merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating | - Participants:
| Reopen merge request | Project members [1] | [1] higher than participating | - the author and assignee of the issue/merge request
| Merge merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating | - authors of comments on the issue/merge request
| New comment | Mentioned users [1], users participating [2], project members [3] | [1] [2] not disabled, [3] higher than participating | - anyone mentioned by `@username` in the issue/merge request description
- anyone mentioned by `@username` in any of the comments on the issue/merge request
...with notification level "Participating" or higher
- Watchers: project members with notification level "Watch"
- Subscribers: anyone who manually subscribed to the issue/merge request
| Event | Sent to |
|------------------------|---------|
| New issue | |
| Close issue | |
| Reassign issue | The above, plus the old assignee |
| Reopen issue | |
| New merge request | |
| Reassign merge request | The above, plus the old assignee |
| Close merge request | |
| Reopen merge request | |
| Merge merge request | |
| New comment | The above, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher |
...@@ -300,7 +300,7 @@ describe NotificationService do ...@@ -300,7 +300,7 @@ describe NotificationService do
describe 'Merge Requests' do describe 'Merge Requests' do
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
let(:merge_request) { create :merge_request, source_project: project, assignee: create(:user) } let(:merge_request) { create :merge_request, source_project: project, assignee: create(:user), description: 'cc @participant' }
before do before do
build_team(merge_request.target_project) build_team(merge_request.target_project)
...@@ -311,6 +311,7 @@ describe NotificationService do ...@@ -311,6 +311,7 @@ describe NotificationService do
it do it do
should_email(merge_request.assignee_id) should_email(merge_request.assignee_id)
should_email(@u_watcher.id) should_email(@u_watcher.id)
should_email(@u_participant_mentioned.id)
should_not_email(@u_participating.id) should_not_email(@u_participating.id)
should_not_email(@u_disabled.id) should_not_email(@u_disabled.id)
notification.new_merge_request(merge_request, @u_disabled) notification.new_merge_request(merge_request, @u_disabled)
...@@ -329,6 +330,7 @@ describe NotificationService do ...@@ -329,6 +330,7 @@ describe NotificationService do
it do it do
should_email(merge_request.assignee_id) should_email(merge_request.assignee_id)
should_email(@u_watcher.id) should_email(@u_watcher.id)
should_email(@u_participant_mentioned.id)
should_email(@subscriber.id) should_email(@subscriber.id)
should_not_email(@unsubscriber.id) should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id) should_not_email(@u_participating.id)
...@@ -349,6 +351,7 @@ describe NotificationService do ...@@ -349,6 +351,7 @@ describe NotificationService do
it do it do
should_email(merge_request.assignee_id) should_email(merge_request.assignee_id)
should_email(@u_watcher.id) should_email(@u_watcher.id)
should_email(@u_participant_mentioned.id)
should_email(@subscriber.id) should_email(@subscriber.id)
should_not_email(@unsubscriber.id) should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id) should_not_email(@u_participating.id)
...@@ -369,6 +372,7 @@ describe NotificationService do ...@@ -369,6 +372,7 @@ describe NotificationService do
it do it do
should_email(merge_request.assignee_id) should_email(merge_request.assignee_id)
should_email(@u_watcher.id) should_email(@u_watcher.id)
should_email(@u_participant_mentioned.id)
should_email(@subscriber.id) should_email(@subscriber.id)
should_not_email(@unsubscriber.id) should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id) should_not_email(@u_participating.id)
...@@ -389,6 +393,7 @@ describe NotificationService do ...@@ -389,6 +393,7 @@ describe NotificationService do
it do it do
should_email(merge_request.assignee_id) should_email(merge_request.assignee_id)
should_email(@u_watcher.id) should_email(@u_watcher.id)
should_email(@u_participant_mentioned.id)
should_email(@subscriber.id) should_email(@subscriber.id)
should_not_email(@unsubscriber.id) should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id) should_not_email(@u_participating.id)
......
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