Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-10-17 21:10:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-10-17 21:10:11 +0300
commit5cbf24858edb03505b16474e3b7b41a49b677ff6 (patch)
tree21999fbb911fe2410cf498b3ed668d202dc90098 /app
parent673a1a02e97181a5f2d94cd0b116ebb4dba3d875 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/crm/organizations/components/graphql/create_customer_relations_organization.mutation.graphql (renamed from app/assets/javascripts/crm/organizations/components/graphql/create_organization.mutation.graphql)2
-rw-r--r--app/assets/javascripts/crm/organizations/components/organization_form_wrapper.vue4
-rw-r--r--app/assets/javascripts/environments/graphql/resolvers/kubernetes.js2
-rw-r--r--app/assets/javascripts/import_entities/components/group_dropdown.vue72
-rw-r--r--app/assets/javascripts/import_entities/components/import_target_dropdown.vue54
-rw-r--r--app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue56
-rw-r--r--app/assets/javascripts/integrations/constants.js8
-rw-r--r--app/assets/javascripts/ml/model_registry/routes/models/index/components/ml_models_index.vue11
-rw-r--r--app/assets/javascripts/ml/model_registry/routes/models/index/components/model_row.vue35
-rw-r--r--app/assets/javascripts/ml/model_registry/routes/models/index/translations.js14
-rw-r--r--app/assets/javascripts/notes/components/email_participants_warning.vue7
-rw-r--r--app/assets/javascripts/organizations/mock_data.js8
-rw-r--r--app/assets/javascripts/organizations/new/components/app.vue73
-rw-r--r--app/assets/javascripts/organizations/new/graphql/mutations/create_organization.mutation.graphql9
-rw-r--r--app/assets/javascripts/organizations/new/graphql/typedefs.graphql5
-rw-r--r--app/assets/javascripts/organizations/new/index.js35
-rw-r--r--app/assets/javascripts/organizations/shared/components/new_edit_form.vue125
-rw-r--r--app/assets/javascripts/organizations/shared/graphql/resolvers.js15
-rw-r--r--app/assets/javascripts/pages/organizations/organizations/new/index.js3
-rw-r--r--app/assets/javascripts/vue_shared/components/incubation/pagination.vue1
-rw-r--r--app/assets/stylesheets/page_bundles/organizations.scss4
-rw-r--r--app/components/projects/ml/models_index_component.rb1
-rw-r--r--app/finders/concerns/packages/finder_helper.rb4
-rw-r--r--app/finders/packages/npm/packages_for_user_finder.rb7
-rw-r--r--app/finders/projects/ml/model_finder.rb1
-rw-r--r--app/helpers/integrations_helper.rb8
-rw-r--r--app/helpers/organizations/organization_helper.rb7
-rw-r--r--app/models/ci/catalog/components_project.rb94
-rw-r--r--app/models/integrations/pushover.rb4
-rw-r--r--app/models/ml/model.rb5
-rw-r--r--app/models/project.rb1
-rw-r--r--app/services/ci/components/fetch_service.rb15
-rw-r--r--app/services/ml/find_or_create_model_version_service.rb1
-rw-r--r--app/views/organizations/organizations/new.html.haml3
-rw-r--r--app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb1
-rw-r--r--app/workers/concerns/auto_devops_queue.rb2
-rw-r--r--app/workers/concerns/chaos_queue.rb2
-rw-r--r--app/workers/concerns/limited_capacity/job_tracker.rb1
-rw-r--r--app/workers/database/batched_background_migration/ci_database_worker.rb1
-rw-r--r--app/workers/gitlab/github_gists_import/import_gist_worker.rb6
-rw-r--r--app/workers/gitlab/github_gists_import/start_import_worker.rb2
-rw-r--r--app/workers/gitlab/import/stuck_project_import_jobs_worker.rb1
-rw-r--r--app/workers/projects/after_import_worker.rb2
43 files changed, 552 insertions, 160 deletions
diff --git a/app/assets/javascripts/crm/organizations/components/graphql/create_organization.mutation.graphql b/app/assets/javascripts/crm/organizations/components/graphql/create_customer_relations_organization.mutation.graphql
index 2cc7e53ee9b..8e019420eb7 100644
--- a/app/assets/javascripts/crm/organizations/components/graphql/create_organization.mutation.graphql
+++ b/app/assets/javascripts/crm/organizations/components/graphql/create_customer_relations_organization.mutation.graphql
@@ -1,6 +1,6 @@
#import "./crm_organization_fields.fragment.graphql"
-mutation createOrganization($input: CustomerRelationsOrganizationCreateInput!) {
+mutation createCustomerRelationsOrganization($input: CustomerRelationsOrganizationCreateInput!) {
customerRelationsOrganizationCreate(input: $input) {
organization {
...OrganizationFragment
diff --git a/app/assets/javascripts/crm/organizations/components/organization_form_wrapper.vue b/app/assets/javascripts/crm/organizations/components/organization_form_wrapper.vue
index 4d2a038458d..fb056e4fa2c 100644
--- a/app/assets/javascripts/crm/organizations/components/organization_form_wrapper.vue
+++ b/app/assets/javascripts/crm/organizations/components/organization_form_wrapper.vue
@@ -4,7 +4,7 @@ import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_CRM_ORGANIZATION, TYPENAME_GROUP } from '~/graphql_shared/constants';
import CrmForm from '../../components/crm_form.vue';
import getGroupOrganizationsQuery from './graphql/get_group_organizations.query.graphql';
-import createOrganizationMutation from './graphql/create_organization.mutation.graphql';
+import createCustomerRelationsOrganizationMutation from './graphql/create_customer_relations_organization.mutation.graphql';
import updateOrganizationMutation from './graphql/update_organization.mutation.graphql';
export default {
@@ -31,7 +31,7 @@ export default {
mutation() {
if (this.isEditMode) return updateOrganizationMutation;
- return createOrganizationMutation;
+ return createCustomerRelationsOrganizationMutation;
},
getQuery() {
return {
diff --git a/app/assets/javascripts/environments/graphql/resolvers/kubernetes.js b/app/assets/javascripts/environments/graphql/resolvers/kubernetes.js
index 4e330ab16a8..67a472dac93 100644
--- a/app/assets/javascripts/environments/graphql/resolvers/kubernetes.js
+++ b/app/assets/javascripts/environments/graphql/resolvers/kubernetes.js
@@ -73,7 +73,7 @@ export default {
k8sServices(_, { configuration, namespace }) {
const coreV1Api = new CoreV1Api(new Configuration(configuration));
const servicesApi = namespace
- ? coreV1Api.listCoreV1NamespacedService(namespace)
+ ? coreV1Api.listCoreV1NamespacedService({ namespace })
: coreV1Api.listCoreV1ServiceForAllNamespaces();
return servicesApi
diff --git a/app/assets/javascripts/import_entities/components/group_dropdown.vue b/app/assets/javascripts/import_entities/components/group_dropdown.vue
deleted file mode 100644
index 68bdcf7ef90..00000000000
--- a/app/assets/javascripts/import_entities/components/group_dropdown.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-<script>
-import { GlDropdown, GlSearchBoxByType } from '@gitlab/ui';
-import { debounce } from 'lodash';
-
-import { s__ } from '~/locale';
-import { createAlert } from '~/alert';
-import searchNamespacesWhereUserCanImportProjectsQuery from '~/import_entities/import_projects/graphql/queries/search_namespaces_where_user_can_import_projects.query.graphql';
-import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants';
-import { MINIMUM_SEARCH_LENGTH } from '~/graphql_shared/constants';
-import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
-
-// This is added outside the component as each dropdown on the page triggers a query,
-// so if multiple queries fail, we only show 1 error.
-const reportNamespaceLoadError = debounce(
- () =>
- createAlert({
- message: s__('ImportProjects|Requesting namespaces failed'),
- }),
- DEFAULT_DEBOUNCE_AND_THROTTLE_MS,
-);
-
-export default {
- components: {
- GlDropdown,
- GlSearchBoxByType,
- },
- inheritAttrs: false,
- data() {
- return { searchTerm: '' };
- },
- apollo: {
- namespaces: {
- query: searchNamespacesWhereUserCanImportProjectsQuery,
- variables() {
- return {
- search: this.searchTerm,
- };
- },
- skip() {
- const hasNotEnoughSearchCharacters =
- this.searchTerm.length > 0 && this.searchTerm.length < MINIMUM_SEARCH_LENGTH;
- return hasNotEnoughSearchCharacters;
- },
- update(data) {
- return data.currentUser.groups.nodes;
- },
- error: reportNamespaceLoadError,
- debounce: DEBOUNCE_DELAY,
- },
- },
- computed: {
- filteredNamespaces() {
- return (this.namespaces ?? []).filter((ns) =>
- ns.fullPath.toLowerCase().includes(this.searchTerm.toLowerCase()),
- );
- },
- },
-};
-</script>
-<template>
- <gl-dropdown
- toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
- class="gl-h-7 gl-flex-fill-1"
- data-qa-selector="target_namespace_selector_dropdown"
- v-bind="$attrs"
- >
- <template #header>
- <gl-search-box-by-type v-model.trim="searchTerm" />
- </template>
- <slot :namespaces="filteredNamespaces"></slot>
- </gl-dropdown>
-</template>
diff --git a/app/assets/javascripts/import_entities/components/import_target_dropdown.vue b/app/assets/javascripts/import_entities/components/import_target_dropdown.vue
index b18a106608a..47c030bf1fc 100644
--- a/app/assets/javascripts/import_entities/components/import_target_dropdown.vue
+++ b/app/assets/javascripts/import_entities/components/import_target_dropdown.vue
@@ -26,13 +26,19 @@ export default {
},
props: {
+ disabled: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
selected: {
type: String,
required: true,
},
userNamespace: {
type: String,
- required: true,
+ required: false,
+ default: undefined,
},
},
@@ -66,6 +72,10 @@ export default {
},
computed: {
+ isProject() {
+ return Boolean(this.userNamespace);
+ },
+
filteredNamespaces() {
return (this.namespaces ?? []).filter((ns) =>
ns.fullPath.toLowerCase().includes(this.searchTerm.toLowerCase()),
@@ -78,14 +88,33 @@ export default {
items() {
return [
- {
- text: __('Users'),
- options: [{ text: this.userNamespace, value: this.userNamespace }],
- },
+ this.isProject
+ ? {
+ text: __('Users'),
+ options: [
+ {
+ text: this.userNamespace,
+ value: this.userNamespace,
+ },
+ ],
+ }
+ : {
+ text: __('Parent'),
+ textSrOnly: true,
+ options: [
+ {
+ text: s__('BulkImport|No parent'),
+ value: '',
+ },
+ ],
+ },
{
text: __('Groups'),
options: this.filteredNamespaces.map((namespace) => {
- return { text: namespace.fullPath, value: namespace.fullPath };
+ return {
+ text: namespace.fullPath,
+ value: namespace.fullPath,
+ };
}),
},
];
@@ -94,7 +123,15 @@ export default {
methods: {
onSelect(value) {
- this.$emit('select', value);
+ if (this.isProject) {
+ this.$emit('select', value);
+ } else if (value === '') {
+ this.$emit('select', { fullPath: '', id: null });
+ } else {
+ const { fullPath, id } = this.filteredNamespaces.find((ns) => ns.fullPath === value);
+
+ this.$emit('select', { fullPath, id });
+ }
},
onSearch(value) {
@@ -107,12 +144,13 @@ export default {
<template>
<gl-collapsible-listbox
:items="items"
+ :disabled="disabled"
:selected="selected"
:toggle-text="toggleText"
searchable
fluid-width
toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
- data-qa-selector="target_namespace_selector_dropdown"
+ data-testid="target-namespace-dropdown"
@select="onSelect"
@search="onSearch"
/>
diff --git a/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue b/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue
index 8af64e882ab..b4484c89b9f 100644
--- a/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue
+++ b/app/assets/javascripts/import_entities/import_groups/components/import_target_cell.vue
@@ -1,20 +1,12 @@
<script>
-import {
- GlDropdownDivider,
- GlDropdownItem,
- GlDropdownSectionHeader,
- GlFormInput,
-} from '@gitlab/ui';
-import { s__ } from '~/locale';
-import ImportGroupDropdown from '../../components/group_dropdown.vue';
+import { GlFormInput } from '@gitlab/ui';
+import ImportTargetDropdown from '../../components/import_target_dropdown.vue';
+
import { getInvalidNameValidationMessage } from '../utils';
export default {
components: {
- ImportGroupDropdown,
- GlDropdownDivider,
- GlDropdownItem,
- GlDropdownSectionHeader,
+ ImportTargetDropdown,
GlFormInput,
},
props: {
@@ -25,8 +17,8 @@ export default {
},
computed: {
- fullPath() {
- return this.group.importTarget.targetNamespace.fullPath || s__('BulkImport|No parent');
+ selectedImportTarget() {
+ return this.group.importTarget.targetNamespace.fullPath || '';
},
validationMessage() {
return (
@@ -47,6 +39,10 @@ export default {
focusNewName() {
this.$refs.newName.$el.focus();
},
+
+ onImportTargetSelect(namespace) {
+ this.$emit('update-target-namespace', namespace);
+ },
},
};
</script>
@@ -54,34 +50,12 @@ export default {
<template>
<div>
<div class="gl-display-flex gl-align-items-stretch">
- <import-group-dropdown
- #default="{ namespaces }"
- :text="fullPath"
+ <import-target-dropdown
+ :selected="selectedImportTarget"
:disabled="!isPathSelectionAvailable"
- toggle-class="gl-rounded-top-right-none! gl-rounded-bottom-right-none!"
- class="gl-h-7 gl-flex-grow-1"
- data-qa-selector="target_namespace_selector_dropdown"
- data-testid="target-namespace-selector"
- >
- <gl-dropdown-item @click="$emit('update-target-namespace', { fullPath: '', id: null })">{{
- s__('BulkImport|No parent')
- }}</gl-dropdown-item>
- <template v-if="namespaces.length">
- <gl-dropdown-divider />
- <gl-dropdown-section-header>
- {{ s__('BulkImport|Existing groups') }}
- </gl-dropdown-section-header>
- <gl-dropdown-item
- v-for="ns in namespaces"
- :key="ns.fullPath"
- data-qa-selector="target_group_dropdown_item"
- :data-qa-group-name="ns.fullPath"
- @click="$emit('update-target-namespace', ns)"
- >
- {{ ns.fullPath }}
- </gl-dropdown-item>
- </template>
- </import-group-dropdown>
+ @select="onImportTargetSelect"
+ />
+
<div
class="gl-h-7 gl-px-3 gl-display-flex gl-align-items-center gl-border-solid gl-border-0 gl-border-t-1 gl-border-b-1 gl-bg-gray-10"
:class="{
diff --git a/app/assets/javascripts/integrations/constants.js b/app/assets/javascripts/integrations/constants.js
index e803e11bf6d..12f5fa21137 100644
--- a/app/assets/javascripts/integrations/constants.js
+++ b/app/assets/javascripts/integrations/constants.js
@@ -59,6 +59,8 @@ export const integrationTriggerEvents = {
DEPLOYMENT: 'deployment_events',
ALERT: 'alert_events',
INCIDENT: 'incident_events',
+ GROUP_MENTION: 'group_mention_events',
+ GROUP_CONFIDENTIAL_MENTION: 'group_confidential_mention_events',
};
export const integrationTriggerEventTitles = {
@@ -88,6 +90,12 @@ export const integrationTriggerEventTitles = {
[integrationTriggerEvents.INCIDENT]: s__(
'IntegrationEvents|An incident is created, closed, or reopened',
),
+ [integrationTriggerEvents.GROUP_MENTION]: s__(
+ 'IntegrationEvents|A group is mentioned in a public context',
+ ),
+ [integrationTriggerEvents.GROUP_CONFIDENTIAL_MENTION]: s__(
+ 'IntegrationEvents|A group is mentioned in a confidential context',
+ ),
};
export const billingPlans = {
diff --git a/app/assets/javascripts/ml/model_registry/routes/models/index/components/ml_models_index.vue b/app/assets/javascripts/ml/model_registry/routes/models/index/components/ml_models_index.vue
index 9c5be18345c..3770b4ec3ac 100644
--- a/app/assets/javascripts/ml/model_registry/routes/models/index/components/ml_models_index.vue
+++ b/app/assets/javascripts/ml/model_registry/routes/models/index/components/ml_models_index.vue
@@ -1,14 +1,14 @@
<script>
-import { GlLink } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import * as translations from '~/ml/model_registry/routes/models/index/translations';
import Pagination from '~/vue_shared/components/incubation/pagination.vue';
+import ModelRow from './model_row.vue';
export default {
- name: 'MlExperimentsIndexApp',
+ name: 'MlModelRegistryApp',
components: {
- GlLink,
Pagination,
+ ModelRow,
},
props: {
models: {
@@ -40,10 +40,7 @@ export default {
</div>
<template v-if="hasModels">
- <div v-for="model in models" :key="model.name">
- <gl-link :href="model.path"> {{ model.name }} / {{ model.version }} </gl-link>
- </div>
-
+ <model-row v-for="model in models" :key="model.name" :model="model" />
<pagination v-bind="pageInfo" />
</template>
diff --git a/app/assets/javascripts/ml/model_registry/routes/models/index/components/model_row.vue b/app/assets/javascripts/ml/model_registry/routes/models/index/components/model_row.vue
new file mode 100644
index 00000000000..4f91f0939a8
--- /dev/null
+++ b/app/assets/javascripts/ml/model_registry/routes/models/index/components/model_row.vue
@@ -0,0 +1,35 @@
+<script>
+import { GlLink } from '@gitlab/ui';
+import { modelVersionCountMessage } from '../translations';
+
+export default {
+ name: 'MlModelRow',
+ components: {
+ GlLink,
+ },
+ props: {
+ model: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ hasVersions() {
+ return this.model.version != null;
+ },
+ },
+ modelVersionCountMessage,
+};
+</script>
+
+<template>
+ <div class="gl-border-b-solid gl-border-b-1 gl-border-b-gray-100 gl-py-3">
+ <gl-link :href="model.path" class="gl-text-body gl-font-weight-bold gl-line-height-24">
+ {{ model.name }}
+ </gl-link>
+
+ <div class="gl-text-secondary">
+ {{ $options.modelVersionCountMessage(model.version, model.versionCount) }}
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ml/model_registry/routes/models/index/translations.js b/app/assets/javascripts/ml/model_registry/routes/models/index/translations.js
index 6f61b0aff46..9210d816373 100644
--- a/app/assets/javascripts/ml/model_registry/routes/models/index/translations.js
+++ b/app/assets/javascripts/ml/model_registry/routes/models/index/translations.js
@@ -1,4 +1,16 @@
-import { s__ } from '~/locale';
+import { s__, n__, sprintf } from '~/locale';
export const TITLE_LABEL = s__('MlModelRegistry|Model registry');
export const NO_MODELS_LABEL = s__('MlModelRegistry|No models registered in this project');
+
+export const modelVersionCountMessage = (version, versionCount) => {
+ if (!versionCount) return s__('MlModelRegistry|No registered versions');
+
+ const message = n__(
+ 'MlModelRegistry|%{version} · No other versions',
+ 'MlModelRegistry|%{version} · %{versionCount} versions',
+ versionCount,
+ );
+
+ return sprintf(message, { version, versionCount });
+};
diff --git a/app/assets/javascripts/notes/components/email_participants_warning.vue b/app/assets/javascripts/notes/components/email_participants_warning.vue
index cf9108992be..478c5847b41 100644
--- a/app/assets/javascripts/notes/components/email_participants_warning.vue
+++ b/app/assets/javascripts/notes/components/email_participants_warning.vue
@@ -1,11 +1,12 @@
<script>
-import { GlSprintf } from '@gitlab/ui';
+import { GlSprintf, GlButton } from '@gitlab/ui';
import { toNounSeriesText } from '~/lib/utils/grammar';
import { s__, sprintf } from '~/locale';
export default {
components: {
GlSprintf,
+ GlButton,
},
props: {
emails: {
@@ -58,9 +59,9 @@ export default {
<div class="issuable-note-warning">
<gl-sprintf :message="message">
<template #andMore>
- <button type="button" class="gl-button btn-link" @click="showMoreParticipants">
+ <gl-button variant="link" class="gl-vertical-align-baseline" @click="showMoreParticipants">
{{ moreLabel }}
- </button>
+ </gl-button>
</template>
<template #emails>
<span>{{ title }}</span>
diff --git a/app/assets/javascripts/organizations/mock_data.js b/app/assets/javascripts/organizations/mock_data.js
index b73c18f19ab..d281a0d8a1c 100644
--- a/app/assets/javascripts/organizations/mock_data.js
+++ b/app/assets/javascripts/organizations/mock_data.js
@@ -280,3 +280,11 @@ export const organizationGroups = {
},
],
};
+
+export const createOrganizationResponse = {
+ organization: {
+ name: 'Default',
+ path: '/-/organizations/default',
+ },
+ errors: [],
+};
diff --git a/app/assets/javascripts/organizations/new/components/app.vue b/app/assets/javascripts/organizations/new/components/app.vue
new file mode 100644
index 00000000000..e97626ef4f8
--- /dev/null
+++ b/app/assets/javascripts/organizations/new/components/app.vue
@@ -0,0 +1,73 @@
+<script>
+import { GlSprintf, GlLink } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import { visitUrl } from '~/lib/utils/url_utility';
+import { createAlert } from '~/alert';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import createOrganizationMutation from '../graphql/mutations/create_organization.mutation.graphql';
+import NewEditForm from '../../shared/components/new_edit_form.vue';
+
+export default {
+ name: 'OrganizationNewApp',
+ components: { NewEditForm, GlSprintf, GlLink },
+ i18n: {
+ pageTitle: s__('Organization|New organization'),
+ pageDescription: s__(
+ 'Organization|%{linkStart}Organizations%{linkEnd} are a top-level container to hold your groups and projects.',
+ ),
+ errorMessage: s__('Organization|An error occurred creating an organization. Please try again.'),
+ },
+ data() {
+ return {
+ loading: false,
+ };
+ },
+ computed: {
+ organizationsHelpPagePath() {
+ return helpPagePath('user/organization/index');
+ },
+ },
+ methods: {
+ async onSubmit(formValues) {
+ this.loading = true;
+ try {
+ const {
+ data: {
+ createOrganization: { organization, errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: createOrganizationMutation,
+ variables: {
+ ...formValues,
+ },
+ });
+
+ if (errors.length) {
+ // TODO: handle errors when using real API after https://gitlab.com/gitlab-org/gitlab/-/issues/417891 is complete.
+ return;
+ }
+
+ visitUrl(organization.path);
+ } catch (error) {
+ createAlert({ message: this.$options.i18n.errorMessage, error, captureError: true });
+ } finally {
+ this.loading = false;
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="gl-py-6">
+ <h1 class="gl-mt-0 gl-font-size-h-display">{{ $options.i18n.pageTitle }}</h1>
+ <p>
+ <gl-sprintf :message="$options.i18n.pageDescription">
+ <template #link="{ content }"
+ ><gl-link :href="organizationsHelpPagePath">{{ content }}</gl-link></template
+ >
+ </gl-sprintf>
+ </p>
+ <new-edit-form :loading="loading" @submit="onSubmit" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/organizations/new/graphql/mutations/create_organization.mutation.graphql b/app/assets/javascripts/organizations/new/graphql/mutations/create_organization.mutation.graphql
new file mode 100644
index 00000000000..766c7e96d14
--- /dev/null
+++ b/app/assets/javascripts/organizations/new/graphql/mutations/create_organization.mutation.graphql
@@ -0,0 +1,9 @@
+mutation createOrganization($input: LocalCreateOrganizationInput!) {
+ createOrganization(input: $input) @client {
+ organization {
+ name
+ path
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/organizations/new/graphql/typedefs.graphql b/app/assets/javascripts/organizations/new/graphql/typedefs.graphql
new file mode 100644
index 00000000000..f708c4ad162
--- /dev/null
+++ b/app/assets/javascripts/organizations/new/graphql/typedefs.graphql
@@ -0,0 +1,5 @@
+# TODO: Use real input type when https://gitlab.com/gitlab-org/gitlab/-/issues/417891 is complete.
+input LocalCreateOrganizationInput {
+ name: String
+ path: String
+}
diff --git a/app/assets/javascripts/organizations/new/index.js b/app/assets/javascripts/organizations/new/index.js
new file mode 100644
index 00000000000..a65603227f6
--- /dev/null
+++ b/app/assets/javascripts/organizations/new/index.js
@@ -0,0 +1,35 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import createDefaultClient from '~/lib/graphql';
+import resolvers from '../shared/graphql/resolvers';
+import App from './components/app.vue';
+
+export const initOrganizationsNew = () => {
+ const el = document.getElementById('js-organizations-new');
+
+ if (!el) return false;
+
+ const {
+ dataset: { appData },
+ } = el;
+ const { organizationsPath, rootUrl } = convertObjectPropsToCamelCase(JSON.parse(appData));
+
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(resolvers),
+ });
+
+ return new Vue({
+ el,
+ name: 'OrganizationNewRoot',
+ apolloProvider,
+ provide: {
+ organizationsPath,
+ rootUrl,
+ },
+ render(createElement) {
+ return createElement(App);
+ },
+ });
+};
diff --git a/app/assets/javascripts/organizations/shared/components/new_edit_form.vue b/app/assets/javascripts/organizations/shared/components/new_edit_form.vue
new file mode 100644
index 00000000000..db33f240966
--- /dev/null
+++ b/app/assets/javascripts/organizations/shared/components/new_edit_form.vue
@@ -0,0 +1,125 @@
+<script>
+import {
+ GlForm,
+ GlFormFields,
+ GlButton,
+ GlFormInputGroup,
+ GlFormInput,
+ GlInputGroupText,
+ GlTruncate,
+} from '@gitlab/ui';
+import { formValidators } from '@gitlab/ui/dist/utils';
+import { s__, __ } from '~/locale';
+import { slugify } from '~/lib/utils/text_utility';
+import { joinPaths } from '~/lib/utils/url_utility';
+
+export default {
+ name: 'NewEditForm',
+ components: {
+ GlForm,
+ GlFormFields,
+ GlButton,
+ GlFormInputGroup,
+ GlFormInput,
+ GlInputGroupText,
+ GlTruncate,
+ },
+ i18n: {
+ createOrganization: s__('Organization|Create organization'),
+ cancel: __('Cancel'),
+ pathPlaceholder: s__('Organization|my-organization'),
+ },
+ formId: 'new-organization-form',
+ fields: {
+ name: {
+ label: s__('Organization|Organization name'),
+ validators: [formValidators.required(s__('Organization|Organization name is required.'))],
+ groupAttrs: {
+ description: s__(
+ 'Organization|Must start with a letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses.',
+ ),
+ },
+ inputAttrs: {
+ class: 'gl-md-form-input-lg',
+ placeholder: s__('Organization|My organization'),
+ },
+ },
+ path: {
+ label: s__('Organization|Organization URL'),
+ validators: [formValidators.required(s__('Organization|Organization URL is required.'))],
+ },
+ },
+ inject: ['organizationsPath', 'rootUrl'],
+ props: {
+ loading: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ formValues: {
+ name: '',
+ path: '',
+ },
+ hasPathBeenManuallySet: false,
+ };
+ },
+ computed: {
+ baseUrl() {
+ return joinPaths(this.rootUrl, this.organizationsPath, '/');
+ },
+ },
+ watch: {
+ 'formValues.name': function watchName(value) {
+ if (this.hasPathBeenManuallySet) {
+ return;
+ }
+
+ this.formValues.path = slugify(value);
+ },
+ },
+ methods: {
+ onPathInput(event, formFieldsInputEvent) {
+ formFieldsInputEvent(event);
+ this.hasPathBeenManuallySet = true;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-form :id="$options.formId">
+ <gl-form-fields
+ v-model="formValues"
+ :form-id="$options.formId"
+ :fields="$options.fields"
+ @submit="$emit('submit', formValues)"
+ >
+ <template #input(path)="{ id, value, validation, input, blur }">
+ <gl-form-input-group>
+ <template #prepend>
+ <gl-input-group-text class="organization-root-path">
+ <gl-truncate :text="baseUrl" position="middle" />
+ </gl-input-group-text>
+ </template>
+ <gl-form-input
+ v-bind="validation"
+ :id="id"
+ :value="value"
+ :placeholder="$options.i18n.pathPlaceholder"
+ class="gl-h-auto! gl-md-form-input-lg"
+ @input="onPathInput($event, input)"
+ @blur="blur"
+ />
+ </gl-form-input-group>
+ </template>
+ </gl-form-fields>
+ <div class="gl-display-flex gl-gap-3">
+ <gl-button type="submit" variant="confirm" class="js-no-auto-disable" :loading="loading">{{
+ $options.i18n.createOrganization
+ }}</gl-button>
+ <gl-button :href="organizationsPath">{{ $options.i18n.cancel }}</gl-button>
+ </div>
+ </gl-form>
+</template>
diff --git a/app/assets/javascripts/organizations/shared/graphql/resolvers.js b/app/assets/javascripts/organizations/shared/graphql/resolvers.js
index 318b41647bc..9f7e9b22e1d 100644
--- a/app/assets/javascripts/organizations/shared/graphql/resolvers.js
+++ b/app/assets/javascripts/organizations/shared/graphql/resolvers.js
@@ -1,4 +1,9 @@
-import { organizations, organizationProjects, organizationGroups } from '../../mock_data';
+import {
+ organizations,
+ organizationProjects,
+ organizationGroups,
+ createOrganizationResponse,
+} from '../../mock_data';
const simulateLoading = () => {
return new Promise((resolve) => {
@@ -28,4 +33,12 @@ export default {
};
},
},
+ Mutation: {
+ createOrganization: async () => {
+ // Simulate API loading
+ await simulateLoading();
+
+ return createOrganizationResponse;
+ },
+ },
};
diff --git a/app/assets/javascripts/pages/organizations/organizations/new/index.js b/app/assets/javascripts/pages/organizations/organizations/new/index.js
new file mode 100644
index 00000000000..ab23fbf155d
--- /dev/null
+++ b/app/assets/javascripts/pages/organizations/organizations/new/index.js
@@ -0,0 +1,3 @@
+import { initOrganizationsNew } from '~/organizations/new';
+
+initOrganizationsNew();
diff --git a/app/assets/javascripts/vue_shared/components/incubation/pagination.vue b/app/assets/javascripts/vue_shared/components/incubation/pagination.vue
index b5afe92316a..6b70e9f3ed9 100644
--- a/app/assets/javascripts/vue_shared/components/incubation/pagination.vue
+++ b/app/assets/javascripts/vue_shared/components/incubation/pagination.vue
@@ -57,6 +57,7 @@ export default {
:next-text="$options.i18n.nextPageButtonLabel"
:prev-button-link="previousPageLink"
:next-button-link="nextPageLink"
+ class="gl-mt-4"
/>
</div>
</template>
diff --git a/app/assets/stylesheets/page_bundles/organizations.scss b/app/assets/stylesheets/page_bundles/organizations.scss
index 7591be064c6..1f1d127a82a 100644
--- a/app/assets/stylesheets/page_bundles/organizations.scss
+++ b/app/assets/stylesheets/page_bundles/organizations.scss
@@ -4,3 +4,7 @@
.organization-row .organization-description p {
@include gl-mb-0;
}
+
+.organization-root-path {
+ max-width: 40vw;
+}
diff --git a/app/components/projects/ml/models_index_component.rb b/app/components/projects/ml/models_index_component.rb
index 8569d26945c..57900165ad1 100644
--- a/app/components/projects/ml/models_index_component.rb
+++ b/app/components/projects/ml/models_index_component.rb
@@ -25,6 +25,7 @@ module Projects
{
name: m.name,
version: m.latest_version_name,
+ version_count: m.version_count,
path: m.latest_package_path
}
end
diff --git a/app/finders/concerns/packages/finder_helper.rb b/app/finders/concerns/packages/finder_helper.rb
index 0ae99782cd3..585b35981a6 100644
--- a/app/finders/concerns/packages/finder_helper.rb
+++ b/app/finders/concerns/packages/finder_helper.rb
@@ -13,11 +13,13 @@ module Packages
project.packages.installable
end
- def packages_visible_to_user(user, within_group:)
+ def packages_visible_to_user(user, within_group:, with_package_registry_enabled: false)
return ::Packages::Package.none unless within_group
return ::Packages::Package.none unless Ability.allowed?(user, :read_group, within_group)
projects = projects_visible_to_reporters(user, within_group: within_group)
+ projects = projects.with_package_registry_enabled if with_package_registry_enabled
+
::Packages::Package.for_projects(projects.select(:id)).installable
end
diff --git a/app/finders/packages/npm/packages_for_user_finder.rb b/app/finders/packages/npm/packages_for_user_finder.rb
index f42e49f9184..dc1d3b6e7fe 100644
--- a/app/finders/packages/npm/packages_for_user_finder.rb
+++ b/app/finders/packages/npm/packages_for_user_finder.rb
@@ -3,6 +3,8 @@
module Packages
module Npm
class PackagesForUserFinder < ::Packages::GroupOrProjectPackageFinder
+ extend ::Gitlab::Utils::Override
+
def execute
packages
end
@@ -13,6 +15,11 @@ module Packages
base.npm
.with_name(@params[:package_name])
end
+
+ override :group_packages
+ def group_packages
+ packages_visible_to_user(@current_user, within_group: @project_or_group, with_package_registry_enabled: true)
+ end
end
end
end
diff --git a/app/finders/projects/ml/model_finder.rb b/app/finders/projects/ml/model_finder.rb
index 004fd20403d..1e407ba4aa4 100644
--- a/app/finders/projects/ml/model_finder.rb
+++ b/app/finders/projects/ml/model_finder.rb
@@ -11,6 +11,7 @@ module Projects
::Ml::Model
.by_project(@project)
.including_latest_version
+ .with_version_count
end
end
end
diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb
index a88be976337..510561ec614 100644
--- a/app/helpers/integrations_helper.rb
+++ b/app/helpers/integrations_helper.rb
@@ -30,10 +30,6 @@ module IntegrationsHelper
_("Alert")
when "incident"
_("Incident")
- when "group_mention"
- _("Group mention in public")
- when "group_confidential_mention"
- _("Group mention in private")
end
end
# rubocop:enable Metrics/CyclomaticComplexity
@@ -295,10 +291,6 @@ module IntegrationsHelper
s_("ProjectService|Trigger event when a new, unique alert is recorded.")
when "incident", "incident_events"
s_("ProjectService|Trigger event when an incident is created.")
- when "group_mention"
- s_("ProjectService|Trigger event when a group is mentioned in a public context.")
- when "group_confidential_mention"
- s_("ProjectService|Trigger event when a group is mentioned in a confidential context.")
when "build_events"
s_("ProjectService|Trigger event when a build is created.")
when "archive_trace_events"
diff --git a/app/helpers/organizations/organization_helper.rb b/app/helpers/organizations/organization_helper.rb
index 0f760d87173..5d89bb93000 100644
--- a/app/helpers/organizations/organization_helper.rb
+++ b/app/helpers/organizations/organization_helper.rb
@@ -16,6 +16,13 @@ module Organizations
}.merge(shared_groups_and_projects_app_data).to_json
end
+ def organization_new_app_data
+ {
+ organizations_path: organizations_path,
+ root_url: root_url
+ }.to_json
+ end
+
def organization_groups_and_projects_app_data
shared_groups_and_projects_app_data.to_json
end
diff --git a/app/models/ci/catalog/components_project.rb b/app/models/ci/catalog/components_project.rb
new file mode 100644
index 00000000000..2bc33a6f050
--- /dev/null
+++ b/app/models/ci/catalog/components_project.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+module Ci
+ module Catalog
+ class ComponentsProject
+ # ComponentsProject is a type of Catalog Resource which contains one or more
+ # CI/CD components.
+ # It is responsible for retrieving the data of a component file, including the content, name, and file path.
+
+ TEMPLATE_FILE = 'template.yml'
+ TEMPLATES_DIR = 'templates'
+ TEMPLATE_PATH_REGEX = '^templates\/\w+\-?\w+(?:\/template)?\.yml$'
+
+ ComponentData = Struct.new(:content, :path, keyword_init: true)
+
+ def initialize(project, sha = project&.default_branch)
+ @project = project
+ @sha = sha
+ end
+
+ def fetch_component_paths(sha)
+ project.repository.search_files_by_regexp(TEMPLATE_PATH_REGEX, sha)
+ end
+
+ def extract_component_name(path)
+ return unless path.match?(TEMPLATE_PATH_REGEX)
+
+ dirname = File.dirname(path)
+ filename = File.basename(path, '.*')
+
+ if dirname == TEMPLATES_DIR
+ filename
+ else
+ File.basename(dirname)
+ end
+ end
+
+ def extract_inputs(blob)
+ result = Gitlab::Ci::Config::Yaml::Loader.new(blob).load_uninterpolated_yaml
+
+ raise result.error_class, result.error unless result.valid?
+
+ result.inputs
+ end
+
+ def fetch_component(component_name)
+ path = simple_template_path(component_name)
+ content = fetch_content(path)
+
+ if content.nil?
+ path = complex_template_path(component_name)
+ content = fetch_content(path)
+ end
+
+ if content.nil?
+ path = legacy_template_path(component_name)
+ content = fetch_content(path)
+ end
+
+ ComponentData.new(content: content, path: path)
+ end
+
+ private
+
+ attr_reader :project, :sha
+
+ def fetch_content(component_path)
+ project.repository.blob_data_at(sha, component_path)
+ end
+
+ # A simple template consists of a single file
+ def simple_template_path(component_name)
+ # TODO: Extract this line and move to fetch_content once we remove legacy fetching
+ return unless component_name.index('/').nil?
+
+ File.join(TEMPLATES_DIR, "#{component_name}.yml")
+ end
+
+ # A complex template is directory-based and may consist of multiple files.
+ # Given a path like "my-org/sub-group/the-project/templates/component"
+ # returns the entry point path: "templates/component/template.yml".
+ def complex_template_path(component_name)
+ # TODO: Extract this line and move to fetch_content once we remove legacy fetching
+ return unless component_name.index('/').nil?
+
+ File.join(TEMPLATES_DIR, component_name, TEMPLATE_FILE)
+ end
+
+ def legacy_template_path(component_name)
+ File.join(component_name, TEMPLATE_FILE).delete_prefix('/')
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/pushover.rb b/app/models/integrations/pushover.rb
index e97c7e5e738..2feae29f627 100644
--- a/app/models/integrations/pushover.rb
+++ b/app/models/integrations/pushover.rb
@@ -125,5 +125,9 @@ module Integrations
Gitlab::HTTP.post('/messages.json', base_uri: BASE_URI, body: pushover_data)
end
+
+ def avatar_url
+ ActionController::Base.helpers.image_path('illustrations/third-party-logos/integrations-logos/pushover.svg')
+ end
end
end
diff --git a/app/models/ml/model.rb b/app/models/ml/model.rb
index 0680bb0d381..27f03ed5857 100644
--- a/app/models/ml/model.rb
+++ b/app/models/ml/model.rb
@@ -19,6 +19,11 @@ module Ml
has_one :latest_version, -> { latest_by_model }, class_name: 'Ml::ModelVersion', inverse_of: :model
scope :including_latest_version, -> { includes(:latest_version) }
+ scope :with_version_count, -> {
+ left_outer_joins(:versions)
+ .select("ml_models.*, count(ml_model_versions.id) as version_count")
+ .group(:id)
+ }
scope :by_project, ->(project) { where(project_id: project.id) }
def valid_default_experiment?
diff --git a/app/models/project.rb b/app/models/project.rb
index 6c12c85d45d..fd226d23e77 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -753,6 +753,7 @@ class Project < ApplicationRecord
scope :service_desk_enabled, -> { where(service_desk_enabled: true) }
scope :with_builds_enabled, -> { with_feature_enabled(:builds) }
scope :with_issues_enabled, -> { with_feature_enabled(:issues) }
+ scope :with_package_registry_enabled, -> { with_feature_enabled(:package_registry) }
scope :with_issues_available_for_user, ->(current_user) { with_feature_available_for_user(:issues, current_user) }
scope :with_merge_requests_available_for_user, ->(current_user) { with_feature_available_for_user(:merge_requests, current_user) }
scope :with_issues_or_mrs_available_for_user, -> (user) do
diff --git a/app/services/ci/components/fetch_service.rb b/app/services/ci/components/fetch_service.rb
index 45abb415174..4f09d47b530 100644
--- a/app/services/ci/components/fetch_service.rb
+++ b/app/services/ci/components/fetch_service.rb
@@ -5,8 +5,6 @@ module Ci
class FetchService
include Gitlab::Utils::StrongMemoize
- TEMPLATE_FILE = 'template.yml'
-
COMPONENT_PATHS = [
::Gitlab::Ci::Components::InstancePath
].freeze
@@ -23,11 +21,16 @@ module Ci
reason: :unsupported_path)
end
- component_path = component_path_class.new(address: address, content_filename: TEMPLATE_FILE)
- content = component_path.fetch_content!(current_user: current_user)
+ component_path = component_path_class.new(address: address)
+ result = component_path.fetch_content!(current_user: current_user)
- if content.present?
- ServiceResponse.success(payload: { content: content, path: component_path })
+ if result
+ ServiceResponse.success(payload: {
+ content: result.content,
+ path: result.path,
+ project: component_path.project,
+ sha: component_path.sha
+ })
else
ServiceResponse.error(message: "#{error_prefix} content not found", reason: :content_not_found)
end
diff --git a/app/services/ml/find_or_create_model_version_service.rb b/app/services/ml/find_or_create_model_version_service.rb
index 1316b2546b9..f4d3f3e72d3 100644
--- a/app/services/ml/find_or_create_model_version_service.rb
+++ b/app/services/ml/find_or_create_model_version_service.rb
@@ -11,7 +11,6 @@ module Ml
def execute
model = Ml::FindOrCreateModelService.new(project, name).execute
-
Ml::ModelVersion.find_or_create!(model, version, package)
end
diff --git a/app/views/organizations/organizations/new.html.haml b/app/views/organizations/organizations/new.html.haml
index 4d7f552c87b..1a6c5a79ff6 100644
--- a/app/views/organizations/organizations/new.html.haml
+++ b/app/views/organizations/organizations/new.html.haml
@@ -1,3 +1,6 @@
+- add_page_specific_style 'page_bundles/organizations'
- page_title s_('Organization|New organization')
- header_title _("Your work"), root_path
- add_to_breadcrumbs s_('Organization|Organizations'), organizations_path
+
+#js-organizations-new{ data: { app_data: organization_new_app_data } }
diff --git a/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb b/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
index 98bb259db0a..8bcbe9d6c9f 100644
--- a/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
+++ b/app/workers/ci/merge_requests/add_todo_when_build_fails_worker.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Ci
module MergeRequests
class AddTodoWhenBuildFailsWorker
diff --git a/app/workers/concerns/auto_devops_queue.rb b/app/workers/concerns/auto_devops_queue.rb
index 61e3c1544bd..cdf429a8be5 100644
--- a/app/workers/concerns/auto_devops_queue.rb
+++ b/app/workers/concerns/auto_devops_queue.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-#
+
module AutoDevopsQueue
extend ActiveSupport::Concern
diff --git a/app/workers/concerns/chaos_queue.rb b/app/workers/concerns/chaos_queue.rb
index 23e58b5182b..9a3d518dda8 100644
--- a/app/workers/concerns/chaos_queue.rb
+++ b/app/workers/concerns/chaos_queue.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-#
+
module ChaosQueue
extend ActiveSupport::Concern
diff --git a/app/workers/concerns/limited_capacity/job_tracker.rb b/app/workers/concerns/limited_capacity/job_tracker.rb
index 4b5ce8a01f6..b4d884f914d 100644
--- a/app/workers/concerns/limited_capacity/job_tracker.rb
+++ b/app/workers/concerns/limited_capacity/job_tracker.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module LimitedCapacity
class JobTracker # rubocop:disable Scalability/IdempotentWorker
include Gitlab::Utils::StrongMemoize
diff --git a/app/workers/database/batched_background_migration/ci_database_worker.rb b/app/workers/database/batched_background_migration/ci_database_worker.rb
index 58b0f5496f4..417af4c7172 100644
--- a/app/workers/database/batched_background_migration/ci_database_worker.rb
+++ b/app/workers/database/batched_background_migration/ci_database_worker.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Database
module BatchedBackgroundMigration
class CiDatabaseWorker # rubocop:disable Scalability/IdempotentWorker
diff --git a/app/workers/gitlab/github_gists_import/import_gist_worker.rb b/app/workers/gitlab/github_gists_import/import_gist_worker.rb
index 60e4c8fdad6..151788150dd 100644
--- a/app/workers/gitlab/github_gists_import/import_gist_worker.rb
+++ b/app/workers/gitlab/github_gists_import/import_gist_worker.rb
@@ -106,9 +106,9 @@ module Gitlab
def error(user_id, error_message, github_identifiers)
attributes = {
user_id: user_id,
- github_identifiers: github_identifiers,
+ external_identifiers: github_identifiers,
message: 'importer failed',
- 'error.message': error_message
+ 'exception.message': error_message
}
Gitlab::GithubImport::Logger.error(structured_payload(attributes))
@@ -120,7 +120,7 @@ module Gitlab
attributes = {
user_id: user_id,
message: message,
- github_identifiers: gist_id
+ external_identifiers: gist_id
}
Gitlab::GithubImport::Logger.info(structured_payload(attributes))
diff --git a/app/workers/gitlab/github_gists_import/start_import_worker.rb b/app/workers/gitlab/github_gists_import/start_import_worker.rb
index 33c91611719..f7d3eb1d759 100644
--- a/app/workers/gitlab/github_gists_import/start_import_worker.rb
+++ b/app/workers/gitlab/github_gists_import/start_import_worker.rb
@@ -51,7 +51,7 @@ module Gitlab
end
def log_error_and_raise!(user_id, error)
- logger.error(structured_payload(user_id: user_id, message: 'import failed', 'error.message': error.message))
+ logger.error(structured_payload(user_id: user_id, message: 'import failed', 'exception.message': error.message))
raise(error)
end
diff --git a/app/workers/gitlab/import/stuck_project_import_jobs_worker.rb b/app/workers/gitlab/import/stuck_project_import_jobs_worker.rb
index 01979b2029f..93d670e1b8b 100644
--- a/app/workers/gitlab/import/stuck_project_import_jobs_worker.rb
+++ b/app/workers/gitlab/import/stuck_project_import_jobs_worker.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
module Gitlab
module Import
class StuckProjectImportJobsWorker # rubocop:disable Scalability/IdempotentWorker
diff --git a/app/workers/projects/after_import_worker.rb b/app/workers/projects/after_import_worker.rb
index 06211b2d991..47bd07d0850 100644
--- a/app/workers/projects/after_import_worker.rb
+++ b/app/workers/projects/after_import_worker.rb
@@ -31,7 +31,7 @@ module Projects
message: 'Project housekeeping failed',
project_full_path: @project.full_path,
project_id: @project.id,
- 'error.message' => e.message
+ 'exception.message' => e.message
)
end