summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-01 12:09:35 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-01 12:09:35 +0000
commit4ee706fcd1ffcb2926fd9258e9f296c260a3d06c (patch)
tree47ef82efe01cd18bc0da6eb0922273aed9e060ea
parent5a9468a4e504d06fd8f5a558f953f4af6355f702 (diff)
downloadgitlab-ce-4ee706fcd1ffcb2926fd9258e9f296c260a3d06c.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop.yml16
-rw-r--r--.rubocop_todo/rails/http_status.yml9
-rw-r--r--app/assets/javascripts/gitlab_pages/components/pages_pipeline_wizard.vue2
-rw-r--r--app/assets/javascripts/groups/components/group_item.vue8
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue90
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_item.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/jobs_shared/job_name_component.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_mini_graph/job_item.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue2
-rw-r--r--app/assets/javascripts/search/topbar/components/app.vue8
-rw-r--r--app/assets/javascripts/search/topbar/index.js20
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/page_bundles/_pipeline_mixins.scss23
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss194
-rw-r--r--app/assets/stylesheets/themes/_dark.scss135
-rw-r--r--app/assets/stylesheets/themes/dark_mode_overrides.scss134
-rw-r--r--app/controllers/concerns/invisible_captcha_on_signup.rb2
-rw-r--r--app/controllers/dashboard/snippets_controller.rb2
-rw-r--r--app/controllers/explore/snippets_controller.rb2
-rw-r--r--app/controllers/projects/autocomplete_sources_controller.rb2
-rw-r--r--app/controllers/projects/runner_projects_controller.rb2
-rw-r--r--app/controllers/projects/service_ping_controller.rb6
-rw-r--r--app/controllers/projects/snippets/application_controller.rb2
-rw-r--r--app/controllers/repositories/lfs_storage_controller.rb2
-rw-r--r--app/controllers/search_controller.rb7
-rw-r--r--app/controllers/snippets/application_controller.rb2
-rw-r--r--app/controllers/snippets/notes_controller.rb2
-rw-r--r--app/controllers/users_controller.rb3
-rw-r--r--app/models/user.rb28
-rw-r--r--app/models/user_preference.rb69
-rw-r--r--app/services/chat_names/find_user_service.rb7
-rw-r--r--app/views/search/show.html.haml2
-rw-r--r--config/feature_categories.yml4
-rw-r--r--config/webpack.config.js1
-rw-r--r--doc/api/product_analytics.md6
-rw-r--r--doc/operations/incident_management/alerts.md17
-rw-r--r--doc/operations/incident_management/img/alert_detail_add_todo_v13_9.pngbin26763 -> 0 bytes
-rw-r--r--doc/user/product_analytics/index.md24
-rw-r--r--jest.config.base.js2
-rw-r--r--lib/api/helpers/award_emoji.rb2
-rw-r--r--lib/api/helpers/discussions_helpers.rb2
-rw-r--r--lib/api/helpers/notes_helpers.rb2
-rw-r--r--lib/api/project_snippets.rb2
-rw-r--r--lib/api/snippets.rb2
-rw-r--r--lib/gitlab/memory/watchdog.rb51
-rw-r--r--lib/gitlab/memory/watchdog/configuration.rb6
-rw-r--r--lib/gitlab/memory/watchdog/configurator.rb3
-rw-r--r--lib/gitlab/memory/watchdog/event_reporter.rb73
-rw-r--r--locale/gitlab.pot24
-rw-r--r--package.json2
-rw-r--r--rubocop/cop/rspec/timecop_freeze.rb41
-rw-r--r--rubocop/cop/rspec/timecop_travel.rb41
-rw-r--r--spec/features/dashboard/snippets_spec.rb2
-rw-r--r--spec/features/projects/settings/packages_settings_spec.rb4
-rw-r--r--spec/features/snippets/embedded_snippet_spec.rb2
-rw-r--r--spec/features/snippets/explore_spec.rb2
-rw-r--r--spec/features/snippets/internal_snippet_spec.rb2
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb2
-rw-r--r--spec/features/snippets/private_snippets_spec.rb2
-rw-r--r--spec/features/snippets/public_snippets_spec.rb2
-rw-r--r--spec/features/snippets/search_snippets_spec.rb2
-rw-r--r--spec/features/snippets/show_spec.rb2
-rw-r--r--spec/features/snippets/spam_snippets_spec.rb2
-rw-r--r--spec/features/snippets/user_creates_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_deletes_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_edits_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_snippets_spec.rb2
-rw-r--r--spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js74
-rw-r--r--spec/lib/api/every_api_endpoint_spec.rb15
-rw-r--r--spec/lib/gitlab/memory/watchdog/configuration_spec.rb8
-rw-r--r--spec/lib/gitlab/memory/watchdog/configurator_spec.rb12
-rw-r--r--spec/lib/gitlab/memory/watchdog/event_reporter_spec.rb118
-rw-r--r--spec/lib/gitlab/memory/watchdog_spec.rb97
-rw-r--r--spec/models/user_preference_spec.rb157
-rw-r--r--spec/models/user_spec.rb64
-rw-r--r--spec/rubocop/cop/rspec/timecop_freeze_spec.rb28
-rw-r--r--spec/rubocop/cop/rspec/timecop_travel_spec.rb28
-rw-r--r--spec/services/chat_names/find_user_service_spec.rb8
-rw-r--r--workhorse/go.mod2
-rw-r--r--workhorse/go.sum3
-rw-r--r--yarn.lock8
81 files changed, 961 insertions, 788 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index 2367cef34b8..8113b7d6a7b 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -450,22 +450,6 @@ Cop/ActiveModelErrorsDirectManipulation:
Gitlab/AvoidFeatureGet:
Enabled: true
-RSpec/TimecopFreeze:
- Enabled: true
- AutoCorrect: true
- Include:
- - 'spec/**/*.rb'
- - 'ee/spec/**/*.rb'
- - 'qa/spec/**/*.rb'
-
-RSpec/TimecopTravel:
- Enabled: true
- AutoCorrect: true
- Include:
- - 'spec/**/*.rb'
- - 'ee/spec/**/*.rb'
- - 'qa/spec/**/*.rb'
-
RSpec/WebMockEnable:
Enabled: true
Include:
diff --git a/.rubocop_todo/rails/http_status.yml b/.rubocop_todo/rails/http_status.yml
deleted file mode 100644
index b1f64f7aa18..00000000000
--- a/.rubocop_todo/rails/http_status.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-# Cop supports --autocorrect.
-Rails/HttpStatus:
- Exclude:
- - 'app/controllers/concerns/invisible_captcha_on_signup.rb'
- - 'app/controllers/projects/runner_projects_controller.rb'
- - 'app/controllers/projects/service_ping_controller.rb'
- - 'app/controllers/repositories/lfs_storage_controller.rb'
- - 'ee/app/controllers/trials_controller.rb'
diff --git a/app/assets/javascripts/gitlab_pages/components/pages_pipeline_wizard.vue b/app/assets/javascripts/gitlab_pages/components/pages_pipeline_wizard.vue
index f17a05999b0..bf71f682048 100644
--- a/app/assets/javascripts/gitlab_pages/components/pages_pipeline_wizard.vue
+++ b/app/assets/javascripts/gitlab_pages/components/pages_pipeline_wizard.vue
@@ -2,7 +2,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { captureException } from '@sentry/browser';
import PipelineWizard from '~/pipeline_wizard/pipeline_wizard.vue';
-import PagesWizardTemplate from '~/pipeline_wizard/templates/pages.yml';
+import PagesWizardTemplate from '~/pipeline_wizard/templates/pages.yml?raw';
import { logError } from '~/lib/logger';
import { s__ } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility';
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue
index 3874d06da91..d9781ef9c84 100644
--- a/app/assets/javascripts/groups/components/group_item.vue
+++ b/app/assets/javascripts/groups/components/group_item.vue
@@ -200,11 +200,9 @@ export default {
class="no-expand gl-mr-3 gl-text-gray-900!"
:itemprop="microdata.nameItemprop"
>
- {{
- // ending bracket must be by closing tag to prevent
- // link hover text-decoration from over-extending
- group.name
- }}
+ <!-- ending bracket must be by closing tag to prevent -->
+ <!-- link hover text-decoration from over-extending -->
+ {{ group.name }}
</a>
<gl-icon
v-gl-tooltip.hover.bottom
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index b344c4f1891..79a9bbb84c2 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -23,6 +23,12 @@ import ProjectSettingRow from './project_setting_row.vue';
const FEATURE_ACCESS_LEVEL_ANONYMOUS = [30, s__('ProjectSettings|Everyone')];
+const PACKAGE_REGISTRY_ACCESS_LEVEL_DEFAULT_BY_PROJECT_VISIBILITY = {
+ [VISIBILITY_LEVEL_PRIVATE_INTEGER]: featureAccessLevel.PROJECT_MEMBERS,
+ [VISIBILITY_LEVEL_INTERNAL_INTEGER]: featureAccessLevel.EVERYONE,
+ [VISIBILITY_LEVEL_PUBLIC_INTEGER]: FEATURE_ACCESS_LEVEL_ANONYMOUS[0],
+};
+
export default {
i18n: {
...CVE_ID_REQUEST_BUTTON_I18N,
@@ -47,11 +53,15 @@ export default {
packagesHelpText: s__(
'ProjectSettings|Every project can have its own space to store its packages. Note: The Package Registry is always visible when a project is public.',
),
- packageRegistryHelpText: s__(
- 'ProjectSettings|Every project can have its own space to store its packages.',
+ packageRegistryHelpText: s__('ProjectSettings|Publish, store, and view packages in a project.'),
+ packageRegistryForEveryoneHelpText: s__(
+ 'ProjectSettings|Anyone can pull packages with a package manager API.',
),
packagesLabel: s__('ProjectSettings|Packages'),
packageRegistryLabel: s__('ProjectSettings|Package registry'),
+ packageRegistryForEveryoneLabel: s__(
+ 'ProjectSettings|Allow anyone to pull from Package Registry',
+ ),
pagesLabel: s__('ProjectSettings|Pages'),
ciCdLabel: __('CI/CD'),
repositoryLabel: s__('ProjectSettings|Repository'),
@@ -287,18 +297,6 @@ export default {
);
},
- packageRegistryFeatureAccessLevelOptions() {
- const options = [FEATURE_ACCESS_LEVEL_ANONYMOUS];
-
- if (this.visibilityLevel === VISIBILITY_LEVEL_PRIVATE_INTEGER) {
- options.unshift(featureAccessLevelMembers);
- } else if (this.visibilityLevel === VISIBILITY_LEVEL_INTERNAL_INTEGER) {
- options.unshift(featureAccessLevelEveryone);
- }
-
- return options;
- },
-
pagesFeatureAccessLevelOptions() {
const options = [featureAccessLevelMembers];
@@ -366,6 +364,15 @@ export default {
packageRegistryAccessLevelEnabled() {
return this.glFeatures.packageRegistryAccessLevel;
},
+ packageRegistryEnabled() {
+ return this.packageRegistryAccessLevel > featureAccessLevel.NOT_ENABLED;
+ },
+ packageRegistryApiForEveryoneEnabled() {
+ return this.packageRegistryAccessLevel === FEATURE_ACCESS_LEVEL_ANONYMOUS[0];
+ },
+ packageRegistryApiForEveryoneEnabledShown() {
+ return this.visibilityLevel !== VISIBILITY_LEVEL_PUBLIC_INTEGER;
+ },
splitOperationsEnabled() {
return this.glFeatures.splitOperationsVisibilityPermissions;
},
@@ -474,9 +481,8 @@ export default {
this.packageRegistryAccessLevelEnabled &&
this.packageRegistryAccessLevel === featureAccessLevel.PROJECT_MEMBERS
) {
- this.packageRegistryAccessLevel = Math.min(
- ...this.packageRegistryFeatureAccessLevelOptions.map((option) => option[0]),
- );
+ this.packageRegistryAccessLevel =
+ PACKAGE_REGISTRY_ACCESS_LEVEL_DEFAULT_BY_PROJECT_VISIBILITY[value];
}
if (this.buildsAccessLevel > featureAccessLevel.NOT_ENABLED)
this.buildsAccessLevel = featureAccessLevel.EVERYONE;
@@ -561,6 +567,22 @@ export default {
visibilityAllowed(option) {
return this.allowedVisibilityOptions.includes(option);
},
+ onPackageRegistryEnabledToggle(value) {
+ this.packageRegistryAccessLevel = value
+ ? this.packageRegistryAccessLevelDefault()
+ : featureAccessLevel.NOT_ENABLED;
+ },
+ onPackageRegistryApiForEveryoneEnabledToggle(value) {
+ this.packageRegistryAccessLevel = value
+ ? FEATURE_ACCESS_LEVEL_ANONYMOUS[0]
+ : this.packageRegistryAccessLevelDefault();
+ },
+ packageRegistryAccessLevelDefault() {
+ return (
+ PACKAGE_REGISTRY_ACCESS_LEVEL_DEFAULT_BY_PROJECT_VISIBILITY[this.visibilityLevel] ??
+ featureAccessLevel.NOT_ENABLED
+ );
+ },
},
};
</script>
@@ -897,10 +919,36 @@ export default {
:help-text="$options.i18n.packageRegistryHelpText"
data-testid="package-registry-access-level"
>
- <project-feature-setting
- v-model="packageRegistryAccessLevel"
+ <gl-toggle
+ class="gl-my-2"
+ :value="packageRegistryEnabled"
:label="$options.i18n.packageRegistryLabel"
- :options="packageRegistryFeatureAccessLevelOptions"
+ label-position="hidden"
+ name="package_registry_enabled"
+ @change="onPackageRegistryEnabledToggle"
+ />
+ <div
+ v-if="packageRegistryApiForEveryoneEnabledShown"
+ class="project-feature-setting-group gl-pl-7 gl-sm-pl-5 gl-my-3"
+ >
+ <project-setting-row
+ :label="$options.i18n.packageRegistryForEveryoneLabel"
+ :help-text="$options.i18n.packageRegistryForEveryoneHelpText"
+ >
+ <gl-toggle
+ class="gl-my-2"
+ :value="packageRegistryApiForEveryoneEnabled"
+ :disabled="!packageRegistryEnabled"
+ :label="$options.i18n.packageRegistryForEveryoneLabel"
+ label-position="hidden"
+ name="package_registry_api_for_everyone_enabled"
+ @change="onPackageRegistryApiForEveryoneEnabledToggle"
+ />
+ </project-setting-row>
+ </div>
+ <input
+ :value="packageRegistryAccessLevel"
+ type="hidden"
name="project[project_feature_attributes][package_registry_access_level]"
/>
</project-setting-row>
@@ -927,7 +975,7 @@ export default {
ref="monitor-settings"
:label="$options.i18n.monitorLabel"
:help-text="
- s__('ProjectSettings|Configure your project resources and monitor their health.')
+ s__('ProjectSettings|Monitor the health of your project and respond to incidents.')
"
>
<project-feature-setting
diff --git a/app/assets/javascripts/pipelines/components/graph/job_item.vue b/app/assets/javascripts/pipelines/components/graph/job_item.vue
index 377f21b299f..4f2be27486c 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_item.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_item.vue
@@ -252,7 +252,7 @@ export default {
@click="jobItemClick"
@mouseout="hideTooltips"
>
- <div class="ci-job-name-component gl-display-flex gl-align-items-center">
+ <div class="gl-display-flex gl-align-items-center gl-flex-grow-1">
<ci-icon :size="24" :status="job.status" class="gl-line-height-0" />
<div class="gl-pl-3 gl-pr-3 gl-display-flex gl-flex-direction-column gl-pipeline-job-width">
<div class="gl-text-truncate gl-pr-9 gl-line-height-normal">{{ job.name }}</div>
diff --git a/app/assets/javascripts/pipelines/components/jobs_shared/job_name_component.vue b/app/assets/javascripts/pipelines/components/jobs_shared/job_name_component.vue
index f4fc6893520..1c7f5a7476d 100644
--- a/app/assets/javascripts/pipelines/components/jobs_shared/job_name_component.vue
+++ b/app/assets/javascripts/pipelines/components/jobs_shared/job_name_component.vue
@@ -29,7 +29,7 @@ export default {
};
</script>
<template>
- <span class="ci-job-name-component mw-100 gl-display-flex gl-align-items-center">
+ <span class="mw-100 gl-display-flex gl-align-items-center gl-flex-grow-1">
<ci-icon :size="iconSize" :status="status" class="gl-line-height-0" />
<span class="gl-text-truncate mw-70p gl-pl-3 gl-display-inline-block">
{{ name }}
diff --git a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/job_item.vue b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/job_item.vue
index 211c5f117c7..efa2b3a4fff 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/job_item.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/job_item.vue
@@ -163,7 +163,7 @@ export default {
@click.stop="hideTooltips"
@mouseout="hideTooltips"
>
- <job-name-component :name="job.name" :status="job.status" :icon-size="24" />
+ <job-name-component :name="job.name" :status="job.status" />
</gl-link>
<div
@@ -175,7 +175,7 @@ export default {
data-testid="job-without-link"
@mouseout="hideTooltips"
>
- <job-name-component :name="job.name" :status="job.status" :icon-size="24" />
+ <job-name-component :name="job.name" :status="job.status" />
</div>
<action-component
diff --git a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue
index ba150919e58..98f558c7df5 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue
@@ -149,7 +149,7 @@ export default {
class="js-builds-dropdown-list scrollable-menu"
data-testid="mini-pipeline-graph-dropdown-menu-list"
>
- <div class="gl--flex-center gl-border-b gl-font-weight-bold gl-pb-3">
+ <div class="gl--flex-center gl-border-b gl-font-weight-bold gl-mb-3 gl-pb-3">
<span class="gl-mr-1">{{ $options.i18n.stage }}</span>
<span data-testid="pipeline-stage-dropdown-menu-title">{{ stageName }}</span>
</div>
diff --git a/app/assets/javascripts/search/topbar/components/app.vue b/app/assets/javascripts/search/topbar/components/app.vue
index d0fcbb0d83b..22ebf998620 100644
--- a/app/assets/javascripts/search/topbar/components/app.vue
+++ b/app/assets/javascripts/search/topbar/components/app.vue
@@ -20,12 +20,12 @@ export default {
},
mixins: [glFeatureFlagsMixin()],
props: {
- groupInitialData: {
+ groupInitialJson: {
type: Object,
required: false,
default: () => ({}),
},
- projectInitialData: {
+ projectInitialJson: {
type: Object,
required: false,
default: () => ({}),
@@ -72,11 +72,11 @@ export default {
</div>
<div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2">
<label class="gl-display-block">{{ __('Group') }}</label>
- <group-filter :initial-data="groupInitialData" />
+ <group-filter :initial-data="groupInitialJson" />
</div>
<div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2">
<label class="gl-display-block">{{ __('Project') }}</label>
- <project-filter :initial-data="projectInitialData" />
+ <project-filter :initial-data="projectInitialJson" />
</div>
</div>
<hr v-if="hasVerticalNav" class="gl-mt-5 gl-mb-0 gl-border-gray-100" />
diff --git a/app/assets/javascripts/search/topbar/index.js b/app/assets/javascripts/search/topbar/index.js
index 87316e10e8d..d6e16085c28 100644
--- a/app/assets/javascripts/search/topbar/index.js
+++ b/app/assets/javascripts/search/topbar/index.js
@@ -11,10 +11,18 @@ export const initTopbar = (store) => {
return false;
}
- let { groupInitialData, projectInitialData } = el.dataset;
+ const {
+ groupInitialJson,
+ projectInitialJson,
+ elasticsearchEnabled,
+ defaultBranchName,
+ } = el.dataset;
- groupInitialData = JSON.parse(groupInitialData);
- projectInitialData = JSON.parse(projectInitialData);
+ const groupInitialJsonParsed = JSON.parse(groupInitialJson);
+ const projectInitialJsonParsed = JSON.parse(projectInitialJson);
+ const elasticsearchEnabledParsed = elasticsearchEnabled
+ ? JSON.parse(elasticsearchEnabled)
+ : false;
return new Vue({
el,
@@ -22,8 +30,10 @@ export const initTopbar = (store) => {
render(createElement) {
return createElement(GlobalSearchTopbar, {
props: {
- groupInitialData,
- projectInitialData,
+ groupInitialJson: groupInitialJsonParsed,
+ projectInitialJson: projectInitialJsonParsed,
+ elasticsearchEnabled: elasticsearchEnabledParsed,
+ defaultBranchName,
},
});
},
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index f817ad8f24f..97ad342997b 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -822,7 +822,6 @@ Pipeline Graph
$ci-action-icon-size: 22px;
$ci-action-icon-size-lg: 24px;
$pipeline-dropdown-line-height: 20px;
-$pipeline-dropdown-status-icon-size: 18px;
$ci-action-dropdown-button-size: 24px;
$ci-action-dropdown-svg-size: 12px;
diff --git a/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss b/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss
index 613d27a2f39..ed15e352b7d 100644
--- a/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss
+++ b/app/assets/stylesheets/page_bundles/_pipeline_mixins.scss
@@ -33,8 +33,8 @@
.ci-action-icon-container {
position: absolute;
- right: 8px;
- top: 8px;
+ right: 11px;
+ top: 7px;
&.ci-action-icon-wrapper {
height: $ci-action-dropdown-button-size;
@@ -84,25 +84,6 @@
&.non-details-job-component {
padding: $gl-padding-8 $gl-btn-horz-padding;
}
-
- .ci-job-name-component {
- align-items: center;
- display: flex;
- flex: 1;
- }
-
- .ci-status-icon {
- position: relative;
-
- > svg {
- width: $pipeline-dropdown-status-icon-size;
- height: $pipeline-dropdown-status-icon-size;
- margin: 3px 0;
- position: relative;
- overflow: visible;
- display: block;
- }
- }
}
// ensure .mini-pipeline-graph-dropdown-item has hover style when action-icon is hovered
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index fdd4df27a2e..e986fd9316e 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -2,25 +2,6 @@
// Please see the feedback issue for more details and help:
// https://gitlab.com/gitlab-org/gitlab/-/issues/331812
@charset "UTF-8";
-:root {
- color-scheme: dark;
-}
-body.gl-dark {
- --gray-10: #1f1e24;
- --gray-50: #333238;
- --gray-100: #434248;
- --gray-200: #535158;
- --gray-700: #bfbfc3;
- --gray-900: #ececef;
- --green-100: #0d532a;
- --green-700: #91d4a8;
- --gl-text-color: #ececef;
- --border-color: #4f4f4f;
- --black: #fff;
-}
-:root {
- --white: #333238;
-}
*,
*::before,
*::after {
@@ -1705,97 +1686,18 @@ svg.s16 {
}
:root {
color-scheme: dark;
-}
-body.gl-dark {
--gray-10: #1f1e24;
--gray-50: #333238;
--gray-100: #434248;
--gray-200: #535158;
- --gray-300: #626168;
- --gray-400: #737278;
- --gray-500: #89888d;
- --gray-600: #a4a3a8;
--gray-700: #bfbfc3;
- --gray-800: #dcdcde;
--gray-900: #ececef;
- --gray-950: #fbfafd;
- --green-50: #0a4020;
--green-100: #0d532a;
- --green-200: #24663b;
- --green-300: #217645;
- --green-400: #108548;
- --green-500: #2da160;
- --green-600: #52b87a;
--green-700: #91d4a8;
- --green-800: #c3e6cd;
- --green-900: #ecf4ee;
- --green-950: #f1fdf6;
- --blue-50: #033464;
- --blue-100: #064787;
- --blue-200: #0b5cad;
- --blue-300: #1068bf;
- --blue-400: #1f75cb;
- --blue-500: #428fdc;
- --blue-600: #63a6e9;
- --blue-700: #9dc7f1;
- --blue-800: #cbe2f9;
- --blue-900: #e9f3fc;
- --blue-950: #f2f9ff;
- --orange-50: #5c2900;
- --orange-100: #703800;
- --orange-200: #8f4700;
- --orange-300: #9e5400;
- --orange-400: #ab6100;
- --orange-500: #c17d10;
- --orange-600: #d99530;
- --orange-700: #e9be74;
- --orange-800: #f5d9a8;
- --orange-900: #fdf1dd;
- --orange-950: #fff4e1;
- --red-50: #660e00;
- --red-100: #8d1300;
- --red-200: #ae1800;
- --red-300: #c91c00;
- --red-400: #dd2b0e;
- --red-500: #ec5941;
- --red-600: #f57f6c;
- --red-700: #fcb5aa;
- --red-800: #fdd4cd;
- --red-900: #fcf1ef;
- --red-950: #fff4f3;
- --indigo-50: #1a1a40;
- --indigo-100: #292961;
- --indigo-200: #393982;
- --indigo-300: #4b4ba3;
- --indigo-400: #5b5bbd;
- --indigo-500: #6666c4;
- --indigo-600: #7c7ccc;
- --indigo-700: #a6a6de;
- --indigo-800: #d1d1f0;
- --indigo-900: #ebebfa;
- --indigo-950: #f7f7ff;
- --purple-50: #232150;
- --purple-100: #2f2a6b;
- --purple-200: #453894;
- --purple-300: #5943b6;
- --purple-400: #694cc0;
- --purple-500: #7b58cf;
- --purple-600: #9475db;
- --purple-700: #ac93e6;
- --purple-800: #cbbbf2;
- --purple-900: #e1d8f9;
- --purple-950: #f4f0ff;
- --dark-icon-color-purple-1: #524a68;
- --dark-icon-color-purple-2: #715bae;
- --dark-icon-color-purple-3: #9a79f7;
- --dark-icon-color-orange-1: #665349;
- --dark-icon-color-orange-2: #b37a5d;
--gl-text-color: #ececef;
- --border-color: #4f4f4f;
+ --border-color: #434248;
--white: #333238;
--black: #fff;
- --gray-light: #333238;
- --svg-status-bg: #333238;
}
.nav-sidebar,
.toggle-sidebar-button,
@@ -1947,100 +1849,6 @@ body.gl-dark .navbar-gitlab .search form .search-input {
color: var(--gl-text-color);
}
-:root {
- color-scheme: dark;
-}
-body.gl-dark {
- --gray-10: #1f1e24;
- --gray-50: #333238;
- --gray-100: #434248;
- --gray-200: #535158;
- --gray-300: #626168;
- --gray-400: #737278;
- --gray-500: #89888d;
- --gray-600: #a4a3a8;
- --gray-700: #bfbfc3;
- --gray-800: #dcdcde;
- --gray-900: #ececef;
- --gray-950: #fbfafd;
- --green-50: #0a4020;
- --green-100: #0d532a;
- --green-200: #24663b;
- --green-300: #217645;
- --green-400: #108548;
- --green-500: #2da160;
- --green-600: #52b87a;
- --green-700: #91d4a8;
- --green-800: #c3e6cd;
- --green-900: #ecf4ee;
- --green-950: #f1fdf6;
- --blue-50: #033464;
- --blue-100: #064787;
- --blue-200: #0b5cad;
- --blue-300: #1068bf;
- --blue-400: #1f75cb;
- --blue-500: #428fdc;
- --blue-600: #63a6e9;
- --blue-700: #9dc7f1;
- --blue-800: #cbe2f9;
- --blue-900: #e9f3fc;
- --blue-950: #f2f9ff;
- --orange-50: #5c2900;
- --orange-100: #703800;
- --orange-200: #8f4700;
- --orange-300: #9e5400;
- --orange-400: #ab6100;
- --orange-500: #c17d10;
- --orange-600: #d99530;
- --orange-700: #e9be74;
- --orange-800: #f5d9a8;
- --orange-900: #fdf1dd;
- --orange-950: #fff4e1;
- --red-50: #660e00;
- --red-100: #8d1300;
- --red-200: #ae1800;
- --red-300: #c91c00;
- --red-400: #dd2b0e;
- --red-500: #ec5941;
- --red-600: #f57f6c;
- --red-700: #fcb5aa;
- --red-800: #fdd4cd;
- --red-900: #fcf1ef;
- --red-950: #fff4f3;
- --indigo-50: #1a1a40;
- --indigo-100: #292961;
- --indigo-200: #393982;
- --indigo-300: #4b4ba3;
- --indigo-400: #5b5bbd;
- --indigo-500: #6666c4;
- --indigo-600: #7c7ccc;
- --indigo-700: #a6a6de;
- --indigo-800: #d1d1f0;
- --indigo-900: #ebebfa;
- --indigo-950: #f7f7ff;
- --purple-50: #232150;
- --purple-100: #2f2a6b;
- --purple-200: #453894;
- --purple-300: #5943b6;
- --purple-400: #694cc0;
- --purple-500: #7b58cf;
- --purple-600: #9475db;
- --purple-700: #ac93e6;
- --purple-800: #cbbbf2;
- --purple-900: #e1d8f9;
- --purple-950: #f4f0ff;
- --dark-icon-color-purple-1: #524a68;
- --dark-icon-color-purple-2: #715bae;
- --dark-icon-color-purple-3: #9a79f7;
- --dark-icon-color-orange-1: #665349;
- --dark-icon-color-orange-2: #b37a5d;
- --gl-text-color: #ececef;
- --border-color: #4f4f4f;
- --white: #333238;
- --black: #fff;
- --gray-light: #333238;
- --svg-status-bg: #333238;
-}
.tab-width-8 {
tab-size: 8;
}
diff --git a/app/assets/stylesheets/themes/_dark.scss b/app/assets/stylesheets/themes/_dark.scss
index cdb72c79d6a..8db91fd9908 100644
--- a/app/assets/stylesheets/themes/_dark.scss
+++ b/app/assets/stylesheets/themes/_dark.scss
@@ -113,141 +113,6 @@ $data-viz-blue-800: #b7c6ff;
$data-viz-blue-900: #d2dcff;
$data-viz-blue-950: #e9ebff;
-:root {
- color-scheme: dark;
-}
-
-body.gl-dark {
- --gray-10: #{$gray-10};
- --gray-50: #{$gray-50};
- --gray-100: #{$gray-100};
- --gray-200: #{$gray-200};
- --gray-300: #{$gray-300};
- --gray-400: #{$gray-400};
- --gray-500: #{$gray-500};
- --gray-600: #{$gray-600};
- --gray-700: #{$gray-700};
- --gray-800: #{$gray-800};
- --gray-900: #{$gray-900};
- --gray-950: #{$gray-950};
-
- --green-50: #{$green-50};
- --green-100: #{$green-100};
- --green-200: #{$green-200};
- --green-300: #{$green-300};
- --green-400: #{$green-400};
- --green-500: #{$green-500};
- --green-600: #{$green-600};
- --green-700: #{$green-700};
- --green-800: #{$green-800};
- --green-900: #{$green-900};
- --green-950: #{$green-950};
-
- --blue-50: #{$blue-50};
- --blue-100: #{$blue-100};
- --blue-200: #{$blue-200};
- --blue-300: #{$blue-300};
- --blue-400: #{$blue-400};
- --blue-500: #{$blue-500};
- --blue-600: #{$blue-600};
- --blue-700: #{$blue-700};
- --blue-800: #{$blue-800};
- --blue-900: #{$blue-900};
- --blue-950: #{$blue-950};
-
- --orange-50: #{$orange-50};
- --orange-100: #{$orange-100};
- --orange-200: #{$orange-200};
- --orange-300: #{$orange-300};
- --orange-400: #{$orange-400};
- --orange-500: #{$orange-500};
- --orange-600: #{$orange-600};
- --orange-700: #{$orange-700};
- --orange-800: #{$orange-800};
- --orange-900: #{$orange-900};
- --orange-950: #{$orange-950};
-
- --red-50: #{$red-50};
- --red-100: #{$red-100};
- --red-200: #{$red-200};
- --red-300: #{$red-300};
- --red-400: #{$red-400};
- --red-500: #{$red-500};
- --red-600: #{$red-600};
- --red-700: #{$red-700};
- --red-800: #{$red-800};
- --red-900: #{$red-900};
- --red-950: #{$red-950};
-
- --indigo-50: #{$indigo-50};
- --indigo-100: #{$indigo-100};
- --indigo-200: #{$indigo-200};
- --indigo-300: #{$indigo-300};
- --indigo-400: #{$indigo-400};
- --indigo-500: #{$indigo-500};
- --indigo-600: #{$indigo-600};
- --indigo-700: #{$indigo-700};
- --indigo-800: #{$indigo-800};
- --indigo-900: #{$indigo-900};
- --indigo-950: #{$indigo-950};
-
- --purple-50: #{$purple-50};
- --purple-100: #{$purple-100};
- --purple-200: #{$purple-200};
- --purple-300: #{$purple-300};
- --purple-400: #{$purple-400};
- --purple-500: #{$purple-500};
- --purple-600: #{$purple-600};
- --purple-700: #{$purple-700};
- --purple-800: #{$purple-800};
- --purple-900: #{$purple-900};
- --purple-950: #{$purple-950};
-
- --dark-icon-color-purple-1: #524a68;
- --dark-icon-color-purple-2: #715bae;
- --dark-icon-color-purple-3: #9a79f7;
- --dark-icon-color-orange-1: #665349;
- --dark-icon-color-orange-2: #b37a5d;
-
- --gl-text-color: #{$gray-900};
- --border-color: #{$border-color};
-
- --white: #{$white};
- --black: #{$black};
- --gray-light: #{$gray-50};
-
- --svg-status-bg: #{$white};
-
- .gl-button.gl-button,
- .gl-button.gl-button.btn-block {
- &.btn-default,
- &.btn-dashed,
- &.btn-info,
- &.btn-success,
- &.btn-danger,
- &.btn-confirm {
- &-tertiary {
- mix-blend-mode: screen;
- }
- }
- }
-
- .gl-datepicker-theme {
- .pika-prev,
- .pika-next {
- filter: invert(0.9);
- }
-
- .is-selected > .pika-button {
- color: $gray-900;
- }
-
- :not(.is-selected) > .pika-button:hover {
- background-color: $gray-200;
- }
- }
-}
-
$border-white-normal: $border-color;
$body-bg: $gray-10;
diff --git a/app/assets/stylesheets/themes/dark_mode_overrides.scss b/app/assets/stylesheets/themes/dark_mode_overrides.scss
index a0d19c3de2a..3395eb7bda2 100644
--- a/app/assets/stylesheets/themes/dark_mode_overrides.scss
+++ b/app/assets/stylesheets/themes/dark_mode_overrides.scss
@@ -2,6 +2,140 @@
@import 'page_bundles/mixins_and_variables_and_functions';
@import './themes/theme_helper';
+:root {
+ color-scheme: dark;
+ --gray-10: #{$gray-10};
+ --gray-50: #{$gray-50};
+ --gray-100: #{$gray-100};
+ --gray-200: #{$gray-200};
+ --gray-300: #{$gray-300};
+ --gray-400: #{$gray-400};
+ --gray-500: #{$gray-500};
+ --gray-600: #{$gray-600};
+ --gray-700: #{$gray-700};
+ --gray-800: #{$gray-800};
+ --gray-900: #{$gray-900};
+ --gray-950: #{$gray-950};
+
+ --green-50: #{$green-50};
+ --green-100: #{$green-100};
+ --green-200: #{$green-200};
+ --green-300: #{$green-300};
+ --green-400: #{$green-400};
+ --green-500: #{$green-500};
+ --green-600: #{$green-600};
+ --green-700: #{$green-700};
+ --green-800: #{$green-800};
+ --green-900: #{$green-900};
+ --green-950: #{$green-950};
+
+ --blue-50: #{$blue-50};
+ --blue-100: #{$blue-100};
+ --blue-200: #{$blue-200};
+ --blue-300: #{$blue-300};
+ --blue-400: #{$blue-400};
+ --blue-500: #{$blue-500};
+ --blue-600: #{$blue-600};
+ --blue-700: #{$blue-700};
+ --blue-800: #{$blue-800};
+ --blue-900: #{$blue-900};
+ --blue-950: #{$blue-950};
+
+ --orange-50: #{$orange-50};
+ --orange-100: #{$orange-100};
+ --orange-200: #{$orange-200};
+ --orange-300: #{$orange-300};
+ --orange-400: #{$orange-400};
+ --orange-500: #{$orange-500};
+ --orange-600: #{$orange-600};
+ --orange-700: #{$orange-700};
+ --orange-800: #{$orange-800};
+ --orange-900: #{$orange-900};
+ --orange-950: #{$orange-950};
+
+ --red-50: #{$red-50};
+ --red-100: #{$red-100};
+ --red-200: #{$red-200};
+ --red-300: #{$red-300};
+ --red-400: #{$red-400};
+ --red-500: #{$red-500};
+ --red-600: #{$red-600};
+ --red-700: #{$red-700};
+ --red-800: #{$red-800};
+ --red-900: #{$red-900};
+ --red-950: #{$red-950};
+
+ --indigo-50: #{$indigo-50};
+ --indigo-100: #{$indigo-100};
+ --indigo-200: #{$indigo-200};
+ --indigo-300: #{$indigo-300};
+ --indigo-400: #{$indigo-400};
+ --indigo-500: #{$indigo-500};
+ --indigo-600: #{$indigo-600};
+ --indigo-700: #{$indigo-700};
+ --indigo-800: #{$indigo-800};
+ --indigo-900: #{$indigo-900};
+ --indigo-950: #{$indigo-950};
+
+ --purple-50: #{$purple-50};
+ --purple-100: #{$purple-100};
+ --purple-200: #{$purple-200};
+ --purple-300: #{$purple-300};
+ --purple-400: #{$purple-400};
+ --purple-500: #{$purple-500};
+ --purple-600: #{$purple-600};
+ --purple-700: #{$purple-700};
+ --purple-800: #{$purple-800};
+ --purple-900: #{$purple-900};
+ --purple-950: #{$purple-950};
+
+ --dark-icon-color-purple-1: #524a68;
+ --dark-icon-color-purple-2: #715bae;
+ --dark-icon-color-purple-3: #9a79f7;
+ --dark-icon-color-orange-1: #665349;
+ --dark-icon-color-orange-2: #b37a5d;
+
+ --gl-text-color: #{$gray-900};
+ --border-color: #{$border-color};
+
+ --white: #{$white};
+ --black: #{$black};
+ --gray-light: #{$gray-50};
+
+ --svg-status-bg: #{$white};
+}
+
+.gl-dark {
+ .gl-button.gl-button,
+ .gl-button.gl-button.btn-block {
+ &.btn-default,
+ &.btn-dashed,
+ &.btn-info,
+ &.btn-success,
+ &.btn-danger,
+ &.btn-confirm {
+ &-tertiary {
+ mix-blend-mode: screen;
+ }
+ }
+ }
+
+ .gl-datepicker-theme {
+ .pika-prev,
+ .pika-next {
+ filter: invert(0.9);
+ }
+
+ .is-selected > .pika-button {
+ color: $gray-900;
+ }
+
+ :not(.is-selected) > .pika-button:hover {
+ background-color: $gray-200;
+ }
+ }
+}
+
// Some hacks and overrides for things that don't properly support dark mode
.gl-label {
filter: brightness(0.9) contrast(1.1);
diff --git a/app/controllers/concerns/invisible_captcha_on_signup.rb b/app/controllers/concerns/invisible_captcha_on_signup.rb
index c7fd6d08744..b78869e02d0 100644
--- a/app/controllers/concerns/invisible_captcha_on_signup.rb
+++ b/app/controllers/concerns/invisible_captcha_on_signup.rb
@@ -13,7 +13,7 @@ module InvisibleCaptchaOnSignup
invisible_captcha_honeypot_counter.increment
log_request('Invisible_Captcha_Honeypot_Request')
- head(200)
+ head(:ok)
end
def on_timestamp_spam_callback
diff --git a/app/controllers/dashboard/snippets_controller.rb b/app/controllers/dashboard/snippets_controller.rb
index 5a885349467..d72a5e44b9f 100644
--- a/app/controllers/dashboard/snippets_controller.rb
+++ b/app/controllers/dashboard/snippets_controller.rb
@@ -7,7 +7,7 @@ class Dashboard::SnippetsController < Dashboard::ApplicationController
skip_cross_project_access_check :index
- feature_category :snippets
+ feature_category :source_code_management
def index
@snippet_counts = Snippets::CountService
diff --git a/app/controllers/explore/snippets_controller.rb b/app/controllers/explore/snippets_controller.rb
index 617cc2e7f3d..dee94b53cc1 100644
--- a/app/controllers/explore/snippets_controller.rb
+++ b/app/controllers/explore/snippets_controller.rb
@@ -3,7 +3,7 @@
class Explore::SnippetsController < Explore::ApplicationController
include Gitlab::NoteableMetadata
- feature_category :snippets
+ feature_category :source_code_management
def index
@snippets = SnippetsFinder.new(current_user, explore: true)
diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb
index 7755effe1da..ef20c71cd77 100644
--- a/app/controllers/projects/autocomplete_sources_controller.rb
+++ b/app/controllers/projects/autocomplete_sources_controller.rb
@@ -7,7 +7,7 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController
feature_category :team_planning, [:issues, :labels, :milestones, :commands, :contacts]
feature_category :code_review, [:merge_requests]
feature_category :users, [:members]
- feature_category :snippets, [:snippets]
+ feature_category :source_code_management, [:snippets]
urgency :low, [:merge_requests, :members]
urgency :low, [:issues, :labels, :milestones, :commands, :contacts]
diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb
index 5946c43b134..6f896244acb 100644
--- a/app/controllers/projects/runner_projects_controller.rb
+++ b/app/controllers/projects/runner_projects_controller.rb
@@ -11,7 +11,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
- return head(403) unless can?(current_user, :assign_runner, @runner)
+ return head(:forbidden) unless can?(current_user, :assign_runner, @runner)
path = project_runners_path(project)
diff --git a/app/controllers/projects/service_ping_controller.rb b/app/controllers/projects/service_ping_controller.rb
index 43c249afd8e..cfc322b47e7 100644
--- a/app/controllers/projects/service_ping_controller.rb
+++ b/app/controllers/projects/service_ping_controller.rb
@@ -10,7 +10,7 @@ class Projects::ServicePingController < Projects::ApplicationController
Gitlab::UsageDataCounters::WebIdeCounter.increment_previews_count
- head(200)
+ head(:ok)
end
def web_ide_clientside_preview_success
@@ -20,12 +20,12 @@ class Projects::ServicePingController < Projects::ApplicationController
Gitlab::UsageDataCounters::EditorUniqueCounter.track_live_preview_edit_action(author: current_user,
project: project)
- head(200)
+ head(:ok)
end
def web_ide_pipelines_count
Gitlab::UsageDataCounters::WebIdeCounter.increment_pipelines_count
- head(200)
+ head(:ok)
end
end
diff --git a/app/controllers/projects/snippets/application_controller.rb b/app/controllers/projects/snippets/application_controller.rb
index 8ee12bf3795..b8faf464531 100644
--- a/app/controllers/projects/snippets/application_controller.rb
+++ b/app/controllers/projects/snippets/application_controller.rb
@@ -4,7 +4,7 @@ class Projects::Snippets::ApplicationController < Projects::ApplicationControlle
include FindSnippet
include SnippetAuthorizations
- feature_category :snippets
+ feature_category :source_code_management
private
diff --git a/app/controllers/repositories/lfs_storage_controller.rb b/app/controllers/repositories/lfs_storage_controller.rb
index d54b51b463a..22f1a81b95b 100644
--- a/app/controllers/repositories/lfs_storage_controller.rb
+++ b/app/controllers/repositories/lfs_storage_controller.rb
@@ -49,7 +49,7 @@ module Repositories
validate_uploaded_file!
if store_file!(oid, size)
- head 200, content_type: LfsRequest::CONTENT_TYPE
+ head :ok, content_type: LfsRequest::CONTENT_TYPE
else
render plain: 'Unprocessable entity', status: :unprocessable_entity
end
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 5351e3e9e77..9fb7a183597 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -32,7 +32,7 @@ class SearchController < ApplicationController
before_action only: :show do
push_frontend_feature_flag(:search_page_vertical_nav, current_user)
end
-
+ before_action :elasticsearch_in_use, only: :show
rescue_from ActiveRecord::QueryCanceled, with: :render_timeout
layout 'search'
@@ -118,6 +118,11 @@ class SearchController < ApplicationController
def opensearch
end
+ def elasticsearch_in_use
+ search_service.respond_to?(:use_elasticsearch?) && search_service.use_elasticsearch?
+ end
+ strong_memoize_attr :elasticsearch_in_use
+
private
# overridden in EE
diff --git a/app/controllers/snippets/application_controller.rb b/app/controllers/snippets/application_controller.rb
index f259f4569ef..64adc4e6611 100644
--- a/app/controllers/snippets/application_controller.rb
+++ b/app/controllers/snippets/application_controller.rb
@@ -4,7 +4,7 @@ class Snippets::ApplicationController < ApplicationController
include FindSnippet
include SnippetAuthorizations
- feature_category :snippets
+ feature_category :source_code_management
private
diff --git a/app/controllers/snippets/notes_controller.rb b/app/controllers/snippets/notes_controller.rb
index 8a4e8edbf3c..9e23eef4178 100644
--- a/app/controllers/snippets/notes_controller.rb
+++ b/app/controllers/snippets/notes_controller.rb
@@ -8,7 +8,7 @@ class Snippets::NotesController < ApplicationController
before_action :authorize_read_snippet!, only: [:show, :index]
before_action :authorize_create_note!, only: [:create]
- feature_category :snippets
+ feature_category :source_code_management
private
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 0f03333d793..f23e513e419 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -31,8 +31,7 @@ class UsersController < ApplicationController
:followers, :following, :calendar, :calendar_activities,
:exists, :activity, :follow, :unfollow, :ssh_keys]
- feature_category :snippets, [:snippets]
- feature_category :source_code_management, [:gpg_keys]
+ feature_category :source_code_management, [:snippets, :gpg_keys]
# TODO: Set higher urgency after resolving https://gitlab.com/gitlab-org/gitlab/-/issues/357914
urgency :low, [:show, :calendar_activities, :contributed, :activity, :projects, :groups, :calendar, :snippets]
diff --git a/app/models/user.rb b/app/models/user.rb
index ea7a9cd5742..939b5430769 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -58,16 +58,16 @@ class User < ApplicationRecord
add_authentication_token_field :feed_token
add_authentication_token_field :static_object_token, encrypted: :optional
- default_value_for :admin, false
- default_value_for(:external) { Gitlab::CurrentSettings.user_default_external }
- default_value_for(:can_create_group) { Gitlab::CurrentSettings.can_create_group }
- default_value_for :can_create_team, false
- default_value_for :hide_no_ssh_key, false
- default_value_for :hide_no_password, false
- default_value_for :project_view, :files
- default_value_for :notified_of_own_activity, false
- default_value_for :preferred_language, I18n.default_locale
- default_value_for :theme_id, gitlab_config.default_theme
+ attribute :admin, default: false
+ attribute :external, default: -> { Gitlab::CurrentSettings.user_default_external }
+ attribute :can_create_group, default: -> { Gitlab::CurrentSettings.can_create_group }
+ attribute :can_create_team, default: false
+ attribute :hide_no_ssh_key, default: false
+ attribute :hide_no_password, default: false
+ attribute :project_view, default: :files
+ attribute :notified_of_own_activity, default: false
+ attribute :preferred_language, default: -> { I18n.default_locale }
+ attribute :theme_id, default: -> { gitlab_config.default_theme }
attr_encrypted :otp_secret,
key: Gitlab::Application.secrets.otp_key_base,
@@ -376,6 +376,14 @@ class User < ApplicationRecord
accepts_nested_attributes_for :credit_card_validation, update_only: true, allow_destroy: true
state_machine :state, initial: :active do
+ # state_machine uses this method at class loading time to fetch the default
+ # value for the `state` column but in doing so it also evaluates all other
+ # columns default values which could trigger the recursive generation of
+ # ApplicationSetting records. We're setting it to `nil` here because we
+ # don't have a database default for the `state` column.
+ #
+ def owner_class_attribute_default; end
+
event :block do
transition active: :blocked
transition deactivated: :blocked
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index c6ebd550daf..bc2c6b526b8 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -26,10 +26,10 @@ class UserPreference < ApplicationRecord
ignore_columns :experience_level, remove_with: '14.10', remove_after: '2021-03-22'
- default_value_for :tab_width, value: Gitlab::TabWidth::DEFAULT, allows_nil: false
- default_value_for :time_display_relative, value: true, allows_nil: false
- default_value_for :time_format_in_24h, value: false, allows_nil: false
- default_value_for :render_whitespace_in_code, value: false, allows_nil: false
+ attribute :tab_width, default: -> { Gitlab::TabWidth::DEFAULT }
+ attribute :time_display_relative, default: true
+ attribute :time_format_in_24h, default: false
+ attribute :render_whitespace_in_code, default: false
class << self
def notes_filters
@@ -59,6 +59,67 @@ class UserPreference < ApplicationRecord
self[notes_filter_field_for(resource)]
end
+ def tab_width
+ read_attribute(:tab_width) || self.class.column_defaults['tab_width']
+ end
+
+ def tab_width=(value)
+ if value.nil?
+ default = self.class.column_defaults['tab_width']
+ super(default)
+ else
+ super(value)
+ end
+ end
+
+ def time_display_relative
+ value = read_attribute(:time_display_relative)
+ return value unless value.nil?
+
+ self.class.column_defaults['time_display_relative']
+ end
+
+ def time_display_relative=(value)
+ if value.nil?
+ default = self.class.column_defaults['time_display_relative']
+ super(default)
+ else
+ super(value)
+ end
+ end
+
+ def time_format_in_24h
+ value = read_attribute(:time_format_in_24h)
+ return value unless value.nil?
+
+ self.class.column_defaults['time_format_in_24h']
+ end
+
+ def time_format_in_24h=(value)
+ if value.nil?
+ default = self.class.column_defaults['time_format_in_24h']
+ super(default)
+ else
+ super(value)
+ end
+ end
+
+ def render_whitespace_in_code
+ value = read_attribute(:render_whitespace_in_code)
+ return value unless value.nil?
+
+ self.class.column_defaults['render_whitespace_in_code']
+ end
+
+ def render_whitespace_in_code=(value)
+ if value.nil?
+ default = self.class.column_defaults['render_whitespace_in_code']
+ super(default)
+ else
+ super(value)
+ end
+ end
+
private
def notes_filter_field_for(resource)
diff --git a/app/services/chat_names/find_user_service.rb b/app/services/chat_names/find_user_service.rb
index 3dd3ba7f01c..ba6ebb7206b 100644
--- a/app/services/chat_names/find_user_service.rb
+++ b/app/services/chat_names/find_user_service.rb
@@ -19,6 +19,13 @@ module ChatNames
# rubocop: disable CodeReuse/ActiveRecord
def find_chat_name
+ if @integration.nil?
+ return ChatName.find_by(
+ team_id: @params[:team_id],
+ chat_id: @params[:user_id]
+ )
+ end
+
ChatName.find_by(
integration: @integration,
team_id: @params[:team_id],
diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml
index 9d812e77ad4..c58f492f633 100644
--- a/app/views/search/show.html.haml
+++ b/app/views/search/show.html.haml
@@ -20,7 +20,7 @@
= render_if_exists 'search/form_elasticsearch', attrs: { class: 'mb-2 mb-sm-0 align-self-center' }
.gl-mt-3
- #js-search-topbar{ data: { "group-initial-data": group_attributes.to_json, "project-initial-data": project_attributes.to_json } }
+ #js-search-topbar{ data: { "group-initial-json": group_attributes.to_json, "project-initial-json": project_attributes.to_json, "elasticsearch-enabled": @elasticsearch_in_use.to_s, "default-branch-name": @project&.default_branch } }
- if @search_term
- if Feature.disabled?(:search_page_vertical_nav, current_user)
= render 'search/category'
diff --git a/config/feature_categories.yml b/config/feature_categories.yml
index 94a50dc416e..0aa77bdb66b 100644
--- a/config/feature_categories.yml
+++ b/config/feature_categories.yml
@@ -67,7 +67,6 @@
- geo_replication
- git_lfs
- gitaly
-- gitlab_docs
- global_search
- helm_chart_registry
- importers
@@ -105,6 +104,7 @@
- pubsec_services
- purchase
- quality_management
+- rate_limiting
- redis
- release_evidence
- release_orchestration
@@ -116,6 +116,7 @@
- runner_fleet
- runner_saas
- saas_provisioning
+- sbom
- scalability
- secret_detection
- secrets_management
@@ -124,7 +125,6 @@
- service_desk
- service_ping
- sm_provisioning
-- snippets
- source_code_management
- static_application_security_testing
- subgroups
diff --git a/config/webpack.config.js b/config/webpack.config.js
index c8a159605d1..4564530120c 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -435,6 +435,7 @@ module.exports = {
},
{
test: /\.(yml|yaml)$/,
+ resourceQuery: /raw/,
loader: 'raw-loader',
},
].filter(Boolean),
diff --git a/doc/api/product_analytics.md b/doc/api/product_analytics.md
index b7401f83128..90df1090f62 100644
--- a/doc/api/product_analytics.md
+++ b/doc/api/product_analytics.md
@@ -31,7 +31,7 @@ POST /projects/:id/product_analytics/request/dry-run
### Request body
-The body of the load request should be a valid Cube query.
+The body of the load request must be a valid Cube query.
```json
{
@@ -68,9 +68,9 @@ The body of the load request should be a valid Cube query.
}
```
-## Send meta request to Cube
+## Send metadata request to Cube
-Returns Cube Meta data for the Analytics data. For example:
+Return Cube Metadata for the Analytics data. For example:
```plaintext
GET /projects/:id/product_analytics/request/meta
diff --git a/doc/operations/incident_management/alerts.md b/doc/operations/incident_management/alerts.md
index 41dacd327a7..44e619ed166 100644
--- a/doc/operations/incident_management/alerts.md
+++ b/doc/operations/incident_management/alerts.md
@@ -225,18 +225,7 @@ and clear the user from the list of assignees, or select **Unassigned**.
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3066) in GitLab 13.1.
-You can manually create [To-Do list items](../../user/todos.md) for yourself
-from the Alert details screen, and view them later on your **To-Do List**. To
-add a to-do item:
+You can manually create a [to-do item](../../user/todos.md) for yourself
+from an alert, and view it later on your **To-Do List**.
-1. Display the list of current alerts:
-
- 1. On the top bar, select **Main menu > Projects** and find your project.
- 1. On the left sidebar, select **Monitor > Alerts**.
-
-1. Select your desired alert to display its **Alert Management Details View**.
-1. On the right sidebar, select **Add a to do**:
-
- ![Alert Details Add a to do](img/alert_detail_add_todo_v13_9.png)
-
-To view your To-Do List, on the top bar, select **To-Do List** (**{todo-done}**).
+To add a to-do item, on the right sidebar, select **Add a to do**.
diff --git a/doc/operations/incident_management/img/alert_detail_add_todo_v13_9.png b/doc/operations/incident_management/img/alert_detail_add_todo_v13_9.png
deleted file mode 100644
index 5beb1cd0bfb..00000000000
--- a/doc/operations/incident_management/img/alert_detail_add_todo_v13_9.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/product_analytics/index.md b/doc/user/product_analytics/index.md
index ebeb1f171a8..fa2dfc2e271 100644
--- a/doc/user/product_analytics/index.md
+++ b/doc/user/product_analytics/index.md
@@ -32,24 +32,24 @@ Prerequisite:
1. Select **Enable product analytics** and enter the configuration values.
The following table shows the required configuration parameters and example values:
- | Name | Value |
- |------------------------------|----------------------------|
- | Jitsu host | `https://jitsu.gitlab.com` |
- | Jitsu project ID | `g0maofw84gx5sjxgse2k` |
- | Jitsu administrator email | `jitsu.admin@gitlab.com` |
- | Jitsu administrator password | `<your_password>` |
+ | Name | Value |
+ |------------------------------|------------------------------------------------------------|
+ | Jitsu host | `https://jitsu.gitlab.com` |
+ | Jitsu project ID | `g0maofw84gx5sjxgse2k` |
+ | Jitsu administrator email | `jitsu.admin@gitlab.com` |
+ | Jitsu administrator password | `<your_password>` |
| Clickhouse URL | `https://<username>:<password>@clickhouse.gitlab.com:8123` |
- | Cube API URL | `https://cube.gitlab.com` |
- | Cube API key | `25718201b3e9...ae6bbdc62dbb` |
+ | Cube API URL | `https://cube.gitlab.com` |
+ | Cube API key | `25718201b3e9...ae6bbdc62dbb` |
1. Select **Save changes**.
## Product analytics dashboards
Each project can define an unlimited number of dashboards. These dashboards are defined using our YAML schema and stored
-in the `.gitlab/product_analytics/dashboards/` directory. The name of the file is the name of the dashboard, and visualizations are shared across dashboards..
+in the `.gitlab/product_analytics/dashboards/` directory of a project repository. The name of the file is the name of the dashboard, and visualizations are shared across dashboards.
-Project maintainers can enforce approval rules on dashboard changes, and dashboards can be versioned in source control.
+Project maintainers can enforce approval rules on dashboard changes using features such as code owners and approval rules. Dashboards are versioned in source control with the rest of a project's code.
### Define a dashboard
@@ -57,8 +57,8 @@ To define a dashboard:
1. In `.gitlab/product_analytics/dashboards/`, create a directory named like the dashboard. Each dashboard should have its own directory.
1. In the new directory, create a `.yaml` file with the same name as the directory. This file contains the dashboard definition, and must conform to the JSON schema defined in `ee/app/validators/json_schemas/product_analytics_dashboard.json`.
-1. In the `.gitlab/product_analytics/dashboards/visualizations/` directory, create a `yaml` file. This file defines the visualization type for the dashboard, and must conform to the schema in
-`ee/app/validators/json_schemas/product_analytics_visualization.json`.
+1. In the `.gitlab/product_analytics/dashboards/visualizations/` directory, create a `yaml` file. This file defines the visualization type for the dashboard, and must conform to the schema in
+ `ee/app/validators/json_schemas/product_analytics_visualization.json`.
The example below includes three dashboards and one visualization that applies to all dashboards.
diff --git a/jest.config.base.js b/jest.config.base.js
index 56473d1643f..0f77517a9e3 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -43,6 +43,8 @@ module.exports = (path, options = {}) => {
const TEST_FIXTURES_PATTERN = 'test_fixtures(/.*)$';
const moduleNameMapper = {
+ '^~(/.*)\\?raw$': '<rootDir>/app/assets/javascripts$1',
+ '^(.*)\\?raw$': '$1',
'^~(/.*)$': '<rootDir>/app/assets/javascripts$1',
'^ee_component(/.*)$':
'<rootDir>/app/assets/javascripts/vue_shared/components/empty_component.js',
diff --git a/lib/api/helpers/award_emoji.rb b/lib/api/helpers/award_emoji.rb
index 3ea35381c97..625635f768b 100644
--- a/lib/api/helpers/award_emoji.rb
+++ b/lib/api/helpers/award_emoji.rb
@@ -7,7 +7,7 @@ module API
[
{ type: 'issue', resource: :projects, find_by: :iid, feature_category: :team_planning },
{ type: 'merge_request', resource: :projects, find_by: :iid, feature_category: :code_review },
- { type: 'snippet', resource: :projects, find_by: :id, feature_category: :snippets }
+ { type: 'snippet', resource: :projects, find_by: :id, feature_category: :source_code_management }
]
end
diff --git a/lib/api/helpers/discussions_helpers.rb b/lib/api/helpers/discussions_helpers.rb
index c94199b17bc..182ada54a12 100644
--- a/lib/api/helpers/discussions_helpers.rb
+++ b/lib/api/helpers/discussions_helpers.rb
@@ -8,7 +8,7 @@ module API
# extend it.
{
Issue => :team_planning,
- Snippet => :snippets,
+ Snippet => :source_code_management,
MergeRequest => :code_review,
Commit => :code_review
}
diff --git a/lib/api/helpers/notes_helpers.rb b/lib/api/helpers/notes_helpers.rb
index 45671b09be9..9c4128509c8 100644
--- a/lib/api/helpers/notes_helpers.rb
+++ b/lib/api/helpers/notes_helpers.rb
@@ -9,7 +9,7 @@ module API
{
Issue => :team_planning,
MergeRequest => :code_review,
- Snippet => :snippets
+ Snippet => :source_code_management
}
end
diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb
index 93ffb23fea8..7ef722301ca 100644
--- a/lib/api/project_snippets.rb
+++ b/lib/api/project_snippets.rb
@@ -6,7 +6,7 @@ module API
before { check_snippets_enabled }
- feature_category :snippets
+ feature_category :source_code_management
params do
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb
index 36698a220bd..104848206a3 100644
--- a/lib/api/snippets.rb
+++ b/lib/api/snippets.rb
@@ -5,7 +5,7 @@ module API
class Snippets < ::API::Base
include PaginationParams
- feature_category :snippets
+ feature_category :source_code_management
urgency :low
resource :snippets do
diff --git a/lib/gitlab/memory/watchdog.rb b/lib/gitlab/memory/watchdog.rb
index 435b416e7e9..2e0add73478 100644
--- a/lib/gitlab/memory/watchdog.rb
+++ b/lib/gitlab/memory/watchdog.rb
@@ -50,8 +50,6 @@ module Gitlab
def initialize
@configuration = Configuration.new
@alive = true
-
- init_prometheus_metrics
end
##
@@ -62,7 +60,7 @@ module Gitlab
end
def call
- logger.info(log_labels.merge(message: 'started'))
+ event_reporter.started(log_labels)
while @alive
sleep(sleep_time_seconds)
@@ -70,7 +68,7 @@ module Gitlab
monitor if Feature.enabled?(:gitlab_memory_watchdog, type: :ops)
end
- logger.info(log_labels.merge(message: 'stopped'))
+ event_reporter.stopped(log_labels)
end
def stop
@@ -85,18 +83,16 @@ module Gitlab
next unless result.threshold_violated?
- @counter_violations.increment(reason: result.monitor_name)
+ event_reporter.threshold_violated(result.monitor_name)
next unless result.strikes_exceeded?
- @alive = !memory_limit_exceeded_callback(result.monitor_name, result.payload)
+ @alive = !strike_exceeded_callback(result.monitor_name, result.payload)
end
end
- def memory_limit_exceeded_callback(monitor_name, monitor_payload)
- all_labels = log_labels.merge(monitor_payload)
- logger.warn(all_labels)
- @counter_violations_handled.increment(reason: monitor_name)
+ def strike_exceeded_callback(monitor_name, monitor_payload)
+ event_reporter.strikes_exceeded(monitor_name, log_labels(monitor_payload))
Gitlab::Memory::Reports::HeapDump.enqueue! if @configuration.write_heap_dumps?
@@ -111,43 +107,18 @@ module Gitlab
@configuration.handler
end
- def logger
- @configuration.logger
+ def event_reporter
+ @configuration.event_reporter
end
def sleep_time_seconds
@configuration.sleep_time_seconds
end
- def log_labels
- {
- pid: $$,
- worker_id: worker_id,
+ def log_labels(extra = {})
+ extra.merge(
memwd_handler_class: handler.class.name,
- memwd_sleep_time_s: sleep_time_seconds,
- memwd_rss_bytes: process_rss_bytes
- }
- end
-
- def process_rss_bytes
- Gitlab::Metrics::System.memory_usage_rss[:total]
- end
-
- def worker_id
- ::Prometheus::PidProvider.worker_id
- end
-
- def init_prometheus_metrics
- default_labels = { pid: worker_id }
- @counter_violations = Gitlab::Metrics.counter(
- :gitlab_memwd_violations_total,
- 'Total number of times a Ruby process violated a memory threshold',
- default_labels
- )
- @counter_violations_handled = Gitlab::Metrics.counter(
- :gitlab_memwd_violations_handled_total,
- 'Total number of times Ruby process memory violations were handled',
- default_labels
+ memwd_sleep_time_s: sleep_time_seconds
)
end
end
diff --git a/lib/gitlab/memory/watchdog/configuration.rb b/lib/gitlab/memory/watchdog/configuration.rb
index 885772d6119..980b6bf750b 100644
--- a/lib/gitlab/memory/watchdog/configuration.rb
+++ b/lib/gitlab/memory/watchdog/configuration.rb
@@ -35,7 +35,7 @@ module Gitlab
DEFAULT_SLEEP_TIME_SECONDS = 60
- attr_writer :logger, :handler, :sleep_time_seconds, :write_heap_dumps
+ attr_writer :event_reporter, :handler, :sleep_time_seconds, :write_heap_dumps
def monitors
@monitor_stack ||= MonitorStack.new
@@ -47,8 +47,8 @@ module Gitlab
@handler ||= NullHandler.instance
end
- def logger
- @logger ||= Gitlab::Logger.new($stdout)
+ def event_reporter
+ @event_reporter ||= EventReporter.new
end
# Used to control the frequency with which the watchdog will wake up and poll the GC.
diff --git a/lib/gitlab/memory/watchdog/configurator.rb b/lib/gitlab/memory/watchdog/configurator.rb
index 610d8ca9e97..880f9800d96 100644
--- a/lib/gitlab/memory/watchdog/configurator.rb
+++ b/lib/gitlab/memory/watchdog/configurator.rb
@@ -17,7 +17,6 @@ module Gitlab
class << self
def configure_for_puma
->(config) do
- config.logger = Gitlab::AppLogger
config.handler = Gitlab::Memory::Watchdog::PumaHandler.new
config.write_heap_dumps = write_heap_dumps?
config.sleep_time_seconds = ENV.fetch('GITLAB_MEMWD_SLEEP_TIME_SEC', DEFAULT_SLEEP_INTERVAL_S).to_i
@@ -27,11 +26,11 @@ module Gitlab
def configure_for_sidekiq
->(config) do
- config.logger = Sidekiq.logger
config.handler = Gitlab::Memory::Watchdog::TermProcessHandler.new
config.write_heap_dumps = write_heap_dumps?
config.sleep_time_seconds = sidekiq_sleep_time
config.monitors(&configure_monitors_for_sidekiq)
+ config.event_reporter = EventReporter.new(logger: ::Sidekiq.logger)
end
end
diff --git a/lib/gitlab/memory/watchdog/event_reporter.rb b/lib/gitlab/memory/watchdog/event_reporter.rb
new file mode 100644
index 00000000000..4d37a5e14fd
--- /dev/null
+++ b/lib/gitlab/memory/watchdog/event_reporter.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Memory
+ class Watchdog
+ class EventReporter
+ include ::Gitlab::Utils::StrongMemoize
+
+ attr_reader :logger
+
+ def initialize(logger: Gitlab::AppLogger)
+ @logger = logger
+ end
+
+ def started(labels = {})
+ logger.info(message: 'started', **log_labels(labels))
+ end
+
+ def stopped(labels = {})
+ logger.info(message: 'stopped', **log_labels(labels))
+ end
+
+ def threshold_violated(monitor_name)
+ counter_violations.increment(reason: monitor_name)
+ end
+
+ def strikes_exceeded(monitor_name, labels = {})
+ logger.warn(log_labels(labels))
+
+ counter_violations_handled.increment(reason: monitor_name)
+ end
+
+ private
+
+ def log_labels(extra = {})
+ extra.merge(
+ pid: $$,
+ worker_id: worker_id,
+ memwd_rss_bytes: process_rss_bytes
+ )
+ end
+
+ def process_rss_bytes
+ Gitlab::Metrics::System.memory_usage_rss[:total]
+ end
+
+ def worker_id
+ ::Prometheus::PidProvider.worker_id
+ end
+
+ def counter_violations
+ strong_memoize("counter_violations") do
+ ::Gitlab::Metrics.counter(
+ :gitlab_memwd_violations_total,
+ 'Total number of times a Ruby process violated a memory threshold',
+ { pid: worker_id }
+ )
+ end
+ end
+
+ def counter_violations_handled
+ strong_memoize("counter_violations_handled") do
+ ::Gitlab::Metrics.counter(
+ :gitlab_memwd_violations_handled_total,
+ 'Total number of times Ruby process memory violations were handled',
+ { pid: worker_id }
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 053b4b150e9..0256549ddbe 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -27129,6 +27129,9 @@ msgstr ""
msgid "New incident"
msgstr ""
+msgid "New incident has been created"
+msgstr ""
+
msgid "New issue"
msgstr ""
@@ -32209,12 +32212,18 @@ msgstr ""
msgid "ProjectSettings|Allow"
msgstr ""
+msgid "ProjectSettings|Allow anyone to pull from Package Registry"
+msgstr ""
+
msgid "ProjectSettings|Always show thumbs-up and thumbs-down award emoji buttons on issues, merge requests, and snippets."
msgstr ""
msgid "ProjectSettings|Analytics"
msgstr ""
+msgid "ProjectSettings|Anyone can pull packages with a package manager API."
+msgstr ""
+
msgid "ProjectSettings|Auto-close referenced issues on default branch"
msgstr ""
@@ -32296,9 +32305,6 @@ msgstr ""
msgid "ProjectSettings|Every project can have its own space to store its Docker images"
msgstr ""
-msgid "ProjectSettings|Every project can have its own space to store its packages."
-msgstr ""
-
msgid "ProjectSettings|Every project can have its own space to store its packages. Note: The Package Registry is always visible when a project is public."
msgstr ""
@@ -32413,6 +32419,9 @@ msgstr ""
msgid "ProjectSettings|Monitor"
msgstr ""
+msgid "ProjectSettings|Monitor the health of your project and respond to incidents."
+msgstr ""
+
msgid "ProjectSettings|No merge commits are created."
msgstr ""
@@ -32458,6 +32467,9 @@ msgstr ""
msgid "ProjectSettings|Public"
msgstr ""
+msgid "ProjectSettings|Publish, store, and view packages in a project."
+msgstr ""
+
msgid "ProjectSettings|Releases"
msgstr ""
@@ -38667,6 +38679,9 @@ msgstr ""
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
+msgid "Something went wrong when sending the incident link to Slack."
+msgstr ""
+
msgid "Something went wrong while adding timeline event."
msgstr ""
@@ -41488,6 +41503,9 @@ msgstr ""
msgid "There was a problem communicating with your device."
msgstr ""
+msgid "There was a problem creating the incident. Please try again."
+msgstr ""
+
msgid "There was a problem fetching CRM contacts."
msgstr ""
diff --git a/package.json b/package.json
index 4d67b5b1a23..66ffcc85012 100644
--- a/package.json
+++ b/package.json
@@ -54,7 +54,7 @@
"@cubejs-client/core": "^0.31.0",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
- "@gitlab/svgs": "3.11.0",
+ "@gitlab/svgs": "3.12.0",
"@gitlab/ui": "50.1.2",
"@gitlab/visual-review-tools": "1.7.3",
"@gitlab/web-ide": "0.0.1-dev-20221114183058",
diff --git a/rubocop/cop/rspec/timecop_freeze.rb b/rubocop/cop/rspec/timecop_freeze.rb
deleted file mode 100644
index b13f5050040..00000000000
--- a/rubocop/cop/rspec/timecop_freeze.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-require 'rubocop-rspec'
-
-module RuboCop
- module Cop
- module RSpec
- # This cop checks for `Timecop.freeze` usage in specs.
- #
- # @example
- #
- # # bad
- # Timecop.freeze(Time.current) { example.run }
- #
- # # good
- # freeze_time(Time.current) { example.run }
- #
- class TimecopFreeze < RuboCop::Cop::Base
- extend RuboCop::Cop::AutoCorrector
-
- include MatchRange
- MESSAGE = 'Do not use `Timecop.freeze`, use `freeze_time` instead. ' \
- 'See https://gitlab.com/gitlab-org/gitlab/-/issues/214432 for more info.'
-
- def_node_matcher :timecop_freeze?, <<~PATTERN
- (send (const nil? :Timecop) :freeze ?_)
- PATTERN
-
- def on_send(node)
- return unless timecop_freeze?(node)
-
- add_offense(node, message: MESSAGE) do |corrector|
- each_match_range(node.source_range, /^(Timecop\.freeze)/) do |match_range|
- corrector.replace(match_range, 'freeze_time')
- end
- end
- end
- end
- end
- end
-end
diff --git a/rubocop/cop/rspec/timecop_travel.rb b/rubocop/cop/rspec/timecop_travel.rb
deleted file mode 100644
index 03f978be349..00000000000
--- a/rubocop/cop/rspec/timecop_travel.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-require 'rubocop-rspec'
-
-module RuboCop
- module Cop
- module RSpec
- # This cop checks for `Timecop.travel` usage in specs.
- #
- # @example
- #
- # # bad
- # Timecop.travel(1.day.ago) { create(:issue) }
- #
- # # good
- # travel_to(1.day.ago) { create(:issue) }
- #
- class TimecopTravel < RuboCop::Cop::Base
- extend RuboCop::Cop::AutoCorrector
-
- include MatchRange
- MESSAGE = 'Do not use `Timecop.travel`, use `travel_to` instead. ' \
- 'See https://gitlab.com/gitlab-org/gitlab/-/issues/214432 for more info.'
-
- def_node_matcher :timecop_travel?, <<~PATTERN
- (send (const nil? :Timecop) :travel _)
- PATTERN
-
- def on_send(node)
- return unless timecop_travel?(node)
-
- add_offense(node, message: MESSAGE) do |corrector|
- each_match_range(node.source_range, /^(Timecop\.travel)/) do |match_range|
- corrector.replace(match_range, 'travel_to')
- end
- end
- end
- end
- end
- end
-end
diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb
index fcfd6ca9cf1..ab2cfc0573e 100644
--- a/spec/features/dashboard/snippets_spec.rb
+++ b/spec/features/dashboard/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Dashboard snippets', feature_category: :snippets do
+RSpec.describe 'Dashboard snippets', feature_category: :source_code_management do
let_it_be(:user) { create(:user) }
context 'when the project has snippets' do
diff --git a/spec/features/projects/settings/packages_settings_spec.rb b/spec/features/projects/settings/packages_settings_spec.rb
index 1c2b0faa215..57e9816ddd1 100644
--- a/spec/features/projects/settings/packages_settings_spec.rb
+++ b/spec/features/projects/settings/packages_settings_spec.rb
@@ -33,6 +33,10 @@ RSpec.describe 'Projects > Settings > Packages', :js do
it 'displays the packages access level setting' do
expect(page).to have_selector('[data-testid="package-registry-access-level"] > label', text: 'Package registry')
+ expect(page).to have_selector('input[name="package_registry_enabled"]', visible: false)
+ expect(page).to have_selector('input[name="package_registry_enabled"] + button', visible: true)
+ expect(page).to have_selector('input[name="package_registry_api_for_everyone_enabled"]', visible: false)
+ expect(page).to have_selector('input[name="package_registry_api_for_everyone_enabled"] + button', visible: true)
expect(page).to have_selector(
'input[name="project[project_feature_attributes][package_registry_access_level]"]',
visible: false
diff --git a/spec/features/snippets/embedded_snippet_spec.rb b/spec/features/snippets/embedded_snippet_spec.rb
index 7bd61824494..73b29ffd575 100644
--- a/spec/features/snippets/embedded_snippet_spec.rb
+++ b/spec/features/snippets/embedded_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Embedded Snippets', feature_category: :snippets do
+RSpec.describe 'Embedded Snippets', feature_category: :source_code_management do
let_it_be(:snippet) { create(:personal_snippet, :public, :repository) }
let(:blobs) { snippet.blobs.first(3) }
diff --git a/spec/features/snippets/explore_spec.rb b/spec/features/snippets/explore_spec.rb
index d0f4d888d94..ef4b75ac3b4 100644
--- a/spec/features/snippets/explore_spec.rb
+++ b/spec/features/snippets/explore_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Explore Snippets', feature_category: :snippets do
+RSpec.describe 'Explore Snippets', feature_category: :source_code_management do
let!(:public_snippet) { create(:personal_snippet, :public) }
let!(:internal_snippet) { create(:personal_snippet, :internal) }
let!(:private_snippet) { create(:personal_snippet, :private) }
diff --git a/spec/features/snippets/internal_snippet_spec.rb b/spec/features/snippets/internal_snippet_spec.rb
index 5169cc2a0f8..9645c9c110d 100644
--- a/spec/features/snippets/internal_snippet_spec.rb
+++ b/spec/features/snippets/internal_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Internal Snippets', :js, feature_category: :snippets do
+RSpec.describe 'Internal Snippets', :js, feature_category: :source_code_management do
let(:internal_snippet) { create(:personal_snippet, :internal, :repository) }
let(:content) { internal_snippet.blobs.first.data.strip! }
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index b9d5e56d432..c281e5906ad 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Comments on personal snippets', :js, feature_category: :snippets do
+RSpec.describe 'Comments on personal snippets', :js, feature_category: :source_code_management do
include NoteInteractionHelpers
include Spec::Support::Helpers::ModalHelpers
diff --git a/spec/features/snippets/private_snippets_spec.rb b/spec/features/snippets/private_snippets_spec.rb
index 198ea11972d..0620a50ea72 100644
--- a/spec/features/snippets/private_snippets_spec.rb
+++ b/spec/features/snippets/private_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Private Snippets', :js, feature_category: :snippets do
+RSpec.describe 'Private Snippets', :js, feature_category: :source_code_management do
let(:user) { create(:user) }
let(:private_snippet) { create(:personal_snippet, :repository, :private, author: user) }
let(:content) { private_snippet.blobs.first.data.strip! }
diff --git a/spec/features/snippets/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb
index 627a12aa765..be6d6b2c0fa 100644
--- a/spec/features/snippets/public_snippets_spec.rb
+++ b/spec/features/snippets/public_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Public Snippets', :js, feature_category: :snippets do
+RSpec.describe 'Public Snippets', :js, feature_category: :source_code_management do
let(:public_snippet) { create(:personal_snippet, :public, :repository) }
let(:content) { public_snippet.blobs.first.data.strip! }
diff --git a/spec/features/snippets/search_snippets_spec.rb b/spec/features/snippets/search_snippets_spec.rb
index 002fe05fcb0..98842f54015 100644
--- a/spec/features/snippets/search_snippets_spec.rb
+++ b/spec/features/snippets/search_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Search Snippets', :js, feature_category: :snippets do
+RSpec.describe 'Search Snippets', :js, feature_category: :source_code_management do
it 'user searches for snippets by title' do
public_snippet = create(:personal_snippet, :public, title: 'Beginning and Middle')
private_snippet = create(:personal_snippet, :private, title: 'Middle and End')
diff --git a/spec/features/snippets/show_spec.rb b/spec/features/snippets/show_spec.rb
index 6cce60fbef3..a6e0bc32d42 100644
--- a/spec/features/snippets/show_spec.rb
+++ b/spec/features/snippets/show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Snippet', :js, feature_category: :snippets do
+RSpec.describe 'Snippet', :js, feature_category: :source_code_management do
let_it_be(:user) { create(:user) }
let_it_be(:snippet) { create(:personal_snippet, :public, :repository, author: user) }
diff --git a/spec/features/snippets/spam_snippets_spec.rb b/spec/features/snippets/spam_snippets_spec.rb
index 9e74df3ac05..5d49b36f4fe 100644
--- a/spec/features/snippets/spam_snippets_spec.rb
+++ b/spec/features/snippets/spam_snippets_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'snippet editor with spam', skip: "Will be handled in https://gitlab.com/gitlab-org/gitlab/-/issues/217722",
- feature_category: :snippets do
+ feature_category: :source_code_management do
include_context 'includes Spam constants'
let_it_be(:user) { create(:user) }
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index 4aa099e5737..064250c5673 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User creates snippet', :js, feature_category: :snippets do
+RSpec.describe 'User creates snippet', :js, feature_category: :source_code_management do
include DropzoneHelper
include Spec::Support::Helpers::Features::SnippetSpecHelpers
diff --git a/spec/features/snippets/user_deletes_snippet_spec.rb b/spec/features/snippets/user_deletes_snippet_spec.rb
index 23436a8933c..3c4c41b0181 100644
--- a/spec/features/snippets/user_deletes_snippet_spec.rb
+++ b/spec/features/snippets/user_deletes_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User deletes snippet', :js, feature_category: :snippets do
+RSpec.describe 'User deletes snippet', :js, feature_category: :source_code_management do
let(:user) { create(:user) }
let(:content) { 'puts "test"' }
let(:snippet) { create(:personal_snippet, :repository, :public, content: content, author: user) }
diff --git a/spec/features/snippets/user_edits_snippet_spec.rb b/spec/features/snippets/user_edits_snippet_spec.rb
index 561f1cce26b..5096472ebe1 100644
--- a/spec/features/snippets/user_edits_snippet_spec.rb
+++ b/spec/features/snippets/user_edits_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User edits snippet', :js, feature_category: :snippets do
+RSpec.describe 'User edits snippet', :js, feature_category: :source_code_management do
include DropzoneHelper
include Spec::Support::Helpers::Features::SnippetSpecHelpers
diff --git a/spec/features/snippets/user_snippets_spec.rb b/spec/features/snippets/user_snippets_spec.rb
index 9839f8a472a..09e0e30666d 100644
--- a/spec/features/snippets/user_snippets_spec.rb
+++ b/spec/features/snippets/user_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User Snippets', feature_category: :snippets do
+RSpec.describe 'User Snippets', feature_category: :source_code_management do
let(:author) { create(:user) }
let!(:public_snippet) { create(:personal_snippet, :public, author: author, title: "This is a public snippet") }
let!(:internal_snippet) { create(:personal_snippet, :internal, author: author, title: "This is an internal snippet") }
diff --git a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
index 155f1ff4ef3..8e0ca544a1c 100644
--- a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
+++ b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
@@ -114,9 +114,14 @@ describe('Settings Panel', () => {
const findPackageSettings = () => wrapper.findComponent({ ref: 'package-settings' });
const findPackageAccessLevel = () =>
wrapper.find('[data-testid="package-registry-access-level"]');
- const findPackageAccessLevels = () =>
- wrapper.find('[name="project[project_feature_attributes][package_registry_access_level]"]');
const findPackagesEnabledInput = () => wrapper.find('[name="project[packages_enabled]"]');
+ const findPackageRegistryEnabledInput = () => wrapper.find('[name="package_registry_enabled"]');
+ const findPackageRegistryAccessLevelHiddenInput = () =>
+ wrapper.find(
+ 'input[name="project[project_feature_attributes][package_registry_access_level]"]',
+ );
+ const findPackageRegistryApiForEveryoneEnabledInput = () =>
+ wrapper.find('[name="package_registry_api_for_everyone_enabled"]');
const findPagesSettings = () => wrapper.findComponent({ ref: 'pages-settings' });
const findPagesAccessLevels = () =>
wrapper.find('[name="project[project_feature_attributes][pages_access_level]"]');
@@ -587,28 +592,63 @@ describe('Settings Panel', () => {
expect(findPackageAccessLevel().exists()).toBe(true);
});
+ it('has hidden input field for package registry access level', () => {
+ wrapper = mountComponent({
+ glFeatures: { packageRegistryAccessLevel: true },
+ packagesAvailable: true,
+ });
+
+ expect(findPackageRegistryAccessLevelHiddenInput().exists()).toBe(true);
+ });
+
it.each`
- visibilityLevel | output
- ${VISIBILITY_LEVEL_PRIVATE_INTEGER} | ${[[featureAccessLevel.PROJECT_MEMBERS, 'Only Project Members'], [30, 'Everyone']]}
- ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${[[featureAccessLevel.EVERYONE, 'Everyone With Access'], [30, 'Everyone']]}
- ${VISIBILITY_LEVEL_PUBLIC_INTEGER} | ${[[30, 'Everyone']]}
+ projectVisibilityLevel | packageRegistryEnabled | packageRegistryApiForEveryoneEnabled | expectedAccessLevel
+ ${VISIBILITY_LEVEL_PRIVATE_INTEGER} | ${false} | ${'disabled'} | ${featureAccessLevel.NOT_ENABLED}
+ ${VISIBILITY_LEVEL_PRIVATE_INTEGER} | ${true} | ${false} | ${featureAccessLevel.PROJECT_MEMBERS}
+ ${VISIBILITY_LEVEL_PRIVATE_INTEGER} | ${true} | ${true} | ${FEATURE_ACCESS_LEVEL_ANONYMOUS}
+ ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${false} | ${'disabled'} | ${featureAccessLevel.NOT_ENABLED}
+ ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${true} | ${false} | ${featureAccessLevel.EVERYONE}
+ ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${true} | ${true} | ${FEATURE_ACCESS_LEVEL_ANONYMOUS}
+ ${VISIBILITY_LEVEL_PUBLIC_INTEGER} | ${false} | ${'hidden'} | ${featureAccessLevel.NOT_ENABLED}
+ ${VISIBILITY_LEVEL_PUBLIC_INTEGER} | ${true} | ${'hidden'} | ${FEATURE_ACCESS_LEVEL_ANONYMOUS}
`(
- 'renders correct options when visibilityLevel is $visibilityLevel',
- async ({ visibilityLevel, output }) => {
+ 'sets correct access level',
+ async ({
+ projectVisibilityLevel,
+ packageRegistryEnabled,
+ packageRegistryApiForEveryoneEnabled,
+ expectedAccessLevel,
+ }) => {
wrapper = mountComponent({
glFeatures: { packageRegistryAccessLevel: true },
packagesAvailable: true,
currentSettings: {
- visibilityLevel,
+ visibilityLevel: projectVisibilityLevel,
},
});
- expect(findPackageAccessLevels().props('options')).toStrictEqual(output);
+ await findPackageRegistryEnabledInput().vm.$emit('change', packageRegistryEnabled);
+
+ const packageRegistryApiForEveryoneEnabledInput = findPackageRegistryApiForEveryoneEnabledInput();
+
+ if (packageRegistryApiForEveryoneEnabled === 'hidden') {
+ expect(packageRegistryApiForEveryoneEnabledInput.exists()).toBe(false);
+ } else if (packageRegistryApiForEveryoneEnabled === 'disabled') {
+ expect(packageRegistryApiForEveryoneEnabledInput.props('disabled')).toBe(true);
+ } else {
+ expect(packageRegistryApiForEveryoneEnabledInput.props('disabled')).toBe(false);
+ await packageRegistryApiForEveryoneEnabledInput.vm.$emit(
+ 'change',
+ packageRegistryApiForEveryoneEnabled,
+ );
+ }
+
+ expect(wrapper.vm.packageRegistryAccessLevel).toBe(expectedAccessLevel);
},
);
it.each`
- initialProjectVisibilityLevel | newProjectVisibilityLevel | initialPackageRegistryOption | expectedPackageRegistryOption
+ initialProjectVisibilityLevel | newProjectVisibilityLevel | initialAccessLevel | expectedAccessLevel
${VISIBILITY_LEVEL_PRIVATE_INTEGER} | ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${featureAccessLevel.NOT_ENABLED} | ${featureAccessLevel.NOT_ENABLED}
${VISIBILITY_LEVEL_PRIVATE_INTEGER} | ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${featureAccessLevel.PROJECT_MEMBERS} | ${featureAccessLevel.EVERYONE}
${VISIBILITY_LEVEL_PRIVATE_INTEGER} | ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${FEATURE_ACCESS_LEVEL_ANONYMOUS} | ${FEATURE_ACCESS_LEVEL_ANONYMOUS}
@@ -626,27 +666,25 @@ describe('Settings Panel', () => {
${VISIBILITY_LEVEL_PUBLIC_INTEGER} | ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${featureAccessLevel.NOT_ENABLED} | ${featureAccessLevel.NOT_ENABLED}
${VISIBILITY_LEVEL_PUBLIC_INTEGER} | ${VISIBILITY_LEVEL_INTERNAL_INTEGER} | ${FEATURE_ACCESS_LEVEL_ANONYMOUS} | ${featureAccessLevel.EVERYONE}
`(
- 'changes option from $initialPackageRegistryOption to $expectedPackageRegistryOption when visibilityLevel changed from $initialProjectVisibilityLevel to $newProjectVisibilityLevel',
+ 'changes access level when project visibility level changed',
async ({
initialProjectVisibilityLevel,
newProjectVisibilityLevel,
- initialPackageRegistryOption,
- expectedPackageRegistryOption,
+ initialAccessLevel,
+ expectedAccessLevel,
}) => {
wrapper = mountComponent({
glFeatures: { packageRegistryAccessLevel: true },
packagesAvailable: true,
currentSettings: {
visibilityLevel: initialProjectVisibilityLevel,
- packageRegistryAccessLevel: initialPackageRegistryOption,
+ packageRegistryAccessLevel: initialAccessLevel,
},
});
await findProjectVisibilityLevelInput().setValue(newProjectVisibilityLevel);
- expect(findPackageAccessLevels().props('value')).toStrictEqual(
- expectedPackageRegistryOption,
- );
+ expect(wrapper.vm.packageRegistryAccessLevel).toBe(expectedAccessLevel);
},
);
});
diff --git a/spec/lib/api/every_api_endpoint_spec.rb b/spec/lib/api/every_api_endpoint_spec.rb
index 5fe14823a29..c45ff9eb628 100644
--- a/spec/lib/api/every_api_endpoint_spec.rb
+++ b/spec/lib/api/every_api_endpoint_spec.rb
@@ -32,10 +32,21 @@ RSpec.describe 'Every API endpoint' do
next unless used_category
next if used_category == :not_owned
- [path, used_category] unless feature_categories.include?(used_category)
+ [klass, path, used_category] unless feature_categories.include?(used_category)
end.compact
- expect(routes_unknown_category).to be_empty, "#{routes_unknown_category.first(10)} had an unknown category"
+ message = -> do
+ list = routes_unknown_category.map do |klass, path, category|
+ "- #{klass} (#{path}): #{category}"
+ end
+
+ <<~MESSAGE
+ Unknown categories found for:
+ #{list.join("\n")}
+ MESSAGE
+ end
+
+ expect(routes_unknown_category).to be_empty, message
end
# This is required for API::Base.path_for_app to work, as it picks
diff --git a/spec/lib/gitlab/memory/watchdog/configuration_spec.rb b/spec/lib/gitlab/memory/watchdog/configuration_spec.rb
index 8c9b26ce2c4..f1405ca7d68 100644
--- a/spec/lib/gitlab/memory/watchdog/configuration_spec.rb
+++ b/spec/lib/gitlab/memory/watchdog/configuration_spec.rb
@@ -20,10 +20,10 @@ RSpec.describe Gitlab::Memory::Watchdog::Configuration do
end
end
- describe '#logger' do
- context 'when logger is not set, defaults to stdout logger' do
- it 'defaults to Logger' do
- expect(configuration.logger).to be_an_instance_of(::Gitlab::Logger)
+ describe '#event_reporter' do
+ context 'when event reporter is not set' do
+ it 'defaults to EventReporter' do
+ expect(configuration.event_reporter).to be_an_instance_of(::Gitlab::Memory::Watchdog::EventReporter)
end
end
end
diff --git a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
index ec61d027329..892bad603a8 100644
--- a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
+++ b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
@@ -6,17 +6,23 @@ require 'sidekiq'
require_dependency 'gitlab/cluster/lifecycle_events'
RSpec.describe Gitlab::Memory::Watchdog::Configurator do
- shared_examples 'as configurator' do |handler_class, sleep_time_env, sleep_time|
+ shared_examples 'as configurator' do |handler_class, event_reporter_class, sleep_time_env, sleep_time|
it 'configures the correct handler' do
configurator.call(configuration)
expect(configuration.handler).to be_an_instance_of(handler_class)
end
+ it 'configures the correct event reporter' do
+ configurator.call(configuration)
+
+ expect(configuration.event_reporter).to be_an_instance_of(event_reporter_class)
+ end
+
it 'configures the correct logger' do
configurator.call(configuration)
- expect(configuration.logger).to eq(logger)
+ expect(configuration.event_reporter.logger).to eq(logger)
end
it 'does not enable writing heap dumps by default' do
@@ -129,6 +135,7 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do
it_behaves_like 'as configurator',
Gitlab::Memory::Watchdog::PumaHandler,
+ Gitlab::Memory::Watchdog::EventReporter,
'GITLAB_MEMWD_SLEEP_TIME_SEC',
described_class::DEFAULT_SLEEP_INTERVAL_S
@@ -236,6 +243,7 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do
it_behaves_like 'as configurator',
Gitlab::Memory::Watchdog::TermProcessHandler,
+ Gitlab::Memory::Watchdog::EventReporter,
'SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL',
described_class::DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S
diff --git a/spec/lib/gitlab/memory/watchdog/event_reporter_spec.rb b/spec/lib/gitlab/memory/watchdog/event_reporter_spec.rb
new file mode 100644
index 00000000000..f667bc724d2
--- /dev/null
+++ b/spec/lib/gitlab/memory/watchdog/event_reporter_spec.rb
@@ -0,0 +1,118 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'prometheus/client'
+
+RSpec.describe Gitlab::Memory::Watchdog::EventReporter, feature_category: :application_performance do
+ let(:logger) { instance_double(::Logger) }
+ let(:violations_counter) { instance_double(::Prometheus::Client::Counter) }
+ let(:violations_handled_counter) { instance_double(::Prometheus::Client::Counter) }
+ let(:reporter) { described_class.new(logger: logger) }
+
+ def stub_prometheus_metrics
+ allow(Gitlab::Metrics).to receive(:counter)
+ .with(:gitlab_memwd_violations_total, anything, anything)
+ .and_return(violations_counter)
+ allow(Gitlab::Metrics).to receive(:counter)
+ .with(:gitlab_memwd_violations_handled_total, anything, anything)
+ .and_return(violations_handled_counter)
+
+ allow(violations_counter).to receive(:increment)
+ allow(violations_handled_counter).to receive(:increment)
+ end
+
+ before do
+ stub_prometheus_metrics
+ allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).at_least(:once).and_return(
+ total: 1024
+ )
+ allow(::Prometheus::PidProvider).to receive(:worker_id).and_return('worker_1')
+ end
+
+ describe '#logger' do
+ context 'when logger is not provided' do
+ let(:reporter) { described_class.new }
+
+ it 'uses default Gitlab::AppLogger' do
+ expect(reporter.logger).to eq(Gitlab::AppLogger)
+ end
+ end
+ end
+
+ describe '#started' do
+ it 'logs start message once' do
+ expect(logger).to receive(:info).once
+ .with(
+ pid: Process.pid,
+ worker_id: 'worker_1',
+ custom_label: 'dummy_label',
+ memwd_rss_bytes: 1024,
+ message: 'started')
+
+ reporter.started(custom_label: 'dummy_label')
+ end
+ end
+
+ describe '#stopped' do
+ subject { reporter.stopped(custom_label: 'dummy_label') }
+
+ it 'logs stop message once' do
+ expect(logger).to receive(:info).once
+ .with(
+ pid: Process.pid,
+ worker_id: 'worker_1',
+ custom_label: 'dummy_label',
+ memwd_rss_bytes: 1024,
+ message: 'stopped')
+
+ reporter.stopped(custom_label: 'dummy_label')
+ end
+ end
+
+ describe '#threshold_violated' do
+ subject { reporter.threshold_violated(:monitor_name) }
+
+ it 'increments violations counter' do
+ expect(violations_counter).to receive(:increment).with(reason: :monitor_name)
+
+ subject
+ end
+
+ it 'does not increment handled violations counter' do
+ expect(violations_handled_counter).not_to receive(:increment)
+
+ subject
+ end
+
+ it 'does not log violation' do
+ expect(logger).not_to receive(:warn)
+
+ subject
+ end
+ end
+
+ describe '#strikes_exceeded' do
+ subject { reporter.strikes_exceeded(:monitor_name, { message: 'dummy_text' }) }
+
+ before do
+ allow(logger).to receive(:warn)
+ end
+
+ it 'increments handled violations counter' do
+ expect(violations_handled_counter).to receive(:increment).with(reason: :monitor_name)
+
+ subject
+ end
+
+ it 'logs violation' do
+ expect(logger).to receive(:warn)
+ .with(
+ pid: Process.pid,
+ worker_id: 'worker_1',
+ memwd_rss_bytes: 1024,
+ message: 'dummy_text')
+
+ subject
+ end
+ end
+end
diff --git a/spec/lib/gitlab/memory/watchdog_spec.rb b/spec/lib/gitlab/memory/watchdog_spec.rb
index 8703bf8b00b..fca31d590f5 100644
--- a/spec/lib/gitlab/memory/watchdog_spec.rb
+++ b/spec/lib/gitlab/memory/watchdog_spec.rb
@@ -6,12 +6,10 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
context 'watchdog' do
let(:configuration) { instance_double(described_class::Configuration) }
let(:handler) { instance_double(described_class::NullHandler) }
- let(:logger) { instance_double(::Logger) }
+ let(:reporter) { instance_double(described_class::EventReporter) }
let(:sleep_time_seconds) { 60 }
let(:write_heap_dumps) { false }
let(:threshold_violated) { false }
- let(:violations_counter) { instance_double(::Prometheus::Client::Counter) }
- let(:violations_handled_counter) { instance_double(::Prometheus::Client::Counter) }
let(:watchdog_iterations) { 1 }
let(:name) { :monitor_name }
let(:payload) { { message: 'dummy_text' } }
@@ -38,18 +36,6 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
end
end
- def stub_prometheus_metrics
- allow(Gitlab::Metrics).to receive(:counter)
- .with(:gitlab_memwd_violations_total, anything, anything)
- .and_return(violations_counter)
- allow(Gitlab::Metrics).to receive(:counter)
- .with(:gitlab_memwd_violations_handled_total, anything, anything)
- .and_return(violations_handled_counter)
-
- allow(violations_counter).to receive(:increment)
- allow(violations_handled_counter).to receive(:increment)
- end
-
describe '#initialize' do
it 'initialize new configuration' do
expect(described_class::Configuration).to receive(:new)
@@ -60,34 +46,27 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
describe '#call' do
before do
- stub_prometheus_metrics
- allow(Gitlab::Metrics::System).to receive(:memory_usage_rss).at_least(:once).and_return(
- total: 1024
- )
- allow(::Prometheus::PidProvider).to receive(:worker_id).and_return('worker_1')
-
watchdog.configure do |config|
config.handler = handler
- config.logger = logger
+ config.event_reporter = reporter
config.sleep_time_seconds = sleep_time_seconds
config.write_heap_dumps = write_heap_dumps
config.monitors.push monitor_class, threshold_violated, payload, max_strikes: max_strikes
end
allow(handler).to receive(:call).and_return(true)
- allow(logger).to receive(:info)
- allow(logger).to receive(:warn)
+ allow(reporter).to receive(:started)
+ allow(reporter).to receive(:stopped)
+ allow(reporter).to receive(:threshold_violated)
+ allow(reporter).to receive(:strikes_exceeded)
end
- it 'logs start message once' do
- expect(logger).to receive(:info).once
+ it 'reports started event once' do
+ expect(reporter).to receive(:started).once
.with(
- pid: Process.pid,
- worker_id: 'worker_1',
memwd_handler_class: handler.class.name,
- memwd_sleep_time_s: sleep_time_seconds,
- memwd_rss_bytes: 1024,
- message: 'started')
+ memwd_sleep_time_s: sleep_time_seconds
+ )
watchdog.call
end
@@ -109,15 +88,9 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
end
context 'when process does not exceed threshold' do
- it 'does not increment violations counters' do
- expect(violations_counter).not_to receive(:increment)
- expect(violations_handled_counter).not_to receive(:increment)
-
- watchdog.call
- end
-
- it 'does not log violation' do
- expect(logger).not_to receive(:warn)
+ it 'does not report violations event' do
+ expect(reporter).not_to receive(:threshold_violated)
+ expect(reporter).not_to receive(:strikes_exceeded)
watchdog.call
end
@@ -132,21 +105,15 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
context 'when process exceeds threshold' do
let(:threshold_violated) { true }
- it 'increments violations counter' do
- expect(violations_counter).to receive(:increment).with(reason: name)
+ it 'reports threshold violated event' do
+ expect(reporter).to receive(:threshold_violated).with(name)
watchdog.call
end
context 'when process does not exceed the allowed number of strikes' do
- it 'does not increment handled violations counter' do
- expect(violations_handled_counter).not_to receive(:increment)
-
- watchdog.call
- end
-
- it 'does not log violation' do
- expect(logger).not_to receive(:warn)
+ it 'does not report strikes exceeded event' do
+ expect(reporter).not_to receive(:strikes_exceeded)
watchdog.call
end
@@ -171,23 +138,16 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
context 'when monitor exceeds the allowed number of strikes' do
let(:max_strikes) { 0 }
- it 'increments handled violations counter' do
- expect(violations_handled_counter).to receive(:increment).with(reason: name)
-
- watchdog.call
- end
-
- it 'logs violation' do
- expect(logger).to receive(:warn)
+ it 'reports strikes exceeded event' do
+ expect(reporter).to receive(:strikes_exceeded)
.with(
- pid: Process.pid,
- worker_id: 'worker_1',
+ name,
memwd_handler_class: handler.class.name,
memwd_sleep_time_s: sleep_time_seconds,
- memwd_rss_bytes: 1024,
memwd_cur_strikes: 1,
memwd_max_strikes: max_strikes,
- message: 'dummy_text')
+ message: "dummy_text"
+ )
watchdog.call
end
@@ -225,7 +185,7 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
before do
watchdog.configure do |config|
config.handler = handler
- config.logger = logger
+ config.event_reporter = reporter
config.sleep_time_seconds = sleep_time_seconds
config.monitors.push monitor_class, threshold_violated, payload, max_strikes: max_strikes
config.monitors.push monitor_class, threshold_violated, payload, max_strikes: max_strikes
@@ -241,15 +201,12 @@ RSpec.describe Gitlab::Memory::Watchdog, :aggregate_failures do
end
end
- it 'logs stop message once' do
- expect(logger).to receive(:info).once
+ it 'reports stopped event once' do
+ expect(reporter).to receive(:stopped).once
.with(
- pid: Process.pid,
- worker_id: 'worker_1',
memwd_handler_class: handler.class.name,
- memwd_sleep_time_s: sleep_time_seconds,
- memwd_rss_bytes: 1024,
- message: 'stopped')
+ memwd_sleep_time_s: sleep_time_seconds
+ )
watchdog.call
end
diff --git a/spec/models/user_preference_spec.rb b/spec/models/user_preference_spec.rb
index d76334d7c9e..a6f64c90657 100644
--- a/spec/models/user_preference_spec.rb
+++ b/spec/models/user_preference_spec.rb
@@ -3,7 +3,9 @@
require 'spec_helper'
RSpec.describe UserPreference do
- let(:user_preference) { create(:user_preference) }
+ let_it_be(:user) { create(:user) }
+
+ let(:user_preference) { create(:user_preference, user: user) }
describe 'validations' do
describe 'diffs_deletion_color and diffs_addition_color' do
@@ -132,10 +134,24 @@ RSpec.describe UserPreference do
describe '#tab_width' do
it 'is set to 8 by default' do
# Intentionally not using factory here to test the constructor.
- pref = UserPreference.new
+ pref = described_class.new
+
+ expect(pref.tab_width).to eq(8)
+ end
+
+ it 'returns default value when assigning nil' do
+ pref = described_class.new(tab_width: nil)
+
expect(pref.tab_width).to eq(8)
end
+ it 'returns default value when the value is NULL' do
+ pref = create(:user_preference, user: user)
+ pref.update_column(:tab_width, nil)
+
+ expect(pref.reload.tab_width).to eq(8)
+ end
+
it do
is_expected.to validate_numericality_of(:tab_width)
.only_integer
@@ -143,4 +159,141 @@ RSpec.describe UserPreference do
.is_less_than_or_equal_to(12)
end
end
+
+ describe '#tab_width=' do
+ it 'sets to default value when nil' do
+ pref = described_class.new(tab_width: nil)
+
+ expect(pref.read_attribute(:tab_width)).to eq(8)
+ end
+
+ it 'sets user values' do
+ pref = described_class.new(tab_width: 12)
+
+ expect(pref.read_attribute(:tab_width)).to eq(12)
+ end
+ end
+
+ describe '#time_display_relative' do
+ it 'is set to true by default' do
+ pref = described_class.new
+
+ expect(pref.time_display_relative).to eq(true)
+ end
+
+ it 'returns default value when assigning nil' do
+ pref = described_class.new(time_display_relative: nil)
+
+ expect(pref.time_display_relative).to eq(true)
+ end
+
+ it 'returns default value when the value is NULL' do
+ pref = create(:user_preference, user: user)
+ pref.update_column(:time_display_relative, nil)
+
+ expect(pref.reload.time_display_relative).to eq(true)
+ end
+
+ it 'returns assigned value' do
+ pref = described_class.new(time_display_relative: false)
+
+ expect(pref.time_display_relative).to eq(false)
+ end
+ end
+
+ describe '#time_display_relative=' do
+ it 'sets to default value when nil' do
+ pref = described_class.new(time_display_relative: nil)
+
+ expect(pref.read_attribute(:time_display_relative)).to eq(true)
+ end
+
+ it 'sets user values' do
+ pref = described_class.new(time_display_relative: false)
+
+ expect(pref.read_attribute(:time_display_relative)).to eq(false)
+ end
+ end
+
+ describe '#time_format_in_24h' do
+ it 'is set to false by default' do
+ pref = described_class.new
+
+ expect(pref.time_format_in_24h).to eq(false)
+ end
+
+ it 'returns default value when assigning nil' do
+ pref = described_class.new(time_format_in_24h: nil)
+
+ expect(pref.time_format_in_24h).to eq(false)
+ end
+
+ it 'returns default value when the value is NULL' do
+ pref = create(:user_preference, user: user)
+ pref.update_column(:time_format_in_24h, nil)
+
+ expect(pref.reload.time_format_in_24h).to eq(false)
+ end
+
+ it 'returns assigned value' do
+ pref = described_class.new(time_format_in_24h: true)
+
+ expect(pref.time_format_in_24h).to eq(true)
+ end
+ end
+
+ describe '#time_format_in_24h=' do
+ it 'sets to default value when nil' do
+ pref = described_class.new(time_format_in_24h: nil)
+
+ expect(pref.read_attribute(:time_format_in_24h)).to eq(false)
+ end
+
+ it 'sets user values' do
+ pref = described_class.new(time_format_in_24h: true)
+
+ expect(pref.read_attribute(:time_format_in_24h)).to eq(true)
+ end
+ end
+
+ describe '#render_whitespace_in_code' do
+ it 'is set to false by default' do
+ pref = described_class.new
+
+ expect(pref.render_whitespace_in_code).to eq(false)
+ end
+
+ it 'returns default value when assigning nil' do
+ pref = described_class.new(render_whitespace_in_code: nil)
+
+ expect(pref.render_whitespace_in_code).to eq(false)
+ end
+
+ it 'returns default value when the value is NULL' do
+ pref = create(:user_preference, user: user)
+ pref.update_column(:render_whitespace_in_code, nil)
+
+ expect(pref.reload.render_whitespace_in_code).to eq(false)
+ end
+
+ it 'returns assigned value' do
+ pref = described_class.new(render_whitespace_in_code: true)
+
+ expect(pref.render_whitespace_in_code).to eq(true)
+ end
+ end
+
+ describe '#render_whitespace_in_code=' do
+ it 'sets to default value when nil' do
+ pref = described_class.new(render_whitespace_in_code: nil)
+
+ expect(pref.read_attribute(:render_whitespace_in_code)).to eq(false)
+ end
+
+ it 'sets user values' do
+ pref = described_class.new(render_whitespace_in_code: true)
+
+ expect(pref.read_attribute(:render_whitespace_in_code)).to eq(true)
+ end
+ end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 0f2f5d65dda..7faf9b51720 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -146,6 +146,21 @@ RSpec.describe User do
it { is_expected.to have_many(:project_callouts).class_name('Users::ProjectCallout') }
it { is_expected.to have_many(:created_projects).dependent(:nullify).class_name('Project') }
+ describe 'default values' do
+ let(:user) { described_class.new }
+
+ it { expect(user.admin).to be_falsey }
+ it { expect(user.external).to eq(Gitlab::CurrentSettings.user_default_external) }
+ it { expect(user.can_create_group).to eq(Gitlab::CurrentSettings.can_create_group) }
+ it { expect(user.can_create_team).to be_falsey }
+ it { expect(user.hide_no_ssh_key).to be_falsey }
+ it { expect(user.hide_no_password).to be_falsey }
+ it { expect(user.project_view).to eq('files') }
+ it { expect(user.notified_of_own_activity).to be_falsey }
+ it { expect(user.preferred_language).to eq(I18n.default_locale.to_s) }
+ it { expect(user.theme_id).to eq(described_class.gitlab_config.default_theme) }
+ end
+
describe '#user_detail' do
it 'does not persist `user_detail` by default' do
expect(create(:user).user_detail).not_to be_persisted
@@ -398,7 +413,7 @@ RSpec.describe User do
end
it 'falls back to english when I18n.default_locale is not an available language' do
- I18n.default_locale = :kl
+ allow(I18n).to receive(:default_locale) { :kl }
default_preferred_language = user.send(:default_preferred_language)
expect(user.preferred_language).to eq default_preferred_language
@@ -7307,4 +7322,51 @@ RSpec.describe User do
expect(user.account_age_in_days).to be(1)
end
end
+
+ describe 'state machine and default attributes' do
+ let(:model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = User.table_name
+
+ attribute :external, default: -> { 1 / 0 }
+
+ state_machine :state, initial: :active do
+ end
+ end
+ end
+
+ it 'raises errors by default' do
+ expect { model }.to raise_error(ZeroDivisionError)
+ end
+
+ context 'with state machine default attributes override' do
+ let(:model) do
+ Class.new(ApplicationRecord) do
+ self.table_name = User.table_name
+
+ attribute :external, default: -> { 1 / 0 }
+
+ state_machine :state, initial: :active do
+ def owner_class_attribute_default; end
+ end
+ end
+ end
+
+ it 'does not raise errors' do
+ expect { model }.not_to raise_error
+ end
+
+ it 'raises errors when default attributes are used' do
+ expect { model.new.attributes }.to raise_error(ZeroDivisionError)
+ end
+
+ it 'does not evaluate default attributes when values are provided' do
+ expect { model.new(external: false).attributes }.not_to raise_error
+ end
+
+ it 'sets the state machine default value' do
+ expect(model.new(external: true).state).to eq('active')
+ end
+ end
+ end
end
diff --git a/spec/rubocop/cop/rspec/timecop_freeze_spec.rb b/spec/rubocop/cop/rspec/timecop_freeze_spec.rb
deleted file mode 100644
index 4361f587da3..00000000000
--- a/spec/rubocop/cop/rspec/timecop_freeze_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-require 'rubocop_spec_helper'
-
-require_relative '../../../../rubocop/cop/rspec/timecop_freeze'
-
-RSpec.describe RuboCop::Cop::RSpec::TimecopFreeze do
- context 'when calling Timecop.freeze' do
- it 'registers an offense and corrects', :aggregate_failures do
- expect_offense(<<~CODE)
- Timecop.freeze(Time.current) { example.run }
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `Timecop.freeze`, use `freeze_time` instead. [...]
- CODE
-
- expect_correction(<<~CODE)
- freeze_time(Time.current) { example.run }
- CODE
- end
- end
-
- context 'when calling a different method on Timecop' do
- it 'does not register an offense' do
- expect_no_offenses(<<~CODE)
- Timecop.travel(Time.current)
- CODE
- end
- end
-end
diff --git a/spec/rubocop/cop/rspec/timecop_travel_spec.rb b/spec/rubocop/cop/rspec/timecop_travel_spec.rb
deleted file mode 100644
index 89c46ff6c59..00000000000
--- a/spec/rubocop/cop/rspec/timecop_travel_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-require 'rubocop_spec_helper'
-
-require_relative '../../../../rubocop/cop/rspec/timecop_travel'
-
-RSpec.describe RuboCop::Cop::RSpec::TimecopTravel do
- context 'when calling Timecop.travel' do
- it 'registers an offense and corrects', :aggregate_failures do
- expect_offense(<<~CODE)
- Timecop.travel(1.day.ago) { create(:issue) }
- ^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `Timecop.travel`, use `travel_to` instead. [...]
- CODE
-
- expect_correction(<<~CODE)
- travel_to(1.day.ago) { create(:issue) }
- CODE
- end
- end
-
- context 'when calling a different method on Timecop' do
- it 'does not register an offense' do
- expect_no_offenses(<<~CODE)
- Timecop.freeze { create(:issue) }
- CODE
- end
- end
-end
diff --git a/spec/services/chat_names/find_user_service_spec.rb b/spec/services/chat_names/find_user_service_spec.rb
index 4b0a1204558..b65a76ca37c 100644
--- a/spec/services/chat_names/find_user_service_spec.rb
+++ b/spec/services/chat_names/find_user_service_spec.rb
@@ -40,6 +40,14 @@ RSpec.describe ChatNames::FindUserService, :clean_gitlab_redis_shared_state do
expect(chat_name.reload.last_used_at).to eq(time)
end
+
+ context 'when integration is not passed' do
+ it 'returns chat name' do
+ requested_chat_name = described_class.new(nil, params).execute
+
+ expect(requested_chat_name).to eq(chat_name)
+ end
+ end
end
context 'when different user is requested' do
diff --git a/workhorse/go.mod b/workhorse/go.mod
index 05d0db1cfac..88e6748ee8e 100644
--- a/workhorse/go.mod
+++ b/workhorse/go.mod
@@ -10,7 +10,7 @@ require (
github.com/aws/aws-sdk-go v1.44.145
github.com/disintegration/imaging v1.6.2
github.com/getsentry/raven-go v0.2.0
- github.com/golang-jwt/jwt/v4 v4.4.2
+ github.com/golang-jwt/jwt/v4 v4.4.3
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f
github.com/golang/protobuf v1.5.2
github.com/gomodule/redigo v2.0.0+incompatible
diff --git a/workhorse/go.sum b/workhorse/go.sum
index 2c96dc02e88..a9090fa0706 100644
--- a/workhorse/go.sum
+++ b/workhorse/go.sum
@@ -686,8 +686,9 @@ github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfE
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
-github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
+github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f h1:16RtHeWGkJMc80Etb8RPCcKevXGldr57+LOyZt8zOlg=
diff --git a/yarn.lock b/yarn.lock
index f47edb442bc..083d117f274 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1120,10 +1120,10 @@
stylelint-declaration-strict-value "1.8.0"
stylelint-scss "4.2.0"
-"@gitlab/svgs@3.11.0":
- version "3.11.0"
- resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.11.0.tgz#91e8e25583cddef48c0c79175203e5b0a4eaa519"
- integrity sha512-1cJu1WXPoOHfGgv5fT3nmA9cgAQ3U1Fm/oMSVYUgBxU35R0I8W704GMLsIZwBuQ/S/Ow7WLwIkoOhLb/spNKPg==
+"@gitlab/svgs@3.12.0":
+ version "3.12.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.12.0.tgz#cebd2ebf21e803d0d9e674d43fcb2d868f5d5a62"
+ integrity sha512-7GDMXuBoOL380sjdBSpPufUzwd5dJgkzqgpx26JBlrO2ShSW0k5KnmIurSXSe8gpqwAEIEw/BbpjCz0SRRRwQg==
"@gitlab/ui@50.1.2":
version "50.1.2"