Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-02-28 21:09:15 +00:00
parent 1c8fa70f9d
commit 8831c2df7f
21 changed files with 267 additions and 141 deletions

View File

@ -20,6 +20,10 @@ module CacheMarkdownField
false false
end end
def can_cache_field?(field)
true
end
# Returns the default Banzai render context for the cached markdown field. # Returns the default Banzai render context for the cached markdown field.
def banzai_render_context(field) def banzai_render_context(field)
raise ArgumentError.new("Unknown field: #{field.inspect}") unless raise ArgumentError.new("Unknown field: #{field.inspect}") unless
@ -38,17 +42,23 @@ module CacheMarkdownField
context context
end end
# Update every column in a row if any one is invalidated, as we only store def rendered_field_content(markdown_field)
return unless can_cache_field?(markdown_field)
options = { skip_project_check: skip_project_check? }
Banzai::Renderer.cacheless_render_field(self, markdown_field, options)
end
# Update every applicable column in a row if any one is invalidated, as we only store
# one version per row # one version per row
def refresh_markdown_cache def refresh_markdown_cache
options = { skip_project_check: skip_project_check? }
updates = cached_markdown_fields.markdown_fields.map do |markdown_field| updates = cached_markdown_fields.markdown_fields.map do |markdown_field|
[ [
cached_markdown_fields.html_field(markdown_field), cached_markdown_fields.html_field(markdown_field),
Banzai::Renderer.cacheless_render_field(self, markdown_field, options) rendered_field_content(markdown_field)
] ]
end.to_h end.to_h
updates['cached_markdown_version'] = latest_cached_markdown_version updates['cached_markdown_version'] = latest_cached_markdown_version
updates.each { |field, data| write_markdown_field(field, data) } updates.each { |field, data| write_markdown_field(field, data) }

View File

@ -406,11 +406,15 @@ class Group < Namespace
end end
def ci_variables_for(ref, project) def ci_variables_for(ref, project)
list_of_ids = [self] + ancestors cache_key = "ci_variables_for:group:#{self&.id}:project:#{project&.id}:ref:#{ref}"
variables = Ci::GroupVariable.where(group: list_of_ids)
variables = variables.unprotected unless project.protected_for?(ref) ::Gitlab::SafeRequestStore.fetch(cache_key) do
variables = variables.group_by(&:group_id) list_of_ids = [self] + ancestors
list_of_ids.reverse.flat_map { |group| variables[group.id] }.compact variables = Ci::GroupVariable.where(group: list_of_ids)
variables = variables.unprotected unless project.protected_for?(ref)
variables = variables.group_by(&:group_id)
list_of_ids.reverse.flat_map { |group| variables[group.id] }.compact
end
end end
def group_member(user) def group_member(user)

View File

@ -1963,6 +1963,14 @@ class Project < ApplicationRecord
end end
def ci_variables_for(ref:, environment: nil) def ci_variables_for(ref:, environment: nil)
cache_key = "ci_variables_for:project:#{self&.id}:ref:#{ref}:environment:#{environment}"
::Gitlab::SafeRequestStore.fetch(cache_key) do
uncached_ci_variables_for(ref: ref, environment: environment)
end
end
def uncached_ci_variables_for(ref:, environment: nil)
result = if protected_for?(ref) result = if protected_for?(ref)
variables variables
else else

View File

@ -301,6 +301,10 @@ class Snippet < ApplicationRecord
repository.update!(shard_name: repository_storage, disk_path: disk_path) repository.update!(shard_name: repository_storage, disk_path: disk_path)
end end
def can_cache_field?(field)
field != :content || MarkupHelper.gitlab_markdown?(file_name)
end
class << self class << self
# Searches for snippets with a matching title or file name. # Searches for snippets with a matching title or file name.
# #

View File

@ -0,0 +1,5 @@
---
title: Fix Snippet content incorrectly caching
merge_request: 25985
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Add link to dependency proxy docs on the dependency proxy page
merge_request: 26092
author:
type: changed

View File

@ -0,0 +1,5 @@
---
title: 'Geo: Show secondary-only setting on only on secondaries'
merge_request: 26029
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Memoize loading of CI variables
merge_request: 26147
author:
type: performance

View File

@ -9,10 +9,6 @@ and [deployments](../../ci/environments.md) when using [Auto DevOps](../../topic
You can install them after you You can install them after you
[create a cluster](../project/clusters/add_remove_clusters.md). [create a cluster](../project/clusters/add_remove_clusters.md).
Interested in contributing a new GitLab managed app? Visit the
[development guidelines page](../../development/kubernetes.md#gitlab-managed-apps)
to get started.
## Installing applications ## Installing applications
Applications managed by GitLab will be installed onto the `gitlab-managed-apps` namespace. Applications managed by GitLab will be installed onto the `gitlab-managed-apps` namespace.
@ -466,6 +462,12 @@ The chart will deploy 5 Elasticsearch nodes: 2 masters, 2 data and 1 client node
with resource requests totalling 0.125 CPU and 4.5GB RAM. Each data node requests 1.5GB of memory, with resource requests totalling 0.125 CPU and 4.5GB RAM. Each data node requests 1.5GB of memory,
which makes it incompatible with clusters of `f1-micro` and `g1-small` instance types. which makes it incompatible with clusters of `f1-micro` and `g1-small` instance types.
### Future apps
Interested in contributing a new GitLab managed app? Visit the
[development guidelines page](../../development/kubernetes.md#gitlab-managed-apps)
to get started.
## Install using GitLab CI (alpha) ## Install using GitLab CI (alpha)
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20822) in GitLab 12.6. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20822) in GitLab 12.6.

View File

@ -82,7 +82,7 @@ module.exports = {
'^.+\\.js$': 'babel-jest', '^.+\\.js$': 'babel-jest',
'^.+\\.vue$': 'vue-jest', '^.+\\.vue$': 'vue-jest',
}, },
transformIgnorePatterns: ['node_modules/(?!(@gitlab/ui)/)'], transformIgnorePatterns: ['node_modules/(?!(@gitlab/ui|bootstrap-vue)/)'],
timers: 'fake', timers: 'fake',
testEnvironment: '<rootDir>/spec/frontend/environment.js', testEnvironment: '<rootDir>/spec/frontend/environment.js',
testEnvironmentOptions: { testEnvironmentOptions: {

View File

@ -38,8 +38,8 @@
"@babel/plugin-syntax-import-meta": "^7.8.3", "@babel/plugin-syntax-import-meta": "^7.8.3",
"@babel/preset-env": "^7.8.4", "@babel/preset-env": "^7.8.4",
"@gitlab/at.js": "^1.5.5", "@gitlab/at.js": "^1.5.5",
"@gitlab/svgs": "^1.103.0", "@gitlab/svgs": "^1.104.0",
"@gitlab/ui": "^9.17.0", "@gitlab/ui": "^9.18.0",
"@gitlab/visual-review-tools": "1.5.1", "@gitlab/visual-review-tools": "1.5.1",
"@sentry/browser": "^5.10.2", "@sentry/browser": "^5.10.2",
"@sourcegraph/code-host-integration": "0.0.30", "@sourcegraph/code-host-integration": "0.0.30",

View File

@ -1,9 +1,10 @@
import $ from 'jquery'; import $ from 'jquery';
import blobBundle from '~/blob_edit/blob_bundle'; import blobBundle from '~/blob_edit/blob_bundle';
jest.mock('~/blob_edit/edit_blob');
describe('BlobBundle', () => { describe('BlobBundle', () => {
beforeEach(() => { beforeEach(() => {
spyOnDependency(blobBundle, 'EditBlob').and.stub();
setFixtures(` setFixtures(`
<div class="js-edit-blob-form" data-blob-filename="blah"> <div class="js-edit-blob-form" data-blob-filename="blah">
<button class="js-commit-button"></button> <button class="js-commit-button"></button>

View File

@ -0,0 +1,121 @@
export const defaultProps = {
endpoint: '/foo/bar/issues/1/related_issues',
currentNamespacePath: 'foo',
currentProjectPath: 'bar',
};
export const issuable1 = {
id: 200,
epicIssueId: 1,
confidential: false,
reference: 'foo/bar#123',
displayReference: '#123',
title: 'some title',
path: '/foo/bar/issues/123',
relationPath: '/foo/bar/issues/123/relation',
state: 'opened',
linkType: 'relates_to',
dueDate: '2010-11-22',
weight: 5,
};
export const issuable2 = {
id: 201,
epicIssueId: 2,
confidential: false,
reference: 'foo/bar#124',
displayReference: '#124',
title: 'some other thing',
path: '/foo/bar/issues/124',
relationPath: '/foo/bar/issues/124/relation',
state: 'opened',
linkType: 'blocks',
};
export const issuable3 = {
id: 202,
epicIssueId: 3,
confidential: false,
reference: 'foo/bar#125',
displayReference: '#125',
title: 'some other other thing',
path: '/foo/bar/issues/125',
relationPath: '/foo/bar/issues/125/relation',
state: 'opened',
linkType: 'is_blocked_by',
};
export const issuable4 = {
id: 203,
epicIssueId: 4,
confidential: false,
reference: 'foo/bar#126',
displayReference: '#126',
title: 'some other other other thing',
path: '/foo/bar/issues/126',
relationPath: '/foo/bar/issues/126/relation',
state: 'opened',
};
export const issuable5 = {
id: 204,
epicIssueId: 5,
confidential: false,
reference: 'foo/bar#127',
displayReference: '#127',
title: 'some other other other thing',
path: '/foo/bar/issues/127',
relationPath: '/foo/bar/issues/127/relation',
state: 'opened',
};
export const defaultMilestone = {
id: 1,
state: 'active',
title: 'Milestone title',
start_date: '2018-01-01',
due_date: '2019-12-31',
};
export const defaultAssignees = [
{
id: 1,
name: 'Administrator',
username: 'root',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/root`,
status_tooltip_html: null,
path: '/root',
},
{
id: 13,
name: 'Brooks Beatty',
username: 'brynn_champlin',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/brynn_champlin`,
status_tooltip_html: null,
path: '/brynn_champlin',
},
{
id: 6,
name: 'Bryce Turcotte',
username: 'melynda',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/melynda`,
status_tooltip_html: null,
path: '/melynda',
},
{
id: 20,
name: 'Conchita Eichmann',
username: 'juliana_gulgowski',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/juliana_gulgowski`,
status_tooltip_html: null,
path: '/juliana_gulgowski',
},
];

View File

@ -1,116 +1 @@
export const defaultProps = { export * from '../../../../frontend/vue_shared/components/issue/related_issuable_mock_data';
endpoint: '/foo/bar/issues/1/related_issues',
currentNamespacePath: 'foo',
currentProjectPath: 'bar',
};
export const issuable1 = {
id: 200,
epicIssueId: 1,
confidential: false,
reference: 'foo/bar#123',
displayReference: '#123',
title: 'some title',
path: '/foo/bar/issues/123',
state: 'opened',
linkType: 'relates_to',
dueDate: '2010-11-22',
weight: 5,
};
export const issuable2 = {
id: 201,
epicIssueId: 2,
confidential: false,
reference: 'foo/bar#124',
displayReference: '#124',
title: 'some other thing',
path: '/foo/bar/issues/124',
state: 'opened',
linkType: 'blocks',
};
export const issuable3 = {
id: 202,
epicIssueId: 3,
confidential: false,
reference: 'foo/bar#125',
displayReference: '#125',
title: 'some other other thing',
path: '/foo/bar/issues/125',
state: 'opened',
linkType: 'is_blocked_by',
};
export const issuable4 = {
id: 203,
epicIssueId: 4,
confidential: false,
reference: 'foo/bar#126',
displayReference: '#126',
title: 'some other other other thing',
path: '/foo/bar/issues/126',
state: 'opened',
};
export const issuable5 = {
id: 204,
epicIssueId: 5,
confidential: false,
reference: 'foo/bar#127',
displayReference: '#127',
title: 'some other other other thing',
path: '/foo/bar/issues/127',
state: 'opened',
};
export const defaultMilestone = {
id: 1,
state: 'active',
title: 'Milestone title',
start_date: '2018-01-01',
due_date: '2019-12-31',
};
export const defaultAssignees = [
{
id: 1,
name: 'Administrator',
username: 'root',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/root`,
status_tooltip_html: null,
path: '/root',
},
{
id: 13,
name: 'Brooks Beatty',
username: 'brynn_champlin',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/brynn_champlin`,
status_tooltip_html: null,
path: '/brynn_champlin',
},
{
id: 6,
name: 'Bryce Turcotte',
username: 'melynda',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/melynda`,
status_tooltip_html: null,
path: '/melynda',
},
{
id: 20,
name: 'Conchita Eichmann',
username: 'juliana_gulgowski',
state: 'active',
avatar_url: `${gl.TEST_HOST}`,
web_url: `${gl.TEST_HOST}/juliana_gulgowski`,
status_tooltip_html: null,
path: '/juliana_gulgowski',
},
];

View File

@ -230,6 +230,26 @@ describe CacheMarkdownField, :clean_gitlab_redis_cache do
end end
end end
end end
describe '#rendered_field_content' do
let(:thing) { klass.new(description: markdown, description_html: nil, cached_markdown_version: cache_version) }
context 'when a field can be cached' do
it 'returns the html' do
thing.description = updated_markdown
expect(thing.rendered_field_content(:description)).to eq updated_html
end
end
context 'when a field cannot be cached' do
it 'returns nil' do
allow(thing).to receive(:can_cache_field?).with(:description).and_return false
expect(thing.rendered_field_content(:description)).to eq nil
end
end
end
end end
context 'for Active record classes' do context 'for Active record classes' do

View File

@ -911,6 +911,16 @@ describe Group do
subject { group.ci_variables_for('ref', project) } subject { group.ci_variables_for('ref', project) }
it 'memoizes the result by ref', :request_store do
expect(project).to receive(:protected_for?).with('ref').once.and_return(true)
expect(project).to receive(:protected_for?).with('other').once.and_return(false)
2.times do
expect(group.ci_variables_for('ref', project)).to contain_exactly(ci_variable, protected_variable)
expect(group.ci_variables_for('other', project)).to contain_exactly(ci_variable)
end
end
shared_examples 'ref is protected' do shared_examples 'ref is protected' do
it 'contains all the variables' do it 'contains all the variables' do
is_expected.to contain_exactly(ci_variable, protected_variable) is_expected.to contain_exactly(ci_variable, protected_variable)

View File

@ -2930,6 +2930,19 @@ describe Project do
end end
end end
it 'memoizes the result by ref and environment', :request_store do
scoped_variable = create(:ci_variable, value: 'secret', project: project, environment_scope: 'scoped')
expect(project).to receive(:protected_for?).with('ref').once.and_return(true)
expect(project).to receive(:protected_for?).with('other').twice.and_return(false)
2.times do
expect(project.reload.ci_variables_for(ref: 'ref', environment: 'production')).to contain_exactly(ci_variable, protected_variable)
expect(project.reload.ci_variables_for(ref: 'other')).to contain_exactly(ci_variable)
expect(project.reload.ci_variables_for(ref: 'other', environment: 'scoped')).to contain_exactly(ci_variable, scoped_variable)
end
end
context 'when the ref is not protected' do context 'when the ref is not protected' do
before do before do
allow(project).to receive(:protected_for?).with('ref').and_return(false) allow(project).to receive(:protected_for?).with('ref').and_return(false)

View File

@ -632,4 +632,26 @@ describe Snippet do
end end
end end
end end
describe '#can_cache_field?' do
using RSpec::Parameterized::TableSyntax
let(:snippet) { create(:snippet, file_name: file_name) }
subject { snippet.can_cache_field?(field) }
where(:field, :file_name, :result) do
:title | nil | true
:title | 'foo.bar' | true
:description | nil | true
:description | 'foo.bar' | true
:content | nil | false
:content | 'bar.foo' | false
:content | 'markdown.md' | true
end
with_them do
it { is_expected.to eq result }
end
end
end end

0
vendor/gitignore/C++.gitignore vendored Executable file → Normal file
View File

0
vendor/gitignore/Java.gitignore vendored Executable file → Normal file
View File

View File

@ -796,15 +796,15 @@
dependencies: dependencies:
vue-eslint-parser "^7.0.0" vue-eslint-parser "^7.0.0"
"@gitlab/svgs@^1.103.0": "@gitlab/svgs@^1.104.0":
version "1.103.0" version "1.104.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.103.0.tgz#fb7136df9f5df3f53685740daf0ebf565b735608" resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.104.0.tgz#ebbf99788d74b7224f116f1c0040fa0c90034d99"
integrity sha512-+Bt+a8ln9KSz3QxB2P57ub71/eiEnKXJQSheTagYh2KlT6Glzh7XeLjyc3W6uGWBOONqsp96H/tYEa9dmDnLqQ== integrity sha512-lWg/EzxFdbx4YIdDWB2p5ag6Cna78AYGET8nXQYXYwd21/U3wKXKL7vsGR4kOxe1goA9ZAYG9eY+MK7cf+X2cA==
"@gitlab/ui@^9.17.0": "@gitlab/ui@^9.18.0":
version "9.17.0" version "9.18.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-9.17.0.tgz#2c2e0412b8293889ab3c2e8f9d7ae1e4b9b508b7" resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-9.18.0.tgz#3f4f09e8b7791d0bd01f90920ac6e4477e977ab9"
integrity sha512-6Ph3eE7ygUc6A72J6+mfce/MQSkyN4Rl2moSIZeMcAnHhIXBn6qoj4+Pq+jTWXYFqy3/ow6Iddle63Flj1dnkA== integrity sha512-GdQFuH4fPU+/wvX+UL5wSYN6VB2EuIXHBjjrdLHeUhEWuXrtrbBBmtoVEfmii0XcX5iUccgw55orz8Dmq3DlGg==
dependencies: dependencies:
"@babel/standalone" "^7.0.0" "@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0" "@gitlab/vue-toasted" "^1.3.0"
@ -819,6 +819,7 @@
url-search-params-polyfill "^5.0.0" url-search-params-polyfill "^5.0.0"
vue "^2.6.10" vue "^2.6.10"
vue-loader "^15.4.2" vue-loader "^15.4.2"
vue-runtime-helpers "^1.1.2"
"@gitlab/visual-review-tools@1.5.1": "@gitlab/visual-review-tools@1.5.1":
version "1.5.1" version "1.5.1"
@ -11849,6 +11850,11 @@ vue-router@^3.0.2:
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be" resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be"
integrity sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg== integrity sha512-opKtsxjp9eOcFWdp6xLQPLmRGgfM932Tl56U9chYTnoWqKxQ8M20N7AkdEbM5beUh6wICoFGYugAX9vQjyJLFg==
vue-runtime-helpers@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vue-runtime-helpers/-/vue-runtime-helpers-1.1.2.tgz#446b7b820888ab0c5264d2c3a32468e72e4100f3"
integrity sha512-pZfGp+PW/IXEOyETE09xQHR1CKkR9HfHZdnMD/FVLUNI+HxYTa82evx5WrF6Kz4s82qtqHvMZ8MZpbk2zT2E1Q==
vue-style-loader@^4.1.0: vue-style-loader@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.0.tgz#7588bd778e2c9f8d87bfc3c5a4a039638da7a863" resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.0.tgz#7588bd778e2c9f8d87bfc3c5a4a039638da7a863"