Commit e5abf266 authored by Stan Hu's avatar Stan Hu

Merge branch 'ce-to-ee-2018-06-26' into 'master'

CE upstream - 2018-06-26 13:51 UTC

See merge request gitlab-org/gitlab-ee!6288
parents 04f2c344 a4b7877b
...@@ -69,7 +69,7 @@ export default { ...@@ -69,7 +69,7 @@ export default {
> >
<icon <icon
:size="16" :size="16"
name="pipeline" name="rocket"
/> />
</button> </button>
</li> </li>
......
...@@ -54,7 +54,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -54,7 +54,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
private private
def set_application_setting def set_application_setting
@application_setting = ApplicationSetting.current_without_cache @application_setting = Gitlab::CurrentSettings.current_application_settings
end end
def application_setting_params def application_setting_params
......
...@@ -213,14 +213,6 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -213,14 +213,6 @@ class ApplicationSetting < ActiveRecord::Base
end end
end end
validates_each :disabled_oauth_sign_in_sources do |record, attr, value|
value&.each do |source|
unless Devise.omniauth_providers.include?(source.to_sym)
record.errors.add(attr, "'#{source}' is not an OAuth sign-in source")
end
end
end
validate :terms_exist, if: :enforce_terms? validate :terms_exist, if: :enforce_terms?
before_validation :ensure_uuid! before_validation :ensure_uuid!
...@@ -331,6 +323,11 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -331,6 +323,11 @@ class ApplicationSetting < ActiveRecord::Base
::Gitlab::Database.cached_column_exists?(:application_settings, :sidekiq_throttling_enabled) ::Gitlab::Database.cached_column_exists?(:application_settings, :sidekiq_throttling_enabled)
end end
def disabled_oauth_sign_in_sources=(sources)
sources = (sources || []).map(&:to_s) & Devise.omniauth_providers.map(&:to_s)
super(sources)
end
def domain_whitelist_raw def domain_whitelist_raw
self.domain_whitelist&.join("\n") self.domain_whitelist&.join("\n")
end end
......
...@@ -19,7 +19,7 @@ class BaseCountService ...@@ -19,7 +19,7 @@ class BaseCountService
end end
def refresh_cache(&block) def refresh_cache(&block)
Rails.cache.write(cache_key, block_given? ? yield : uncached_count, raw: raw?) update_cache_for_key(cache_key, &block)
end end
def uncached_count def uncached_count
...@@ -43,4 +43,8 @@ class BaseCountService ...@@ -43,4 +43,8 @@ class BaseCountService
def cache_options def cache_options
{ raw: raw? } { raw: raw? }
end end
def update_cache_for_key(key, &block)
Rails.cache.write(key, block_given? ? yield : uncached_count, raw: raw?)
end
end end
...@@ -22,8 +22,10 @@ module Projects ...@@ -22,8 +22,10 @@ module Projects
) )
end end
def cache_key def cache_key(key = nil)
['projects', 'count_service', VERSION, @project.id, cache_key_name] cache_key = key || cache_key_name
['projects', 'count_service', VERSION, @project.id, cache_key]
end end
def self.query(project_ids) def self.query(project_ids)
......
...@@ -4,6 +4,10 @@ module Projects ...@@ -4,6 +4,10 @@ module Projects
class OpenIssuesCountService < Projects::CountService class OpenIssuesCountService < Projects::CountService
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
# Cache keys used to store issues count
PUBLIC_COUNT_KEY = 'public_open_issues_count'.freeze
TOTAL_COUNT_KEY = 'total_open_issues_count'.freeze
def initialize(project, user = nil) def initialize(project, user = nil)
@user = user @user = user
...@@ -11,7 +15,7 @@ module Projects ...@@ -11,7 +15,7 @@ module Projects
end end
def cache_key_name def cache_key_name
public_only? ? 'public_open_issues_count' : 'total_open_issues_count' public_only? ? PUBLIC_COUNT_KEY : TOTAL_COUNT_KEY
end end
def public_only? def public_only?
...@@ -28,6 +32,32 @@ module Projects ...@@ -28,6 +32,32 @@ module Projects
end end
end end
def public_count_cache_key
cache_key(PUBLIC_COUNT_KEY)
end
def total_count_cache_key
cache_key(TOTAL_COUNT_KEY)
end
def refresh_cache(&block)
if block_given?
super(&block)
else
count_grouped_by_confidential = self.class.query(@project, public_only: false).group(:confidential).count
public_count = count_grouped_by_confidential[false] || 0
total_count = public_count + (count_grouped_by_confidential[true] || 0)
update_cache_for_key(public_count_cache_key) do
public_count
end
update_cache_for_key(total_count_cache_key) do
total_count
end
end
end
# We only show total issues count for reporters # We only show total issues count for reporters
# which are allowed to view confidential issues # which are allowed to view confidential issues
# This will still show a discrepancy on issues number but should be less than before. # This will still show a discrepancy on issues number but should be less than before.
......
...@@ -10,16 +10,16 @@ ...@@ -10,16 +10,16 @@
.col-sm-10 .col-sm-10
= f.text_field :description, class: "form-control js-quick-submit" = f.text_field :description, class: "form-control js-quick-submit"
.form-group.row .form-group.row
= f.label :color, "Background color", class: 'col-form-label col-sm-2' = f.label :color, _("Background color"), class: 'col-form-label col-sm-2'
.col-sm-10 .col-sm-10
.input-group .input-group
.input-group-prepend .input-group-prepend
.input-group-text.label-color-preview &nbsp; .input-group-text.label-color-preview &nbsp;
= f.text_field :color, class: "form-control" = f.text_field :color, class: "form-control"
.form-text.text-muted .form-text.text-muted
Choose any color. = _('Choose any color.')
%br %br
Or you can choose one of the suggested colors below = _("Or you can choose one of the suggested colors below")
.suggest-colors .suggest-colors
- suggested_colors.each do |color| - suggested_colors.each do |color|
...@@ -27,5 +27,5 @@ ...@@ -27,5 +27,5 @@
&nbsp; &nbsp;
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-save js-save-button' = f.submit _('Save'), class: 'btn btn-save js-save-button'
= link_to "Cancel", admin_labels_path, class: 'btn btn-cancel' = link_to _("Cancel"), admin_labels_path, class: 'btn btn-cancel'
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
= render_colored_label(label, tooltip: false) = render_colored_label(label, tooltip: false)
= markdown_field(label, :description) = markdown_field(label, :description)
.float-right .float-right
= link_to 'Edit', edit_admin_label_path(label), class: 'btn btn-sm' = link_to _('Edit'), edit_admin_label_path(label), class: 'btn btn-sm'
= link_to 'Delete', admin_label_path(label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Delete this label? Are you sure?"} = link_to _('Delete'), admin_label_path(label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Delete this label? Are you sure?"}
- add_to_breadcrumbs "Labels", admin_labels_path - add_to_breadcrumbs _("Labels"), admin_labels_path
- breadcrumb_title "Edit Label" - breadcrumb_title _("Edit Label")
- page_title "Edit", @label.name, "Labels" - page_title _("Edit"), @label.name, _("Labels")
%h3.page-title %h3.page-title
Edit Label = _('Edit Label')
%hr %hr
= render 'form' = render 'form'
- page_title "Labels" - page_title _("Labels")
%div %div
= link_to new_admin_label_path, class: "float-right btn btn-nr btn-new" do = link_to new_admin_label_path, class: "float-right btn btn-nr btn-new" do
New label = _('New label')
%h3.page-title %h3.page-title
Labels = _('Labels')
%hr %hr
.labels .labels
...@@ -14,5 +14,5 @@ ...@@ -14,5 +14,5 @@
= paginate @labels, theme: 'gitlab' = paginate @labels, theme: 'gitlab'
- else - else
.card.bg-light .card.bg-light
.nothing-here-block There are no labels yet .nothing-here-block= _('There are no labels yet')
- page_title "New Label" - page_title _("New Label")
%h3.page-title %h3.page-title
New Label = _('New Label')
%hr %hr
= render 'form' = render 'form'
...@@ -14,4 +14,4 @@ ...@@ -14,4 +14,4 @@
= author_avatar(deployment.commit, size: 20) = author_avatar(deployment.commit, size: 20)
= link_to_markdown commit_title, project_commit_path(@project, deployment.sha), class: "commit-row-message" = link_to_markdown commit_title, project_commit_path(@project, deployment.sha), class: "commit-row-message"
- else - else
Cant find HEAD commit for this branch = _("Can't find HEAD commit for this branch")
.gl-responsive-table-row.deployment{ role: 'row' } .gl-responsive-table-row.deployment{ role: 'row' }
.table-section.section-10{ role: 'gridcell' } .table-section.section-10{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' } ID .table-mobile-header{ role: 'rowheader' }= _("ID")
%strong.table-mobile-content ##{deployment.iid} %strong.table-mobile-content ##{deployment.iid}
.table-section.section-30{ role: 'gridcell' } .table-section.section-30{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' } Commit .table-mobile-header{ role: 'rowheader' }= _("Commit")
= render 'projects/deployments/commit', deployment: deployment = render 'projects/deployments/commit', deployment: deployment
.table-section.section-25.build-column{ role: 'gridcell' } .table-section.section-25.build-column{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' } Job .table-mobile-header{ role: 'rowheader' }= _("Job")
- if deployment.deployable - if deployment.deployable
.table-mobile-content .table-mobile-content
.flex-truncate-parent .flex-truncate-parent
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
= user_avatar(user: deployment.user, size: 20) = user_avatar(user: deployment.user, size: 20)
.table-section.section-15{ role: 'gridcell' } .table-section.section-15{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' } Created .table-mobile-header{ role: 'rowheader' }= _("Created")
%span.table-mobile-content= time_ago_with_tooltip(deployment.created_at) %span.table-mobile-content= time_ago_with_tooltip(deployment.created_at)
.table-section.section-20.table-button-footer{ role: 'gridcell' } .table-section.section-20.table-button-footer{ role: 'gridcell' }
......
- if can?(current_user, :create_deployment, deployment) && deployment.deployable - if can?(current_user, :create_deployment, deployment) && deployment.deployable
= link_to [:retry, @project.namespace.becomes(Namespace), @project, deployment.deployable], method: :post, class: 'btn btn-build' do = link_to [:retry, @project.namespace.becomes(Namespace), @project, deployment.deployable], method: :post, class: 'btn btn-build' do
- if deployment.last? - if deployment.last?
Re-deploy = _("Re-deploy")
- else - else
Rollback = _("Rollback")
---
title: Ignore unknown OAuth sources in ApplicationSetting
merge_request: 20129
author:
type: fixed
---
title: Fix refreshing cache keys for open issues count
merge_request:
author:
type: fixed
---
title: Rails5 fix arel from in mysql_median_datetime_sql
merge_request: 20167
author: Jasper Maes
type: fixed
---
title: Update pipeline icon in web ide sidebar
merge_request: 20058
author: George Tsiolis
type: changed
...@@ -12,9 +12,8 @@ Since installations from source don't have Runit, Sidekiq can't be terminated an ...@@ -12,9 +12,8 @@ Since installations from source don't have Runit, Sidekiq can't be terminated an
## Select Version to Install ## Select Version to Install
Make sure you view [this installation guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md) from the tag (version) of GitLab you would like to install. Make sure you view [this installation guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md) from the branch (version) of GitLab you would like to install (e.g., `11-0-stable`).
In most cases this should be the highest numbered production tag (without rc in it). You can select the branch in the version dropdown in the top left corner of GitLab (below the menu bar).
You can select the tag in the version dropdown in the top left corner of GitLab (below the menu bar).
If the highest number stable branch is unclear please check the [GitLab Blog](https://about.gitlab.com/blog/) for installation guide links by version. If the highest number stable branch is unclear please check the [GitLab Blog](https://about.gitlab.com/blog/) for installation guide links by version.
......
...@@ -4,10 +4,9 @@ comments: false ...@@ -4,10 +4,9 @@ comments: false
# From 10.8 to 11.0 # From 10.8 to 11.0
Make sure you view this update guide from the tag (version) of GitLab you would Make sure you view this update guide from the branch (version) of GitLab you would
like to install. In most cases this should be the highest numbered production like to install (e.g., `11-0-stable`. You can select the branch in the version
tag (without rc in it). You can select the tag in the version dropdown at the dropdown at the top left corner of GitLab (below the menu bar).
top left corner of GitLab (below the menu bar).
If the highest number stable branch is unclear please check the If the highest number stable branch is unclear please check the
[GitLab Blog](https://about.gitlab.com/blog/archives.html) for installation [GitLab Blog](https://about.gitlab.com/blog/archives.html) for installation
......
...@@ -33,7 +33,13 @@ module Gitlab ...@@ -33,7 +33,13 @@ module Gitlab
end end
def mysql_median_datetime_sql(arel_table, query_so_far, column_sym) def mysql_median_datetime_sql(arel_table, query_so_far, column_sym)
query = arel_table arel_from = if Gitlab.rails5?
arel_table.from
else
arel_table
end
query = arel_from
.from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name)) .from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name))
.project(average([arel_table[column_sym]], 'median')) .project(average([arel_table[column_sym]], 'median'))
.where( .where(
......
...@@ -149,6 +149,29 @@ feature 'Admin updates settings' do ...@@ -149,6 +149,29 @@ feature 'Admin updates settings' do
expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).not_to include('google_oauth2') expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).not_to include('google_oauth2')
end end
scenario 'Oauth providers do not raise validation errors when saving unrelated changes' do
expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to be_empty
page.within('.as-signin') do
uncheck 'Google'
click_button 'Save changes'
end
expect(page).to have_content "Application settings saved successfully"
expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
# Remove google_oauth2 from the Omniauth strategies
allow(Devise).to receive(:omniauth_providers).and_return([])
# Save an unrelated setting
page.within('.as-ci-cd') do
click_button 'Save changes'
end
expect(page).to have_content "Application settings saved successfully"
expect(Gitlab::CurrentSettings.disabled_oauth_sign_in_sources).to include('google_oauth2')
end
scenario 'Change Help page' do scenario 'Change Help page' do
page.within('.as-help-page') do page.within('.as-help-page') do
fill_in 'Help page text', with: 'Example text' fill_in 'Help page text', with: 'Example text'
......
...@@ -25,15 +25,6 @@ describe ApplicationSetting do ...@@ -25,15 +25,6 @@ describe ApplicationSetting do
it { is_expected.to allow_value(https).for(:after_sign_out_path) } it { is_expected.to allow_value(https).for(:after_sign_out_path) }
it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) } it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) }
describe 'disabled_oauth_sign_in_sources validations' do
before do
allow(Devise).to receive(:omniauth_providers).and_return([:github])
end
it { is_expected.to allow_value(['github']).for(:disabled_oauth_sign_in_sources) }
it { is_expected.not_to allow_value(['test']).for(:disabled_oauth_sign_in_sources) }
end
describe 'default_artifacts_expire_in' do describe 'default_artifacts_expire_in' do
it 'sets an error if it cannot parse' do it 'sets an error if it cannot parse' do
setting.update(default_artifacts_expire_in: 'a') setting.update(default_artifacts_expire_in: 'a')
...@@ -314,6 +305,33 @@ describe ApplicationSetting do ...@@ -314,6 +305,33 @@ describe ApplicationSetting do
end end
end end
describe '#disabled_oauth_sign_in_sources=' do
before do
allow(Devise).to receive(:omniauth_providers).and_return([:github])
end
it 'removes unknown sources (as strings) from the array' do
subject.disabled_oauth_sign_in_sources = %w[github test]
expect(subject).to be_valid
expect(subject.disabled_oauth_sign_in_sources).to eq ['github']
end
it 'removes unknown sources (as symbols) from the array' do
subject.disabled_oauth_sign_in_sources = %i[github test]
expect(subject).to be_valid
expect(subject.disabled_oauth_sign_in_sources).to eq ['github']
end
it 'ignores nil' do
subject.disabled_oauth_sign_in_sources = nil
expect(subject).to be_valid
expect(subject.disabled_oauth_sign_in_sources).to be_empty
end
end
context 'restricted signup domains' do context 'restricted signup domains' do
it 'sets single domain' do it 'sets single domain' do
setting.domain_whitelist_raw = 'example.com' setting.domain_whitelist_raw = 'example.com'
......
require 'spec_helper'
describe Projects::BatchOpenIssuesCountService do
let!(:project_1) { create(:project) }
let!(:project_2) { create(:project) }
let(:subject) { described_class.new([project_1, project_2]) }
context '#refresh_cache', :use_clean_rails_memory_store_caching do
before do
create(:issue, project: project_1)
create(:issue, project: project_1, confidential: true)
create(:issue, project: project_2)
create(:issue, project: project_2, confidential: true)
end
context 'when cache is clean' do
it 'refreshes cache keys correctly' do
subject.refresh_cache
# It does not update total issues cache
expect(Rails.cache.read(get_cache_key(subject, project_1))).to eq(nil)
expect(Rails.cache.read(get_cache_key(subject, project_2))).to eq(nil)
expect(Rails.cache.read(get_cache_key(subject, project_1, true))).to eq(1)
expect(Rails.cache.read(get_cache_key(subject, project_1, true))).to eq(1)
end
end
context 'when issues count is already cached' do
before do
create(:issue, project: project_2)
subject.refresh_cache
end
it 'does update cache again' do
expect(Rails.cache).not_to receive(:write)
subject.refresh_cache
end
end
end
def get_cache_key(subject, project, public_key = false)
service = subject.count_service.new(project)
if public_key
service.cache_key(service.class::PUBLIC_COUNT_KEY)
else
service.cache_key(service.class::TOTAL_COUNT_KEY)
end
end
end
...@@ -50,5 +50,40 @@ describe Projects::OpenIssuesCountService do ...@@ -50,5 +50,40 @@ describe Projects::OpenIssuesCountService do
end end
end end
end end
context '#refresh_cache', :use_clean_rails_memory_store_caching do
let(:subject) { described_class.new(project) }
before do
create(:issue, :opened, project: project)
create(:issue, :opened, project: project)
create(:issue, :opened, confidential: true, project: project)
end
context 'when cache is empty' do
it 'refreshes cache keys correctly' do
subject.refresh_cache
expect(Rails.cache.read(subject.cache_key(described_class::PUBLIC_COUNT_KEY))).to eq(2)
expect(Rails.cache.read(subject.cache_key(described_class::TOTAL_COUNT_KEY))).to eq(3)
end
end
context 'when cache is outdated' do
before do
subject.refresh_cache
end
it 'refreshes cache keys correctly' do
create(:issue, :opened, project: project)
create(:issue, :opened, confidential: true, project: project)
subject.refresh_cache
expect(Rails.cache.read(subject.cache_key(described_class::PUBLIC_COUNT_KEY))).to eq(3)
expect(Rails.cache.read(subject.cache_key(described_class::TOTAL_COUNT_KEY))).to eq(5)
end
end
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment