summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG9
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock7
-rw-r--r--app/assets/javascripts/merge_request_widget.js.coffee11
-rw-r--r--app/assets/stylesheets/base/variables.scss5
-rw-r--r--app/assets/stylesheets/generic/common.scss4
-rw-r--r--app/assets/stylesheets/pages/commit.scss27
-rw-r--r--app/assets/stylesheets/pages/projects.scss82
-rw-r--r--app/controllers/application_controller.rb7
-rw-r--r--app/controllers/passwords_controller.rb21
-rw-r--r--app/controllers/projects/merge_requests_controller.rb1
-rw-r--r--app/helpers/diff_helper.rb2
-rw-r--r--app/helpers/merge_requests_helper.rb13
-rw-r--r--app/mailers/emails/projects.rb3
-rw-r--r--app/mailers/notify.rb2
-rw-r--r--app/models/abuse_report.rb4
-rw-r--r--app/models/ci/build.rb17
-rw-r--r--app/models/ci/project.rb3
-rw-r--r--app/models/namespace.rb4
-rw-r--r--app/models/project.rb10
-rw-r--r--app/models/user.rb1
-rw-r--r--app/services/merge_requests/merge_service.rb4
-rw-r--r--app/services/notification_service.rb4
-rw-r--r--app/services/projects/transfer_service.rb2
-rw-r--r--app/views/ci/projects/show.html.haml2
-rw-r--r--app/views/layouts/_init_auto_complete.html.haml3
-rw-r--r--app/views/layouts/notify.html.haml2
-rw-r--r--app/views/layouts/project.html.haml5
-rw-r--r--app/views/notify/merged_merge_request_email.text.haml2
-rw-r--r--app/views/notify/project_was_moved_email.html.haml2
-rw-r--r--app/views/notify/project_was_moved_email.text.erb2
-rw-r--r--app/views/projects/diffs/_diffs.html.haml6
-rw-r--r--app/views/projects/diffs/_stats.html.haml30
-rw-r--r--app/views/projects/merge_requests/_new_submit.html.haml5
-rw-r--r--app/views/projects/show.html.haml2
-rw-r--r--app/views/users/show.html.haml13
-rw-r--r--config/gitlab.yml.example1
-rw-r--r--config/initializers/devise.rb4
-rw-r--r--db/migrate/20150930001110_merge_request_error_field.rb5
-rw-r--r--db/schema.rb1
-rw-r--r--doc/migrate_ci_to_ce/README.md105
-rw-r--r--doc/update/7.14-to-8.0.md2
-rw-r--r--features/abuse_report.feature7
-rw-r--r--features/steps/abuse_reports.rb4
-rw-r--r--lib/gitlab/diff/file.rb8
-rw-r--r--lib/gitlab/diff/line.rb8
-rw-r--r--lib/gitlab/ldap/user.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb14
-rw-r--r--spec/controllers/projects_controller_spec.rb14
-rw-r--r--spec/features/password_reset_spec.rb48
-rw-r--r--spec/features/users_spec.rb4
-rw-r--r--spec/helpers/merge_requests_helper.rb12
-rw-r--r--spec/helpers/merge_requests_helper_spec.rb32
-rw-r--r--spec/mailers/notify_spec.rb3
-rw-r--r--spec/models/abuse_report_spec.rb12
-rw-r--r--spec/models/ci/build_spec.rb11
-rw-r--r--spec/models/project_spec.rb1
-rw-r--r--spec/models/user_spec.rb1
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb14
-rw-r--r--spec/services/notification_service_spec.rb6
60 files changed, 442 insertions, 196 deletions
diff --git a/CHANGELOG b/CHANGELOG
index aa8c146a6fa..a8b43dd4608 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.1.0 (unreleased)
+ - Include full path of source and target branch names in New Merge Request page (Stan Hu)
+ - Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
- Add user preference to view activities as default dashboard (Stan Hu)
- Add option to admin area to sign in as a specific user (Pavel Forkert)
- Show CI status on all pages where commits list is rendered
@@ -18,6 +20,11 @@ v 8.1.0 (unreleased)
- Move CI triggers page to project settings area
- Move CI project settings page to CE project settings area
- Fix bug when removed file was not appearing in merge request diff
+ - Note the original location of a moved project when notifying users of the move
+ - Improve error message when merging fails
+ - Add support of multibyte characters in LDAP UID (Roman Petrov)
+ - Show additions/deletions stats on merge request diff
+ - Remove footer text in emails (Zeger-Jan van de Weg)
- Ensure code blocks are properly highlighted after a note is updated
v 8.0.3
@@ -104,6 +111,8 @@ v 8.0.0
- Webhook for issue now contains repository field (Jungkook Park)
- Add ability to add custom text to the help page (Jeroen van Baarsen)
- Add pg_schema to backup config
+ - Fix references to target project issues in Merge Requests markdown preview and textareas (Francesco Levorato)
+ - Redirect from incorrectly cased group or project path to correct one (Francesco Levorato)
- Removed API calls from CE to CI
v 7.14.3
diff --git a/Gemfile b/Gemfile
index 6950091b2b0..f1674c560e2 100644
--- a/Gemfile
+++ b/Gemfile
@@ -47,7 +47,7 @@ gem "browser", '~> 1.0.0'
# Extracting information from a git repository
# Provide access to Gitlab::Git library
-gem "gitlab_git", '~> 7.2.15'
+gem "gitlab_git", '~> 7.2.17'
# LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes
diff --git a/Gemfile.lock b/Gemfile.lock
index 4386c6b9abb..6472221bc54 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -278,7 +278,7 @@ GEM
mime-types (~> 1.19)
gitlab_emoji (0.1.1)
gemojione (~> 2.0)
- gitlab_git (7.2.15)
+ gitlab_git (7.2.17)
activesupport (~> 4.0)
charlock_holmes (~> 0.6)
gitlab-linguist (~> 3.0)
@@ -834,7 +834,7 @@ DEPENDENCIES
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-linguist (~> 3.0.1)
gitlab_emoji (~> 0.1)
- gitlab_git (~> 7.2.15)
+ gitlab_git (~> 7.2.17)
gitlab_meta (= 7.0)
gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.0.2)
@@ -937,3 +937,6 @@ DEPENDENCIES
webmock (~> 1.21.0)
whenever (~> 0.8.4)
wikicloth (= 0.8.1)
+
+BUNDLED WITH
+ 1.10.6
diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee
index 995a2f24093..3176e5a8965 100644
--- a/app/assets/javascripts/merge_request_widget.js.coffee
+++ b/app/assets/javascripts/merge_request_widget.js.coffee
@@ -15,11 +15,12 @@ class @MergeRequestWidget
type: 'GET'
url: $('.merge-request').data('url')
success: (data) =>
- switch data.state
- when 'merged'
- location.reload()
- else
- setTimeout(merge_request_widget.mergeInProgress, 2000)
+ if data.state == "merged"
+ location.reload()
+ else if data.merge_error
+ $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>")
+ else
+ setTimeout(merge_request_widget.mergeInProgress, 2000)
dataType: 'json'
getMergeStatus: ->
diff --git a/app/assets/stylesheets/base/variables.scss b/app/assets/stylesheets/base/variables.scss
index f6bdea9a897..befd63832d5 100644
--- a/app/assets/stylesheets/base/variables.scss
+++ b/app/assets/stylesheets/base/variables.scss
@@ -1,5 +1,8 @@
$hover: #FFFAF1;
-$gl-text-color: #54565b;
+$gl-text-color: #54565B;
+$gl-text-green: #4A2;
+$gl-text-red: #D12F19;
+$gl-text-orange: #D90;
$gl-header-color: #4c4e54;
$gl-link-color: #333c48;
$md-text-color: #444;
diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss
index 96fb791c242..016cc015e9c 100644
--- a/app/assets/stylesheets/generic/common.scss
+++ b/app/assets/stylesheets/generic/common.scss
@@ -1,8 +1,8 @@
/** COLORS **/
.cgray { color: $gl-gray; }
.clgray { color: #BBB }
-.cred { color: #D12F19 }
-.cgreen { color: #4a2 }
+.cred { color: $gl-text-red; }
+.cgreen { color: $gl-text-green; }
.cdark { color: #444 }
/** COMMON CLASSES **/
diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss
index 051ca3792c3..741ff9051a2 100644
--- a/app/assets/stylesheets/pages/commit.scss
+++ b/app/assets/stylesheets/pages/commit.scss
@@ -49,30 +49,33 @@
}
.file-stats {
+ ul {
+ list-style: none;
+ margin: 0;
+ padding: 10px 0;
+
+ li {
+ padding: 3px 0px;
+ }
+ }
.new-file {
a {
- color: #090;
- }
- i {
- color: #1BCF00;
+ color: $gl-text-green;
}
}
.renamed-file {
- i {
- color: #FE9300;
+ a {
+ color: $gl-text-orange;
}
}
.deleted-file {
a {
- color: #B00;
- }
- i {
- color: #EE0000;
+ color: $gl-text-red;
}
}
.edit-file{
- i{
- color: #555;
+ a {
+ color: $gl-text-color;
}
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 31051785676..818aa10aefe 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -1,6 +1,6 @@
.alert_holder {
margin: -16px;
-
+
.alert-link {
font-weight: normal;
}
@@ -31,20 +31,20 @@
margin: -$gl-padding;
padding: $gl-padding;
padding: 44px 0 17px 0;
-
+
.project-identicon-holder {
margin-bottom: 16px;
-
+
.avatar, .identicon {
margin: 0 auto;
float: none;
}
-
+
.identicon {
@include border-radius(50%);
}
}
-
+
.project-home-dropdown {
margin: 11px 3px 0;
}
@@ -86,15 +86,15 @@
top: 17px;
margin-bottom: 44px;
}
-
+
.project-repo-buttons {
margin-top: 12px;
margin-bottom: 0px;
-
+
.btn {
@include bnt-project;
@include btn-info;
-
+
.count {
display: inline-block;
}
@@ -105,7 +105,7 @@
.split-one {
display: inline-table;
margin-right: 12px;
-
+
a {
margin: -1px !important;
}
@@ -129,10 +129,10 @@
&.git-protocols {
padding: 0;
border: none;
-
+
.input-group-btn:last-child > .btn {
@include border-radius-right(0);
-
+
border-left: 1px solid #c6cacf;
margin-left: -2px !important;
}
@@ -141,55 +141,55 @@
}
.projects-search-form {
-
+
.input-group .form-control {
height: 42px;
}
}
.input-group-btn {
- .btn {
+ .btn {
@include bnt-project;
@include btn-middle;
-
+
&:hover {
outline: none;
}
-
+
&:focus {
outline: none;
}
-
+
&:active {
outline: none;
}
}
-
+
.active {
@include box-shadow(inset 0 0 4px rgba(0, 0, 0, 0.12));
-
+
border: 1px solid #c6cacf !important;
background-color: #e4e7ed !important;
}
-
+
.btn-green {
@include btn-green
}
-
+
}
.split-repo-buttons {
display: inline-table;
margin: 0 12px 0 12px;
-
+
.btn{
@include bnt-project;
@include btn-info;
}
-
+
.dropdown-toggle {
margin: -5px;
- }
+ }
}
#notification-form {
@@ -202,7 +202,7 @@
.open > .dropdown-new.btn {
@include box-shadow(inset 0 0 4px rgba(0, 0, 0, 0.12));
-
+
border: 1px solid #c6cacf !important;
background-color: #e4e7ed !important;
text-transform: uppercase;
@@ -214,21 +214,21 @@
.dropdown-menu {
@include box-shadow(rgba(76, 86, 103, 0.247059) 0px 0px 1px 0px, rgba(31, 37, 50, 0.317647) 0px 2px 18px 0px);
@include border-radius (0px);
-
+
border: none;
padding: 16px 0;
font-size: 14px;
font-weight: 100;
-
+
li a {
color: #5f697a;
line-height: 30px;
-
+
&:hover {
- background-color: #3084bb !important;
+ background-color: #3084bb !important;
}
}
-
+
.fa-fw {
margin-right: 8px;
}
@@ -370,7 +370,7 @@ table.table.protected-branches-list tr.no-border {
ul.nav-pills {
display:inline-block;
}
-
+
.nav-pills li {
display:inline;
}
@@ -378,12 +378,12 @@ table.table.protected-branches-list tr.no-border {
.nav > li > a {
@include btn-info;
@include bnt-project;
-
+
background-color: transparent;
border: 1px solid #f7f8fa;
margin-left: 12px;
}
-
+
li {
display:inline;
}
@@ -418,27 +418,27 @@ pre.light-well {
.git-empty {
margin: 0 7px 0 7px;
-
+
h5 {
color: #5c5d5e;
}
-
+
.light-well {
@include border-radius (2px);
-
+
color: #5b6169;
- font-size: 13px;
- line-height: 1.6em;
+ font-size: 13px;
+ line-height: 1.6em;
}
}
-.prepend-top-20 {
+.project-footer {
margin-top: 20px;
-
+
.btn-remove {
@include btn-middle;
@include btn-remove;
-
+
float: left !important;
}
}
@@ -446,7 +446,7 @@ pre.light-well {
/*
* Projects list rendered on dashboard and user page
*/
-
+
.projects-list {
@include basic-list;
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 9b6472a7b13..527c9da0faa 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -117,9 +117,14 @@ class ApplicationController < ActionController::Base
redirect_to request.original_url.gsub(/\.git\Z/, '') and return
end
- @project = Project.find_with_namespace("#{namespace}/#{id}")
+ project_path = "#{namespace}/#{id}"
+ @project = Project.find_with_namespace(project_path)
+
if @project and can?(current_user, :read_project, @project)
+ if @project.path_with_namespace != project_path
+ redirect_to request.original_url.gsub(project_path, @project.path_with_namespace) and return
+ end
@project
elsif current_user.nil?
@project = nil
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
index 8450ba31021..edf43935f3c 100644
--- a/app/controllers/passwords_controller.rb
+++ b/app/controllers/passwords_controller.rb
@@ -16,27 +16,6 @@ class PasswordsController < Devise::PasswordsController
end
end
- # After a user resets their password, prompt for 2FA code if enabled instead
- # of signing in automatically
- #
- # See http://git.io/vURrI
- def update
- super do |resource|
- # TODO (rspeicher): In Devise master (> 3.4.1), we can set
- # `Devise.sign_in_after_reset_password = false` and avoid this mess.
- if resource.errors.empty? && resource.try(:two_factor_enabled?)
- resource.unlock_access! if unlockable?(resource)
-
- # Since we are not signing this user in, we use the :updated_not_active
- # message which only contains "Your password was changed successfully."
- set_flash_message(:notice, :updated_not_active) if is_flashing_format?
-
- # Redirect to sign in so they can enter 2FA code
- respond_with(resource, location: new_session_path(resource)) and return
- end
- end
- end
-
def edit
super
reset_password_token = Devise.token_generator.digest(
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 7574842cd43..7570934e727 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -150,6 +150,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return access_denied! unless @merge_request.can_be_merged_by?(current_user)
if @merge_request.mergeable?
+ @merge_request.update(merge_error: nil)
MergeWorker.perform_async(@merge_request.id, current_user.id, params)
@status = true
else
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 9d718e13b85..b896fba3704 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -170,7 +170,7 @@ module DiffHelper
def commit_for_diff(diff)
if diff.deleted_file
- @merge_request ? @merge_request.commits.last : @commit.parent_id
+ @merge_request ? @merge_request.commits.last : @commit.parents.first
else
@commit
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index f8169b4f288..81773e7afcf 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -71,4 +71,17 @@ module MergeRequestsHelper
merge_request.source_branch
end
end
+
+ def format_mr_branch_names(merge_request)
+ source_path = merge_request.source_project_path
+ target_path = merge_request.target_project_path
+ source_branch = merge_request.source_branch
+ target_branch = merge_request.target_branch
+
+ if source_path == target_path
+ [source_branch, target_branch]
+ else
+ ["#{source_path}:#{source_branch}", "#{target_path}:#{target_branch}"]
+ end
+ end
end
diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb
index 4a6e18e6a74..caba63006da 100644
--- a/app/mailers/emails/projects.rb
+++ b/app/mailers/emails/projects.rb
@@ -50,10 +50,11 @@ module Emails
subject: subject("Invitation declined"))
end
- def project_was_moved_email(project_id, user_id)
+ def project_was_moved_email(project_id, user_id, old_path_with_namespace)
@current_user = @user = User.find user_id
@project = Project.find project_id
@target_url = namespace_project_url(@project.namespace, @project)
+ @old_path_with_namespace = old_path_with_namespace
mail(to: @user.notification_email,
subject: subject("Project was moved"))
end
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index db2f9654e14..50a409c3754 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -140,7 +140,7 @@ class Notify < BaseMailer
# * have a 'In-Reply-To' or 'References' header that references the original 'Message-ID'
#
def mail_answer_thread(model, headers = {})
- headers['Message-ID'] = SecureRandom.hex
+ headers['Message-ID'] = "<#{SecureRandom.hex}@#{Gitlab.config.gitlab.host}>"
headers['In-Reply-To'] = message_id(model)
headers['References'] = message_id(model)
diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb
index 07c87a7fe87..89b3116b9f2 100644
--- a/app/models/abuse_report.rb
+++ b/app/models/abuse_report.rb
@@ -11,11 +11,11 @@
#
class AbuseReport < ActiveRecord::Base
- belongs_to :reporter, class_name: "User"
+ belongs_to :reporter, class_name: 'User'
belongs_to :user
validates :reporter, presence: true
validates :user, presence: true
validates :message, presence: true
- validates :user_id, uniqueness: { scope: :reporter_id }
+ validates :user_id, uniqueness: true
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index cda4fdd4982..19f957eb965 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -143,12 +143,6 @@ module Ci
html ||= ''
end
- def trace
- if project && read_attribute(:trace).present?
- read_attribute(:trace).gsub(project.token, 'xxxxxx')
- end
- end
-
def started?
!pending? && !canceled? && started_at
end
@@ -223,7 +217,7 @@ module Ci
end
end
- def trace
+ def raw_trace
if File.exist?(path_to_trace)
File.read(path_to_trace)
else
@@ -232,6 +226,15 @@ module Ci
end
end
+ def trace
+ trace = raw_trace
+ if project && trace.present?
+ trace.gsub(project.token, 'xxxxxx')
+ else
+ trace
+ end
+ end
+
def trace=(trace)
unless Dir.exists? dir_to_trace
FileUtils.mkdir_p dir_to_trace
diff --git a/app/models/ci/project.rb b/app/models/ci/project.rb
index f0a8fc703b5..24f70171094 100644
--- a/app/models/ci/project.rb
+++ b/app/models/ci/project.rb
@@ -169,8 +169,7 @@ module Ci
# using http and basic auth
def repo_url_with_auth
auth = "gitlab-ci-token:#{token}@"
- url = http_url_to_repo + ".git"
- url.sub(/^https?:\/\//) do |prefix|
+ http_url_to_repo.sub(/^https?:\/\//) do |prefix|
prefix + auth
end
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 161a16ca61c..bc8525df5a5 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -137,7 +137,9 @@ class Namespace < ActiveRecord::Base
end
def send_update_instructions
- projects.each(&:send_move_instructions)
+ projects.each do |project|
+ project.send_move_instructions("#{path_was}/#{project.path}")
+ end
end
def kind
diff --git a/app/models/project.rb b/app/models/project.rb
index 953b37e3f7a..8527fa29808 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -238,10 +238,10 @@ class Project < ActiveRecord::Base
return nil unless id.include?('/')
id = id.split('/')
- namespace = Namespace.find_by(path: id.first)
+ namespace = Namespace.by_path(id.first)
return nil unless namespace
- where(namespace_id: namespace.id).find_by(path: id.second)
+ where(namespace_id: namespace.id).where("LOWER(projects.path) = :path", path: id.second.downcase).first
end
def visibility_levels
@@ -481,8 +481,8 @@ class Project < ActiveRecord::Base
end
end
- def send_move_instructions
- NotificationService.new.project_was_moved(self)
+ def send_move_instructions(old_path_with_namespace)
+ NotificationService.new.project_was_moved(self, old_path_with_namespace)
end
def owner
@@ -624,7 +624,7 @@ class Project < ActiveRecord::Base
# So we basically we mute exceptions in next actions
begin
gitlab_shell.mv_repository("#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
- send_move_instructions
+ send_move_instructions(old_path_with_namespace)
reset_events_cache
rescue
# Returning false does not rollback after_* transaction but gives
diff --git a/app/models/user.rb b/app/models/user.rb
index 3879f3fd381..9ea7cabff15 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -129,6 +129,7 @@ class User < ActiveRecord::Base
has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue"
has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest"
has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy
+ has_one :abuse_report, dependent: :destroy
#
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 98a67c0bc99..fcc0f2a6a8d 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -38,6 +38,10 @@ module MergeRequests
}
repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options)
+ rescue Exception => e
+ merge_request.update(merge_error: "Something went wrong during merge")
+ Rails.logger.error(e.message)
+ return false
end
def after_merge
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index e294b23bc23..a6b22348650 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -183,12 +183,12 @@ class NotificationService
mailer.group_access_granted_email(group_member.id)
end
- def project_was_moved(project)
+ def project_was_moved(project, old_path_with_namespace)
recipients = project.team.members
recipients = reject_muted_users(recipients, project)
recipients.each do |recipient|
- mailer.project_was_moved_email(project.id, recipient.id)
+ mailer.project_was_moved_email(project.id, recipient.id, old_path_with_namespace)
end
end
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index 550ed6897dd..c327c244f0d 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -38,7 +38,7 @@ module Projects
project.save!
# Notifications
- project.send_move_instructions
+ project.send_move_instructions(old_path)
# Move main repository
unless gitlab_shell.mv_repository(old_path, new_path)
diff --git a/app/views/ci/projects/show.html.haml b/app/views/ci/projects/show.html.haml
index 73e60795ba6..888b1ea41d5 100644
--- a/app/views/ci/projects/show.html.haml
+++ b/app/views/ci/projects/show.html.haml
@@ -17,7 +17,7 @@
= link_to @ref, ci_project_path(@project, ref: @ref)
%li.pull-right
- = link_to 'View on GitLab', @project.gitlab_url, no_turbolink.merge( class: 'btn btn-sm' )
+ = link_to 'Go to project', project_path(gl_project), class: 'btn btn-sm'
- if @ref
%p
diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml
index 3c58f10e759..035fe0056d3 100644
--- a/app/views/layouts/_init_auto_complete.html.haml
+++ b/app/views/layouts/_init_auto_complete.html.haml
@@ -1,3 +1,4 @@
+- project = @target_project || @project
:javascript
- GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(@project.namespace, @project, type: @noteable.class, type_id: params[:id])}"
+ GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(project.namespace, project, type: @noteable.class, type_id: params[:id])}"
GitLab.GfmAutoComplete.setup();
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index ec209c38eed..2f7d7e86f56 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -42,5 +42,3 @@
- else
#{link_to "View it on GitLab", @target_url}
= email_action @target_url
- - if @project && !@disable_footer
- You're receiving this notification because you are a member of the #{link_to_unless @target_url, @project.name_with_namespace, namespace_project_url(@project.namespace, @project)} project team.
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index 78dafcd8bfa..abf73bcc709 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -3,10 +3,11 @@
- sidebar "project" unless sidebar
- content_for :scripts_body_top do
+ - project = @target_project || @project
- if current_user
:javascript
- window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}";
- window.markdown_preview_path = "#{markdown_preview_namespace_project_path(@project.namespace, @project)}";
+ window.project_uploads_path = "#{namespace_project_uploads_path project.namespace,project}";
+ window.markdown_preview_path = "#{markdown_preview_namespace_project_path(project.namespace, project)}";
- content_for :scripts_body do
= render "layouts/init_auto_complete" if current_user
diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml
index 9db75bdb19e..34dbc60e19b 100644
--- a/app/views/notify/merged_merge_request_email.text.haml
+++ b/app/views/notify/merged_merge_request_email.text.haml
@@ -1,6 +1,6 @@
= "Merge Request ##{@merge_request.iid} was merged"
-Merge Request Url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)}
+Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)}
= merge_path_description(@merge_request, 'to')
diff --git a/app/views/notify/project_was_moved_email.html.haml b/app/views/notify/project_was_moved_email.html.haml
index 3cd759f1f57..87b3ff7f0b3 100644
--- a/app/views/notify/project_was_moved_email.html.haml
+++ b/app/views/notify/project_was_moved_email.html.haml
@@ -1,5 +1,5 @@
%p
- Project was moved to another location
+ Project #{@old_path_with_namespace} was moved to another location
%p
The project is now located under
= link_to namespace_project_url(@project.namespace, @project) do
diff --git a/app/views/notify/project_was_moved_email.text.erb b/app/views/notify/project_was_moved_email.text.erb
index b3f18b35a4d..d8a23dabf49 100644
--- a/app/views/notify/project_was_moved_email.text.erb
+++ b/app/views/notify/project_was_moved_email.text.erb
@@ -1,4 +1,4 @@
-Project was moved to another location
+Project #{@old_path_with_namespace} was moved to another location
The project is now located under
<%= namespace_project_url(@project.namespace, @project) %>
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index c5acafa2630..4f1965bfb39 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -1,14 +1,14 @@
- if params[:view] == 'parallel'
- fluid_layout true
+- diff_files = safe_diff_files(diffs)
+
.gray-content-block.second-block
.inline-parallel-buttons
.btn-group
= inline_diff_btn
= parallel_diff_btn
- = render 'projects/diffs/stats', diffs: diffs
-
-- diff_files = safe_diff_files(diffs)
+ = render 'projects/diffs/stats', diff_files: diff_files
- if diff_files.count < diffs.size
= render 'projects/diffs/warning', diffs: diffs, shown_files_count: diff_files.count
diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml
index c4d7f26430b..ea2a3e01277 100644
--- a/app/views/projects/diffs/_stats.html.haml
+++ b/app/views/projects/diffs/_stats.html.haml
@@ -2,37 +2,35 @@
.commit-stat-summary
Showing
= link_to '#', class: 'js-toggle-button' do
- %strong #{pluralize(diffs.count, "changed file")}
- - if current_controller?(:commit)
- - unless @commit.has_zero_stats?
- with
- %strong.cgreen #{@commit.stats.additions} additions
- and
- %strong.cred #{@commit.stats.deletions} deletions
+ %strong #{pluralize(diff_files.count, "changed file")}
+ with
+ %strong.cgreen #{diff_files.sum(&:added_lines)} additions
+ and
+ %strong.cred #{diff_files.sum(&:removed_lines)} deletions
.file-stats.js-toggle-content.hide
%ul
- - diffs.each_with_index do |diff, i|
+ - diff_files.each_with_index do |diff_file, i|
%li
- - if diff.deleted_file
+ - if diff_file.deleted_file
%span.deleted-file
%a{href: "#diff-#{i}"}
%i.fa.fa-minus
- = diff.old_path
- - elsif diff.renamed_file
+ = diff_file.old_path
+ - elsif diff_file.renamed_file
%span.renamed-file
%a{href: "#diff-#{i}"}
%i.fa.fa-minus
- = diff.old_path
+ = diff_file.old_path
&rarr;
- = diff.new_path
- - elsif diff.new_file
+ = diff_file.new_path
+ - elsif diff_file.new_file
%span.new-file
%a{href: "#diff-#{i}"}
%i.fa.fa-plus
- = diff.new_path
+ = diff_file.new_path
- else
%span.edit-file
%a{href: "#diff-#{i}"}
%i.fa.fa-adjust
- = diff.new_path
+ = diff_file.new_path
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index 46aeecd8733..6244d3ba0b4 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -1,10 +1,11 @@
%h3.page-title
New merge request
%p.slead
+ - source_title, target_title = format_mr_branch_names(@merge_request)
From
- %strong.label-branch #{@merge_request.source_project_namespace}:#{@merge_request.source_branch}
+ %strong.label-branch #{source_title}
%span into
- %strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
+ %strong.label-branch #{target_title}
%span.pull-right
= link_to 'Change branches', mr_change_branches_path(@merge_request)
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 6a5fc689803..efa119edd5a 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -75,7 +75,7 @@
- if current_user
- access = user_max_access_in_project(current_user, @project)
- if access
- .prepend-top-20
+ .prepend-top-20.project-footer
.gray-content-block.footer-block.center
You have #{access} access to this project.
- if @project.project_member_by_id(current_user)
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 37d5dba0330..11beb3e3239 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -19,14 +19,13 @@
= icon('user')
Profile settings
- elsif current_user
- .pull-right
- %span.dropdown
- %a.light.dropdown-toggle.btn.btn-sm{href: '#', "data-toggle" => "dropdown"}
+ .report_abuse.pull-right
+ - if @user.abuse_report
+ %span#report_abuse_btn.light.btn.btn-sm.btn-close{title: 'Already reported for abuse', data: {toggle: 'tooltip', placement: 'right', container: 'body'}}
+ = icon('exclamation-circle')
+ - else
+ %a.light.btn.btn-sm{href: new_abuse_report_path(user_id: @user.id), title: 'Report abuse', data: {toggle: 'tooltip', placement: 'right', container: 'body'}}
= icon('exclamation-circle')
- %ul.dropdown-menu.dropdown-menu-right
- %li
- = link_to new_abuse_report_path(user_id: @user.id) do
- Report abuse
.username
@#{@user.username}
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index c7174f86014..4f7f0b6ef19 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -424,7 +424,6 @@ test:
user_filter: ''
group_base: 'ou=groups,dc=example,dc=com'
admin_group: ''
- sync_ssh_keys: false
staging:
<<: *base
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index 2ce24592f8b..29506970af2 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -148,6 +148,10 @@ Devise.setup do |config|
# When someone else invites you to GitLab this time is also used so it should be pretty long.
config.reset_password_within = 2.days
+ # When set to false, does not sign a user in automatically after their password is
+ # reset. Defaults to true, so a user is signed in automatically after a reset.
+ config.sign_in_after_reset_password = false
+
# ==> Configuration for :encryptable
# Allow you to use another encryption algorithm besides bcrypt (default). You can use
# :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
diff --git a/db/migrate/20150930001110_merge_request_error_field.rb b/db/migrate/20150930001110_merge_request_error_field.rb
new file mode 100644
index 00000000000..c2ee498ef3f
--- /dev/null
+++ b/db/migrate/20150930001110_merge_request_error_field.rb
@@ -0,0 +1,5 @@
+class MergeRequestErrorField < ActiveRecord::Migration
+ def up
+ add_column :merge_requests, :merge_error, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4ce6cee86e5..72609da93f1 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -453,6 +453,7 @@ ActiveRecord::Schema.define(version: 20150930095736) do
t.integer "position", default: 0
t.datetime "locked_at"
t.integer "updated_by_id"
+ t.string "merge_error"
end
add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree
diff --git a/doc/migrate_ci_to_ce/README.md b/doc/migrate_ci_to_ce/README.md
index 56bf7a14182..46ce0fe98c0 100644
--- a/doc/migrate_ci_to_ce/README.md
+++ b/doc/migrate_ci_to_ce/README.md
@@ -36,6 +36,11 @@ mv /var/opt/gitlab/gitlab-ci/builds /var/opt/gitlab/gitlab-ci/builds.$(date +%s)
and run `sudo gitlab-ctl reconfigure`.
+#### 0. Updating Omnibus from versions prior to 7.13
+
+If you are updating from older versions you should first update to 7.14 and then to 8.0.
+Otherwise it's pretty likely that you will encounter problems described in the [Troubleshooting](#troubleshooting).
+
#### 1. Verify that backups work
Make sure that the backup script on both servers can connect to the database.
@@ -43,6 +48,7 @@ Make sure that the backup script on both servers can connect to the database.
```
# On your CI server:
# Omnibus
+sudo chown gitlab-ci:gitlab-ci /var/opt/gitlab/gitlab-ci/builds
sudo gitlab-ci-rake backup:create
# Source
@@ -319,3 +325,102 @@ You should also make sure that you can:
If something went wrong and you need to restore a backup, consult the [Backup
restoration](../raketasks/backup_restore.md) guide.
+
+### Troubleshooting
+
+#### show:secrets problem (Omnibus-only)
+If you see errors like this:
+```
+Missing `secret_key_base` or `db_key_base` for 'production' environment. The secrets will be generated and stored in `config/secrets.yml`
+rake aborted!
+Errno::EACCES: Permission denied @ rb_sysopen - config/secrets.yml
+```
+
+This can happen if you are updating from versions prior to 7.13 straight to 8.0.
+The fix for this is to update to Omnibus 7.14 first and then update it to 8.0.
+
+#### Permission denied when accessing /var/opt/gitlab/gitlab-ci/builds
+To fix that issue you have to change builds/ folder permission before doing final backup:
+```
+chown -R gitlab-ci:gitlab-ci /var/opt/gitlab/gitlab-ci/builds
+```
+
+#### Problems when importing CI database to GitLab
+If you were migrating CI database from MySQL to PostgreSQL manually you can see errros during import about missing sequences:
+```
+ALTER SEQUENCE
+ERROR: relation "ci_builds_id_seq" does not exist
+ERROR: relation "ci_commits_id_seq" does not exist
+ERROR: relation "ci_events_id_seq" does not exist
+ERROR: relation "ci_jobs_id_seq" does not exist
+ERROR: relation "ci_projects_id_seq" does not exist
+ERROR: relation "ci_runner_projects_id_seq" does not exist
+ERROR: relation "ci_runners_id_seq" does not exist
+ERROR: relation "ci_services_id_seq" does not exist
+ERROR: relation "ci_taggings_id_seq" does not exist
+ERROR: relation "ci_tags_id_seq" does not exist
+CREATE TABLE
+```
+
+To fix that you need to apply this SQL statement before doing final backup:
+```
+# Omnibus
+gitlab-ci-rails dbconsole <<EOF
+-- ALTER TABLES - DROP DEFAULTS
+ALTER TABLE ONLY ci_application_settings ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_builds ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_commits ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_events ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_jobs ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_projects ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_runner_projects ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_runners ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_services ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_taggings ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_tags ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_trigger_requests ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_triggers ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_variables ALTER COLUMN id DROP DEFAULT;
+ALTER TABLE ONLY ci_web_hooks ALTER COLUMN id DROP DEFAULT;
+
+-- ALTER SEQUENCES
+ALTER SEQUENCE ci_application_settings_id_seq OWNED BY ci_application_settings.id;
+ALTER SEQUENCE ci_builds_id_seq OWNED BY ci_builds.id;
+ALTER SEQUENCE ci_commits_id_seq OWNED BY ci_commits.id;
+ALTER SEQUENCE ci_events_id_seq OWNED BY ci_events.id;
+ALTER SEQUENCE ci_jobs_id_seq OWNED BY ci_jobs.id;
+ALTER SEQUENCE ci_projects_id_seq OWNED BY ci_projects.id;
+ALTER SEQUENCE ci_runner_projects_id_seq OWNED BY ci_runner_projects.id;
+ALTER SEQUENCE ci_runners_id_seq OWNED BY ci_runners.id;
+ALTER SEQUENCE ci_services_id_seq OWNED BY ci_services.id;
+ALTER SEQUENCE ci_taggings_id_seq OWNED BY ci_taggings.id;
+ALTER SEQUENCE ci_tags_id_seq OWNED BY ci_tags.id;
+ALTER SEQUENCE ci_trigger_requests_id_seq OWNED BY ci_trigger_requests.id;
+ALTER SEQUENCE ci_triggers_id_seq OWNED BY ci_triggers.id;
+ALTER SEQUENCE ci_variables_id_seq OWNED BY ci_variables.id;
+ALTER SEQUENCE ci_web_hooks_id_seq OWNED BY ci_web_hooks.id;
+
+-- ALTER TABLES - RE-APPLY DEFAULTS
+ALTER TABLE ONLY ci_application_settings ALTER COLUMN id SET DEFAULT nextval('ci_application_settings_id_seq'::regclass);
+ALTER TABLE ONLY ci_builds ALTER COLUMN id SET DEFAULT nextval('ci_builds_id_seq'::regclass);
+ALTER TABLE ONLY ci_commits ALTER COLUMN id SET DEFAULT nextval('ci_commits_id_seq'::regclass);
+ALTER TABLE ONLY ci_events ALTER COLUMN id SET DEFAULT nextval('ci_events_id_seq'::regclass);
+ALTER TABLE ONLY ci_jobs ALTER COLUMN id SET DEFAULT nextval('ci_jobs_id_seq'::regclass);
+ALTER TABLE ONLY ci_projects ALTER COLUMN id SET DEFAULT nextval('ci_projects_id_seq'::regclass);
+ALTER TABLE ONLY ci_runner_projects ALTER COLUMN id SET DEFAULT nextval('ci_runner_projects_id_seq'::regclass);
+ALTER TABLE ONLY ci_runners ALTER COLUMN id SET DEFAULT nextval('ci_runners_id_seq'::regclass);
+ALTER TABLE ONLY ci_services ALTER COLUMN id SET DEFAULT nextval('ci_services_id_seq'::regclass);
+ALTER TABLE ONLY ci_taggings ALTER COLUMN id SET DEFAULT nextval('ci_taggings_id_seq'::regclass);
+ALTER TABLE ONLY ci_tags ALTER COLUMN id SET DEFAULT nextval('ci_tags_id_seq'::regclass);
+ALTER TABLE ONLY ci_trigger_requests ALTER COLUMN id SET DEFAULT nextval('ci_trigger_requests_id_seq'::regclass);
+ALTER TABLE ONLY ci_triggers ALTER COLUMN id SET DEFAULT nextval('ci_triggers_id_seq'::regclass);
+ALTER TABLE ONLY ci_variables ALTER COLUMN id SET DEFAULT nextval('ci_variables_id_seq'::regclass);
+ALTER TABLE ONLY ci_web_hooks ALTER COLUMN id SET DEFAULT nextval('ci_web_hooks_id_seq'::regclass);
+EOF
+
+# Source
+cd /home/gitlab_ci/gitlab-ci
+sudo -u gitlab_ci -H bundle exec rails dbconsole production <<EOF
+... COPY SQL STATEMENTS FROM ABOVE ...
+EOF
+```
diff --git a/doc/update/7.14-to-8.0.md b/doc/update/7.14-to-8.0.md
index 552216be932..0e65c32098c 100644
--- a/doc/update/7.14-to-8.0.md
+++ b/doc/update/7.14-to-8.0.md
@@ -101,7 +101,7 @@ EOF
```
If your Git repositories are in a directory other than `/home/git/repositories`,
-you need to tell `gitlab-git-http-server` about it via `/etc/gitlab/default`.
+you need to tell `gitlab-git-http-server` about it via `/etc/default/gitlab`.
See `lib/support/init.d/gitlab.default.example` for the options.
### 6. Copy secrets
diff --git a/features/abuse_report.feature b/features/abuse_report.feature
index 3e1cb455b77..212972a762a 100644
--- a/features/abuse_report.feature
+++ b/features/abuse_report.feature
@@ -8,3 +8,10 @@ Feature: Abuse reports
And I click "Report abuse" button
When I fill and submit abuse form
Then I should see success message
+
+ Scenario: Report abuse available only once
+ Given I visit "Mike" user page
+ And I click "Report abuse" button
+ When I fill and submit abuse form
+ And I visit "Mike" user page
+ Then I should see a red "Report abuse" button
diff --git a/features/steps/abuse_reports.rb b/features/steps/abuse_reports.rb
index 8f9ddb2899f..56652ff6f05 100644
--- a/features/steps/abuse_reports.rb
+++ b/features/steps/abuse_reports.rb
@@ -22,6 +22,10 @@ class Spinach::Features::AbuseReports < Spinach::FeatureSteps
user_mike
end
+ step 'I should see a red "Report abuse" button' do
+ expect(find(:css, '.report_abuse')).to have_selector(:css, 'span.btn-close')
+ end
+
def user_mike
@user_mike ||= create(:user, name: 'Mike')
end
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index 4daf65331e8..142058aa69d 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -44,6 +44,14 @@ module Gitlab
diff.old_path
end
end
+
+ def added_lines
+ diff_lines.select(&:added?).size
+ end
+
+ def removed_lines
+ diff_lines.select(&:removed?).size
+ end
end
end
end
diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb
index 8ac1b15e88a..0072194606e 100644
--- a/lib/gitlab/diff/line.rb
+++ b/lib/gitlab/diff/line.rb
@@ -7,6 +7,14 @@ module Gitlab
@text, @type, @index = text, type, index
@old_pos, @new_pos = old_pos, new_pos
end
+
+ def added?
+ type == 'new'
+ end
+
+ def removed?
+ type == 'old'
+ end
end
end
end
diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb
index cb66fd500fe..1ea7751e27d 100644
--- a/lib/gitlab/ldap/user.rb
+++ b/lib/gitlab/ldap/user.rb
@@ -14,7 +14,7 @@ module Gitlab
# LDAP distinguished name is case-insensitive
identity = ::Identity.
where(provider: provider).
- where('lower(extern_uid) = ?', uid.downcase).last
+ where('lower(extern_uid) = ?', uid.mb_chars.downcase.to_s).last
identity && identity.user
end
end
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 871b9219ca9..76d56bc989d 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -8,28 +8,34 @@ describe Projects::IssuesController do
before do
sign_in(user)
project.team << [user, :developer]
- controller.instance_variable_set(:@project, project)
end
describe "GET #index" do
it "returns index" do
- get :index, namespace_id: project.namespace.id, project_id: project.id
+ get :index, namespace_id: project.namespace.path, project_id: project.path
expect(response.status).to eq(200)
end
+ it "return 301 if request path doesn't match project path" do
+ get :index, namespace_id: project.namespace.path, project_id: project.path.upcase
+
+ expect(response).to redirect_to(namespace_project_issues_path(project.namespace, project))
+ end
+
it "returns 404 when issues are disabled" do
project.issues_enabled = false
project.save
- get :index, namespace_id: project.namespace.id, project_id: project.id
+ get :index, namespace_id: project.namespace.path, project_id: project.path
expect(response.status).to eq(404)
end
it "returns 404 when external issue tracker is enabled" do
+ controller.instance_variable_set(:@project, project)
allow(project).to receive(:default_issues_tracker?).and_return(false)
- get :index, namespace_id: project.namespace.id, project_id: project.id
+ get :index, namespace_id: project.namespace.path, project_id: project.path
expect(response.status).to eq(404)
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 29233e9fae6..21beaf37fce 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -21,6 +21,20 @@ describe ProjectsController do
expect(response.body).to include("content='#{content}'")
end
end
+
+ context "when requested with case sensitive namespace and project path" do
+ it "redirects to the normalized path for case mismatch" do
+ get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase
+
+ expect(response).to redirect_to("/#{public_project.path_with_namespace}")
+ end
+
+ it "loads the page if normalized path matches request path" do
+ get :show, namespace_id: public_project.namespace.path, id: public_project.path
+
+ expect(response.status).to eq(200)
+ end
+ end
end
describe "POST #toggle_star" do
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index 2b6311e4fd7..abf66f2356d 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -1,27 +1,6 @@
require 'spec_helper'
feature 'Password reset', feature: true do
- def forgot_password
- click_on 'Forgot your password?'
- fill_in 'Email', with: user.email
- click_button 'Reset password'
- user.reload
- end
-
- def get_reset_token
- mail = ActionMailer::Base.deliveries.last
- body = mail.body.encoded
- body.scan(/reset_password_token=(.+)\"/).flatten.first
- end
-
- def reset_password(password = 'password')
- visit edit_user_password_path(reset_password_token: get_reset_token)
-
- fill_in 'New password', with: password
- fill_in 'Confirm new password', with: password
- click_button 'Change your password'
- end
-
describe 'with two-factor authentication' do
let(:user) { create(:user, :two_factor) }
@@ -40,14 +19,35 @@ feature 'Password reset', feature: true do
describe 'without two-factor authentication' do
let(:user) { create(:user) }
- it 'automatically logs in after password reset' do
+ it 'requires login after password reset' do
visit root_path
forgot_password
reset_password
- expect(current_path).to eq root_path
- expect(page).to have_content("Your password was changed successfully. You are now signed in.")
+ expect(page).to have_content("Your password was changed successfully.")
+ expect(current_path).to eq new_user_session_path
end
end
+
+ def forgot_password
+ click_on 'Forgot your password?'
+ fill_in 'Email', with: user.email
+ click_button 'Reset password'
+ user.reload
+ end
+
+ def get_reset_token
+ mail = ActionMailer::Base.deliveries.last
+ body = mail.body.encoded
+ body.scan(/reset_password_token=(.+)\"/).flatten.first
+ end
+
+ def reset_password(password = 'password')
+ visit edit_user_password_path(reset_password_token: get_reset_token)
+
+ fill_in 'New password', with: password
+ fill_in 'Confirm new password', with: password
+ click_button 'Change your password'
+ end
end
diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb
index efcb8a31abe..c1248162031 100644
--- a/spec/features/users_spec.rb
+++ b/spec/features/users_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
feature 'Users', feature: true do
+ let(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') }
+
scenario 'GET /users/sign_in creates a new user account' do
visit new_user_session_path
fill_in 'user_name', with: 'Name Surname'
@@ -11,7 +13,6 @@ feature 'Users', feature: true do
end
scenario 'Successful user signin invalidates password reset token' do
- user = create(:user)
expect(user.reset_password_token).to be_nil
visit new_user_password_path
@@ -28,7 +29,6 @@ feature 'Users', feature: true do
expect(user.reset_password_token).to be_nil
end
- let!(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') }
scenario 'Should show one error if email is already taken' do
visit new_user_session_path
fill_in 'user_name', with: 'Another user name'
diff --git a/spec/helpers/merge_requests_helper.rb b/spec/helpers/merge_requests_helper.rb
deleted file mode 100644
index 5262d644048..00000000000
--- a/spec/helpers/merge_requests_helper.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require 'spec_helper'
-
-describe MergeRequestsHelper do
- describe :issues_sentence do
- subject { issues_sentence(issues) }
- let(:issues) do
- [build(:issue, iid: 1), build(:issue, iid: 2), build(:issue, iid: 3)]
- end
-
- it { is_expected.to eq('#1, #2, and #3') }
- end
-end
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb
new file mode 100644
index 00000000000..0ef1efb8bce
--- /dev/null
+++ b/spec/helpers/merge_requests_helper_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe MergeRequestsHelper do
+ describe "#issues_sentence" do
+ subject { issues_sentence(issues) }
+ let(:issues) do
+ [build(:issue, iid: 1), build(:issue, iid: 2), build(:issue, iid: 3)]
+ end
+
+ it { is_expected.to eq('#1, #2, and #3') }
+ end
+
+ describe "#format_mr_branch_names" do
+ describe "within the same project" do
+ let(:merge_request) { create(:merge_request) }
+ subject { format_mr_branch_names(merge_request) }
+
+ it { is_expected.to eq([merge_request.source_branch, merge_request.target_branch]) }
+ end
+
+ describe "within different projects" do
+ let(:project) { create(:project) }
+ let(:fork_project) { create(:project, forked_from_project: project) }
+ let(:merge_request) { create(:merge_request, source_project: fork_project, target_project: project) }
+ subject { format_mr_branch_names(merge_request) }
+ let(:source_title) { "#{fork_project.path_with_namespace}:#{merge_request.source_branch}" }
+ let(:target_title) { "#{project.path_with_namespace}:#{merge_request.target_branch}" }
+
+ it { is_expected.to eq([source_title, target_title]) }
+ end
+ end
+end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 2c97a521d96..cb67ec95d57 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -52,6 +52,7 @@ describe Notify do
end
it 'has headers that reference an existing thread' do
+ 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 'In-Reply-To', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/
is_expected.to have_header 'X-GitLab-Project', /#{project.name}/
@@ -399,7 +400,7 @@ describe Notify do
describe 'project was moved' do
let(:project) { create(:project) }
let(:user) { create(:user) }
- subject { Notify.project_was_moved_email(project.id, user.id) }
+ subject { Notify.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
it_behaves_like 'an email sent from GitLab'
diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb
index 635a6e2518c..d45319b25d4 100644
--- a/spec/models/abuse_report_spec.rb
+++ b/spec/models/abuse_report_spec.rb
@@ -16,4 +16,16 @@ RSpec.describe AbuseReport, type: :model do
subject { create(:abuse_report) }
it { expect(subject).to be_valid }
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:reporter).class_name('User') }
+ it { is_expected.to belong_to(:user) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:reporter) }
+ it { is_expected.to validate_presence_of(:user) }
+ it { is_expected.to validate_presence_of(:message) }
+ it { is_expected.to validate_uniqueness_of(:user_id) }
+ end
end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 82623bd8190..ca070a14975 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -178,6 +178,17 @@ describe Ci::Build do
it { is_expected.to include(text) }
it { expect(subject.length).to be >= text.length }
end
+
+ context 'if build.trace hides token' do
+ let(:token) { 'my_secret_token' }
+
+ before do
+ build.project.update_attributes(token: token)
+ build.update_attributes(trace: token)
+ end
+
+ it { is_expected.to_not include(token) }
+ end
end
describe :timeout do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index ba8897b95d9..fe7bb2cc13f 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -220,6 +220,7 @@ describe Project do
end
it { expect(Project.find_with_namespace('gitlab/gitlabhq')).to eq(@project) }
+ it { expect(Project.find_with_namespace('GitLab/GitlabHQ')).to eq(@project) }
it { expect(Project.find_with_namespace('gitlab-ci')).to be_nil }
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 480950859a2..b7b525bfca2 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -85,6 +85,7 @@ describe User do
it { is_expected.to have_many(:merge_requests).dependent(:destroy) }
it { is_expected.to have_many(:assigned_merge_requests).dependent(:destroy) }
it { is_expected.to have_many(:identities).dependent(:destroy) }
+ it { is_expected.to have_one(:abuse_report) }
end
describe 'validations' do
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 7b564d34d7b..7483f51de03 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -35,5 +35,19 @@ describe MergeRequests::MergeService do
expect(note.note).to include 'Status changed to merged'
end
end
+
+ context "error handling" do
+ let(:service) { MergeRequests::MergeService.new(project, user, {}) }
+
+ it 'saves error if there is an exception' do
+ allow(service).to receive(:repository).and_raise("error")
+
+ allow(service).to receive(:execute_hooks)
+
+ service.execute(merge_request, 'Awesome message')
+
+ expect(merge_request.merge_error).to eq("Something went wrong during merge")
+ end
+ end
end
end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 8865335d0d1..520140917aa 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -427,15 +427,15 @@ describe NotificationService do
should_email(@u_watcher.id)
should_email(@u_participating.id)
should_not_email(@u_disabled.id)
- notification.project_was_moved(project)
+ notification.project_was_moved(project, "gitlab/gitlab")
end
def should_email(user_id)
- expect(Notify).to receive(:project_was_moved_email).with(project.id, user_id)
+ expect(Notify).to receive(:project_was_moved_email).with(project.id, user_id, "gitlab/gitlab")
end
def should_not_email(user_id)
- expect(Notify).not_to receive(:project_was_moved_email).with(project.id, user_id)
+ expect(Notify).not_to receive(:project_was_moved_email).with(project.id, user_id, "gitlab/gitlab")
end
end
end