Commit 8344c795 authored by karen Carias's avatar karen Carias

fixed conflict and comment

parents 082467e8 151d9fb3
...@@ -22,6 +22,7 @@ v 7.14.0 (unreleased) ...@@ -22,6 +22,7 @@ v 7.14.0 (unreleased)
- Fix OAuth provider bug where GitLab would not go return to the redirect_uri after sign-in (Stan Hu) - Fix OAuth provider bug where GitLab would not go return to the redirect_uri after sign-in (Stan Hu)
- Fix file upload dialog for comment editing (Daniel Gerhardt) - Fix file upload dialog for comment editing (Daniel Gerhardt)
- Set OmniAuth full_host parameter to ensure redirect URIs are correct (Stan Hu) - Set OmniAuth full_host parameter to ensure redirect URIs are correct (Stan Hu)
- Return comments in created order in merge request API (Stan Hu)
- Expire Rails cache entries after two weeks to prevent endless Redis growth - Expire Rails cache entries after two weeks to prevent endless Redis growth
- Add support for destroying project milestones (Stan Hu) - Add support for destroying project milestones (Stan Hu)
- Add fetch command to the MR page. - Add fetch command to the MR page.
...@@ -31,16 +32,21 @@ v 7.14.0 (unreleased) ...@@ -31,16 +32,21 @@ 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.
- Disabled autocapitalize and autocorrect on login field (Daryl Chan) - Disabled autocapitalize and autocorrect on login field (Daryl Chan)
- Mention group and project name in creation, update and deletion notices (Achilleas Pipinellis) - Mention group and project name in creation, update and deletion notices (Achilleas Pipinellis)
- Update gravatar link on profile page to link to configured gravatar host (Ben Bodenmiller)
- Remove redis-store TTL monkey patch - Remove redis-store TTL monkey patch
- Add support for CI skipped status - Add support for CI skipped status
- 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)
- Improve MR merge widget text and UI consistency.
- Improve text in MR "How To Merge" modal.
- 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.
...@@ -69,9 +75,6 @@ v 7.13.1 ...@@ -69,9 +75,6 @@ v 7.13.1
v 7.13.0 v 7.13.0
- Remove repository graph log to fix slow cache updates after push event (Stan Hu) - Remove repository graph log to fix slow cache updates after push event (Stan Hu)
- Return comments in created order in merge request API (Stan Hu)
v 7.13.0 (unreleased)
- Only enable HSTS header for HTTPS and port 443 (Stan Hu) - Only enable HSTS header for HTTPS and port 443 (Stan Hu)
- Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu) - Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu)
- Fix redirection to home page URL for unauthorized users (Daniel Gerhardt) - Fix redirection to home page URL for unauthorized users (Daniel Gerhardt)
...@@ -119,12 +122,12 @@ v 7.13.0 (unreleased) ...@@ -119,12 +122,12 @@ v 7.13.0 (unreleased)
- Add error message for SSH key linebreaks - Add error message for SSH key linebreaks
- Store commits count in database (will populate with valid values only after first push) - Store commits count in database (will populate with valid values only after first push)
- Rebuild cache after push to repository in background job - Rebuild cache after push to repository in background job
- Fix transferring of project to another group using the API.
v 7.12.2 v 7.12.2
- Correctly show anonymous authorized applications under Profile > Applications. - Correctly show anonymous authorized applications under Profile > Applications.
- Faster automerge check and merge itself when source and target branches are in same repository - Faster automerge check and merge itself when source and target branches are in same repository
- Audit log for user authentication - Audit log for user authentication
- Fix transferring of project to another group using the API.
- Allow custom label to be set for authentication providers. - Allow custom label to be set for authentication providers.
v 7.12.1 v 7.12.1
......
...@@ -154,7 +154,7 @@ GEM ...@@ -154,7 +154,7 @@ GEM
doorkeeper (2.1.3) doorkeeper (2.1.3)
railties (>= 3.2) railties (>= 3.2)
dotenv (0.9.0) dotenv (0.9.0)
dropzonejs-rails (0.4.14) dropzonejs-rails (0.7.1)
rails (> 3.1) rails (> 3.1)
email_spec (1.6.0) email_spec (1.6.0)
launchy (~> 2.1) launchy (~> 2.1)
...@@ -373,7 +373,7 @@ GEM ...@@ -373,7 +373,7 @@ GEM
mini_portile (0.6.2) mini_portile (0.6.2)
minitest (5.3.5) minitest (5.3.5)
mousetrap-rails (1.4.6) mousetrap-rails (1.4.6)
multi_json (1.11.1) multi_json (1.11.2)
multi_xml (0.5.5) multi_xml (0.5.5)
multipart-post (1.2.0) multipart-post (1.2.0)
mysql2 (0.3.16) mysql2 (0.3.16)
......
...@@ -8,6 +8,7 @@ class @DropzoneInput ...@@ -8,6 +8,7 @@ class @DropzoneInput
divAlert = "<div class=\"" + alertClass + "\"></div>" divAlert = "<div class=\"" + alertClass + "\"></div>"
iconPaperclip = "<i class=\"fa fa-paperclip div-dropzone-icon\"></i>" iconPaperclip = "<i class=\"fa fa-paperclip div-dropzone-icon\"></i>"
iconSpinner = "<i class=\"fa fa-spinner fa-spin div-dropzone-icon\"></i>" iconSpinner = "<i class=\"fa fa-spinner fa-spin div-dropzone-icon\"></i>"
uploadProgress = $("<div class=\"div-dropzone-progress\"></div>")
btnAlert = "<button type=\"button\"" + alertAttr + ">&times;</button>" btnAlert = "<button type=\"button\"" + alertAttr + ">&times;</button>"
project_uploads_path = window.project_uploads_path or null project_uploads_path = window.project_uploads_path or null
markdown_preview_path = window.markdown_preview_path or null markdown_preview_path = window.markdown_preview_path or null
...@@ -28,6 +29,7 @@ class @DropzoneInput ...@@ -28,6 +29,7 @@ class @DropzoneInput
form_dropzone.find(".div-dropzone-hover").append iconPaperclip form_dropzone.find(".div-dropzone-hover").append iconPaperclip
form_dropzone.append divSpinner form_dropzone.append divSpinner
form_dropzone.find(".div-dropzone-spinner").append iconSpinner form_dropzone.find(".div-dropzone-spinner").append iconSpinner
form_dropzone.find(".div-dropzone-spinner").append uploadProgress
form_dropzone.find(".div-dropzone-spinner").css form_dropzone.find(".div-dropzone-spinner").css
"opacity": 0 "opacity": 0
"display": "none" "display": "none"
...@@ -112,13 +114,18 @@ class @DropzoneInput ...@@ -112,13 +114,18 @@ class @DropzoneInput
$(".div-dropzone-alert").append btnAlert + errorMessage $(".div-dropzone-alert").append btnAlert + errorMessage
return return
totaluploadprogress: (totalUploadProgress) ->
uploadProgress.text Math.round(totalUploadProgress) + "%"
return
sending: -> sending: ->
form_dropzone.find(".div-dropzone-spinner").css form_dropzone.find(".div-dropzone-spinner").css
"opacity": 0.7 "opacity": 0.7
"display": "inherit" "display": "inherit"
return return
complete: -> queuecomplete: ->
uploadProgress.text ""
$(".dz-preview").remove() $(".dz-preview").remove()
$(".markdown-area").trigger "input" $(".markdown-area").trigger "input"
$(".div-dropzone-spinner").css $(".div-dropzone-spinner").css
......
...@@ -40,6 +40,15 @@ ...@@ -40,6 +40,15 @@
font-size: inherit; font-size: inherit;
} }
.div-dropzone-progress {
position: absolute;
top: 7px;
left: -40px;
width: 35px;
font-size: 13px;
text-align: right;
}
.dz-preview { .dz-preview {
display: none; display: none;
} }
......
...@@ -91,8 +91,6 @@ ...@@ -91,8 +91,6 @@
@media(min-width: $screen-sm-max) { @media(min-width: $screen-sm-max) {
.merge-request .merge-request-tabs{ .merge-request .merge-request-tabs{
margin: 20px 0;
li { li {
a { a {
padding: 15px 40px; padding: 15px 40px;
...@@ -102,6 +100,11 @@ ...@@ -102,6 +100,11 @@
} }
} }
.merge-request .merge-request-tabs{
margin-top: 30px;
margin-bottom: 20px;
}
.mr_source_commit, .mr_source_commit,
.mr_target_commit { .mr_target_commit {
.commit { .commit {
...@@ -179,3 +182,7 @@ ...@@ -179,3 +182,7 @@
.merge-request-form .select2-container { .merge-request-form .select2-container {
width: 250px !important; width: 250px !important;
} }
#modal_merge_info .modal-dialog {
width: 600px;
}
...@@ -60,7 +60,11 @@ ...@@ -60,7 +60,11 @@
} }
.tree_author { .tree_author {
padding-left: 8px; padding-right: 8px;
.commit-author-name {
color: gray;
}
} }
.tree_commit { .tree_commit {
......
...@@ -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
......
class PostCommitService < BaseService class PostCommitService < BaseService
include Gitlab::Popen
attr_reader :changes, :repo_path
def execute(sha, branch) def execute(sha, branch)
commit = repository.commit(sha) commit = repository.commit(sha)
full_ref = 'refs/heads/' + branch full_ref = Gitlab::Git::BRANCH_REF_PREFIX + branch
old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA
GitPushService.new.execute(project, current_user, old_sha, sha, full_ref) @changes = "#{old_sha} #{sha} #{full_ref}"
@repo_path = repository.path_to_repo
post_receive
end
private
def post_receive
hook = hook_file('post-receive', repo_path)
return true if hook.nil?
call_receive_hook(hook)
end
def call_receive_hook(hook)
# function will return true if succesful
exit_status = false
vars = {
'GL_ID' => Gitlab::ShellEnv.gl_id(current_user),
'PWD' => repo_path
}
options = {
chdir: repo_path
}
# we combine both stdout and stderr as we don't know what stream
# will be used by the custom hook
Open3.popen2e(vars, hook, options) do |stdin, stdout_stderr, wait_thr|
exit_status = true
stdin.sync = true
# in git, pre- and post- receive hooks may just exit without
# reading stdin. We catch the exception to avoid a broken pipe
# warning
begin
# inject all the changes as stdin to the hook
changes.lines do |line|
stdin.puts line
end
rescue Errno::EPIPE
end
# need to close stdin before reading stdout
stdin.close
# only output stdut_stderr if scripts doesn't return 0
unless wait_thr.value == 0
exit_status = false
end
end
exit_status
end
def hook_file(hook_type, repo_path)
hook_path = File.join(repo_path.strip, 'hooks')
hook_file = "#{hook_path}/#{hook_type}"
hook_file if File.exist?(hook_file)
end end
end end
- page_title "Report abuse" - page_title "Report abuse"
%h3.page-title Report abuse %h3.page-title Report abuse
%p Please use this form to report users who create spam issues or comments or who otherwise behave inappropriately. %p Please use this form to report users who create spam issues, comments or behave inappropriately.
%hr %hr
= form_for @abuse_report, html: { class: 'form-horizontal'} do |f| = form_for @abuse_report, html: { class: 'form-horizontal'} do |f|
= f.hidden_field :user_id = f.hidden_field :user_id
......
...@@ -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:'' = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- if event.created_project?
= render "events/event/created_project", event: event = render "events/event/created_project", event: event
- else - elsif event.push?
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- if 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
%span{"data-user-is" => event.author_id, "data-display" => "inline"}
or or
= 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 a merge request 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;
}
...@@ -82,12 +82,12 @@ ...@@ -82,12 +82,12 @@
You can change your avatar here You can change your avatar here
- if Gitlab.config.gravatar.enabled - if Gitlab.config.gravatar.enabled
%br %br
or remove the current avatar to revert to #{link_to "gravatar.com", "http://gravatar.com"} or remove the current avatar to revert to #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
- else - else
You can upload an avatar here You can upload an avatar here
- if Gitlab.config.gravatar.enabled - if Gitlab.config.gravatar.enabled
%br %br
or change it at #{link_to "gravatar.com", "http://gravatar.com"} or change it at #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
%hr %hr
%a.choose-btn.btn.btn-sm.js-choose-user-avatar-button %a.choose-btn.btn.btn-sm.js-choose-user-avatar-button
%i.fa.fa-paperclip %i.fa.fa-paperclip
......
...@@ -3,42 +3,45 @@ ...@@ -3,42 +3,45 @@
.modal-content .modal-content
.modal-header .modal-header
%a.close{href: "#", "data-dismiss" => "modal"} × %a.close{href: "#", "data-dismiss" => "modal"} ×
%h3 How to merge %h3 Check out, review and merge locally
.modal-body .modal-body
- if @merge_request.for_fork?
- source_remote = @merge_request.source_project.namespace.nil? ? "source" :@merge_request.source_project.namespace.path
- target_remote = @merge_request.target_project.namespace.nil? ? "target" :@merge_request.target_project.namespace.path
%p %p
%strong Step 1. %strong Step 1.
Fetch the code and create a new branch pointing to it Fetch and check out the branch for this merge request
%pre.dark %pre.dark
- if @merge_request.for_fork?
:preserve :preserve
git fetch #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch} git fetch #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch}
git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} FETCH_HEAD git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} FETCH_HEAD
- else
:preserve
git fetch origin
git checkout -b #{@merge_request.source_branch} origin/#{@merge_request.source_branch}
%p %p
%strong Step 2. %strong Step 2.
Merge the branch and push the changes to GitLab Review the changes locally
%p
%strong Step 3.
Merge the branch and fix any conflicts that come up
%pre.dark %pre.dark
- if @merge_request.for_fork?
:preserve :preserve
git checkout #{@merge_request.target_branch} git checkout #{@merge_request.target_branch}
git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch} git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch}
git push origin #{@merge_request.target_branch}
- else - else
%p
%strong Step 1.
Update the repo and checkout the branch we are going to merge
%pre.dark
:preserve :preserve
git fetch origin git checkout #{@merge_request.target_branch}
git checkout -b #{@merge_request.source_branch} origin/#{@merge_request.source_branch} git merge --no-ff #{@merge_request.source_branch}
%p %p
%strong Step 2. %strong Step 4.
Merge the branch and push the changes to GitLab Push the result of the merge to GitLab
%pre.dark %pre.dark
:preserve :preserve
git checkout #{@merge_request.target_branch}
git merge --no-ff #{@merge_request.source_branch}
git push origin #{@merge_request.target_branch} git push origin #{@merge_request.target_branch}
- unless @merge_request.can_be_merged_by?(current_user)
%p
Note that pushing to GitLab requires write access to this repository.
:javascript :javascript
$(function(){ $(function(){
......
...@@ -6,4 +6,7 @@ ...@@ -6,4 +6,7 @@
- if @merge_request.closed_event - if @merge_request.closed_event
by #{link_to_member(@project, @merge_request.closed_event.author, avatar: true)} by #{link_to_member(@project, @merge_request.closed_event.author, avatar: true)}
#{time_ago_with_tooltip(@merge_request.closed_event.created_at)} #{time_ago_with_tooltip(@merge_request.closed_event.created_at)}
%p Changes were not merged into target branch %p
= succeed '.' do
The changes were not merged into
%span.label-branch= @merge_request.target_branch
...@@ -3,26 +3,26 @@ ...@@ -3,26 +3,26 @@
- [:success, :skipped, :canceled, :failed, :running, :pending].each do |status| - [:success, :skipped, :canceled, :failed, :running, :pending].each do |status|
.ci_widget{class: "ci-#{status}", style: "display:none"} .ci_widget{class: "ci-#{status}", style: "display:none"}
- if status == :success - if status == :success
- status = "passed"
= icon("check-circle") = icon("check-circle")
- else - else
= icon("circle") = icon("circle")
%span CI build #{status} %span CI build #{status}
for #{@merge_request.last_commit_short_sha}. for #{@merge_request.last_commit_short_sha}.
%span.ci-coverage %span.ci-coverage
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" = link_to "View build details", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget .ci_widget
= icon("spinner spin") = icon("spinner spin")
Checking for CI status for #{@merge_request.last_commit_short_sha} Checking CI status for #{@merge_request.last_commit_short_sha}&hellip;
.ci_widget.ci-not_found{style: "display:none"} .ci_widget.ci-not_found{style: "display:none"}
= icon("times-circle") = icon("times-circle")
%span Can not find commit in the CI server Could not find CI status for #{@merge_request.last_commit_short_sha}.
for #{@merge_request.last_commit_short_sha}.
.ci_widget.ci-error{style: "display:none"} .ci_widget.ci-error{style: "display:none"}
= icon("times-circle") = icon("times-circle")
%span Cannot connect to the CI server. Please check your settings and try again. Could not connect to the CI server. Please check your settings and try again.
:coffeescript :coffeescript
$ -> $ ->
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
= render 'projects/merge_requests/widget/heading' = render 'projects/merge_requests/widget/heading'
.mr-widget-body .mr-widget-body
%h4 %h4
Merge in progress... = icon("spinner spin")
Merge in progress&hellip;
%p %p
Merging is in progress. While merging this request is locked and cannot be closed. This merge request is in the process of being merged, during which time it is locked and cannot be closed.
...@@ -7,23 +7,31 @@ ...@@ -7,23 +7,31 @@
by #{link_to_member(@project, @merge_request.merge_event.author, avatar: true)} by #{link_to_member(@project, @merge_request.merge_event.author, avatar: true)}
#{time_ago_with_tooltip(@merge_request.merge_event.created_at)} #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}
%div %div
- if @source_branch.blank? - if !@merge_request.source_branch_exists?
Source branch has been removed = succeed '.' do
The changes were merged into
%span.label-branch= @merge_request.target_branch
The source branch has been removed.
- elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && @merge_request.merged? - elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch)
.remove_source_branch_widget .remove_source_branch_widget
%p Changes merged into #{@merge_request.target_branch}. You can remove source branch now %p
= succeed '.' do
The changes were merged into
%span.label-branch= @merge_request.target_branch
You can remove the source branch now.
= link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-sm remove_source_branch" do = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-sm remove_source_branch" do
%i.fa.fa-times %i.fa.fa-times
Remove Source Branch Remove Source Branch
.remove_source_branch_widget.failed.hide .remove_source_branch_widget.failed.hide
Failed to remove source branch '#{@merge_request.source_branch}' %p
Failed to remove source branch '#{@merge_request.source_branch}'.
.remove_source_branch_in_progress.hide .remove_source_branch_in_progress.hide
%i.fa.fa-spinner.fa-spin %p
&nbsp; = icon('spinner spin')
Removing source branch '#{@merge_request.source_branch}'. Please wait. Page will be automatically reloaded. &nbsp; Removing source branch '#{@merge_request.source_branch}'. Please wait. This page will be automatically reload.
:coffeescript :coffeescript
$('.remove_source_branch').on 'click', -> $('.remove_source_branch').on 'click', ->
......
...@@ -22,6 +22,6 @@ ...@@ -22,6 +22,6 @@
.mr-widget-footer .mr-widget-footer
%span %span
%i.fa.fa-check %i.fa.fa-check
Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'} Accepting this merge request will close #{"issue".pluralize(@closes_issues.size)}
= succeed '.' do = succeed '.' do
!= gfm(issues_sentence(@closes_issues)) != gfm(issues_sentence(@closes_issues))
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
.accept-control.checkbox .accept-control.checkbox
= label_tag :should_remove_source_branch, class: "remove_source_checkbox" do = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do
= check_box_tag :should_remove_source_branch = check_box_tag :should_remove_source_branch
Remove source-branch Remove source branch
.accept-control .accept-control
= link_to "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" do = link_to "#", class: "modify-merge-commit-link js-toggle-button" do
%i.fa.fa-edit = icon('edit')
Modify commit message Modify commit message
.js-toggle-content.hide.prepend-top-20 .js-toggle-content.hide.prepend-top-20
= render 'shared/commit_message_container', params: params, = render 'shared/commit_message_container', params: params,
......
%h4
Project is archived
%p %p
%strong Archived projects do not provide commit access. This merge request cannot be merged because archived projects cannot be written to.
%strong %strong
%i.fa.fa-spinner.fa-spin = icon("spinner spin")
Checking automatic merge… Checking ability to merge automatically&hellip;
:coffeescript :coffeescript
$ -> $ ->
......
%h4 %h4
This merge request contains merge conflicts that must be resolved. = icon("exclamation-triangle")
This merge request contains merge conflicts
- if @merge_request.can_be_merged_by?(current_user) %p
%p Please resolve these conflicts or
You can merge it manually using the - if @merge_request.can_be_merged_by?(current_user)
%strong #{link_to "merge this request manually", "#modal_merge_info", class: "how_to_merge_link vlink", "data-toggle" => "modal"}.
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" - else
- else ask someone with write access to this repository to merge this request manually.
%p
Only those with write access to this repository can merge merge requests.
%h4 - unless @merge_request.source_branch_exists?
Can't be merged %h4
%p = icon("exclamation-triangle")
This merge request can not be accepted because branch Source branch
- unless @merge_request.source_branch_exists? %span.label-branch= source_branch_with_namespace(@merge_request)
%span.label.label-inverse= @merge_request.source_branch does not exist
does not exist in %p
%span.label.label-info= @merge_request.source_project_path Please restore the source branch or close this merge request and open a new merge request with a different source branch.
%br - else
%strong Please close this merge request and open a new merge request to change source branches. %h4
- else = icon("exclamation-triangle")
%span.label.label-inverse= @merge_request.target_branch Target branch
does not exist in %span.label-branch= @merge_request.target_branch
%span.label.label-info= @merge_request.target_project_path does not exist
%br %p
%strong Please close this merge request or change to another target branch. Please restore the target branch or use a different target branch.
%strong This request can be merged automatically. %h4
Only those with write access to this repository can merge merge requests. Ready to be merged automatically
%p
Ask someone with write access to this repository to merge this request.
%h4 Nothing to merge %h4
%p = icon("exclamation-triangle")
Nothing to merge from Nothing to merge from
%span.label-branch #{@merge_request.source_branch} %span.label-branch= source_branch_with_namespace(@merge_request)
to into
%span.label-branch #{@merge_request.target_branch} %span.label-branch= @merge_request.target_branch
%br %p
Try to use different branches or push new code. Please push new commits to the source branch or use a different target branch.
This merge request cannot be merged. Try to reload the page. %h4
= icon("exclamation-triangle")
This merge request failed to be merged automatically
%p
Please reload the page to find out the reason.
- if @merge_request.can_be_merged_by?(current_user) %h4
%h4 This merge request is currently a Work In Progress
This merge request cannot be accepted because it is marked as Work In Progress.
%p %p
%button.btn.disabled{:type => 'button'} When this merge request is ready, remove the "WIP" prefix from the title to allow it to be merged.
%i.fa.fa-warning
Accept Merge Request
&nbsp;
When the merge request is ready, remove the "WIP" prefix from the title to allow it to be accepted.
- else
%strong This merge request is marked as Work In Progress.
Only those with write access to this repository can merge merge requests.
%span.str-truncated %span.str-truncated
%span.tree_author= commit_author_link(commit, avatar: true, size: 16)
= link_to_gfm commit.title, namespace_project_commit_path(@project.namespace, @project, commit.id), class: "tree-commit-link" = link_to_gfm commit.title, namespace_project_commit_path(@project.namespace, @project, commit.id), class: "tree-commit-link"
%span.tree_author
[
commit_author_link(commit, avatar: false)
]
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
%p.help-block %p.help-block
- if issuable.work_in_progress? - if issuable.work_in_progress?
Remove the <code>WIP</code> prefix from the title to allow this Remove the <code>WIP</code> prefix from the title to allow this
<strong>Work In Progress</strong> merge request to be accepted when it's ready. <strong>Work In Progress</strong> merge request to be merged when it's ready.
- else - else
Start the title with <code>[WIP]</code> or <code>WIP:</code> to prevent a Start the title with <code>[WIP]</code> or <code>WIP:</code> to prevent a
<strong>Work In Progress</strong> merge request from being accepted before it's ready. <strong>Work In Progress</strong> merge request from being merged before it's ready.
.form-group.issuable-description .form-group.issuable-description
= f.label :description, 'Description', class: 'control-label' = f.label :description, 'Description', class: 'control-label'
.col-sm-10 .col-sm-10
......
...@@ -9,6 +9,15 @@ class Settings < Settingslogic ...@@ -9,6 +9,15 @@ class Settings < Settingslogic
gitlab.port.to_i == (gitlab.https ? 443 : 80) gitlab.port.to_i == (gitlab.https ? 443 : 80)
end end
# get host without www, thanks to http://stackoverflow.com/a/6674363/1233435
def get_host_without_www(url)
url = URI.encode(url)
uri = URI.parse(url)
uri = URI.parse("http://#{url}") if uri.scheme.nil?
host = uri.host.downcase
host.start_with?('www.') ? host[4..-1] : host
end
private private
def build_gitlab_shell_ssh_path_prefix def build_gitlab_shell_ssh_path_prefix
...@@ -147,6 +156,7 @@ Settings['gravatar'] ||= Settingslogic.new({}) ...@@ -147,6 +156,7 @@ Settings['gravatar'] ||= Settingslogic.new({})
Settings.gravatar['enabled'] = true if Settings.gravatar['enabled'].nil? Settings.gravatar['enabled'] = true if Settings.gravatar['enabled'].nil?
Settings.gravatar['plain_url'] ||= 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon' Settings.gravatar['plain_url'] ||= 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
Settings.gravatar['ssl_url'] ||= 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon' Settings.gravatar['ssl_url'] ||= 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
Settings.gravatar['host'] = Settings.get_host_without_www(Settings.gravatar['plain_url'])
# #
# GitLab Shell # GitLab Shell
......
...@@ -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,11 +52,9 @@ Below is the table of events users can be notified of: ...@@ -52,11 +52,9 @@ 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 | | Close issue | Issue author [1], issue assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
| Reassign issue | New issue assignee [1], old issue assignee [2] | [1] [2] not disabled | | Reassign issue | New issue assignee [1], old issue assignee [2] | [1] [2] not disabled |
...@@ -67,5 +65,36 @@ Below is the table of events users can be notified of: ...@@ -67,5 +65,36 @@ Below is the table of events users can be notified of:
| Reopen merge request | Project members [1] | [1] higher than participating | | Reopen merge request | Project members [1] | [1] higher than participating |
| Merge merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating | | Merge merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
| New comment | Mentioned users [1], users participating [2], project members [3] | [1] [2] not disabled, [3] higher than participating | | New comment | Mentioned users [1], users participating [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
| Project moved | Project members [1] | [1] not disabled |
You won't receive notifications for Issues, Merge Requests or Milestones created by yourself. You will only receive automatic notifications when somebody else creates one and they mention you. Also, when somebody comments or adds changes to the ones that you've created. ### Issue / Merge Request events
In all of the below cases, the notification will be sent to:
- Participants:
- the author and assignee of the issue/merge request
- authors of comments on the issue/merge request
- 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 |
You won't receive notifications for Issues, Merge Requests or Milestones
created by yourself. You will only receive automatic notifications when
somebody else comments or adds changes to the ones that you've created or
mentions you.
...@@ -35,6 +35,7 @@ Feature: Profile ...@@ -35,6 +35,7 @@ Feature: Profile
Then I change my avatar Then I change my avatar
And I should see new avatar And I should see new avatar
And I should see the "Remove avatar" button And I should see the "Remove avatar" button
And I should see the gravatar host link
Scenario: I remove my avatar Scenario: I remove my avatar
Given I visit profile page Given I visit profile page
...@@ -42,6 +43,7 @@ Feature: Profile ...@@ -42,6 +43,7 @@ Feature: Profile
When I remove my avatar When I remove my avatar
Then I should see my gravatar Then I should see my gravatar
And I should not see the "Remove avatar" button And I should not see the "Remove avatar" button
And I should see the gravatar host link
Scenario: My password is expired Scenario: My password is expired
Given my password is expired Given my password is expired
......
...@@ -60,6 +60,10 @@ class Spinach::Features::Profile < Spinach::FeatureSteps ...@@ -60,6 +60,10 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
expect(page).not_to have_link("Remove avatar") expect(page).not_to have_link("Remove avatar")
end end
step 'I should see the gravatar host link' do
expect(page).to have_link("gravatar.com")
end
step 'I try change my password w/o old one' do step 'I try change my password w/o old one' do
page.within '.update-password' do page.within '.update-password' do
fill_in "user_password", with: "22233344" fill_in "user_password", with: "22233344"
......
...@@ -57,10 +57,11 @@ module Gitlab ...@@ -57,10 +57,11 @@ module Gitlab
title = range.reference_title title = range.reference_title
klass = reference_class(:commit_range) klass = reference_class(:commit_range)
data = data_attribute(project.id)
project_ref += '@' if project_ref project_ref += '@' if project_ref
%(<a href="#{url}" %(<a href="#{url}" #{data}
title="#{title}" title="#{title}"
class="#{klass}">#{project_ref}#{range}</a>) class="#{klass}">#{project_ref}#{range}</a>)
else else
......
...@@ -47,10 +47,11 @@ module Gitlab ...@@ -47,10 +47,11 @@ module Gitlab
title = escape_once(commit.link_title) title = escape_once(commit.link_title)
klass = reference_class(:commit) klass = reference_class(:commit)
data = data_attribute(project.id)
project_ref += '@' if project_ref project_ref += '@' if project_ref
%(<a href="#{url}" %(<a href="#{url}" #{data}
title="#{title}" title="#{title}"
class="#{klass}">#{project_ref}#{commit.short_id}</a>) class="#{klass}">#{project_ref}#{commit.short_id}</a>)
else else
......
...@@ -49,8 +49,9 @@ module Gitlab ...@@ -49,8 +49,9 @@ module Gitlab
title = escape_once("Issue: #{issue.title}") title = escape_once("Issue: #{issue.title}")
klass = reference_class(:issue) klass = reference_class(:issue)
data = data_attribute(project.id)
%(<a href="#{url}" %(<a href="#{url}" #{data}
title="#{title}" title="#{title}"
class="#{klass}">#{match}</a>) class="#{klass}">#{match}</a>)
else else
......
...@@ -43,8 +43,9 @@ module Gitlab ...@@ -43,8 +43,9 @@ module Gitlab
url = url_for_label(project, label) url = url_for_label(project, label)
klass = reference_class(:label) klass = reference_class(:label)
data = data_attribute(project.id)
%(<a href="#{url}" %(<a href="#{url}" #{data}
class="#{klass}">#{render_colored_label(label)}</a>) class="#{klass}">#{render_colored_label(label)}</a>)
else else
match match
......
...@@ -47,10 +47,11 @@ module Gitlab ...@@ -47,10 +47,11 @@ module Gitlab
title = escape_once("Merge Request: #{merge_request.title}") title = escape_once("Merge Request: #{merge_request.title}")
klass = reference_class(:merge_request) klass = reference_class(:merge_request)
data = data_attribute(project.id)
url = url_for_merge_request(merge_request, project) url = url_for_merge_request(merge_request, project)
%(<a href="#{url}" %(<a href="#{url}" #{data}
title="#{title}" title="#{title}"
class="#{klass}">#{match}</a>) class="#{klass}">#{match}</a>)
else else
......
...@@ -21,6 +21,22 @@ module Gitlab ...@@ -21,6 +21,22 @@ module Gitlab
result[:references] = Hash.new { |hash, type| hash[type] = [] } result[:references] = Hash.new { |hash, type| hash[type] = [] }
end end
# Returns a data attribute String to attach to a reference link
#
# id - Object ID
# type - Object type (default: :project)
#
# Examples:
#
# data_attribute(1) # => "data-project-id=\"1\""
# data_attribute(2, :user) # => "data-user-id=\"2\""
# data_attribute(3, :group) # => "data-group-id=\"3\""
#
# Returns a String
def data_attribute(id, type = :project)
%Q(data-#{type}-id="#{id}")
end
def escape_once(html) def escape_once(html)
ERB::Util.html_escape_once(html) ERB::Util.html_escape_once(html)
end end
......
...@@ -47,10 +47,11 @@ module Gitlab ...@@ -47,10 +47,11 @@ module Gitlab
title = escape_once("Snippet: #{snippet.title}") title = escape_once("Snippet: #{snippet.title}")
klass = reference_class(:snippet) klass = reference_class(:snippet)
data = data_attribute(project.id)
url = url_for_snippet(snippet, project) url = url_for_snippet(snippet, project)
%(<a href="#{url}" %(<a href="#{url}" #{data}
title="#{title}" title="#{title}"
class="#{klass}">#{match}</a>) class="#{klass}">#{match}</a>)
else else
......
...@@ -83,18 +83,20 @@ module Gitlab ...@@ -83,18 +83,20 @@ module Gitlab
push_result(:user, *namespace.users) push_result(:user, *namespace.users)
url = urls.group_url(group, only_path: context[:only_path]) url = urls.group_url(group, only_path: context[:only_path])
data = data_attribute(namespace.id, :group)
text = Group.reference_prefix + group text = Group.reference_prefix + group
%(<a href="#{url}" class="#{link_class}">#{text}</a>) %(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end end
def link_to_user(user, namespace) def link_to_user(user, namespace)
push_result(:user, namespace.owner) push_result(:user, namespace.owner)
url = urls.user_url(user, only_path: context[:only_path]) url = urls.user_url(user, only_path: context[:only_path])
data = data_attribute(namespace.owner_id, :user)
text = User.reference_prefix + user text = User.reference_prefix + user
%(<a href="#{url}" class="#{link_class}">#{text}</a>) %(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end end
def user_can_reference_group?(group) def user_can_reference_group?(group)
......
...@@ -80,6 +80,14 @@ module Gitlab::Markdown ...@@ -80,6 +80,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom' expect(doc.css('a').first.attr('class')).to include 'custom'
end end
it 'includes a data-project-id attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
end
it 'supports an :only_path option' do it 'supports an :only_path option' do
doc = filter("See #{reference}", only_path: true) doc = filter("See #{reference}", only_path: true)
link = doc.css('a').first.attr('href') link = doc.css('a').first.attr('href')
......
...@@ -76,6 +76,14 @@ module Gitlab::Markdown ...@@ -76,6 +76,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom' expect(doc.css('a').first.attr('class')).to include 'custom'
end end
it 'includes a data-project-id attribute' do
doc = filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
end
it 'supports an :only_path context' do it 'supports an :only_path context' do
doc = filter("See #{reference}", only_path: true) doc = filter("See #{reference}", only_path: true)
link = doc.css('a').first.attr('href') link = doc.css('a').first.attr('href')
......
...@@ -73,6 +73,14 @@ module Gitlab::Markdown ...@@ -73,6 +73,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom' expect(doc.css('a').first.attr('class')).to include 'custom'
end end
it 'includes a data-project-id attribute' do
doc = filter("Issue #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
end
it 'supports an :only_path context' do it 'supports an :only_path context' do
doc = filter("Issue #{reference}", only_path: true) doc = filter("Issue #{reference}", only_path: true)
link = doc.css('a').first.attr('href') link = doc.css('a').first.attr('href')
......
...@@ -30,6 +30,14 @@ module Gitlab::Markdown ...@@ -30,6 +30,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom' expect(doc.css('a').first.attr('class')).to include 'custom'
end end
it 'includes a data-project-id attribute' do
doc = filter("Label #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
end
it 'supports an :only_path context' do it 'supports an :only_path context' do
doc = filter("Label #{reference}", only_path: true) doc = filter("Label #{reference}", only_path: true)
link = doc.css('a').first.attr('href') link = doc.css('a').first.attr('href')
......
...@@ -61,6 +61,14 @@ module Gitlab::Markdown ...@@ -61,6 +61,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom' expect(doc.css('a').first.attr('class')).to include 'custom'
end end
it 'includes a data-project-id attribute' do
doc = filter("Merge #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
end
it 'supports an :only_path context' do it 'supports an :only_path context' do
doc = filter("Merge #{reference}", only_path: true) doc = filter("Merge #{reference}", only_path: true)
link = doc.css('a').first.attr('href') link = doc.css('a').first.attr('href')
......
...@@ -60,6 +60,14 @@ module Gitlab::Markdown ...@@ -60,6 +60,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom' expect(doc.css('a').first.attr('class')).to include 'custom'
end end
it 'includes a data-project-id attribute' do
doc = filter("Snippet #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project-id')
expect(link.attr('data-project-id')).to eq project.id.to_s
end
it 'supports an :only_path context' do it 'supports an :only_path context' do
doc = filter("Snippet #{reference}", only_path: true) doc = filter("Snippet #{reference}", only_path: true)
link = doc.css('a').first.attr('href') link = doc.css('a').first.attr('href')
......
...@@ -64,6 +64,14 @@ module Gitlab::Markdown ...@@ -64,6 +64,14 @@ module Gitlab::Markdown
expect(doc.css('a').length).to eq 1 expect(doc.css('a').length).to eq 1
end end
it 'includes a data-user-id attribute' do
doc = filter("Hey #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-user-id')
expect(link.attr('data-user-id')).to eq user.namespace.owner_id.to_s
end
it 'adds to the results hash' do it 'adds to the results hash' do
result = pipeline_result("Hey #{reference}") result = pipeline_result("Hey #{reference}")
expect(result[:references][:user]).to eq [user] expect(result[:references][:user]).to eq [user]
...@@ -85,6 +93,14 @@ module Gitlab::Markdown ...@@ -85,6 +93,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('href')).to eq urls.group_url(group) expect(doc.css('a').first.attr('href')).to eq urls.group_url(group)
end end
it 'includes a data-group-id attribute' do
doc = filter("Hey #{reference}", current_user: user)
link = doc.css('a').first
expect(link).to have_attribute('data-group-id')
expect(link.attr('data-group-id')).to eq group.id.to_s
end
it 'adds to the results hash' do it 'adds to the results hash' do
result = pipeline_result("Hey #{reference}", current_user: user) result = pipeline_result("Hey #{reference}", current_user: user)
expect(result[:references][:user]).to eq group.users expect(result[:references][:user]).to eq group.users
......
...@@ -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