From ae4fbae26cefbf10848719ee8c06d418c348420c Mon Sep 17 00:00:00 2001 From: Jonathan Rochkind Date: Thu, 8 Oct 2015 11:13:28 -0400 Subject: [PATCH 01/37] Send an email (to support) when a user is reported for spam --- app/controllers/abuse_reports_controller.rb | 3 ++ .../admin/application_settings_controller.rb | 1 + app/mailers/abuse_report_mailer.rb | 8 +++ .../abuse_report_mailer/notify.text.haml | 5 ++ .../application_settings/_form.html.haml | 4 ++ ...19_add_admin_notification_email_setting.rb | 5 ++ db/schema.rb | 3 +- .../abuse_reports_controller_spec.rb | 53 +++++++++++++++++++ 8 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 app/mailers/abuse_report_mailer.rb create mode 100644 app/views/abuse_report_mailer/notify.text.haml create mode 100644 db/migrate/20151008143519_add_admin_notification_email_setting.rb create mode 100644 spec/controllers/abuse_reports_controller_spec.rb diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb index 65dbd5ef55..482ec5054a 100644 --- a/app/controllers/abuse_reports_controller.rb +++ b/app/controllers/abuse_reports_controller.rb @@ -11,6 +11,9 @@ class AbuseReportsController < ApplicationController if @abuse_report.save message = "Thank you for your report. A GitLab administrator will look into it shortly." redirect_to root_path, notice: message + if current_application_settings.admin_notification_email.present? + AbuseReportMailer.delay.notify(@abuse_report, current_application_settings.admin_notification_email) + end else render :new end diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 5f70582cbb..18a258c139 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -55,6 +55,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :default_snippet_visibility, :restricted_signup_domains_raw, :version_check_enabled, + :admin_notification_email, :user_oauth_applications, :ci_enabled, restricted_visibility_levels: [], diff --git a/app/mailers/abuse_report_mailer.rb b/app/mailers/abuse_report_mailer.rb new file mode 100644 index 0000000000..c8b9c9c162 --- /dev/null +++ b/app/mailers/abuse_report_mailer.rb @@ -0,0 +1,8 @@ +class AbuseReportMailer < BaseMailer + + def notify(abuse_report, to_email) + @abuse_report = abuse_report + + mail(to: to_email, subject: "[Gitlab] Abuse report filed for `#{@abuse_report.user.username}`") + end +end diff --git a/app/views/abuse_report_mailer/notify.text.haml b/app/views/abuse_report_mailer/notify.text.haml new file mode 100644 index 0000000000..70e4e6a3c6 --- /dev/null +++ b/app/views/abuse_report_mailer/notify.text.haml @@ -0,0 +1,5 @@ +An abuse report was filed on `#{@abuse_report.user.username}` by `#{@abuse_report.reporter.username}`. +\ += @abuse_report.message +\ +Abuse report admin screen: #{abuse_reports_url} \ No newline at end of file diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 143cd10c54..036e24d3a4 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -47,6 +47,10 @@ = f.label :version_check_enabled do = f.check_box :version_check_enabled Version check enabled + .form-group + = f.label :admin_notification_email, class: 'control-label col-sm-2' + .col-sm-10 + = f.text_field :admin_notification_email, class: 'form-control' %fieldset %legend Account and Limit Settings diff --git a/db/migrate/20151008143519_add_admin_notification_email_setting.rb b/db/migrate/20151008143519_add_admin_notification_email_setting.rb new file mode 100644 index 0000000000..0bb581efe2 --- /dev/null +++ b/db/migrate/20151008143519_add_admin_notification_email_setting.rb @@ -0,0 +1,5 @@ +class AddAdminNotificationEmailSetting < ActiveRecord::Migration + def change + add_column :application_settings, :admin_notification_email, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 72609da93f..23627bdaa2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150930095736) do +ActiveRecord::Schema.define(version: 20151008143519) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -47,6 +47,7 @@ ActiveRecord::Schema.define(version: 20150930095736) do t.text "import_sources" t.text "help_page_text" t.boolean "ci_enabled", default: true, null: false + t.string "admin_notification_email" end create_table "audit_events", force: true do |t| diff --git a/spec/controllers/abuse_reports_controller_spec.rb b/spec/controllers/abuse_reports_controller_spec.rb new file mode 100644 index 0000000000..6d157406a2 --- /dev/null +++ b/spec/controllers/abuse_reports_controller_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe AbuseReportsController do + let(:reporter) { create(:user) } + let(:user) { create(:user) } + let(:message) { "This user is a spammer" } + + before do + sign_in(reporter) + end + + describe "with admin notification_email set" do + let(:admin_email) { "admin@example.com"} + before(:example) { allow(current_application_settings).to receive(:admin_notification_email).and_return(admin_email) } + + it "sends a notification email" do + post(:create, + abuse_report: { + user_id: user.id, + message: message + } + ) + + expect(response).to have_http_status(:redirect) + expect(flash[:notice]).to start_with("Thank you for your report") + + email = ActionMailer::Base.deliveries.last + + expect(email).to be_present + expect(email.subject).to eq("[Gitlab] Abuse report filed for `#{user.username}`") + expect(email.to).to eq([admin_email]) + expect(email.body).to include(message) + end + end + + describe "without admin notification email set" do + before(:example) { allow(current_application_settings).to receive(:admin_notification_email).and_return(nil) } + + it "does not send a notification email" do + expect do + post(:create, + abuse_report: { + user_id: user.id, + message: message + } + ) + end.to_not change{ActionMailer::Base.deliveries} + + expect(response).to have_http_status(:redirect) + expect(flash[:notice]).to start_with("Thank you for your report") + end + end +end \ No newline at end of file From b8f5e7427f7cbcdb19dcc5554301e87a880cfe2a Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 12 Oct 2015 12:07:31 +0200 Subject: [PATCH 02/37] Show notifications button even if user is not member of a project Notifications button was unavailable if user wasn't member of the project, even if protected project is available via group privileges. Showing disabled button with explanation tool-tip is less confusing. This closes #2846. --- app/controllers/projects_controller.rb | 1 + .../projects/buttons/_notifications.html.haml | 33 +++++++++++-------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 213c2a7173..ffbd91324c 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -88,6 +88,7 @@ class ProjectsController < ApplicationController else if current_user @membership = @project.project_member_by_id(current_user.id) + @group_member = GroupMember.find_by(user_id: current_user.id) end render :show diff --git a/app/views/projects/buttons/_notifications.html.haml b/app/views/projects/buttons/_notifications.html.haml index 4b69a6d7a6..501a51d0e8 100644 --- a/app/views/projects/buttons/_notifications.html.haml +++ b/app/views/projects/buttons/_notifications.html.haml @@ -1,14 +1,21 @@ -- return unless @membership +- return unless [@membership, @group_member].any? -= form_tag profile_notifications_path, method: :put, remote: true, class: 'inline-form', id: 'notification-form' do - = hidden_field_tag :notification_type, 'project' - = hidden_field_tag :notification_id, @membership.id - = hidden_field_tag :notification_level - %span.dropdown - %a.dropdown-new.btn.btn-new#notifications-button{href: '#', "data-toggle" => "dropdown"} - = icon('bell') - = notification_label(@membership) - = icon('angle-down') - %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown - - Notification.project_notification_levels.each do |level| - = notification_list_item(level, @membership) +- if @membership + = form_tag profile_notifications_path, method: :put, remote: true, class: 'inline-form', id: 'notification-form' do + = hidden_field_tag :notification_type, 'project' + = hidden_field_tag :notification_id, @membership.id + = hidden_field_tag :notification_level + %span.dropdown + %a.dropdown-new.btn.btn-new#notifications-button{href: '#', "data-toggle" => "dropdown"} + = icon('bell') + = notification_label(@membership) + = icon('angle-down') + %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown + - Notification.project_notification_levels.each do |level| + = notification_list_item(level, @membership) + +- elsif @group_member + .btn.btn-new.disabled#notifications-button + = icon('bell') + = notification_label(@group_member) + = icon('angle-down') From ddeb766e9638d14dd86d966ef097fbeebb9dffab Mon Sep 17 00:00:00 2001 From: Mike Kelly Date: Wed, 14 Oct 2015 18:42:59 +0000 Subject: [PATCH 03/37] Remove some padding from code blocks This creates a weird "leading indent" on the first line of code blocks, at least in Chrome 46, and ends up making the first row not line up nicely with everything else. --- app/assets/stylesheets/framework/typography.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index bf36f96cc9..b56758a97d 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -17,7 +17,6 @@ font-family: $monospace_font; white-space: pre; word-wrap: normal; - padding: 1px 2px; } kbd { @@ -268,4 +267,4 @@ textarea.js-gfm-input { .strikethrough { text-decoration: line-through; -} +} \ No newline at end of file From 64504b636470ad1048ba6310d6bd2dff8a28b914 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Tue, 13 Oct 2015 16:04:36 +0200 Subject: [PATCH 04/37] Add an index to milestones title and label title --- db/migrate/20151013133938_add_index_to_milestones.rb | 6 ++++++ db/schema.rb | 2 ++ 2 files changed, 8 insertions(+) create mode 100644 db/migrate/20151013133938_add_index_to_milestones.rb diff --git a/db/migrate/20151013133938_add_index_to_milestones.rb b/db/migrate/20151013133938_add_index_to_milestones.rb new file mode 100644 index 0000000000..41cd91e570 --- /dev/null +++ b/db/migrate/20151013133938_add_index_to_milestones.rb @@ -0,0 +1,6 @@ +class AddIndexToMilestones < ActiveRecord::Migration + def change + add_index :milestones, :title + add_index :labels, :title + end +end diff --git a/db/schema.rb b/db/schema.rb index 7a11dfca03..68bd9d2c3e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -410,6 +410,7 @@ ActiveRecord::Schema.define(version: 20151008130321) do end add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree + add_index "labels", ["title"], name: "index_labels_on_title", using: :btree create_table "members", force: true do |t| t.integer "access_level", null: false @@ -491,6 +492,7 @@ ActiveRecord::Schema.define(version: 20151008130321) do add_index "milestones", ["due_date"], name: "index_milestones_on_due_date", using: :btree add_index "milestones", ["project_id", "iid"], name: "index_milestones_on_project_id_and_iid", unique: true, using: :btree add_index "milestones", ["project_id"], name: "index_milestones_on_project_id", using: :btree + add_index "milestones", ["title"], name: "index_milestones_on_title", using: :btree create_table "namespaces", force: true do |t| t.string "name", null: false From b5762104abbf373d69a20532de08564eb9ae93f6 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Tue, 13 Oct 2015 16:05:04 +0200 Subject: [PATCH 05/37] Minor refactoring in seeding --- db/fixtures/development/05_users.rb | 4 ++-- db/fixtures/development/07_milestones.rb | 2 +- db/fixtures/development/09_issues.rb | 2 +- db/fixtures/development/12_snippets.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/db/fixtures/development/05_users.rb b/db/fixtures/development/05_users.rb index 378354efd5..03da29c4c6 100644 --- a/db/fixtures/development/05_users.rb +++ b/db/fixtures/development/05_users.rb @@ -1,5 +1,5 @@ Gitlab::Seeder.quiet do - (2..20).each do |i| + 20.times do |i| begin User.create!( username: FFaker::Internet.user_name, @@ -15,7 +15,7 @@ Gitlab::Seeder.quiet do end end - (1..5).each do |i| + 5.times do |i| begin User.create!( username: "user#{i}", diff --git a/db/fixtures/development/07_milestones.rb b/db/fixtures/development/07_milestones.rb index a43116829d..e028ac82ba 100644 --- a/db/fixtures/development/07_milestones.rb +++ b/db/fixtures/development/07_milestones.rb @@ -1,6 +1,6 @@ Gitlab::Seeder.quiet do Project.all.each do |project| - (1..5).each do |i| + 5.times do |i| milestone_params = { title: "v#{i}.0", description: FFaker::Lorem.sentence, diff --git a/db/fixtures/development/09_issues.rb b/db/fixtures/development/09_issues.rb index c636e96381..4fa572fca9 100644 --- a/db/fixtures/development/09_issues.rb +++ b/db/fixtures/development/09_issues.rb @@ -1,6 +1,6 @@ Gitlab::Seeder.quiet do Project.all.each do |project| - (1..10).each do |i| + 10.times do issue_params = { title: FFaker::Lorem.sentence(6), description: FFaker::Lorem.sentence, diff --git a/db/fixtures/development/12_snippets.rb b/db/fixtures/development/12_snippets.rb index 3bd4b442ad..74898544a6 100644 --- a/db/fixtures/development/12_snippets.rb +++ b/db/fixtures/development/12_snippets.rb @@ -22,7 +22,7 @@ class Member < ActiveRecord::Base end eos - (1..50).each do |i| + 50.times do |i| user = User.all.sample PersonalSnippet.seed(:id, [{ From ac44e3844deac1c13f35ca0e9a7ce995be58aab7 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 14 Oct 2015 12:20:48 +0200 Subject: [PATCH 06/37] Add project scope to milestone search --- app/finders/issuable_finder.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 97c7e74c29..d60f36e1af 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -81,7 +81,14 @@ class IssuableFinder @milestones = if milestones? - Milestone.where(title: params[:milestone_title]) + scope = + if project + project.milestones + else + Milestone.all + end + + scope.where(title: params[:milestone_title]) else nil end From 9127ae5ca80aa06b0a83d275e2a2d9b7ccfbfc3d Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 14 Oct 2015 12:23:49 +0200 Subject: [PATCH 07/37] Improve performance of queries Credits to Douwe Maan --- CHANGELOG | 1 + app/finders/issuable_finder.rb | 74 ++++++++++++------- .../20151013133938_add_index_to_milestones.rb | 6 -- 3 files changed, 47 insertions(+), 34 deletions(-) delete mode 100644 db/migrate/20151013133938_add_index_to_milestones.rb diff --git a/CHANGELOG b/CHANGELOG index 814a6772cf..8f696009d6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -63,6 +63,7 @@ v 8.1.0 (unreleased) - Only render 404 page from /public - Hide passwords from services API (Alex Lossent) - Fix: Images cannot show when projects' path was changed + - Optimize query when filtering on issuables (Zeger-Jan van de Weg) v 8.0.4 - Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu) diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index d60f36e1af..3170c0f672 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -53,15 +53,36 @@ class IssuableFinder end end + def project? + params[:project_id].present? + end + def project return @project if defined?(@project) - @project = - if params[:project_id].present? - Project.find(params[:project_id]) - else - nil - end + if project? + @project = Project.find(params[:project_id]) + + unless Ability.abilities.allowed?(current_user, :read_project, @project) + @project = nil + end + else + @project = nil + end + + @project + end + + def projects + return if project? + + return @projects if defined?(@projects) + + if current_user && params[:authorized_only].presence && !current_user_related? + current_user.authorized_projects + else + ProjectsFinder.new.execute(current_user) + end end def search @@ -84,8 +105,10 @@ class IssuableFinder scope = if project project.milestones + elsif projects + Milestone.where(project_id: projects) else - Milestone.all + Milestone.none end scope.where(title: params[:milestone_title]) @@ -127,19 +150,7 @@ class IssuableFinder private def init_collection - table_name = klass.table_name - - if project - if Ability.abilities.allowed?(current_user, :read_project, project) - project.send(table_name) - else - [] - end - elsif current_user && params[:authorized_only].presence && !current_user_related? - klass.of_projects(current_user.authorized_projects).references(:project) - else - klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project) - end + klass.all end def by_scope(items) @@ -177,7 +188,14 @@ class IssuableFinder end def by_project(items) - items = items.of_projects(project.id) if project + items = + if project + items.of_projects(project) + elsif projects + items.of_projects(projects).references(:project) + else + items.none + end items end @@ -223,17 +241,17 @@ class IssuableFinder def by_label(items) if params[:label_name].present? if params[:label_name] == Label::None.title - item_ids = LabelLink.where(target_type: klass.name).pluck(:target_id) - - items = items.where('id NOT IN (?)', item_ids) + items = items. + joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{klass.name}' AND label_links.target_id = #{klass.table_name}.id"). + where(label_links: { id: nil }) else label_names = params[:label_name].split(",") - item_ids = LabelLink.joins(:label). - where('labels.title in (?)', label_names). - where(target_type: klass.name).pluck(:target_id) + items = items.joins(:labels).where(labels: { title: label_names }) - items = items.where(id: item_ids) + if project + items = items.where('labels.project_id = :id', id: project.id) + end end end diff --git a/db/migrate/20151013133938_add_index_to_milestones.rb b/db/migrate/20151013133938_add_index_to_milestones.rb deleted file mode 100644 index 41cd91e570..0000000000 --- a/db/migrate/20151013133938_add_index_to_milestones.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddIndexToMilestones < ActiveRecord::Migration - def change - add_index :milestones, :title - add_index :labels, :title - end -end From 0108cdf49514dcaccc6a53c7b6e257fa9acfea98 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 16 Oct 2015 11:43:26 +0200 Subject: [PATCH 08/37] Improve performance of filtering issues by milestone --- app/finders/issuable_finder.rb | 63 ++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 3170c0f672..f00bb02d0f 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -74,11 +74,11 @@ class IssuableFinder end def projects - return if project? - return @projects if defined?(@projects) - if current_user && params[:authorized_only].presence && !current_user_related? + if project? + project + elsif current_user && params[:authorized_only].presence && !current_user_related? current_user.authorized_projects else ProjectsFinder.new.execute(current_user) @@ -102,14 +102,7 @@ class IssuableFinder @milestones = if milestones? - scope = - if project - project.milestones - elsif projects - Milestone.where(project_id: projects) - else - Milestone.none - end + scope = Milestone.where(project_id: projects) scope.where(title: params[:milestone_title]) else @@ -117,6 +110,14 @@ class IssuableFinder end end + def labels? + params[:label_name].present? + end + + def no_labels? + labels? && params[:label_name] == Label::None.title + end + def assignee? params[:assignee_id].present? end @@ -189,9 +190,7 @@ class IssuableFinder def by_project(items) items = - if project - items.of_projects(project) - elsif projects + if projects items.of_projects(projects).references(:project) else items.none @@ -210,18 +209,6 @@ class IssuableFinder items.sort(params[:sort]) end - def by_milestone(items) - if milestones? - if no_milestones? - items = items.where(milestone_id: [-1, nil]) - else - items = items.where(milestone_id: milestones.try(:pluck, :id)) - end - end - - items - end - def by_assignee(items) if assignee? items = items.where(assignee_id: assignee.try(:id)) @@ -238,9 +225,25 @@ class IssuableFinder items end + def by_milestone(items) + if milestones? + if no_milestones? + items = items.where(milestone_id: [-1, nil]) + else + items = items.joins(:milestone).where(milestones: { title: params[:milestone_title] }) + + if projects + items = items.where(milestones: { project_id: projects }) + end + end + end + + items + end + def by_label(items) - if params[:label_name].present? - if params[:label_name] == Label::None.title + if labels? + if no_labels? items = items. joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{klass.name}' AND label_links.target_id = #{klass.table_name}.id"). where(label_links: { id: nil }) @@ -249,8 +252,8 @@ class IssuableFinder items = items.joins(:labels).where(labels: { title: label_names }) - if project - items = items.where('labels.project_id = :id', id: project.id) + if projects + items = items.where(labels: { project_id: projects }) end end end From 7c85ebf6dc9c083d53642cbe2b6a5276c6b95aa6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 16 Oct 2015 13:24:28 +0200 Subject: [PATCH 09/37] Partly implement new UI for user page Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/framework/blocks.scss | 45 +++++++++ app/assets/stylesheets/pages/profile.scss | 6 ++ .../{ => admin}/users/_profile.html.haml | 0 app/views/admin/users/show.html.haml | 2 +- app/views/users/calendar.html.haml | 6 +- app/views/users/show.html.haml | 94 ++++++++++++------- features/steps/abuse_reports.rb | 2 +- 7 files changed, 114 insertions(+), 41 deletions(-) rename app/views/{ => admin}/users/_profile.html.haml (100%) diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 6ce34b5c3e..a09339050c 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -60,3 +60,48 @@ line-height: 42px; } } + +.cover-block { + text-align: center; + background: #f7f8fa; + margin: -$gl-padding; + margin-bottom: 0; + padding: 44px $gl-padding; + border-bottom: 1px solid $border-color; + position: relative; + + .avatar-holder { + margin-bottom: 16px; + + .avatar, .identicon { + margin: 0 auto; + float: none; + } + + .identicon { + @include border-radius(50%); + } + } + + .cover-title { + color: $gl-header-color; + margin: 0; + font-size: 23px; + font-weight: normal; + margin: 16px 0 5px 0; + color: #4c4e54; + font-size: 23px; + line-height: 1.1; + } + + .cover-desc { + padding: 0 $gl-padding; + color: $gl-text-color; + } + + .cover-controls { + position: absolute; + top: 10px; + right: 10px; + } +} diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 8e4f0eb2b2..b7391e5303 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -47,3 +47,9 @@ } } } + +.calendar-hint { + margin-top: -12px; + float: right; + font-size: 12px; +} diff --git a/app/views/users/_profile.html.haml b/app/views/admin/users/_profile.html.haml similarity index 100% rename from app/views/users/_profile.html.haml rename to app/views/admin/users/_profile.html.haml diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 231bcb0426..0848504b7a 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -14,7 +14,7 @@ %strong = link_to user_path(@user) do = @user.username - = render 'users/profile', user: @user + = render 'admin/users/profile', user: @user .panel.panel-default .panel-heading diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml index 922b0c6ceb..7f29918dba 100644 --- a/app/views/users/calendar.html.haml +++ b/app/views/users/calendar.html.haml @@ -1,7 +1,3 @@ -%h4 - Contributions calendar - .pull-right - %small Issues, merge requests and push events #cal-heatmap.calendar :javascript new Calendar( @@ -10,3 +6,5 @@ #{@starting_month}, '#{user_calendar_activities_path}' ); + +.calendar-hint Summary of issues, merge requests and push events diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 2a64708d07..4ea4a1f92c 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -6,47 +6,72 @@ = render 'shared/show_aside' -.row +.cover-block + .avatar-holder + = link_to avatar_icon(@user, 400), target: '_blank' do + = image_tag avatar_icon(@user, 90), class: "avatar s90", alt: '' + .cover-title + = @user.name + + .cover-desc + %span + @#{@user.username}. + - if @user.bio.present? + %span + #{@user.bio}. + %span + Member since #{@user.created_at.stamp("Aug 21, 2011")} + + .cover-desc + - unless @user.public_email.blank? + = link_to @user.public_email, "mailto:#{@user.public_email}" + - unless @user.skype.blank? + · + = link_to "Skype", "skype:#{@user.skype}" + - unless @user.linkedin.blank? + · + = link_to "LinkedIn", "http://www.linkedin.com/in/#{@user.linkedin}" + - unless @user.twitter.blank? + · + = link_to "Twitter", "http://www.twitter.com/#{@user.twitter}" + - unless @user.website_url.blank? + · + = link_to @user.short_website_url, @user.full_website_url + - unless @user.location.blank? + · + = @user.location + + + .cover-controls + - if @user == current_user + = link_to profile_path, class: 'btn btn-gray' do + = icon('pencil') + - elsif current_user + .report-abuse + - if @user.abuse_report + %button.btn.btn-danger{ title: 'Already reported for abuse', + data: { toggle: 'tooltip', placement: 'left', container: 'body' }} + = icon('exclamation-circle') + - else + = link_to new_abuse_report_path(user_id: @user.id), class: 'btn btn-gray', + title: 'Report abuse', data: {toggle: 'tooltip', placement: 'left', container: 'body'} do + = icon('exclamation-circle') + +.gray-content-block.second-block + .user-calendar + %h4.center.light + %i.fa.fa-spinner.fa-spin + .user-calendar-activities + + +.row.prepend-top-20 %section.col-md-7 - .header-with-avatar - = link_to avatar_icon(@user, 400), target: '_blank' do - = image_tag avatar_icon(@user, 90), class: "avatar avatar-tile s90", alt: '' - %h3 - = @user.name - - if @user == current_user - .pull-right.hidden-xs - = link_to profile_path, class: 'btn btn-sm' do - = icon('user') - Profile settings - - elsif current_user - .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') - - .username - @#{@user.username} - .description - - if @user.bio.present? - = @user.bio - - .clearfix - - if @groups.any? .prepend-top-20 %h4 Groups = render 'groups', groups: @groups %hr - .hidden-xs - .user-calendar - %h4.center.light - %i.fa.fa-spinner.fa-spin - .user-calendar-activities - %hr %h4 User Activity @@ -59,7 +84,6 @@ .content_list = spinner %aside.col-md-5 - = render 'profile', user: @user = render 'projects', projects: @projects, contributed_projects: @contributed_projects :coffeescript diff --git a/features/steps/abuse_reports.rb b/features/steps/abuse_reports.rb index 56652ff6f0..499accb0b0 100644 --- a/features/steps/abuse_reports.rb +++ b/features/steps/abuse_reports.rb @@ -23,7 +23,7 @@ class Spinach::Features::AbuseReports < Spinach::FeatureSteps end step 'I should see a red "Report abuse" button' do - expect(find(:css, '.report_abuse')).to have_selector(:css, 'span.btn-close') + expect(page).to have_button("Already reported for abuse") end def user_mike From 6909b309935f32da6bcccb1148242f19eec5de26 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 16 Oct 2015 16:39:31 +0200 Subject: [PATCH 10/37] Fix missing commit status for widget when no CI service is enabled --- .../merge_requests/widget/_heading.html.haml | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml index 68dda1424c..10efb81193 100644 --- a/app/views/projects/merge_requests/widget/_heading.html.haml +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -1,44 +1,43 @@ -- if @merge_request.has_ci? - - ci_commit = @merge_request.source_project.ci_commit(@merge_request.source_sha) - - if ci_commit - - status = ci_commit.status - .mr-widget-heading - .ci_widget{class: "ci-#{status}"} - = ci_status_icon(ci_commit) +- ci_commit = @merge_request.source_project.ci_commit(@merge_request.source_sha) +- if ci_commit + - status = ci_commit.status + .mr-widget-heading + .ci_widget{class: "ci-#{status}"} + = ci_status_icon(ci_commit) + %span CI build #{status} + for #{@merge_request.last_commit_short_sha}. + %span.ci-coverage + = link_to "View build details", ci_status_path(ci_commit) + +- elsif @merge_request.has_ci? + - # Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX + - # Remove in later versions when services like Jenkins will set CI status via Commit status API + .mr-widget-heading + - [:success, :skipped, :canceled, :failed, :running, :pending].each do |status| + .ci_widget{class: "ci-#{status}", style: "display:none"} + - if status == :success + - status = "passed" + = icon("check-circle") + - else + = icon("circle") %span CI build #{status} for #{@merge_request.last_commit_short_sha}. %span.ci-coverage - = link_to "View build details", ci_status_path(ci_commit) + - if ci_build_details_path(@merge_request) + = link_to "View build details", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - else - - # Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX - - # Remove in later versions when services like Jenkins will set CI status via Commit status API - .mr-widget-heading - - [:success, :skipped, :canceled, :failed, :running, :pending].each do |status| - .ci_widget{class: "ci-#{status}", style: "display:none"} - - if status == :success - - status = "passed" - = icon("check-circle") - - else - = icon("circle") - %span CI build #{status} - for #{@merge_request.last_commit_short_sha}. - %span.ci-coverage - - if ci_build_details_path(@merge_request) - = link_to "View build details", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" + .ci_widget + = icon("spinner spin") + Checking CI status for #{@merge_request.last_commit_short_sha}… - .ci_widget - = icon("spinner spin") - Checking CI status for #{@merge_request.last_commit_short_sha}… + .ci_widget.ci-not_found{style: "display:none"} + = icon("times-circle") + Could not find CI status for #{@merge_request.last_commit_short_sha}. - .ci_widget.ci-not_found{style: "display:none"} - = icon("times-circle") - Could not find CI status for #{@merge_request.last_commit_short_sha}. + .ci_widget.ci-error{style: "display:none"} + = icon("times-circle") + Could not connect to the CI server. Please check your settings and try again. - .ci_widget.ci-error{style: "display:none"} - = icon("times-circle") - Could not connect to the CI server. Please check your settings and try again. - - :coffeescript - $ -> - merge_request_widget.getCiStatus() + :coffeescript + $ -> + merge_request_widget.getCiStatus() From 6ad683bf13f820283a23cf44e15b241b0f4d7d87 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 11:58:14 +0200 Subject: [PATCH 11/37] Tweak email body. --- app/views/abuse_report_mailer/notify.text.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/abuse_report_mailer/notify.text.haml b/app/views/abuse_report_mailer/notify.text.haml index 70e4e6a3c6..7dacf85703 100644 --- a/app/views/abuse_report_mailer/notify.text.haml +++ b/app/views/abuse_report_mailer/notify.text.haml @@ -1,5 +1,5 @@ -An abuse report was filed on `#{@abuse_report.user.username}` by `#{@abuse_report.reporter.username}`. +#{@abuse_report.user.name} (@#{@abuse_report.user.username}) was reported for abuse by #{@abuse_report.reporter.name} (@#{@abuse_report.reporter.username}). \ -= @abuse_report.message +> #{@abuse_report.message} \ -Abuse report admin screen: #{abuse_reports_url} \ No newline at end of file +View details: #{admin_abuse_reports_url} From dc170516edb4760d9dc8843830459fe8066dff42 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 11:58:24 +0200 Subject: [PATCH 12/37] Add HTML abuse report notification email. --- app/views/abuse_report_mailer/notify.html.haml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 app/views/abuse_report_mailer/notify.html.haml diff --git a/app/views/abuse_report_mailer/notify.html.haml b/app/views/abuse_report_mailer/notify.html.haml new file mode 100644 index 0000000000..619533e09a --- /dev/null +++ b/app/views/abuse_report_mailer/notify.html.haml @@ -0,0 +1,11 @@ +%p + #{link_to @abuse_report.user.name, user_url(@abuse_report.user)} + (@#{@abuse_report.user.username}) was reported for abuse by + #{link_to @abuse_report.reporter.name, user_url(@abuse_report.reporter)} + (@#{@abuse_report.reporter.username}). + +%blockquote + = @abuse_report.message + +%p + = link_to "View details", abuse_reports_url From 9f6dc2a4b2e5eca01f5712bd7ec4d007ad4e57e5 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 11:58:45 +0200 Subject: [PATCH 13/37] Only pass abuse report ID to AbuseReportMailer. --- app/controllers/abuse_reports_controller.rb | 7 ++++--- app/mailers/abuse_report_mailer.rb | 10 +++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb index 482ec5054a..2f4054eaa1 100644 --- a/app/controllers/abuse_reports_controller.rb +++ b/app/controllers/abuse_reports_controller.rb @@ -9,11 +9,12 @@ class AbuseReportsController < ApplicationController @abuse_report.reporter = current_user if @abuse_report.save + if current_application_settings.admin_notification_email.present? + AbuseReportMailer.delay.notify(@abuse_report.id) + end + message = "Thank you for your report. A GitLab administrator will look into it shortly." redirect_to root_path, notice: message - if current_application_settings.admin_notification_email.present? - AbuseReportMailer.delay.notify(@abuse_report, current_application_settings.admin_notification_email) - end else render :new end diff --git a/app/mailers/abuse_report_mailer.rb b/app/mailers/abuse_report_mailer.rb index c8b9c9c162..f0c41f69a5 100644 --- a/app/mailers/abuse_report_mailer.rb +++ b/app/mailers/abuse_report_mailer.rb @@ -1,8 +1,12 @@ class AbuseReportMailer < BaseMailer + include Gitlab::CurrentSettings - def notify(abuse_report, to_email) - @abuse_report = abuse_report + def notify(abuse_report_id) + @abuse_report = AbuseReport.find(abuse_report_id) - mail(to: to_email, subject: "[Gitlab] Abuse report filed for `#{@abuse_report.user.username}`") + mail( + to: current_application_settings.admin_notification_email, + subject: "#{@abuse_report.user.name} (#{@abuse_report.user.username}) was reported for abuse" + ) end end From 3b1c702572facf3aff58beb91b2c5de4903d7a83 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 11:58:53 +0200 Subject: [PATCH 14/37] Fix spec. --- .../abuse_reports_controller_spec.rb | 86 ++++++++++++------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/spec/controllers/abuse_reports_controller_spec.rb b/spec/controllers/abuse_reports_controller_spec.rb index 6d157406a2..10a2cc3c3a 100644 --- a/spec/controllers/abuse_reports_controller_spec.rb +++ b/spec/controllers/abuse_reports_controller_spec.rb @@ -9,45 +9,65 @@ describe AbuseReportsController do sign_in(reporter) end - describe "with admin notification_email set" do - let(:admin_email) { "admin@example.com"} - before(:example) { allow(current_application_settings).to receive(:admin_notification_email).and_return(admin_email) } + describe "POST create" do + context "with admin notification email set" do + let(:admin_email) { "admin@example.com"} - it "sends a notification email" do - post(:create, - abuse_report: { - user_id: user.id, - message: message - } - ) + before(:each) do + stub_application_setting(admin_notification_email: admin_email) + end - expect(response).to have_http_status(:redirect) - expect(flash[:notice]).to start_with("Thank you for your report") - - email = ActionMailer::Base.deliveries.last - - expect(email).to be_present - expect(email.subject).to eq("[Gitlab] Abuse report filed for `#{user.username}`") - expect(email.to).to eq([admin_email]) - expect(email.body).to include(message) - end - end - - describe "without admin notification email set" do - before(:example) { allow(current_application_settings).to receive(:admin_notification_email).and_return(nil) } - - it "does not send a notification email" do - expect do - post(:create, + it "sends a notification email" do + post :create, abuse_report: { user_id: user.id, message: message } - ) - end.to_not change{ActionMailer::Base.deliveries} - expect(response).to have_http_status(:redirect) - expect(flash[:notice]).to start_with("Thank you for your report") + email = ActionMailer::Base.deliveries.last + + expect(email.to).to eq([admin_email]) + expect(email.subject).to include(user.username) + expect(email.text_part.body).to include(message) + end + + it "saves the abuse report" do + expect { + post :create, + abuse_report: { + user_id: user.id, + message: message + } + }.to change { AbuseReport.count }.by(1) + end + end + + context "without admin notification email set" do + before(:each) do + stub_application_setting(admin_notification_email: nil) + end + + it "does not send a notification email" do + expect { + post :create, + abuse_report: { + user_id: user.id, + message: message + } + + }.not_to change { ActionMailer::Base.deliveries.count } + end + + it "saves the abuse report" do + expect { + post :create, + abuse_report: { + user_id: user.id, + message: message + } + }.to change { AbuseReport.count }.by(1) + end end end -end \ No newline at end of file + +end From 551512b147f63a9fcab938603eb70c112e80fee7 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 11:58:59 +0200 Subject: [PATCH 15/37] Validate admin notification email. --- app/models/application_setting.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index c8841178e9..05430c2ee1 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -44,6 +44,10 @@ class ApplicationSetting < ActiveRecord::Base allow_blank: true, format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" } + validates :admin_notification_email, + allow_blank: true, + email: true + validates_each :restricted_visibility_levels do |record, attr, value| unless value.nil? value.each do |level| From 7ccfbcccef9a78f9dd469b22070663028ff0e972 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 11:59:07 +0200 Subject: [PATCH 16/37] Add help text to admin settings notification email. --- app/views/admin/application_settings/_form.html.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 791734dd80..7a78526e09 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -51,6 +51,8 @@ = f.label :admin_notification_email, class: 'control-label col-sm-2' .col-sm-10 = f.text_field :admin_notification_email, class: 'form-control' + .help-block + Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area. %fieldset %legend Account and Limit Settings From 024b6fa11a3d0d4aed017997148524e0df1eb177 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 12:06:47 +0200 Subject: [PATCH 17/37] Add changelog item --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 8f17c5c2ba..b18a08bf89 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ v 8.2.0 (unreleased) - Highlight comment based on anchor in URL v 8.1.0 (unreleased) + - Send an email to admin email when a user is reported for spam (Jonathan Rochkind) - Fix nonatomic database update potentially causing project star counts to go negative (Stan Hu) - Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu) - Speed up load times of issue detail pages by roughly 1.5x From 99b8568ff79b188d664de9744797ce4013e55526 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 12:19:30 +0200 Subject: [PATCH 18/37] Find correct group membership. --- app/controllers/projects_controller.rb | 3 +-- app/views/projects/buttons/_notifications.html.haml | 11 +++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index ffbd91324c..1ea992c4e8 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -87,8 +87,7 @@ class ProjectsController < ApplicationController render 'projects/empty' else if current_user - @membership = @project.project_member_by_id(current_user.id) - @group_member = GroupMember.find_by(user_id: current_user.id) + @membership = @project.team.find_member(current_user.id) end render :show diff --git a/app/views/projects/buttons/_notifications.html.haml b/app/views/projects/buttons/_notifications.html.haml index 6a620e7c23..9783ff8431 100644 --- a/app/views/projects/buttons/_notifications.html.haml +++ b/app/views/projects/buttons/_notifications.html.haml @@ -1,6 +1,5 @@ -- return unless [@membership, @group_member].any? - -- if @membership +- case @membership +- when ProjectMember = form_tag profile_notifications_path, method: :put, remote: true, class: 'inline', id: 'notification-form' do = hidden_field_tag :notification_type, 'project' = hidden_field_tag :notification_id, @membership.id @@ -14,8 +13,8 @@ - Notification.project_notification_levels.each do |level| = notification_list_item(level, @membership) -- elsif @group_member - .btn.btn-new.disabled#notifications-button +- when GroupMember + .btn.btn-new.disabled = icon('bell') - = notification_label(@group_member) + = notification_label(@membership) = icon('angle-down') From 1195ecd1985494704fcbd859078e5ba99182ece0 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 12:19:36 +0200 Subject: [PATCH 19/37] Add tooltip. --- app/views/projects/buttons/_notifications.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/buttons/_notifications.html.haml b/app/views/projects/buttons/_notifications.html.haml index 9783ff8431..0c29884491 100644 --- a/app/views/projects/buttons/_notifications.html.haml +++ b/app/views/projects/buttons/_notifications.html.haml @@ -14,7 +14,7 @@ = notification_list_item(level, @membership) - when GroupMember - .btn.btn-new.disabled + .btn.btn-new.disabled.has_tooltip{title: "To change the notification level, you need to be a member of the project itself, not only its group."} = icon('bell') = notification_label(@membership) = icon('angle-down') From eeea6ef25f222e3935ef4a86e59d982ba6758b9a Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 12:19:42 +0200 Subject: [PATCH 20/37] Sentences end in periods. --- app/views/shared/_clone_panel.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index b23b2f0d5e..2e4aab3630 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -6,7 +6,7 @@ type: 'button', | class: "btn #{ 'active' if default_clone_protocol == 'ssh' }#{ ' has_tooltip' if current_user && current_user.require_ssh_key? }", | :"data-clone" => project.ssh_url_to_repo, | - :"data-title" => "Add an SSH key to your profile
to pull or push via SSH", + :"data-title" => "Add an SSH key to your profile
to pull or push via SSH.", :"data-html" => "true", :"data-container" => "body"} SSH @@ -15,7 +15,7 @@ type: 'button', | class: "btn #{ 'active' if default_clone_protocol == 'http' }#{ ' has_tooltip' if current_user && current_user.require_password? }", | :"data-clone" => project.http_url_to_repo, | - :"data-title" => "Set a password on your account
to pull or push via #{gitlab_config.protocol.upcase}", + :"data-title" => "Set a password on your account
to pull or push via #{gitlab_config.protocol.upcase}.", :"data-html" => "true", :"data-container" => "body"} = gitlab_config.protocol.upcase From ef9284636cbc63a7b6a8f8ddeabb1152ad4f6a96 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 12:21:28 +0200 Subject: [PATCH 21/37] Add changelog item --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 8f17c5c2ba..2e86724b25 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ v 8.2.0 (unreleased) - Highlight comment based on anchor in URL v 8.1.0 (unreleased) + - Show notifications button when user is member of group rather than project (Grzegorz Bizon) - Fix nonatomic database update potentially causing project star counts to go negative (Stan Hu) - Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu) - Speed up load times of issue detail pages by roughly 1.5x From 2e2a2a366fa5a7b1179bf34bf22128138e52e4c7 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 13:08:08 +0200 Subject: [PATCH 22/37] Satisfy Rubocop --- spec/controllers/abuse_reports_controller_spec.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/spec/controllers/abuse_reports_controller_spec.rb b/spec/controllers/abuse_reports_controller_spec.rb index 10a2cc3c3a..0faab8d7ff 100644 --- a/spec/controllers/abuse_reports_controller_spec.rb +++ b/spec/controllers/abuse_reports_controller_spec.rb @@ -32,13 +32,13 @@ describe AbuseReportsController do end it "saves the abuse report" do - expect { + expect do post :create, abuse_report: { user_id: user.id, message: message } - }.to change { AbuseReport.count }.by(1) + end.to change { AbuseReport.count }.by(1) end end @@ -48,24 +48,23 @@ describe AbuseReportsController do end it "does not send a notification email" do - expect { + expect do post :create, abuse_report: { user_id: user.id, message: message } - - }.not_to change { ActionMailer::Base.deliveries.count } + end.not_to change { ActionMailer::Base.deliveries.count } end it "saves the abuse report" do - expect { + expect do post :create, abuse_report: { user_id: user.id, message: message } - }.to change { AbuseReport.count }.by(1) + end.to change { AbuseReport.count }.by(1) end end end From aafb36616cbad9b3478964dffc10fca97c2f55bb Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 14:26:25 +0200 Subject: [PATCH 23/37] Fix schema [ci skip] --- db/schema.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 7d60e3cf9e..886b05f3e5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -416,7 +416,6 @@ ActiveRecord::Schema.define(version: 20151016195706) do end add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree - add_index "labels", ["title"], name: "index_labels_on_title", using: :btree create_table "members", force: true do |t| t.integer "access_level", null: false @@ -498,7 +497,6 @@ ActiveRecord::Schema.define(version: 20151016195706) do add_index "milestones", ["due_date"], name: "index_milestones_on_due_date", using: :btree add_index "milestones", ["project_id", "iid"], name: "index_milestones_on_project_id_and_iid", unique: true, using: :btree add_index "milestones", ["project_id"], name: "index_milestones_on_project_id", using: :btree - add_index "milestones", ["title"], name: "index_milestones_on_title", using: :btree create_table "namespaces", force: true do |t| t.string "name", null: false From 85264ab6a9fa11a2e325d72c02c00d4b8862f933 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 18 Oct 2015 15:24:04 +0200 Subject: [PATCH 24/37] Restore notification footer text. --- app/views/layouts/notify.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 2f7d7e86f5..854cda57c3 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -41,4 +41,8 @@ #{link_to "view it on GitLab", @target_url}. - else #{link_to "View it on GitLab", @target_url} + %br + You're receiving this email because of your account on #{link_to Gitlab.config.gitlab.host, root_url}. + If you'd like to receive fewer emails, you can adjust your notification settings. + = email_action @target_url From 4ff75e317935f990b90dcc5869afe8ebb2b6fee6 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 15 Oct 2015 18:10:35 +0200 Subject: [PATCH 25/37] Improve performance of sorting milestone issues This cuts down the time it takes to sort issues of a milestone by about 10x. In the previous setup the code would run a SQL query for every issue that had to be sorted. The new setup instead runs a single SQL query to update all the given issues at once. The attached benchmark used to run at around 60 iterations per second, using the new setup this hovers around 600 iterations per second. Timing wise a request to update a milestone with 40-something issues would take about 760 ms, in the new setup this only takes about 130 ms. Fixes #3066 --- CHANGELOG | 1 + .../projects/milestones_controller.rb | 6 +--- app/models/milestone.rb | 32 +++++++++++++++++++ spec/benchmarks/models/milestone_spec.rb | 17 ++++++++++ spec/models/milestone_spec.rb | 28 ++++++++++++++++ 5 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 spec/benchmarks/models/milestone_spec.rb diff --git a/CHANGELOG b/CHANGELOG index f8daa6d246..7fefc90c54 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ v 8.2.0 (unreleased) - Show last project commit to default branch on project home page - Highlight comment based on anchor in URL - Adds ability to remove the forked relationship from project settings screen. (Han Loong Liauw) + - Improved performance of sorting milestone issues v 8.1.0 (unreleased) - Fix bug preventing mentioned issued from being closed when MR is merged using fast-forward merge. diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 86f4a02a6e..15506bd677 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -75,11 +75,7 @@ class Projects::MilestonesController < Projects::ApplicationController end def sort_issues - @issues = @milestone.issues.where(id: params['sortable_issue']) - @issues.each do |issue| - issue.position = params['sortable_issue'].index(issue.id.to_s) + 1 - issue.save - end + @milestone.sort_issues(params['sortable_issue'].map(&:to_i)) render json: { saved: true } end diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 84acba30b6..2ff16e2825 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -105,4 +105,36 @@ class Milestone < ActiveRecord::Base def author_id nil end + + # Sorts the issues for the given IDs. + # + # This method runs a single SQL query using a CASE statement to update the + # position of all issues in the current milestone (scoped to the list of IDs). + # + # Given the ids [10, 20, 30] this method produces a SQL query something like + # the following: + # + # UPDATE issues + # SET position = CASE + # WHEN id = 10 THEN 1 + # WHEN id = 20 THEN 2 + # WHEN id = 30 THEN 3 + # ELSE position + # END + # WHERE id IN (10, 20, 30); + # + # This method expects that the IDs given in `ids` are already Fixnums. + def sort_issues(ids) + pairs = [] + + ids.each_with_index do |id, index| + pairs << id + pairs << index + 1 + end + + conditions = 'WHEN id = ? THEN ? ' * ids.length + + issues.where(id: ids). + update_all(["position = CASE #{conditions} ELSE position END", *pairs]) + end end diff --git a/spec/benchmarks/models/milestone_spec.rb b/spec/benchmarks/models/milestone_spec.rb new file mode 100644 index 0000000000..a94afc4c40 --- /dev/null +++ b/spec/benchmarks/models/milestone_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe Milestone, benchmark: true do + describe '#sort_issues' do + let(:milestone) { create(:milestone) } + + let(:issue1) { create(:issue, milestone: milestone) } + let(:issue2) { create(:issue, milestone: milestone) } + let(:issue3) { create(:issue, milestone: milestone) } + + let(:issue_ids) { [issue3.id, issue2.id, issue1.id] } + + benchmark_subject { milestone.sort_issues(issue_ids) } + + it { is_expected.to iterate_per_second(500) } + end +end diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index c88d534966..77c5862732 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -140,4 +140,32 @@ describe Milestone do end end + describe '#sort_issues' do + let(:milestone) { create(:milestone) } + + let(:issue1) { create(:issue, milestone: milestone, position: 1) } + let(:issue2) { create(:issue, milestone: milestone, position: 2) } + let(:issue3) { create(:issue, milestone: milestone, position: 3) } + let(:issue4) { create(:issue, position: 42) } + + it 'sorts the given issues' do + milestone.sort_issues([issue3.id, issue2.id, issue1.id]) + + issue1.reload + issue2.reload + issue3.reload + + expect(issue1.position).to eq(3) + expect(issue2.position).to eq(2) + expect(issue3.position).to eq(1) + end + + it 'ignores issues not part of the milestone' do + milestone.sort_issues([issue3.id, issue2.id, issue1.id, issue4.id]) + + issue4.reload + + expect(issue4.position).to eq(42) + end + end end From 157d891615bbc9d1176b2149cfa5193b9aa4773c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 19 Oct 2015 11:40:13 +0200 Subject: [PATCH 26/37] Add changelog item --- CHANGELOG | 1 + app/controllers/projects_controller.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index f8daa6d246..cfb7a581e8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ v 8.2.0 (unreleased) - Show last project commit to default branch on project home page - Highlight comment based on anchor in URL - Adds ability to remove the forked relationship from project settings screen. (Han Loong Liauw) + - Allow users to select the Files view as default project view (Cristian Bica) v 8.1.0 (unreleased) - Fix bug preventing mentioned issued from being closed when MR is merged using fast-forward merge. diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 73200396ec..9f0cce468b 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -246,6 +246,8 @@ class ProjectsController < ApplicationController project.repository_exists? && !project.empty_repo? end + # Override get_id from ExtractsPath, which returns the branch and file path + # for the blob/tree, which in this case is just the root of the default branch. def get_id project.repository.root_ref end From 8b8fbd4e7f51db32425dd30770c1efcea75c00f7 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 19 Oct 2015 11:46:22 +0200 Subject: [PATCH 27/37] Rename confusing methods --- app/finders/issuable_finder.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index f00bb02d0f..c407dfc163 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -93,7 +93,7 @@ class IssuableFinder params[:milestone_title].present? end - def no_milestones? + def filter_by_no_milestone? milestones? && params[:milestone_title] == Milestone::None.title end @@ -114,7 +114,7 @@ class IssuableFinder params[:label_name].present? end - def no_labels? + def filter_by_no_label? labels? && params[:label_name] == Label::None.title end @@ -227,7 +227,7 @@ class IssuableFinder def by_milestone(items) if milestones? - if no_milestones? + if filter_by_no_milestone? items = items.where(milestone_id: [-1, nil]) else items = items.joins(:milestone).where(milestones: { title: params[:milestone_title] }) @@ -243,7 +243,7 @@ class IssuableFinder def by_label(items) if labels? - if no_labels? + if filter_by_no_label? items = items. joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{klass.name}' AND label_links.target_id = #{klass.table_name}.id"). where(label_links: { id: nil }) From 4ad64ab3f4705b7fa88f855d67e0d2d268c5e395 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 19 Oct 2015 10:32:15 -0700 Subject: [PATCH 28/37] Fix duplicate repositories in GitHub import page By default, all the current user's repositories are accessible via the /users endpoint. There's no need to traverse all the organization repositories as well. See: * http://www.rubydoc.info/github/pengwynn/octokit/Octokit/Client/Repositories#repositories-instance_method * https://developer.github.com/v3/repos/#list-your-repositories Closes #2523 --- CHANGELOG | 1 + app/controllers/import/github_controller.rb | 4 ---- spec/controllers/import/github_controller_spec.rb | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 634cf15f94..5671d8b1d8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.2.0 (unreleased) + - Fix duplicate repositories in GitHub import page (Stan Hu) - Show last project commit to default branch on project home page - Highlight comment based on anchor in URL - Adds ability to remove the forked relationship from project settings screen. (Han Loong Liauw) diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index aae77d384c..67bf4190e7 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -11,10 +11,6 @@ class Import::GithubController < Import::BaseController def status @repos = client.repos - client.orgs.each do |org| - @repos += client.org_repos(org.login) - end - @already_added_projects = current_user.created_projects.where(import_type: "github") already_added_projects_names = @already_added_projects.pluck(:import_source) diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index 766be578f7..bbf8adef53 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -41,7 +41,7 @@ describe Import::GithubController do it "assigns variables" do @project = create(:project, import_type: 'github', creator_id: user.id) - stub_client(repos: [@repo], orgs: [@org], org_repos: [@org_repo]) + stub_client(repos: [@repo, @org_repo], orgs: [@org], org_repos: [@org_repo]) get :status From d02a467d64679dd8ff02b5f4554ae5700f0bdfd7 Mon Sep 17 00:00:00 2001 From: Benny Schimmer Date: Mon, 19 Oct 2015 22:14:22 +0200 Subject: [PATCH 29/37] Fix regex in redis version check --- lib/tasks/gitlab/check.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 606bf241db..2e73f792a9 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -335,7 +335,7 @@ namespace :gitlab do print "Redis version >= #{min_redis_version}? ... " redis_version = run(%W(redis-cli --version)) - redis_version = redis_version.try(:match, /redis-cli (.*)/) + redis_version = redis_version.try(:match, /redis-cli (\d+\.\d+\.\d+)/) if redis_version && (Gem::Version.new(redis_version[1]) > Gem::Version.new(min_redis_version)) puts "yes".green From 8479feeba27800ee2e8286d759247339703f83be Mon Sep 17 00:00:00 2001 From: Benny Schimmer Date: Mon, 19 Oct 2015 23:10:17 +0200 Subject: [PATCH 30/37] Simplify patch version updates (less steps) --- doc/update/patch_versions.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md index da719229ab..593722eb01 100644 --- a/doc/update/patch_versions.md +++ b/doc/update/patch_versions.md @@ -49,9 +49,7 @@ sudo -u git -H bundle install --without development test mysql --deployment sudo -u git -H bundle install --without development test postgres --deployment sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production +sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production ``` ### 5. Start application From ffacb01be202f3b30d79116f84d0a2c7f37c96e2 Mon Sep 17 00:00:00 2001 From: Maurice Mohlek Date: Tue, 20 Oct 2015 09:40:21 +0200 Subject: [PATCH 31/37] Update CHANGELOG --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 634cf15f94..9f4dcf5fc5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,10 @@ v 8.2.0 (unreleased) - Improved performance of sorting milestone issues - Allow users to select the Files view as default project view (Cristian Bica) +v 8.0.5 + - Correct lookup-by-email for LDAP logins + - Fix loading spinner sometimes not being hidden on Merge Request tab switches + v 8.1.0 (unreleased) - Send an email to admin email when a user is reported for spam (Jonathan Rochkind) - Show notifications button when user is member of group rather than project (Grzegorz Bizon) From b0a3ece265350b8d02218746ff636a8363987580 Mon Sep 17 00:00:00 2001 From: Maurice Mohlek Date: Tue, 20 Oct 2015 09:44:13 +0200 Subject: [PATCH 32/37] Fix order --- CHANGELOG | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9f4dcf5fc5..d6b5e275fe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,10 +7,6 @@ v 8.2.0 (unreleased) - Improved performance of sorting milestone issues - Allow users to select the Files view as default project view (Cristian Bica) -v 8.0.5 - - Correct lookup-by-email for LDAP logins - - Fix loading spinner sometimes not being hidden on Merge Request tab switches - v 8.1.0 (unreleased) - Send an email to admin email when a user is reported for spam (Jonathan Rochkind) - Show notifications button when user is member of group rather than project (Grzegorz Bizon) @@ -83,6 +79,10 @@ v 8.1.0 (unreleased) - Optimize query when filtering on issuables (Zeger-Jan van de Weg) - Fix padding of outdated discussion item. +v 8.0.5 + - Correct lookup-by-email for LDAP logins + - Fix loading spinner sometimes not being hidden on Merge Request tab switches + v 8.0.4 - Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu) - Fix referrals for :back and relative URL installs From 8710739e4e5d12ac9e2aa88a553cc1e02dc2b2d1 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 20 Oct 2015 14:23:56 +0200 Subject: [PATCH 33/37] Correctly find last known blob for file deleted in MR. --- app/controllers/projects/compare_controller.rb | 3 ++- .../projects/merge_requests_controller.rb | 5 ++++- app/helpers/diff_helper.rb | 3 ++- app/models/commit.rb | 12 ++++++++---- app/models/merge_request.rb | 14 +++++++++++++- app/models/merge_request_diff.rb | 4 ++++ app/models/repository.rb | 8 +------- app/views/projects/diffs/_diffs.html.haml | 4 ++-- app/views/projects/diffs/_file.html.haml | 4 ++-- 9 files changed, 38 insertions(+), 19 deletions(-) diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index d15004f93a..71aaad1fad 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -17,9 +17,10 @@ class Projects::CompareController < Projects::ApplicationController execute(@project, head_ref, @project, base_ref) if compare_result - @commits = compare_result.commits + @commits = Commit.decorate(compare_result.commits, @project) @diffs = compare_result.diffs @commit = @commits.last + @first_commit = @commits.first @line_notes = [] end end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 0d9c546195..16c4238662 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -56,6 +56,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController def diffs @commit = @merge_request.last_commit + @first_commit = @merge_request.first_commit + @comments_allowed = @reply_allowed = true @comments_target = { noteable_type: 'MergeRequest', @@ -89,7 +91,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController @target_project = merge_request.target_project @source_project = merge_request.source_project @commits = @merge_request.compare_commits - @commit = @merge_request.compare_commits.last + @commit = @merge_request.last_commit + @first_commit = @merge_request.first_commit @diffs = @merge_request.compare_diffs @note_counts = Note.where(commit_id: @commits.map(&:id)). group(:commit_id).count diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index b896fba370..e65e37211c 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -170,7 +170,8 @@ module DiffHelper def commit_for_diff(diff) if diff.deleted_file - @merge_request ? @merge_request.commits.last : @commit.parents.first + first_commit = @first_commit || @commit + first_commit.parent else @commit end diff --git a/app/models/commit.rb b/app/models/commit.rb index 23b5e38336..492f6be1ce 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -164,6 +164,14 @@ class Commit @committer ||= User.find_by_any_email(committer_email) end + def parents + @parents ||= parent_ids.map { |id| project.commit(id) } + end + + def parent + @parent ||= project.commit(self.parent_id) if self.parent_id + end + def notes project.notes.for_commit_id(self.id) end @@ -181,10 +189,6 @@ class Commit @raw.short_id(7) end - def parents - @parents ||= Commit.decorate(super, project) - end - def ci_commit project.ci_commit(sha) end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 0042b95c4f..21861a46a8 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -40,7 +40,7 @@ class MergeRequest < ActiveRecord::Base after_create :create_merge_request_diff after_update :update_merge_request_diff - delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil + delegate :commits, :diffs, to: :merge_request_diff, prefix: nil # When this attribute is true some MR validation is ignored # It allows us to close or modify broken merge requests @@ -157,6 +157,18 @@ class MergeRequest < ActiveRecord::Base reference end + def last_commit + merge_request_diff ? merge_request_diff.last_commit : compare_commits.last + end + + def first_commit + merge_request_diff ? merge_request_diff.first_commit : compare_commits.first + end + + def last_commit_short_sha + last_commit.short_id + end + def validate_branches if target_project == source_project && target_branch == source_branch errors.add :branch_conflict, "You can not use same project/branch for source and target" diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index bc2d691ece..6575d0bc81 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -55,6 +55,10 @@ class MergeRequestDiff < ActiveRecord::Base commits.first end + def first_commit + commits.last + end + def last_commit_short_sha @last_commit_short_sha ||= last_commit.short_id end diff --git a/app/models/repository.rb b/app/models/repository.rb index 921e1a9e42..e2d4f74407 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -312,13 +312,7 @@ class Repository end def blob_for_diff(commit, diff) - file = blob_at(commit.id, diff.new_path) - - unless file - file = prev_blob_for_diff(commit, diff) - end - - file + blob_at(commit.id, diff.file_path) end def prev_blob_for_diff(commit, diff) diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml index 4f1965bfb3..56b51f038b 100644 --- a/app/views/projects/diffs/_diffs.html.haml +++ b/app/views/projects/diffs/_diffs.html.haml @@ -15,8 +15,8 @@ .files - diff_files.each_with_index do |diff_file, index| - - diff_commit = commit_for_diff(diff_file.diff) - - blob = project.repository.blob_for_diff(diff_commit, diff_file.diff) + - diff_commit = commit_for_diff(diff_file) + - blob = project.repository.blob_for_diff(diff_commit, diff_file) - next unless blob = render 'projects/diffs/file', i: index, project: project, diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 9698921f6d..410ff6abb4 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -1,5 +1,5 @@ .diff-file{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)} - .diff-header{id: "file-path-#{hexdigest(diff_file.new_path || diff_file.old_path)}"} + .diff-header{id: "file-path-#{hexdigest(diff_file.file_path)}"} - if diff_file.diff.submodule? %span - submodule_item = project.repository.blob_at(@commit.id, diff_file.file_path) @@ -38,7 +38,7 @@ - else = render "projects/diffs/text_file", diff_file: diff_file, index: i - elsif blob.image? - - old_file = project.repository.prev_blob_for_diff(@commit, diff_file) + - old_file = project.repository.prev_blob_for_diff(diff_commit, diff_file) = render "projects/diffs/image", diff_file: diff_file, old_file: old_file, file: blob, index: i - else .nothing-here-block No preview for this file type From afdc028516f27651d4d94ffd568765cf640c0c44 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 20 Oct 2015 15:49:11 +0200 Subject: [PATCH 34/37] Speed up searching for text references a bit If a node is ignored there's no need for searching for a given pattern. In turn, when searching for the pattern there's no need to construct a MatchData object as we only care about presence (or lack thereof), not the resulting matches. In terms of performance this cuts down about 200 ms when loading issue #2164 locally, though this varies a bit depending on system load. --- CHANGELOG | 1 + lib/gitlab/markdown/reference_filter.rb | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5671d8b1d8..3044ebbd7e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.2.0 (unreleased) + - Improved performance of replacing references in comments - Fix duplicate repositories in GitHub import page (Stan Hu) - Show last project commit to default branch on project home page - Highlight comment based on anchor in URL diff --git a/lib/gitlab/markdown/reference_filter.rb b/lib/gitlab/markdown/reference_filter.rb index adaca78ba2..a4c560f578 100644 --- a/lib/gitlab/markdown/reference_filter.rb +++ b/lib/gitlab/markdown/reference_filter.rb @@ -15,7 +15,7 @@ module Gitlab LazyReference = Struct.new(:klass, :ids) do def self.load(refs) lazy_references, values = refs.partition { |ref| ref.is_a?(self) } - + lazy_values = lazy_references.group_by(&:klass).flat_map do |klass, refs| ids = refs.flat_map(&:ids) klass.where(id: ids) @@ -107,10 +107,10 @@ module Gitlab return doc if project.nil? search_text_nodes(doc).each do |node| - content = node.to_html - - next unless content.match(pattern) next if ignored_ancestry?(node) + next unless node.text =~ pattern + + content = node.to_html html = yield content From e1c3077e4bb718ce841fad175f708623d8375818 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 20 Oct 2015 15:51:02 +0200 Subject: [PATCH 35/37] Added benchmark for ReferenceFilter --- .../gitlab/markdown/reference_filter_spec.rb | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 spec/benchmarks/lib/gitlab/markdown/reference_filter_spec.rb diff --git a/spec/benchmarks/lib/gitlab/markdown/reference_filter_spec.rb b/spec/benchmarks/lib/gitlab/markdown/reference_filter_spec.rb new file mode 100644 index 0000000000..34cd9f7e4e --- /dev/null +++ b/spec/benchmarks/lib/gitlab/markdown/reference_filter_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe Gitlab::Markdown::ReferenceFilter, benchmark: true do + let(:input) do + html = <<-EOF +

Hello @alice and @bob, how are you doing today?

+

This is simple @dummy text to see how the @ReferenceFilter class performs +when @processing HTML.

+ EOF + + Nokogiri::HTML.fragment(html) + end + + let(:project) { create(:empty_project) } + + let(:filter) { described_class.new(input, project: project) } + + describe '#replace_text_nodes_matching' do + let(:iterations) { 6000 } + + describe 'with identical input and output HTML' do + benchmark_subject do + filter.replace_text_nodes_matching(User.reference_pattern) do |content| + content + end + end + + it { is_expected.to iterate_per_second(iterations) } + end + + describe 'with different input and output HTML' do + benchmark_subject do + filter.replace_text_nodes_matching(User.reference_pattern) do |content| + '@eve' + end + end + + it { is_expected.to iterate_per_second(iterations) } + end + end +end From 9bfc531ec611d108c45af239a1e5e016b892231b Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 20 Oct 2015 00:28:28 -0700 Subject: [PATCH 36/37] Redirect to a default path if HTTP_REFERER is not set Safari 9.0 does not yet honor the HTML5 `origin-when-cross-origin` mode, and it's possible load balancers/proxies strip the HTTP_REFERER from the request header. In these cases, default to some default path. Closes #3122 Closes https://github.com/gitlabhq/gitlabhq/issues/9731 --- CHANGELOG | 1 + .../admin/broadcast_messages_controller.rb | 2 +- app/controllers/admin/hooks_controller.rb | 2 +- app/controllers/admin/users_controller.rb | 26 ++++++---- app/controllers/application_controller.rb | 4 ++ .../import/google_code_controller.rb | 6 +-- app/controllers/invites_controller.rb | 4 +- .../profiles/notifications_controller.rb | 2 +- app/controllers/profiles_controller.rb | 2 +- .../projects/ci_services_controller.rb | 2 +- .../projects/ci_web_hooks_controller.rb | 2 +- .../projects/deploy_keys_controller.rb | 2 +- app/controllers/projects/hooks_controller.rb | 2 +- app/controllers/projects/issues_controller.rb | 2 +- app/controllers/projects/notes_controller.rb | 4 +- .../projects/project_members_controller.rb | 3 +- .../projects/services_controller.rb | 4 +- .../admin/users_controller_spec.rb | 26 ++++++++++ spec/controllers/invites_controller_spec.rb | 33 +++++++++++++ .../projects/services_controller_spec.rb | 47 +++++++++++++------ 20 files changed, 133 insertions(+), 43 deletions(-) create mode 100644 spec/controllers/invites_controller_spec.rb diff --git a/CHANGELOG b/CHANGELOG index 5671d8b1d8..8ea1161a4c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.2.0 (unreleased) - Fix duplicate repositories in GitHub import page (Stan Hu) + - Redirect to a default path if HTTP_REFERER is not set (Stan Hu) - Show last project commit to default branch on project home page - Highlight comment based on anchor in URL - Adds ability to remove the forked relationship from project settings screen. (Han Loong Liauw) diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index 0808024fc3..497c34f8f4 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -19,7 +19,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController BroadcastMessage.find(params[:id]).destroy respond_to do |format| - format.html { redirect_to :back } + format.html { redirect_back_or_default(default: { action: 'index' }) } format.js { render nothing: true } end end diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb index d670386f8c..0bd19c49d8 100644 --- a/app/controllers/admin/hooks_controller.rb +++ b/app/controllers/admin/hooks_controller.rb @@ -35,7 +35,7 @@ class Admin::HooksController < Admin::ApplicationController } @hook.execute(data, 'system_hooks') - redirect_to :back + redirect_back_or_default end def hook_params diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 00f41a10dd..c63d0793e3 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -33,33 +33,33 @@ class Admin::UsersController < Admin::ApplicationController def block if user.block - redirect_to :back, notice: "Successfully blocked" + redirect_back_or_admin_user(notice: "Successfully blocked") else - redirect_to :back, alert: "Error occurred. User was not blocked" + redirect_back_or_admin_user(alert: "Error occurred. User was not blocked") end end def unblock if user.activate - redirect_to :back, notice: "Successfully unblocked" + redirect_back_or_admin_user(notice: "Successfully unblocked") else - redirect_to :back, alert: "Error occurred. User was not unblocked" + redirect_back_or_admin_user(alert: "Error occurred. User was not unblocked") end end def unlock if user.unlock_access! - redirect_to :back, alert: "Successfully unlocked" + redirect_back_or_admin_user(alert: "Successfully unlocked") else - redirect_to :back, alert: "Error occurred. User was not unlocked" + redirect_back_or_admin_user(alert: "Error occurred. User was not unlocked") end end def confirm if user.confirm - redirect_to :back, notice: "Successfully confirmed" + redirect_back_or_admin_user(notice: "Successfully confirmed") else - redirect_to :back, alert: "Error occurred. User was not confirmed" + redirect_back_or_admin_user(alert: "Error occurred. User was not confirmed") end end @@ -138,7 +138,7 @@ class Admin::UsersController < Admin::ApplicationController user.update_secondary_emails! respond_to do |format| - format.html { redirect_to :back, notice: "Successfully removed email." } + format.html { redirect_back_or_admin_user(notice: "Successfully removed email.") } format.js { render nothing: true } end end @@ -157,4 +157,12 @@ class Admin::UsersController < Admin::ApplicationController :projects_limit, :can_create_group, :admin, :key_id ) end + + def redirect_back_or_admin_user(options = {}) + redirect_back_or_default(default: default_route, options: options) + end + + def default_route + [:admin, @user] + end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f0124c6bd6..865deb7d46 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -33,6 +33,10 @@ class ApplicationController < ActionController::Base render_404 end + def redirect_back_or_default(default: root_path, options: {}) + redirect_to request.referer.present? ? :back : default, options + end + protected # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb index 41472a6fe6..e0de31f225 100644 --- a/app/controllers/import/google_code_controller.rb +++ b/app/controllers/import/google_code_controller.rb @@ -10,18 +10,18 @@ class Import::GoogleCodeController < Import::BaseController dump_file = params[:dump_file] unless dump_file.respond_to?(:read) - return redirect_to :back, alert: "You need to upload a Google Takeout archive." + return redirect_back_or_default(options: { alert: "You need to upload a Google Takeout archive." }) end begin dump = JSON.parse(dump_file.read) rescue - return redirect_to :back, alert: "The uploaded file is not a valid Google Takeout archive." + return redirect_back_or_default(options: { alert: "The uploaded file is not a valid Google Takeout archive." }) end client = Gitlab::GoogleCodeImport::Client.new(dump) unless client.valid? - return redirect_to :back, alert: "The uploaded file is not a valid Google Takeout archive." + return redirect_back_or_default(options: { alert: "The uploaded file is not a valid Google Takeout archive." }) end session[:google_code_dump] = dump diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 8ef10a17f5..94bb108c5f 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -14,7 +14,7 @@ class InvitesController < ApplicationController redirect_to path, notice: "You have been granted #{member.human_access} access to #{label}." else - redirect_to :back, alert: "The invitation could not be accepted." + redirect_back_or_default(options: { alert: "The invitation could not be accepted." }) end end @@ -31,7 +31,7 @@ class InvitesController < ApplicationController redirect_to path, notice: "You have declined the invitation to join #{label}." else - redirect_to :back, alert: "The invitation could not be declined." + redirect_back_or_default(options: { alert: "The invitation could not be declined." }) end end diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index 22423651c1..1fd1d6882d 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -29,7 +29,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController flash[:alert] = "Failed to save new settings" end - redirect_to :back + redirect_back_or_default(default: profile_notifications_path) end format.js diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 26a4de1546..8da7b4d50e 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -26,7 +26,7 @@ class ProfilesController < Profiles::ApplicationController end respond_to do |format| - format.html { redirect_to :back } + format.html { redirect_back_or_default(default: { action: 'show' }) } end end diff --git a/app/controllers/projects/ci_services_controller.rb b/app/controllers/projects/ci_services_controller.rb index 6d2756eba3..406f313ae7 100644 --- a/app/controllers/projects/ci_services_controller.rb +++ b/app/controllers/projects/ci_services_controller.rb @@ -30,7 +30,7 @@ class Projects::CiServicesController < Projects::ApplicationController message = { alert: 'We tried to test the service but error occurred' } end - redirect_to :back, message + redirect_back_or_default(options: message) end private diff --git a/app/controllers/projects/ci_web_hooks_controller.rb b/app/controllers/projects/ci_web_hooks_controller.rb index 7f40ddcb3f..a2d470d4a6 100644 --- a/app/controllers/projects/ci_web_hooks_controller.rb +++ b/app/controllers/projects/ci_web_hooks_controller.rb @@ -24,7 +24,7 @@ class Projects::CiWebHooksController < Projects::ApplicationController def test Ci::TestHookService.new.execute(hook, current_user) - redirect_to :back + redirect_back_or_default(default: { action: 'index' }) end def destroy diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb index 40e2b37912..7d09288bc8 100644 --- a/app/controllers/projects/deploy_keys_controller.rb +++ b/app/controllers/projects/deploy_keys_controller.rb @@ -46,7 +46,7 @@ class Projects::DeployKeysController < Projects::ApplicationController def disable @project.deploy_keys_projects.find_by(deploy_key_id: params[:id]).destroy - redirect_to :back + redirect_back_or_default(default: { action: 'index' }) end protected diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index 4e5b4125f5..c756954189 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -37,7 +37,7 @@ class Projects::HooksController < Projects::ApplicationController flash[:alert] = 'Hook execution failed. Ensure the project has commits.' end - redirect_to :back + redirect_back_or_default(default: { action: 'index' }) end def destroy diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index cc8321d97a..e767efbdc0 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -106,7 +106,7 @@ class Projects::IssuesController < Projects::ApplicationController def bulk_update result = Issues::BulkUpdateService.new(project, current_user, bulk_update_params).execute - redirect_to :back, notice: "#{result[:count]} issues updated" + redirect_back_or_default(default: { action: 'index' }, options: { notice: "#{result[:count]} issues updated" }) end def toggle_subscription diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 0f5d82ce13..41cd08c93c 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -25,7 +25,7 @@ class Projects::NotesController < Projects::ApplicationController respond_to do |format| format.json { render_note_json(@note) } - format.html { redirect_to :back } + format.html { redirect_back_or_default } end end @@ -34,7 +34,7 @@ class Projects::NotesController < Projects::ApplicationController respond_to do |format| format.json { render_note_json(@note) } - format.html { redirect_to :back } + format.html { redirect_back_or_default } end end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index cf73bc01c8..9de5269cd2 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -72,7 +72,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController def leave if @project.namespace == current_user.namespace - return redirect_to(:back, alert: 'You can not leave your own project. Transfer or delete the project.') + message = 'You can not leave your own project. Transfer or delete the project.' + return redirect_back_or_default(default: { action: 'index' }, options: { alert: message }) end @project.project_members.find_by(user_id: current_user).destroy diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index 129068ef01..42dbb497e0 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -12,7 +12,7 @@ class Projects::ServicesController < Projects::ApplicationController # Parameters to ignore if no value is specified FILTER_BLANK_PARAMS = [:password] - + # Authorize before_action :authorize_admin_project! before_action :service, only: [:edit, :update, :test] @@ -52,7 +52,7 @@ class Projects::ServicesController < Projects::ApplicationController message = { alert: error_message } end - redirect_to :back, message + redirect_back_or_default(options: message) end private diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 7168db117d..fcbe62cace 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -37,6 +37,32 @@ describe Admin::UsersController do end end + describe 'PUT block/:id' do + let(:user) { create(:user) } + + it 'blocks user' do + put :block, id: user.username + user.reload + expect(user.blocked?).to be_truthy + expect(flash[:notice]).to eq 'Successfully blocked' + end + end + + describe 'PUT unblock/:id' do + let(:user) { create(:user) } + + before do + user.block + end + + it 'unblocks user' do + put :unblock, id: user.username + user.reload + expect(user.blocked?).to be_falsey + expect(flash[:notice]).to eq 'Successfully unblocked' + end + end + describe 'PUT unlock/:id' do let(:user) { create(:user) } diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb new file mode 100644 index 0000000000..3c6e54839b --- /dev/null +++ b/spec/controllers/invites_controller_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe InvitesController do + let(:token) { '123456' } + let(:user) { create(:user) } + let(:member) { create(:project_member, invite_token: token, invite_email: 'test@abc.com', user: user) } + + before do + controller.instance_variable_set(:@member, member) + sign_in(user) + end + + describe 'GET #accept' do + it 'accepts user' do + get :accept, id: token + member.reload + + expect(response.status).to eq(302) + expect(member.user).to eq(user) + expect(flash[:notice]).to include 'You have been granted' + end + end + + describe 'GET #decline' do + it 'declines user' do + get :decline, id: token + expect{member.reload}.to raise_error ActiveRecord::RecordNotFound + + expect(response.status).to eq(302) + expect(flash[:notice]).to include 'You have declined the invitation to join' + end + end +end diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index d4ecd98e12..ccd8c741c8 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -10,26 +10,43 @@ describe Projects::ServicesController do project.team << [user, :master] controller.instance_variable_set(:@project, project) controller.instance_variable_set(:@service, service) - request.env["HTTP_REFERER"] = "/" end - describe "#test" do - context 'success' do - it "should redirect and show success message" do - expect(service).to receive(:test).and_return({ success: true, result: 'done' }) - get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html - expect(response.status).to redirect_to('/') - expect(flash[:notice]).to eq('We sent a request to the provided URL') - end + shared_examples_for 'services controller' do |referrer| + before do + request.env["HTTP_REFERER"] = referrer end - context 'failure' do - it "should redirect and show failure message" do - expect(service).to receive(:test).and_return({ success: false, result: 'Bad test' }) - get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html - expect(response.status).to redirect_to('/') - expect(flash[:alert]).to eq('We tried to send a request to the provided URL but an error occurred: Bad test') + describe "#test" do + context 'success' do + it "should redirect and show success message" do + expect(service).to receive(:test).and_return({ success: true, result: 'done' }) + get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html + expect(response.status).to redirect_to('/') + expect(flash[:notice]).to eq('We sent a request to the provided URL') + end end + + context 'failure' do + it "should redirect and show failure message" do + expect(service).to receive(:test).and_return({ success: false, result: 'Bad test' }) + get :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, format: :html + expect(response.status).to redirect_to('/') + expect(flash[:alert]).to eq('We tried to send a request to the provided URL but an error occurred: Bad test') + end + end + end + end + + describe 'referrer defined' do + it_should_behave_like 'services controller' do + let!(:referrer) { "/" } + end + end + + describe 'referrer undefined' do + it_should_behave_like 'services controller' do + let!(:referrer) { nil } end end end From 8052c4ef4e23ea4f4a221fbc6ead138f33fb0f91 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 20 Oct 2015 16:09:11 +0000 Subject: [PATCH 37/37] Merge branch 'rs-8-1-update-guide-changes' into 'master' Update 8.0-to-8.1 update guide - User needs to update gitlab-git-http-server - User needs to update Nginx configuration [ci skip] See merge request !1625 --- doc/update/8.0-to-8.1.md | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/doc/update/8.0-to-8.1.md b/doc/update/8.0-to-8.1.md index 4dacc97f7f..d57c0d0674 100644 --- a/doc/update/8.0-to-8.1.md +++ b/doc/update/8.0-to-8.1.md @@ -70,7 +70,16 @@ sudo -u git -H git fetch sudo -u git -H git checkout v2.6.5 ``` -### 5. Install libs, migrations, etc. +### 5. Update gitlab-git-http-server + +```bash +cd /home/git/gitlab-git-http-server +sudo -u git -H git fetch origin +sudo -u git -H git checkout 0.3.0 +sudo -u git -H make +``` + +### 6. Install libs, migrations, etc. ```bash cd /home/git/gitlab @@ -91,7 +100,7 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab ``` -### 6. Update configuration files +### 7. Update configuration files #### New configuration options for `gitlab.yml` @@ -101,12 +110,33 @@ There are new configuration options available for [`gitlab.yml`](config/gitlab.y git diff origin/8-0-stable:config/gitlab.yml.example origin/8-1-stable:config/gitlab.yml.example ``` -### 7. Start application +#### Nginx configuration + +View changes between the previous recommended Nginx configuration and the +current one: + +```sh +# For HTTPS configurations +git diff origin/8-0-stable:lib/support/nginx/gitlab-ssl origin/8-1-stable:lib/support/nginx/gitlab-ssl + +# For HTTP configurations +git diff origin/8-0-stable:lib/support/nginx/gitlab origin/8-1-stable:lib/support/nginx/gitlab +``` + +If you are using Apache instead of NGINX please see the updated [Apache templates]. +Also note that because Apache does not support upstreams behind Unix sockets you +will need to let gitlab-git-http-server listen on a TCP port. You can do this +via [/etc/default/gitlab]. + +[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache +[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-1-stable/lib/support/init.d/gitlab.default.example#L34 + +### 8. Start application sudo service gitlab start sudo service nginx restart -### 8. Check application status +### 9. Check application status Check if GitLab and its environment are configured correctly: