提交 9bded6fb 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 25f41489
...@@ -365,7 +365,6 @@ RSpec/LeakyConstantDeclaration: ...@@ -365,7 +365,6 @@ RSpec/LeakyConstantDeclaration:
- 'spec/lib/gitlab/no_cache_headers_spec.rb' - 'spec/lib/gitlab/no_cache_headers_spec.rb'
- 'spec/lib/gitlab/path_regex_spec.rb' - 'spec/lib/gitlab/path_regex_spec.rb'
- 'spec/lib/gitlab/quick_actions/dsl_spec.rb' - 'spec/lib/gitlab/quick_actions/dsl_spec.rb'
- 'spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb'
- 'spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb' - 'spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb'
- 'spec/lib/marginalia_spec.rb' - 'spec/lib/marginalia_spec.rb'
- 'spec/mailers/notify_spec.rb' - 'spec/mailers/notify_spec.rb'
......
...@@ -23,6 +23,8 @@ export default { ...@@ -23,6 +23,8 @@ export default {
this.updateActivityBarView(view); this.updateActivityBarView(view);
// TODO: We must use JQuery here to interact with the Bootstrap tooltip API
// https://gitlab.com/gitlab-org/gitlab/-/issues/217577
$(e.currentTarget).tooltip('hide'); $(e.currentTarget).tooltip('hide');
}, },
}, },
......
...@@ -9,7 +9,7 @@ import CommitForm from './commit_sidebar/form.vue'; ...@@ -9,7 +9,7 @@ import CommitForm from './commit_sidebar/form.vue';
import IdeReview from './ide_review.vue'; import IdeReview from './ide_review.vue';
import SuccessMessage from './commit_sidebar/success_message.vue'; import SuccessMessage from './commit_sidebar/success_message.vue';
import IdeProjectHeader from './ide_project_header.vue'; import IdeProjectHeader from './ide_project_header.vue';
import { leftSidebarViews } from '../constants'; import { leftSidebarViews, LEFT_SIDEBAR_INIT_WIDTH } from '../constants';
export default { export default {
components: { components: {
...@@ -33,11 +33,16 @@ export default { ...@@ -33,11 +33,16 @@ export default {
); );
}, },
}, },
LEFT_SIDEBAR_INIT_WIDTH,
}; };
</script> </script>
<template> <template>
<resizable-panel :initial-width="340" side="left" class="flex-column"> <resizable-panel
:initial-width="$options.LEFT_SIDEBAR_INIT_WIDTH"
side="left"
class="multi-file-commit-panel flex-column"
>
<template v-if="loading"> <template v-if="loading">
<div class="multi-file-commit-panel-inner"> <div class="multi-file-commit-panel-inner">
<div v-for="n in 3" :key="n" class="multi-file-loading-container"> <div v-for="n in 3" :key="n" class="multi-file-loading-container">
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import PanelResizer from '~/vue_shared/components/panel_resizer.vue'; import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
import { DEFAULT_SIDEBAR_MIN_WIDTH } from '../constants';
export default { export default {
components: { components: {
...@@ -14,7 +15,7 @@ export default { ...@@ -14,7 +15,7 @@ export default {
minSize: { minSize: {
type: Number, type: Number,
required: false, required: false,
default: 340, default: DEFAULT_SIDEBAR_MIN_WIDTH,
}, },
side: { side: {
type: String, type: String,
...@@ -45,7 +46,7 @@ export default { ...@@ -45,7 +46,7 @@ export default {
</script> </script>
<template> <template>
<div :style="panelStyle" class="multi-file-commit-panel"> <div :style="panelStyle">
<slot></slot> <slot></slot>
<panel-resizer <panel-resizer
:size.sync="width" :size.sync="width"
......
...@@ -4,6 +4,9 @@ export const MAX_WINDOW_HEIGHT_COMPACT = 750; ...@@ -4,6 +4,9 @@ export const MAX_WINDOW_HEIGHT_COMPACT = 750;
export const MAX_TITLE_LENGTH = 50; export const MAX_TITLE_LENGTH = 50;
export const MAX_BODY_LENGTH = 72; export const MAX_BODY_LENGTH = 72;
export const LEFT_SIDEBAR_INIT_WIDTH = 340;
export const DEFAULT_SIDEBAR_MIN_WIDTH = 340;
// File view modes // File view modes
export const FILE_VIEW_MODE_EDITOR = 'editor'; export const FILE_VIEW_MODE_EDITOR = 'editor';
export const FILE_VIEW_MODE_PREVIEW = 'preview'; export const FILE_VIEW_MODE_PREVIEW = 'preview';
......
...@@ -47,7 +47,7 @@ const textAdvancedVariableParser = advTextVar => ({ ...@@ -47,7 +47,7 @@ const textAdvancedVariableParser = advTextVar => ({
*/ */
const normalizeCustomVariableOptions = ({ default: defaultOpt = false, text, value }) => ({ const normalizeCustomVariableOptions = ({ default: defaultOpt = false, text, value }) => ({
default: defaultOpt, default: defaultOpt,
text, text: text || value,
value, value,
}); });
......
...@@ -65,6 +65,7 @@ $ide-commit-header-height: 48px; ...@@ -65,6 +65,7 @@ $ide-commit-header-height: 48px;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
border-left: 1px solid var(--ide-border-color, $white-dark); border-left: 1px solid var(--ide-border-color, $white-dark);
border-right: 1px solid var(--ide-border-color, $white-dark);
overflow: hidden; overflow: hidden;
} }
...@@ -584,14 +585,15 @@ $ide-commit-header-height: 48px; ...@@ -584,14 +585,15 @@ $ide-commit-header-height: 48px;
background: var(--ide-highlight-background, $white); background: var(--ide-highlight-background, $white);
} }
&.is-right { }
padding-right: $gl-padding;
padding-left: $gl-padding + 1px;
&::after { &.is-right {
right: auto; padding-right: $gl-padding;
left: -1px; padding-left: $gl-padding + 1px;
}
&::after {
right: auto;
left: -1px;
} }
} }
} }
...@@ -877,15 +879,11 @@ $ide-commit-header-height: 48px; ...@@ -877,15 +879,11 @@ $ide-commit-header-height: 48px;
} }
.ide-right-sidebar { .ide-right-sidebar {
.ide-activity-bar {
border-left: 1px solid var(--ide-border-color, $white-dark);
}
.multi-file-commit-panel-inner { .multi-file-commit-panel-inner {
width: 350px; width: 350px;
padding: $grid-size 0; padding: $grid-size 0;
background-color: var(--ide-highlight-background, $white); background-color: var(--ide-highlight-background, $white);
border-left: 1px solid var(--ide-border-color, $white-dark); border-right: 1px solid var(--ide-border-color, $white-dark);
} }
.ide-right-sidebar-jobs-detail { .ide-right-sidebar-jobs-detail {
......
...@@ -5,7 +5,6 @@ class SearchService ...@@ -5,7 +5,6 @@ class SearchService
SEARCH_TERM_LIMIT = 64 SEARCH_TERM_LIMIT = 64
SEARCH_CHAR_LIMIT = 4096 SEARCH_CHAR_LIMIT = 4096
DEFAULT_PER_PAGE = Gitlab::SearchResults::DEFAULT_PER_PAGE DEFAULT_PER_PAGE = Gitlab::SearchResults::DEFAULT_PER_PAGE
MAX_PER_PAGE = 200 MAX_PER_PAGE = 200
...@@ -62,8 +61,8 @@ class SearchService ...@@ -62,8 +61,8 @@ class SearchService
@search_results ||= search_service.execute @search_results ||= search_service.execute
end end
def search_objects def search_objects(preload_method = nil)
@search_objects ||= redact_unauthorized_results(search_results.objects(scope, page: params[:page], per_page: per_page)) @search_objects ||= redact_unauthorized_results(search_results.objects(scope, page: params[:page], per_page: per_page, preload_method: preload_method))
end end
private private
......
---
title: Fix leaky constant issue in sidekiq middleware client metric spec
merge_request: 32108
author: Rajendra Kadam
type: fixed
# The `table_exists?` check is needed because during our migration rollback testing, # The explicit schema version check is needed because during our migration rollback testing,
# `Shard.connected?` could be cached and return true even though the table doesn't exist # `Shard.connected?` could be cached and return true even though the table doesn't exist
return unless Shard.connected? return unless Shard.connected?
return unless Shard.table_exists? return unless ActiveRecord::Migrator.current_version >= 20190402150158
return unless Shard.connection.index_exists?(:shards, :name, unique: true)
return if Gitlab::Database.read_only? return if Gitlab::Database.read_only?
Shard.populate! Shard.populate!
...@@ -9,6 +9,7 @@ link: https://about.gitlab.com/handbook/communication/#top-misused-terms ...@@ -9,6 +9,7 @@ link: https://about.gitlab.com/handbook/communication/#top-misused-terms
level: error level: error
ignorecase: true ignorecase: true
swap: swap:
frontmatter: front matter
GitLabber: GitLab team member GitLabber: GitLab team member
gitlab omnibus: Omnibus GitLab gitlab omnibus: Omnibus GitLab
param: parameter param: parameter
......
...@@ -550,7 +550,7 @@ You can also ...@@ -550,7 +550,7 @@ You can also
[configure the text editor of your choice](https://errata-ai.github.io/vale/#local-use-by-a-single-writer) [configure the text editor of your choice](https://errata-ai.github.io/vale/#local-use-by-a-single-writer)
to display the results. to display the results.
Vale's test results [are displayed](#testing) in CI pipelines. Vale's error-level test results [are displayed](#testing) in CI pipelines.
##### Disable a Vale test ##### Disable a Vale test
......
...@@ -173,7 +173,7 @@ we reference the array with a symbol (`:versions`). ...@@ -173,7 +173,7 @@ we reference the array with a symbol (`:versions`).
## Bumping versions of CSS and JavaScript ## Bumping versions of CSS and JavaScript
Whenever the custom CSS and JavaScript files under `content/assets/` change, Whenever the custom CSS and JavaScript files under `content/assets/` change,
make sure to bump their version in the frontmatter. This method guarantees that make sure to bump their version in the front matter. This method guarantees that
your changes will take effect by clearing the cache of previous files. your changes will take effect by clearing the cache of previous files.
Always use Nanoc's way of including those files, do not hardcode them in the Always use Nanoc's way of including those files, do not hardcode them in the
......
...@@ -29,7 +29,7 @@ templates of the default branch will be taken into account. ...@@ -29,7 +29,7 @@ templates of the default branch will be taken into account.
For example, if you have a project for tracking new blog posts, you can require the For example, if you have a project for tracking new blog posts, you can require the
title, outlines, author name, author social media information, and so on. title, outlines, author name, author social media information, and so on.
- Following the previous example, you can make a template for every MR submitted - Following the previous example, you can make a template for every MR submitted
with a new blog post, requiring information about the post date, frontmatter data, with a new blog post, requiring information about the post date, front matter data,
images guidelines, link to the related issue, reviewer name, and so on. images guidelines, link to the related issue, reviewer name, and so on.
- You can also create issues and merge request templates for different - You can also create issues and merge request templates for different
stages of your workflow, for example, feature proposal, feature improvement, or a bug report. stages of your workflow, for example, feature proposal, feature improvement, or a bug report.
......
...@@ -6,19 +6,15 @@ module API ...@@ -6,19 +6,15 @@ module API
expose :merged_by, using: Entities::UserBasic do |merge_request, _options| expose :merged_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.merged_by merge_request.metrics&.merged_by
end end
expose :merged_at do |merge_request, _options| expose :merged_at do |merge_request, _options|
merge_request.metrics&.merged_at merge_request.metrics&.merged_at
end end
expose :closed_by, using: Entities::UserBasic do |merge_request, _options| expose :closed_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.latest_closed_by merge_request.metrics&.latest_closed_by
end end
expose :closed_at do |merge_request, _options| expose :closed_at do |merge_request, _options|
merge_request.metrics&.latest_closed_at merge_request.metrics&.latest_closed_at
end end
expose :title_html, if: -> (_, options) { options[:render_html] } do |entity| expose :title_html, if: -> (_, options) { options[:render_html] } do |entity|
MarkupHelper.markdown_field(entity, :title) MarkupHelper.markdown_field(entity, :title)
end end
...@@ -33,7 +29,6 @@ module API ...@@ -33,7 +29,6 @@ module API
merge_request.assignee merge_request.assignee
end end
expose :author, :assignees, using: Entities::UserBasic expose :author, :assignees, using: Entities::UserBasic
expose :source_project_id, :target_project_id expose :source_project_id, :target_project_id
expose :labels do |merge_request, options| expose :labels do |merge_request, options|
if options[:with_labels_details] if options[:with_labels_details]
...@@ -85,11 +80,8 @@ module API ...@@ -85,11 +80,8 @@ module API
end end
expose :squash expose :squash
expose :task_completion_status expose :task_completion_status
expose :cannot_be_merged?, as: :has_conflicts expose :cannot_be_merged?, as: :has_conflicts
expose :mergeable_discussions_state?, as: :blocking_discussions_resolved expose :mergeable_discussions_state?, as: :blocking_discussions_resolved
end end
end end
......
...@@ -20,6 +20,10 @@ module API ...@@ -20,6 +20,10 @@ module API
users: Entities::UserBasic users: Entities::UserBasic
}.freeze }.freeze
SCOPE_PRELOAD_METHOD = {
merge_requests: :with_api_entity_associations
}.freeze
def search(additional_params = {}) def search(additional_params = {})
search_params = { search_params = {
scope: params[:scope], scope: params[:scope],
...@@ -29,7 +33,7 @@ module API ...@@ -29,7 +33,7 @@ module API
per_page: params[:per_page] per_page: params[:per_page]
}.merge(additional_params) }.merge(additional_params)
results = SearchService.new(current_user, search_params).search_objects results = SearchService.new(current_user, search_params).search_objects(preload_method)
paginate(results) paginate(results)
end end
...@@ -42,6 +46,10 @@ module API ...@@ -42,6 +46,10 @@ module API
SCOPE_ENTITY[params[:scope].to_sym] SCOPE_ENTITY[params[:scope].to_sym]
end end
def preload_method
SCOPE_PRELOAD_METHOD[params[:scope].to_sym]
end
def verify_search_scope!(resource:) def verify_search_scope!(resource:)
# In EE we have additional validation requirements for searches. # In EE we have additional validation requirements for searches.
# Defining this method here as a noop allows us to easily extend it in # Defining this method here as a noop allows us to easily extend it in
......
...@@ -11,7 +11,7 @@ module Gitlab ...@@ -11,7 +11,7 @@ module Gitlab
@query = query @query = query
end end
def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE) def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, preload_method: nil)
case scope case scope
when 'notes' when 'notes'
notes.page(page).per(per_page) notes.page(page).per(per_page)
......
...@@ -26,7 +26,7 @@ module Gitlab ...@@ -26,7 +26,7 @@ module Gitlab
@default_project_filter = default_project_filter @default_project_filter = default_project_filter
end end
def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, without_count: true) def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, without_count: true, preload_method: nil)
collection = case scope collection = case scope
when 'projects' when 'projects'
projects projects
......
...@@ -11,7 +11,7 @@ module Gitlab ...@@ -11,7 +11,7 @@ module Gitlab
@query = query @query = query
end end
def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE) def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, preload_method: nil)
paginated_objects(snippet_titles, page, per_page) paginated_objects(snippet_titles, page, per_page)
end end
......
...@@ -621,6 +621,19 @@ const templatingVariableTypes = { ...@@ -621,6 +621,19 @@ const templatingVariableTypes = {
], ],
}, },
}, },
withoutOptText: {
label: 'Options without text',
type: 'custom',
options: {
values: [
{ value: 'value1' },
{
value: 'value2',
default: true,
},
],
},
},
}, },
}, },
}; };
...@@ -709,6 +722,26 @@ const responseForAdvancedCustomVariableWithoutLabel = { ...@@ -709,6 +722,26 @@ const responseForAdvancedCustomVariableWithoutLabel = {
}, },
}; };
const responseForAdvancedCustomVariableWithoutOptText = {
advCustomWithoutOptText: {
label: 'Options without text',
value: 'value2',
options: [
{
default: false,
text: 'value1',
value: 'value1',
},
{
default: true,
text: 'value2',
value: 'value2',
},
],
type: 'custom',
},
};
const responseForAdvancedCustomVariable = { const responseForAdvancedCustomVariable = {
...responseForSimpleCustomVariable, ...responseForSimpleCustomVariable,
advCustomNormal: { advCustomNormal: {
...@@ -752,6 +785,9 @@ export const mockTemplatingData = { ...@@ -752,6 +785,9 @@ export const mockTemplatingData = {
advCustomWithoutLabel: generateMockTemplatingData({ advCustomWithoutLabel: generateMockTemplatingData({
advCustomWithoutLabel: templatingVariableTypes.custom.advanced.withoutLabel, advCustomWithoutLabel: templatingVariableTypes.custom.advanced.withoutLabel,
}), }),
advCustomWithoutOptText: generateMockTemplatingData({
advCustomWithoutOptText: templatingVariableTypes.custom.advanced.withoutOptText,
}),
simpleAndAdv: generateMockTemplatingData({ simpleAndAdv: generateMockTemplatingData({
simpleCustom: templatingVariableTypes.custom.simple, simpleCustom: templatingVariableTypes.custom.simple,
advCustomNormal: templatingVariableTypes.custom.advanced.normal, advCustomNormal: templatingVariableTypes.custom.advanced.normal,
...@@ -773,6 +809,7 @@ export const mockTemplatingDataResponses = { ...@@ -773,6 +809,7 @@ export const mockTemplatingDataResponses = {
advCustomWithoutOpts: responseForAdvancedCustomVariableWithoutOptions, advCustomWithoutOpts: responseForAdvancedCustomVariableWithoutOptions,
advCustomWithoutType: {}, advCustomWithoutType: {},
advCustomWithoutLabel: responseForAdvancedCustomVariableWithoutLabel, advCustomWithoutLabel: responseForAdvancedCustomVariableWithoutLabel,
advCustomWithoutOptText: responseForAdvancedCustomVariableWithoutOptText,
simpleAndAdv: responseForAdvancedCustomVariable, simpleAndAdv: responseForAdvancedCustomVariable,
allVariableTypes: responsesForAllVariableTypes, allVariableTypes: responsesForAllVariableTypes,
}; };
...@@ -3,19 +3,20 @@ import { mockTemplatingData, mockTemplatingDataResponses } from '../mock_data'; ...@@ -3,19 +3,20 @@ import { mockTemplatingData, mockTemplatingDataResponses } from '../mock_data';
describe('parseTemplatingVariables', () => { describe('parseTemplatingVariables', () => {
it.each` it.each`
case | input | expected case | input | expected
${'Returns empty object for no dashboard input'} | ${{}} | ${{}} ${'Returns empty object for no dashboard input'} | ${{}} | ${{}}
${'Returns empty object for empty dashboard input'} | ${{ dashboard: {} }} | ${{}} ${'Returns empty object for empty dashboard input'} | ${{ dashboard: {} }} | ${{}}
${'Returns empty object for empty templating prop'} | ${mockTemplatingData.emptyTemplatingProp} | ${{}} ${'Returns empty object for empty templating prop'} | ${mockTemplatingData.emptyTemplatingProp} | ${{}}
${'Returns empty object for empty variables prop'} | ${mockTemplatingData.emptyVariablesProp} | ${{}} ${'Returns empty object for empty variables prop'} | ${mockTemplatingData.emptyVariablesProp} | ${{}}
${'Returns parsed object for simple text variable'} | ${mockTemplatingData.simpleText} | ${mockTemplatingDataResponses.simpleText} ${'Returns parsed object for simple text variable'} | ${mockTemplatingData.simpleText} | ${mockTemplatingDataResponses.simpleText}
${'Returns parsed object for advanced text variable'} | ${mockTemplatingData.advText} | ${mockTemplatingDataResponses.advText} ${'Returns parsed object for advanced text variable'} | ${mockTemplatingData.advText} | ${mockTemplatingDataResponses.advText}
${'Returns parsed object for simple custom variable'} | ${mockTemplatingData.simpleCustom} | ${mockTemplatingDataResponses.simpleCustom} ${'Returns parsed object for simple custom variable'} | ${mockTemplatingData.simpleCustom} | ${mockTemplatingDataResponses.simpleCustom}
${'Returns parsed object for advanced custom variable without options'} | ${mockTemplatingData.advCustomWithoutOpts} | ${mockTemplatingDataResponses.advCustomWithoutOpts} ${'Returns parsed object for advanced custom variable without options'} | ${mockTemplatingData.advCustomWithoutOpts} | ${mockTemplatingDataResponses.advCustomWithoutOpts}
${'Returns parsed object for advanced custom variable without type'} | ${mockTemplatingData.advCustomWithoutType} | ${{}} ${'Returns parsed object for advanced custom variable for option without text'} | ${mockTemplatingData.advCustomWithoutOptText} | ${mockTemplatingDataResponses.advCustomWithoutOptText}
${'Returns parsed object for advanced custom variable without label'} | ${mockTemplatingData.advCustomWithoutLabel} | ${mockTemplatingDataResponses.advCustomWithoutLabel} ${'Returns parsed object for advanced custom variable without type'} | ${mockTemplatingData.advCustomWithoutType} | ${{}}
${'Returns parsed object for simple and advanced custom variables'} | ${mockTemplatingData.simpleAndAdv} | ${mockTemplatingDataResponses.simpleAndAdv} ${'Returns parsed object for advanced custom variable without label'} | ${mockTemplatingData.advCustomWithoutLabel} | ${mockTemplatingDataResponses.advCustomWithoutLabel}
${'Returns parsed object for all variable types'} | ${mockTemplatingData.allVariableTypes} | ${mockTemplatingDataResponses.allVariableTypes} ${'Returns parsed object for simple and advanced custom variables'} | ${mockTemplatingData.simpleAndAdv} | ${mockTemplatingDataResponses.simpleAndAdv}
${'Returns parsed object for all variable types'} | ${mockTemplatingData.allVariableTypes} | ${mockTemplatingDataResponses.allVariableTypes}
`('$case', ({ input, expected }) => { `('$case', ({ input, expected }) => {
expect(parseTemplatingVariables(input?.dashboard?.templating)).toEqual(expected); expect(parseTemplatingVariables(input?.dashboard?.templating)).toEqual(expected);
}); });
......
...@@ -47,8 +47,11 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do ...@@ -47,8 +47,11 @@ describe Gitlab::SidekiqMiddleware::ClientMetrics do
end end
context "when workers are not attributed" do context "when workers are not attributed" do
class TestNonAttributedWorker before do
include Sidekiq::Worker stub_const('TestNonAttributedWorker', Class.new)
TestNonAttributedWorker.class_eval do
include Sidekiq::Worker
end
end end
it_behaves_like "a metrics client middleware" do it_behaves_like "a metrics client middleware" do
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册