diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-02 18:09:47 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-02 18:09:47 +0000 |
commit | 0a9b6b99a9bdcacea434501320f1a8d131a33827 (patch) | |
tree | b3fb338cec894837358b82635c90a52f5b8e0c3d | |
parent | d944f09d3212ca8aad09b92dbbae7323ee634237 (diff) | |
download | gitlab-ce-0a9b6b99a9bdcacea434501320f1a8d131a33827.tar.gz |
Add latest changes from gitlab-org/gitlab@master
128 files changed, 624 insertions, 337 deletions
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml index 2864014e17e..54e7e063842 100644 --- a/.gitlab/ci/qa.gitlab-ci.yml +++ b/.gitlab/ci/qa.gitlab-ci.yml @@ -67,6 +67,7 @@ qa:update-qa-cache: e2e:package-and-test: extends: + - .production # this makes sure GITLAB_ALLOW_SEPARATE_CI_DATABASE is passed to the child pipeline - .qa:rules:package-and-test stage: qa needs: diff --git a/.gitlab/issue_templates/Feature Proposal - basic.md b/.gitlab/issue_templates/Feature Proposal - basic.md index b447bcfe0ae..e9815d85f9b 100644 --- a/.gitlab/issue_templates/Feature Proposal - basic.md +++ b/.gitlab/issue_templates/Feature Proposal - basic.md @@ -9,6 +9,7 @@ <!-- Label reminders Use the following resources to find the appropriate labels: +- Use only one tier label choosing the lowest tier this is intended for - https://gitlab.com/gitlab-org/gitlab/-/labels - https://about.gitlab.com/handbook/product/categories/features/ --> diff --git a/.gitlab/issue_templates/Feature Proposal - lean.md b/.gitlab/issue_templates/Feature Proposal - lean.md index c902c254618..3997ffa5c85 100644 --- a/.gitlab/issue_templates/Feature Proposal - lean.md +++ b/.gitlab/issue_templates/Feature Proposal - lean.md @@ -48,6 +48,7 @@ Create tracking issue using the Snowplow event tracking template. See https://gi <!-- Label reminders Use the following resources to find the appropriate labels: +- Use only one tier label choosing the lowest tier this is intended for - https://gitlab.com/gitlab-org/gitlab/-/labels - https://about.gitlab.com/handbook/product/categories/features/ --> diff --git a/.gitlab/issue_templates/Feature proposal - detailed.md b/.gitlab/issue_templates/Feature proposal - detailed.md index 9eac2ca27c5..dcf6d417155 100644 --- a/.gitlab/issue_templates/Feature proposal - detailed.md +++ b/.gitlab/issue_templates/Feature proposal - detailed.md @@ -125,6 +125,7 @@ In which enterprise tier should this feature go? See https://about.gitlab.com/ha <!-- Label reminders - you should have one of each of the following labels. Use the following resources to find the appropriate labels: +- Use only one tier label choosing the lowest tier this is intended for - https://gitlab.com/gitlab-org/gitlab/-/labels - https://about.gitlab.com/handbook/product/categories/features/ --> diff --git a/.rubocop_todo/style/arguments_forwarding.yml b/.rubocop_todo/style/arguments_forwarding.yml index 3f3bc958a7d..d3096575481 100644 --- a/.rubocop_todo/style/arguments_forwarding.yml +++ b/.rubocop_todo/style/arguments_forwarding.yml @@ -3,31 +3,6 @@ Style/ArgumentsForwarding: Details: grace period Exclude: - - 'app/finders/access_requests_finder.rb' - - 'app/finders/concerns/finder_methods.rb' - - 'app/finders/members_finder.rb' - - 'app/graphql/resolvers/concerns/resolves_groups.rb' - - 'app/helpers/json_helper.rb' - - 'app/helpers/routing/snippets_helper.rb' - - 'app/helpers/tree_helper.rb' - - 'app/models/commit.rb' - - 'app/models/compare.rb' - - 'app/models/concerns/integrations/has_web_hook.rb' - - 'app/models/concerns/noteable.rb' - - 'app/models/concerns/reactive_caching.rb' - - 'app/models/legacy_diff_discussion.rb' - - 'app/models/repository.rb' - - 'app/presenters/merge_request_presenter.rb' - - 'app/presenters/project_presenter.rb' - - 'app/presenters/user_presenter.rb' - - 'app/serializers/analytics/cycle_analytics/stage_entity.rb' - - 'app/services/event_create_service.rb' - - 'app/services/notification_recipients/build_service.rb' - - 'app/services/notification_service.rb' - - 'app/services/system_notes/base_service.rb' - - 'app/workers/ci/schedule_delete_objects_cron_worker.rb' - - 'app/workers/concerns/gitlab/github_import/rescheduling_methods.rb' - - 'app/workers/concerns/limited_capacity/worker.rb' - 'ee/app/models/concerns/geo/repository_replicator_strategy.rb' - 'ee/app/serializers/security/vulnerability_report_data_entity.rb' - 'ee/app/services/status_page/publish_base_service.rb' diff --git a/app/assets/javascripts/boards/boards_util.js b/app/assets/javascripts/boards/boards_util.js index c597ffb18ea..42e4cf2d39b 100644 --- a/app/assets/javascripts/boards/boards_util.js +++ b/app/assets/javascripts/boards/boards_util.js @@ -1,5 +1,10 @@ import { sortBy, cloneDeep } from 'lodash'; -import { TYPE_BOARD, TYPE_ITERATION, TYPE_MILESTONE, TYPE_USER } from '~/graphql_shared/constants'; +import { + TYPENAME_BOARD, + TYPENAME_ITERATION, + TYPE_MILESTONE, + TYPE_USER, +} from '~/graphql_shared/constants'; import { isGid, convertToGraphQLId } from '~/graphql_shared/utils'; import { ListType, @@ -86,11 +91,11 @@ export function fullBoardId(boardId) { if (!boardId) { return null; } - return convertToGraphQLId(TYPE_BOARD, boardId); + return convertToGraphQLId(TYPENAME_BOARD, boardId); } export function fullIterationId(id) { - return convertToGraphQLId(TYPE_ITERATION, id); + return convertToGraphQLId(TYPENAME_ITERATION, id); } export function fullUserId(id) { diff --git a/app/assets/javascripts/ci/runner/admin_runner_show/admin_runner_show_app.vue b/app/assets/javascripts/ci/runner/admin_runner_show/admin_runner_show_app.vue index 75c3c4e23f1..8d4303778af 100644 --- a/app/assets/javascripts/ci/runner/admin_runner_show/admin_runner_show_app.vue +++ b/app/assets/javascripts/ci/runner/admin_runner_show/admin_runner_show_app.vue @@ -1,6 +1,6 @@ <script> import { createAlert, VARIANT_SUCCESS } from '~/flash'; -import { TYPE_CI_RUNNER } from '~/graphql_shared/constants'; +import { TYPENAME_CI_RUNNER } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { redirectTo } from '~/lib/utils/url_utility'; @@ -44,7 +44,7 @@ export default { query: runnerQuery, variables() { return { - id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId), + id: convertToGraphQLId(TYPENAME_CI_RUNNER, this.runnerId), }; }, error(error) { diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue b/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue index 6740065e860..6d2b9ce6efa 100644 --- a/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue +++ b/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue @@ -1,7 +1,7 @@ <script> import { GlDropdownItem, GlLoadingIcon, GlModal, GlModalDirective } from '@gitlab/ui'; import { createAlert } from '~/flash'; -import { TYPE_GROUP, TYPE_PROJECT } from '~/graphql_shared/constants'; +import { TYPENAME_GROUP, TYPE_PROJECT } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { __, s__ } from '~/locale'; import runnersRegistrationTokenResetMutation from '~/ci/runner/graphql/list/runners_registration_token_reset.mutation.graphql'; @@ -58,7 +58,7 @@ export default { }; case GROUP_TYPE: return { - id: convertToGraphQLId(TYPE_GROUP, this.groupId), + id: convertToGraphQLId(TYPENAME_GROUP, this.groupId), type: this.type, }; case PROJECT_TYPE: diff --git a/app/assets/javascripts/ci/runner/group_runner_show/group_runner_show_app.vue b/app/assets/javascripts/ci/runner/group_runner_show/group_runner_show_app.vue index 872c9926935..273a9aa823c 100644 --- a/app/assets/javascripts/ci/runner/group_runner_show/group_runner_show_app.vue +++ b/app/assets/javascripts/ci/runner/group_runner_show/group_runner_show_app.vue @@ -1,6 +1,6 @@ <script> import { createAlert, VARIANT_SUCCESS } from '~/flash'; -import { TYPE_CI_RUNNER } from '~/graphql_shared/constants'; +import { TYPENAME_CI_RUNNER } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { redirectTo } from '~/lib/utils/url_utility'; @@ -49,7 +49,7 @@ export default { query: runnerQuery, variables() { return { - id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId), + id: convertToGraphQLId(TYPENAME_CI_RUNNER, this.runnerId), }; }, error(error) { diff --git a/app/assets/javascripts/ci/runner/runner_edit/runner_edit_app.vue b/app/assets/javascripts/ci/runner/runner_edit/runner_edit_app.vue index 879162916a9..4593c9ae52b 100644 --- a/app/assets/javascripts/ci/runner/runner_edit/runner_edit_app.vue +++ b/app/assets/javascripts/ci/runner/runner_edit/runner_edit_app.vue @@ -1,6 +1,6 @@ <script> import { createAlert } from '~/flash'; -import { TYPE_CI_RUNNER } from '~/graphql_shared/constants'; +import { TYPENAME_CI_RUNNER } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import RunnerHeader from '../components/runner_header.vue'; import RunnerUpdateForm from '../components/runner_update_form.vue'; @@ -35,7 +35,7 @@ export default { query: runnerFormQuery, variables() { return { - id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId), + id: convertToGraphQLId(TYPENAME_CI_RUNNER, this.runnerId), }; }, error(error) { diff --git a/app/assets/javascripts/crm/contacts/components/contact_form_wrapper.vue b/app/assets/javascripts/crm/contacts/components/contact_form_wrapper.vue index a851c7a9e85..57931121629 100644 --- a/app/assets/javascripts/crm/contacts/components/contact_form_wrapper.vue +++ b/app/assets/javascripts/crm/contacts/components/contact_form_wrapper.vue @@ -1,7 +1,7 @@ <script> import { s__, __ } from '~/locale'; import { convertToGraphQLId } from '~/graphql_shared/utils'; -import { TYPE_CRM_CONTACT, TYPE_GROUP } from '~/graphql_shared/constants'; +import { TYPENAME_CRM_CONTACT, TYPENAME_GROUP } from '~/graphql_shared/constants'; import CrmForm from '../../components/crm_form.vue'; import getGroupOrganizationsQuery from '../../organizations/components/graphql/get_group_organizations.query.graphql'; import getGroupContactsQuery from './graphql/get_group_contacts.query.graphql'; @@ -44,10 +44,10 @@ export default { contactGraphQLId() { if (!this.isEditMode) return null; - return convertToGraphQLId(TYPE_CRM_CONTACT, this.$route.params.id); + return convertToGraphQLId(TYPENAME_CRM_CONTACT, this.$route.params.id); }, groupGraphQLId() { - return convertToGraphQLId(TYPE_GROUP, this.groupId); + return convertToGraphQLId(TYPENAME_GROUP, this.groupId); }, mutation() { if (this.isEditMode) return updateContactMutation; 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 01bff4b69d6..4d2a038458d 100644 --- a/app/assets/javascripts/crm/organizations/components/organization_form_wrapper.vue +++ b/app/assets/javascripts/crm/organizations/components/organization_form_wrapper.vue @@ -1,7 +1,7 @@ <script> import { s__, __ } from '~/locale'; import { convertToGraphQLId } from '~/graphql_shared/utils'; -import { TYPE_CRM_ORGANIZATION, TYPE_GROUP } from '~/graphql_shared/constants'; +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'; @@ -23,10 +23,10 @@ export default { organizationGraphQLId() { if (!this.isEditMode) return null; - return convertToGraphQLId(TYPE_CRM_ORGANIZATION, this.$route.params.id); + return convertToGraphQLId(TYPENAME_CRM_ORGANIZATION, this.$route.params.id); }, groupGraphQLId() { - return convertToGraphQLId(TYPE_GROUP, this.groupId); + return convertToGraphQLId(TYPENAME_GROUP, this.groupId); }, mutation() { if (this.isEditMode) return updateOrganizationMutation; diff --git a/app/assets/javascripts/graphql_shared/constants.js b/app/assets/javascripts/graphql_shared/constants.js index 22fa2912881..e859c5e6867 100644 --- a/app/assets/javascripts/graphql_shared/constants.js +++ b/app/assets/javascripts/graphql_shared/constants.js @@ -1,15 +1,15 @@ export const MINIMUM_SEARCH_LENGTH = 3; -export const TYPE_BOARD = 'Board'; -export const TYPE_CI_RUNNER = 'Ci::Runner'; -export const TYPE_CRM_CONTACT = 'CustomerRelations::Contact'; -export const TYPE_CRM_ORGANIZATION = 'CustomerRelations::Organization'; -export const TYPE_DISCUSSION = 'Discussion'; -export const TYPE_EPIC = 'Epic'; -export const TYPE_EPIC_BOARD = 'Boards::EpicBoard'; -export const TYPE_GROUP = 'Group'; -export const TYPE_ISSUE = 'Issue'; -export const TYPE_ITERATION = 'Iteration'; +export const TYPENAME_BOARD = 'Board'; +export const TYPENAME_CI_RUNNER = 'Ci::Runner'; +export const TYPENAME_CRM_CONTACT = 'CustomerRelations::Contact'; +export const TYPENAME_CRM_ORGANIZATION = 'CustomerRelations::Organization'; +export const TYPENAME_DISCUSSION = 'Discussion'; +export const TYPENAME_EPIC = 'Epic'; +export const TYPENAME_EPIC_BOARD = 'Boards::EpicBoard'; +export const TYPENAME_GROUP = 'Group'; +export const TYPENAME_ISSUE = 'Issue'; +export const TYPENAME_ITERATION = 'Iteration'; export const TYPE_ITERATIONS_CADENCE = 'Iterations::Cadence'; export const TYPE_MERGE_REQUEST = 'MergeRequest'; export const TYPE_MILESTONE = 'Milestone'; diff --git a/app/assets/javascripts/issues/show/components/description.vue b/app/assets/javascripts/issues/show/components/description.vue index ba0f28d1c7c..b3227999a5a 100644 --- a/app/assets/javascripts/issues/show/components/description.vue +++ b/app/assets/javascripts/issues/show/components/description.vue @@ -119,7 +119,7 @@ export default { }; }, skip() { - return !this.workItemId || !this.workItemsEnabled; + return !this.workItemId || !this.workItemsMvc2Enabled; }, }, workItemTypes: { @@ -133,13 +133,13 @@ export default { return data.workspace?.workItemTypes?.nodes; }, skip() { - return !this.workItemsEnabled; + return !this.workItemsMvc2Enabled; }, }, }, computed: { - workItemsEnabled() { - return this.glFeatures.workItemsCreateFromMarkdown; + workItemsMvc2Enabled() { + return this.glFeatures.workItemsMvc2; }, taskWorkItemType() { return this.workItemTypes.find((type) => type.name === TASK_TYPE_NAME)?.id; @@ -170,7 +170,7 @@ export default { this.renderGFM(); this.updateTaskStatusText(); - if (this.workItemId && this.workItemsEnabled) { + if (this.workItemId && this.workItemsMvc2Enabled) { const taskLink = this.$el.querySelector( `.gfm-issue[data-issue="${getIdFromGraphQLId(this.workItemId)}"]`, ); @@ -202,7 +202,7 @@ export default { this.renderSortableLists(); - if (this.workItemsEnabled) { + if (this.workItemsMvc2Enabled) { this.renderTaskListItemActions(); } } diff --git a/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue b/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue index 81111d42b39..198ff33a249 100644 --- a/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue +++ b/app/assets/javascripts/issues/show/components/incidents/create_timeline_event.vue @@ -5,7 +5,7 @@ import { GlIcon } from '@gitlab/ui'; import { sprintf } from '~/locale'; import { createAlert } from '~/flash'; import { convertToGraphQLId } from '~/graphql_shared/utils'; -import { TYPE_ISSUE } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE } from '~/graphql_shared/constants'; import { timelineFormI18n } from './constants'; import TimelineEventsForm from './timeline_events_form.vue'; @@ -41,7 +41,7 @@ export default { } const variables = { - incidentId: convertToGraphQLId(TYPE_ISSUE, this.issuableId), + incidentId: convertToGraphQLId(TYPENAME_ISSUE, this.issuableId), fullPath: this.fullPath, }; @@ -71,7 +71,7 @@ export default { mutation: CreateTimelineEvent, variables: { input: { - incidentId: convertToGraphQLId(TYPE_ISSUE, this.issuableId), + incidentId: convertToGraphQLId(TYPENAME_ISSUE, this.issuableId), note: eventDetails.note, occurredAt: eventDetails.occurredAt, timelineEventTagNames: eventDetails.timelineEventTags, diff --git a/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue b/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue index c8237766505..cb18d34b70b 100644 --- a/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue +++ b/app/assets/javascripts/issues/show/components/incidents/timeline_events_tab.vue @@ -1,7 +1,7 @@ <script> import { GlButton, GlEmptyState, GlLoadingIcon } from '@gitlab/ui'; import { convertToGraphQLId } from '~/graphql_shared/utils'; -import { TYPE_ISSUE } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE } from '~/graphql_shared/constants'; import { fetchPolicies } from '~/lib/graphql'; import notesEventHub from '~/notes/event_hub'; import getTimelineEvents from './graphql/queries/get_timeline_events.query.graphql'; @@ -33,7 +33,7 @@ export default { variables() { return { fullPath: this.fullPath, - incidentId: convertToGraphQLId(TYPE_ISSUE, this.issuableId), + incidentId: convertToGraphQLId(TYPENAME_ISSUE, this.issuableId), }; }, update(data) { diff --git a/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue b/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue index 0660e4f58e4..c9ecaf4102f 100644 --- a/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue +++ b/app/assets/javascripts/sidebar/components/crm_contacts/crm_contacts.vue @@ -3,7 +3,7 @@ import { GlIcon, GlLink, GlPopover, GlTooltipDirective } from '@gitlab/ui'; import { __, n__, sprintf } from '~/locale'; import { createAlert } from '~/flash'; import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { TYPE_ISSUE } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE } from '~/graphql_shared/constants'; import getIssueCrmContactsQuery from '../../queries/get_issue_crm_contacts.query.graphql'; import issueCrmContactsSubscription from '../../queries/issue_crm_contacts.subscription.graphql'; @@ -65,7 +65,7 @@ export default { return this.contacts?.length; }, queryVariables() { - return { id: convertToGraphQLId(TYPE_ISSUE, this.issueId) }; + return { id: convertToGraphQLId(TYPENAME_ISSUE, this.issueId) }; }, contactsLabel() { return sprintf(n__('%{count} contact', '%{count} contacts', this.contactCount), { diff --git a/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue b/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue index ec8e1ee9952..b85083a8226 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/create_timelog_form.vue @@ -11,7 +11,7 @@ import { } from '@gitlab/ui'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { formatDate } from '~/lib/utils/datetime_utility'; -import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; import { joinPaths } from '~/lib/utils/url_utility'; import { s__ } from '~/locale'; import createTimelogMutation from '../../queries/create_timelog.mutation.graphql'; @@ -130,7 +130,7 @@ export default { return this.issuableType === 'issue'; }, getGraphQLEntityType() { - return this.isIssue() ? TYPE_ISSUE : TYPE_MERGE_REQUEST; + return this.isIssue() ? TYPENAME_ISSUE : TYPE_MERGE_REQUEST; }, updateSpentAtDate(val) { this.spentAt = val; diff --git a/app/assets/javascripts/sidebar/components/time_tracking/report.vue b/app/assets/javascripts/sidebar/components/time_tracking/report.vue index 6f4ced06ddf..0aa2da8e68b 100644 --- a/app/assets/javascripts/sidebar/components/time_tracking/report.vue +++ b/app/assets/javascripts/sidebar/components/time_tracking/report.vue @@ -1,7 +1,7 @@ <script> import { GlLoadingIcon, GlTableLite, GlButton, GlTooltipDirective } from '@gitlab/ui'; import { createAlert } from '~/flash'; -import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { formatDate, parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility'; import { __, s__ } from '~/locale'; @@ -69,7 +69,7 @@ export default { }; }, getGraphQLEntityType() { - return this.isIssue() ? TYPE_ISSUE : TYPE_MERGE_REQUEST; + return this.isIssue() ? TYPENAME_ISSUE : TYPE_MERGE_REQUEST; }, extractTimelogs(data) { const timelogs = data?.issuable?.timelogs?.nodes || []; diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js index bef4c6af6ab..2ad5e5a9772 100644 --- a/app/assets/javascripts/sidebar/mount_sidebar.js +++ b/app/assets/javascripts/sidebar/mount_sidebar.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; -import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils'; import initInviteMembersModal from '~/invite_members/init_invite_members_modal'; import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger'; @@ -75,7 +75,7 @@ function mountSidebarTodoWidget() { fullPath: projectPath, issuableId: isInIssuePage() || isInIncidentPage() || isInDesignPage() - ? convertToGraphQLId(TYPE_ISSUE, id) + ? convertToGraphQLId(TYPENAME_ISSUE, id) : convertToGraphQLId(TYPE_MERGE_REQUEST, id), issuableIid: iid, issuableType: diff --git a/app/assets/javascripts/vue_shared/components/issuable_blocked_icon/issuable_blocked_icon.vue b/app/assets/javascripts/vue_shared/components/issuable_blocked_icon/issuable_blocked_icon.vue index 253aca8837d..7d61b7361bd 100644 --- a/app/assets/javascripts/vue_shared/components/issuable_blocked_icon/issuable_blocked_icon.vue +++ b/app/assets/javascripts/vue_shared/components/issuable_blocked_icon/issuable_blocked_icon.vue @@ -1,7 +1,7 @@ <script> import { GlIcon, GlLink, GlPopover, GlLoadingIcon } from '@gitlab/ui'; import { issuableTypes } from '~/boards/constants'; -import { TYPE_ISSUE, TYPE_EPIC } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE, TYPENAME_EPIC } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { truncate } from '~/lib/utils/text_utility'; import { __, n__, s__, sprintf } from '~/locale'; @@ -15,8 +15,8 @@ export default { }, }, graphQLIdType: { - [issuableTypes.issue]: TYPE_ISSUE, - [issuableTypes.epic]: TYPE_EPIC, + [issuableTypes.issue]: TYPENAME_ISSUE, + [issuableTypes.epic]: TYPENAME_EPIC, }, referenceFormatter: { [issuableTypes.issue]: (r) => r.split('/')[1], diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 47375eb7bcf..6f0b3ad1f35 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -64,7 +64,6 @@ class Projects::IssuesController < Projects::ApplicationController push_force_frontend_feature_flag(:work_items_mvc_2, project&.work_items_mvc_2_feature_flag_enabled?) push_frontend_feature_flag(:epic_widget_edit_confirmation, project) push_frontend_feature_flag(:use_iid_in_work_items_path, project&.group) - push_force_frontend_feature_flag(:work_items_create_from_markdown, project&.work_items_create_from_markdown_feature_flag_enabled?) push_frontend_feature_flag(:incident_event_tags, project) end diff --git a/app/finders/access_requests_finder.rb b/app/finders/access_requests_finder.rb index 65e1934a39f..7b98df68f29 100644 --- a/app/finders/access_requests_finder.rb +++ b/app/finders/access_requests_finder.rb @@ -9,8 +9,8 @@ class AccessRequestsFinder @source = source end - def execute(*args) - execute!(*args) + def execute(...) + execute!(...) rescue Gitlab::Access::AccessDeniedError [] end diff --git a/app/finders/concerns/finder_methods.rb b/app/finders/concerns/finder_methods.rb index ce6001a01d7..a9124e5c56c 100644 --- a/app/finders/concerns/finder_methods.rb +++ b/app/finders/concerns/finder_methods.rb @@ -2,20 +2,20 @@ module FinderMethods # rubocop: disable CodeReuse/ActiveRecord - def find_by!(*args) - raise_not_found_unless_authorized execute.reorder(nil).find_by!(*args) + def find_by!(...) + raise_not_found_unless_authorized execute.reorder(nil).find_by!(...) end # rubocop: enable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord - def find_by(*args) - if_authorized execute.reorder(nil).find_by(*args) + def find_by(...) + if_authorized execute.reorder(nil).find_by(...) end # rubocop: enable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord - def find(*args) - raise_not_found_unless_authorized execute.reorder(nil).find(*args) + def find(...) + raise_not_found_unless_authorized execute.reorder(nil).find(...) end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb index de2a4ce3518..1641219a14c 100644 --- a/app/finders/members_finder.rb +++ b/app/finders/members_finder.rb @@ -22,8 +22,8 @@ class MembersFinder filter_members(members) end - def can?(*args) - Ability.allowed?(*args) + def can?(...) + Ability.allowed?(...) end private diff --git a/app/graphql/resolvers/concerns/resolves_groups.rb b/app/graphql/resolvers/concerns/resolves_groups.rb index 1268e74fd58..86dda5cb1cb 100644 --- a/app/graphql/resolvers/concerns/resolves_groups.rb +++ b/app/graphql/resolvers/concerns/resolves_groups.rb @@ -5,8 +5,8 @@ module ResolvesGroups extend ActiveSupport::Concern include LooksAhead - def resolve_with_lookahead(**args) - apply_lookahead(resolve_groups(**args)) + def resolve_with_lookahead(...) + apply_lookahead(resolve_groups(...)) end private diff --git a/app/helpers/json_helper.rb b/app/helpers/json_helper.rb index e61c789fd08..2a1a6272cc9 100644 --- a/app/helpers/json_helper.rb +++ b/app/helpers/json_helper.rb @@ -4,11 +4,11 @@ module JsonHelper # These two JSON helpers are short-form wrappers for the Gitlab::Json # class, which should be used in place of .to_json calls or calls to # the JSON class. - def json_generate(*args) - Gitlab::Json.generate(*args) + def json_generate(...) + Gitlab::Json.generate(...) end - def json_parse(*args) - Gitlab::Json.parse(*args) + def json_parse(...) + Gitlab::Json.parse(...) end end diff --git a/app/helpers/routing/snippets_helper.rb b/app/helpers/routing/snippets_helper.rb index 19450c1d033..a815204a216 100644 --- a/app/helpers/routing/snippets_helper.rb +++ b/app/helpers/routing/snippets_helper.rb @@ -114,16 +114,16 @@ module Routing end end - def toggle_award_emoji_personal_snippet_path(*args) - toggle_award_emoji_snippet_path(*args) + def toggle_award_emoji_personal_snippet_path(...) + toggle_award_emoji_snippet_path(...) end - def toggle_award_emoji_project_project_snippet_path(*args) - toggle_award_emoji_project_snippet_path(*args) + def toggle_award_emoji_project_project_snippet_path(...) + toggle_award_emoji_project_snippet_path(...) end - def toggle_award_emoji_project_project_snippet_url(*args) - toggle_award_emoji_project_snippet_url(*args) + def toggle_award_emoji_project_project_snippet_url(...) + toggle_award_emoji_project_snippet_url(...) end private diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 370dbb10462..0aeea323ddb 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -14,8 +14,8 @@ module TreeHelper end # Simple shortcut to File.join - def tree_join(*args) - File.join(*args) + def tree_join(...) + File.join(...) end def on_top_of_branch?(project = @project, ref = @ref) diff --git a/app/models/bulk_imports/entity.rb b/app/models/bulk_imports/entity.rb index a7e57b60936..6fc24c77f1d 100644 --- a/app/models/bulk_imports/entity.rb +++ b/app/models/bulk_imports/entity.rb @@ -39,9 +39,28 @@ class BulkImports::Entity < ApplicationRecord validates :project, absence: true, if: :group validates :group, absence: true, if: :project - validates :source_type, :source_full_path, :destination_name, presence: true - validates :destination_namespace, exclusion: [nil], if: :group - validates :destination_namespace, presence: true, if: :project + validates :source_type, presence: true + validates :source_full_path, + presence: true, + format: { with: Gitlab::Regex.bulk_import_source_full_path_regex, + message: Gitlab::Regex.bulk_import_destination_namespace_path_regex_message } + + validates :destination_name, + presence: true, + format: { with: Gitlab::Regex.group_path_regex, + message: Gitlab::Regex.group_path_regex_message } + + validates :destination_namespace, + exclusion: [nil], + format: { with: Gitlab::Regex.bulk_import_destination_namespace_path_regex, + message: Gitlab::Regex.bulk_import_destination_namespace_path_regex_message }, + if: :group + + validates :destination_namespace, + presence: true, + format: { with: Gitlab::Regex.bulk_import_destination_namespace_path_regex, + message: Gitlab::Regex.bulk_import_destination_namespace_path_regex_message }, + if: :project validate :validate_parent_is_a_group, if: :parent validate :validate_imported_entity_type diff --git a/app/models/commit.rb b/app/models/commit.rb index a95ab756600..4517b3ef216 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -501,8 +501,8 @@ class Commit end end - def raw_diffs(*args) - raw.diffs(*args) + def raw_diffs(...) + raw.diffs(...) end def raw_deltas diff --git a/app/models/compare.rb b/app/models/compare.rb index f594a796987..f03390334f4 100644 --- a/app/models/compare.rb +++ b/app/models/compare.rb @@ -79,8 +79,8 @@ class Compare commit&.sha end - def raw_diffs(*args) - @compare.diffs(*args) + def raw_diffs(...) + @compare.diffs(...) end def diffs(diff_options = nil) diff --git a/app/models/concerns/integrations/has_web_hook.rb b/app/models/concerns/integrations/has_web_hook.rb index e622faf4a51..dcf14a4c7dc 100644 --- a/app/models/concerns/integrations/has_web_hook.rb +++ b/app/models/concerns/integrations/has_web_hook.rb @@ -42,9 +42,9 @@ module Integrations end # Execute the webhook, creating it if necessary. - def execute_web_hook!(*args) + def execute_web_hook!(...) update_web_hook! - service_hook.execute(*args) + service_hook.execute(...) end end end diff --git a/app/models/concerns/noteable.rb b/app/models/concerns/noteable.rb index eed396f785b..ec0dccc8d1a 100644 --- a/app/models/concerns/noteable.rb +++ b/app/models/concerns/noteable.rb @@ -123,10 +123,10 @@ module Noteable notes.limit(max).count end - def grouped_diff_discussions(*args) + def grouped_diff_discussions(...) # Doesn't use `discussion_notes`, because this may include commit diff notes # besides MR diff notes, that we do not want to display on the MR Changes tab. - notes.inc_relations_for_view(self).grouped_diff_discussions(*args) + notes.inc_relations_for_view(self).grouped_diff_discussions(...) end # rubocop:disable Gitlab/ModuleWithInstanceVariables diff --git a/app/models/concerns/reactive_caching.rb b/app/models/concerns/reactive_caching.rb index 9ed2070d11c..aa0fced99c4 100644 --- a/app/models/concerns/reactive_caching.rb +++ b/app/models/concerns/reactive_caching.rb @@ -122,8 +122,8 @@ module ReactiveCaching worker_class.perform_async(self.class, id, *args) end - def keep_alive_reactive_cache!(*args) - Rails.cache.write(alive_reactive_cache_key(*args), true, expires_in: self.class.reactive_cache_lifetime) + def keep_alive_reactive_cache!(...) + Rails.cache.write(alive_reactive_cache_key(...), true, expires_in: self.class.reactive_cache_lifetime) end def full_reactive_cache_key(*qualifiers) @@ -145,8 +145,8 @@ module ReactiveCaching Gitlab::ExclusiveLease.cancel(full_reactive_cache_key(*args), uuid) end - def within_reactive_cache_lifetime?(*args) - Rails.cache.exist?(alive_reactive_cache_key(*args)) + def within_reactive_cache_lifetime?(...) + Rails.cache.exist?(alive_reactive_cache_key(...)) end def enqueuing_update(*args) diff --git a/app/models/group.rb b/app/models/group.rb index f48484f04f7..a2d984973bd 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -913,10 +913,6 @@ class Group < Namespace feature_flag_enabled_for_self_or_ancestor?(:work_items_mvc_2) end - def work_items_create_from_markdown_feature_flag_enabled? - feature_flag_enabled_for_self_or_ancestor?(:work_items_create_from_markdown) - end - def usage_quotas_enabled? ::Feature.enabled?(:usage_quotas_for_all_editions, self) && root? end diff --git a/app/models/legacy_diff_discussion.rb b/app/models/legacy_diff_discussion.rb index 7d78c580fa2..984205044a7 100644 --- a/app/models/legacy_diff_discussion.rb +++ b/app/models/legacy_diff_discussion.rb @@ -27,10 +27,10 @@ class LegacyDiffDiscussion < Discussion true end - def active?(*args) + def active?(...) return @active if @active.present? - @active = first_note.active?(*args) + @active = first_note.active?(...) end def collapsed? diff --git a/app/models/merge_request/metrics.rb b/app/models/merge_request/metrics.rb index c546a5a0025..87d8704561f 100644 --- a/app/models/merge_request/metrics.rb +++ b/app/models/merge_request/metrics.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class MergeRequest::Metrics < ApplicationRecord + include IgnorableColumns + belongs_to :merge_request, inverse_of: :metrics belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :pipeline_id belongs_to :latest_closed_by, class_name: 'User' @@ -14,6 +16,8 @@ class MergeRequest::Metrics < ApplicationRecord scope :with_valid_time_to_merge, -> { where(arel_table[:merged_at].gt(arel_table[:created_at])) } scope :by_target_project, ->(project) { where(target_project_id: project) } + ignore_column :id_convert_to_bigint, remove_with: '16.0', remove_after: '2023-05-22' + class << self def time_to_merge_expression Arel.sql('EXTRACT(epoch FROM SUM(AGE(merge_request_metrics.merged_at, merge_request_metrics.created_at)))') diff --git a/app/models/project.rb b/app/models/project.rb index 8c931310614..a4fa20b227e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -3064,10 +3064,6 @@ class Project < ApplicationRecord group&.work_items_mvc_2_feature_flag_enabled? || Feature.enabled?(:work_items_mvc_2) end - def work_items_create_from_markdown_feature_flag_enabled? - group&.work_items_create_from_markdown_feature_flag_enabled? || Feature.enabled?(:work_items_create_from_markdown) - end - def enqueue_record_project_target_platforms return unless Gitlab.com? return unless Feature.enabled?(:record_projects_target_platforms, self) diff --git a/app/models/repository.rb b/app/models/repository.rb index 4100218944f..f71d7bb8d20 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -888,8 +888,8 @@ class Repository end end - def delete_refs(*ref_names) - raw.delete_refs(*ref_names) + def delete_refs(...) + raw.delete_refs(...) end def ff_merge(user, source, target_branch, merge_request: nil) diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb index 417a2f9c51f..353e0fad6fb 100644 --- a/app/presenters/merge_request_presenter.rb +++ b/app/presenters/merge_request_presenter.rb @@ -281,8 +281,8 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated end # Avoid including ActionView::Helpers::UrlHelper - def link_to(*args) - ApplicationController.helpers.link_to(*args) + def link_to(...) + ApplicationController.helpers.link_to(...) end end diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb index 3a1e7f2d228..6dd23be9873 100644 --- a/app/presenters/project_presenter.rb +++ b/app/presenters/project_presenter.rb @@ -462,8 +462,8 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated end # Avoid including ActionView::Helpers::UrlHelper - def content_tag(*args) - ActionController::Base.helpers.content_tag(*args) + def content_tag(...) + ActionController::Base.helpers.content_tag(...) end def can_create_wiki? diff --git a/app/presenters/user_presenter.rb b/app/presenters/user_presenter.rb index 26b8169d2b0..43164cca9c9 100644 --- a/app/presenters/user_presenter.rb +++ b/app/presenters/user_presenter.rb @@ -29,8 +29,8 @@ class UserPresenter < Gitlab::View::Presenter::Delegated private - def can?(*args) - user.can?(*args) + def can?(...) + user.can?(...) end def should_be_private? diff --git a/app/serializers/analytics/cycle_analytics/stage_entity.rb b/app/serializers/analytics/cycle_analytics/stage_entity.rb index c1d415dfb40..06b39fedec9 100644 --- a/app/serializers/analytics/cycle_analytics/stage_entity.rb +++ b/app/serializers/analytics/cycle_analytics/stage_entity.rb @@ -48,8 +48,8 @@ module Analytics end # Avoid including ActionView::Helpers::UrlHelper - def link_to(*args) - ActionController::Base.helpers.link_to(*args) + def link_to(...) + ActionController::Base.helpers.link_to(...) end private diff --git a/app/services/bulk_imports/create_service.rb b/app/services/bulk_imports/create_service.rb index 4dfd7a8ac9c..ac019d9ec5b 100644 --- a/app/services/bulk_imports/create_service.rb +++ b/app/services/bulk_imports/create_service.rb @@ -79,7 +79,7 @@ module BulkImports bulk_import: bulk_import, source_type: entity_params[:source_type], source_full_path: entity_params[:source_full_path], - destination_slug: entity_params[:destination_slug], + destination_slug: entity_params[:destination_slug] || entity_params[:destination_name], destination_namespace: entity_params[:destination_namespace], migrate_projects: Gitlab::Utils.to_boolean(entity_params[:migrate_projects], default: true) ) @@ -103,7 +103,7 @@ module BulkImports full_path = [ entity_params[:destination_namespace], - entity_params[:destination_slug] + entity_params[:destination_slug] || entity_params[:destination_name] ].reject(&:blank?).join('/') case source_type diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb index 6ffda90900a..d848f694598 100644 --- a/app/services/event_create_service.rb +++ b/app/services/event_create_service.rb @@ -273,8 +273,8 @@ class EventCreateService { resource_parent_attr => resource_parent.id } end - def track_event(**params) - Gitlab::UsageDataCounters::TrackUniqueEvents.track_event(**params) + def track_event(...) + Gitlab::UsageDataCounters::TrackUniqueEvents.track_event(...) end def track_snowplow_event(action:, project:, user:, label:, property:) diff --git a/app/services/notification_recipients/build_service.rb b/app/services/notification_recipients/build_service.rb index bdeebc641b8..04563d180b5 100644 --- a/app/services/notification_recipients/build_service.rb +++ b/app/services/notification_recipients/build_service.rb @@ -17,24 +17,24 @@ module NotificationRecipients ::NotificationRecipients::Builder::Default.new(target, current_user, **args).notification_recipients end - def self.build_new_note_recipients(*args) - ::NotificationRecipients::Builder::NewNote.new(*args).notification_recipients + def self.build_new_note_recipients(...) + ::NotificationRecipients::Builder::NewNote.new(...).notification_recipients end - def self.build_merge_request_unmergeable_recipients(*args) - ::NotificationRecipients::Builder::MergeRequestUnmergeable.new(*args).notification_recipients + def self.build_merge_request_unmergeable_recipients(...) + ::NotificationRecipients::Builder::MergeRequestUnmergeable.new(...).notification_recipients end def self.build_project_maintainers_recipients(target, **args) ::NotificationRecipients::Builder::ProjectMaintainers.new(target, **args).notification_recipients end - def self.build_new_review_recipients(*args) - ::NotificationRecipients::Builder::NewReview.new(*args).notification_recipients + def self.build_new_review_recipients(...) + ::NotificationRecipients::Builder::NewReview.new(...).notification_recipients end - def self.build_requested_review_recipients(*args) - ::NotificationRecipients::Builder::RequestReview.new(*args).notification_recipients + def self.build_requested_review_recipients(...) + ::NotificationRecipients::Builder::RequestReview.new(...).notification_recipients end end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 1be240356c6..47bc36fce70 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -939,12 +939,12 @@ class NotificationService NotificationRecipients::BuildService.build_project_maintainers_recipients(target, action: action) end - def notifiable?(*args) - NotificationRecipients::BuildService.notifiable?(*args) + def notifiable?(...) + NotificationRecipients::BuildService.notifiable?(...) end - def notifiable_users(*args) - NotificationRecipients::BuildService.notifiable_users(*args) + def notifiable_users(...) + NotificationRecipients::BuildService.notifiable_users(...) end def deliver_access_request_email(recipient, member) diff --git a/app/services/system_notes/base_service.rb b/app/services/system_notes/base_service.rb index ee7784c127b..1f6d8ab2409 100644 --- a/app/services/system_notes/base_service.rb +++ b/app/services/system_notes/base_service.rb @@ -19,8 +19,8 @@ module SystemNotes Note.create(note_params) end - def content_tag(*args) - ActionController::Base.helpers.content_tag(*args) + def content_tag(...) + ActionController::Base.helpers.content_tag(...) end def url_helpers diff --git a/app/workers/ci/schedule_delete_objects_cron_worker.rb b/app/workers/ci/schedule_delete_objects_cron_worker.rb index 55b23bbab62..b8332838b13 100644 --- a/app/workers/ci/schedule_delete_objects_cron_worker.rb +++ b/app/workers/ci/schedule_delete_objects_cron_worker.rb @@ -14,8 +14,8 @@ module Ci feature_category :continuous_integration idempotent! - def perform(*args) - Ci::DeleteObjectsWorker.perform_with_capacity(*args) + def perform(...) + Ci::DeleteObjectsWorker.perform_with_capacity(...) end end end diff --git a/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb b/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb index 0a43a0fc4d2..64fa705329e 100644 --- a/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb +++ b/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb @@ -25,8 +25,8 @@ module Gitlab end end - def try_import(*args) - import(*args) + def try_import(...) + import(...) true rescue RateLimitError false diff --git a/app/workers/concerns/limited_capacity/worker.rb b/app/workers/concerns/limited_capacity/worker.rb index bcedb4efcc0..af66d80b3e9 100644 --- a/app/workers/concerns/limited_capacity/worker.rb +++ b/app/workers/concerns/limited_capacity/worker.rb @@ -61,8 +61,8 @@ module LimitedCapacity end end - def perform(*args) - perform_registered(*args) if job_tracker.register(jid, max_running_jobs) + def perform(...) + perform_registered(...) if job_tracker.register(jid, max_running_jobs) end def perform_work(*args) @@ -81,9 +81,9 @@ module LimitedCapacity job_tracker.clean_up end - def report_prometheus_metrics(*args) + def report_prometheus_metrics(...) report_running_jobs_metrics - set_metric(:remaining_work_gauge, remaining_work_count(*args)) + set_metric(:remaining_work_gauge, remaining_work_count(...)) set_metric(:max_running_jobs_gauge, max_running_jobs) end diff --git a/config/feature_flags/development/mr_experience_survey.yml b/config/feature_flags/development/mr_experience_survey.yml index c6487dbaf3a..fbf71eab8b5 100644 --- a/config/feature_flags/development/mr_experience_survey.yml +++ b/config/feature_flags/development/mr_experience_survey.yml @@ -1,7 +1,7 @@ --- name: mr_experience_survey introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/90036 -rollout_issue_url: +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/366561 milestone: '15.2' type: development group: group::code review diff --git a/config/feature_flags/development/work_items_create_from_markdown.yml b/config/feature_flags/development/work_items_create_from_markdown.yml deleted file mode 100644 index 9a954001f2b..00000000000 --- a/config/feature_flags/development/work_items_create_from_markdown.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: work_items_create_from_markdown -introduced_by_url: -rollout_issue_url: -milestone: '15.3' -type: development -group: group::project management -default_enabled: false diff --git a/config/metrics/counts_28d/20230120094644_g_runner_fleet_read_jobs_statistics_monthly.yml b/config/metrics/counts_28d/20230120094644_g_runner_fleet_read_jobs_statistics_monthly.yml new file mode 100644 index 00000000000..a99bcf9fdf4 --- /dev/null +++ b/config/metrics/counts_28d/20230120094644_g_runner_fleet_read_jobs_statistics_monthly.yml @@ -0,0 +1,24 @@ +--- +key_path: redis_hll_counters.runner.g_runner_fleet_read_jobs_statistics_monthly +name: g_runner_fleet_read_jobs_statistics_monthly +description: Count of unique users (monthly) who read runner job statistics +product_section: ops +product_stage: verify +product_group: runner +product_category: runner_fleet +value_type: number +status: active +milestone: "15.9" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109113 +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +options: + events: + - g_runner_fleet_read_jobs_statistics +performance_indicator_type: [] +distribution: +- ee +tier: +- ultimate diff --git a/config/metrics/counts_7d/20230120094643_g_runner_fleet_read_jobs_statistics_weekly.yml b/config/metrics/counts_7d/20230120094643_g_runner_fleet_read_jobs_statistics_weekly.yml new file mode 100644 index 00000000000..97659c7ed63 --- /dev/null +++ b/config/metrics/counts_7d/20230120094643_g_runner_fleet_read_jobs_statistics_weekly.yml @@ -0,0 +1,24 @@ +--- +key_path: redis_hll_counters.runner.g_runner_fleet_read_jobs_statistics_weekly +name: g_runner_fleet_read_jobs_statistics_weekly +description: Count of unique users (weekly) who read runner job statistics +product_section: ops +product_stage: verify +product_group: runner +product_category: runner_fleet +value_type: number +status: active +milestone: "15.9" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109113 +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +options: + events: + - g_runner_fleet_read_jobs_statistics +performance_indicator_type: [] +distribution: +- ee +tier: +- ultimate diff --git a/db/migrate/20230127093353_initialize_conversion_of_merge_request_metrics_to_bigint.rb b/db/migrate/20230127093353_initialize_conversion_of_merge_request_metrics_to_bigint.rb new file mode 100644 index 00000000000..dfca67a2e2f --- /dev/null +++ b/db/migrate/20230127093353_initialize_conversion_of_merge_request_metrics_to_bigint.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class InitializeConversionOfMergeRequestMetricsToBigint < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + TABLE = :merge_request_metrics + COLUMNS = %i[id] + + def up + initialize_conversion_of_integer_to_bigint(TABLE, COLUMNS) + end + + def down + revert_initialize_conversion_of_integer_to_bigint(TABLE, COLUMNS) + end +end diff --git a/db/post_migrate/20230127101834_backfill_merge_request_metrics_for_bigint_conversion.rb b/db/post_migrate/20230127101834_backfill_merge_request_metrics_for_bigint_conversion.rb new file mode 100644 index 00000000000..02ef1c230da --- /dev/null +++ b/db/post_migrate/20230127101834_backfill_merge_request_metrics_for_bigint_conversion.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class BackfillMergeRequestMetricsForBigintConversion < Gitlab::Database::Migration[2.1] + restrict_gitlab_migration gitlab_schema: :gitlab_main + + TABLE = :merge_request_metrics + COLUMNS = %i[id] + + def up + backfill_conversion_of_integer_to_bigint(TABLE, COLUMNS, sub_batch_size: 200) + end + + def down + revert_backfill_conversion_of_integer_to_bigint(TABLE, COLUMNS) + end +end diff --git a/db/post_migrate/20230130102855_add_fk_index_to_ci_build_report_results_on_partition_id_and_build_id.rb b/db/post_migrate/20230130102855_add_fk_index_to_ci_build_report_results_on_partition_id_and_build_id.rb new file mode 100644 index 00000000000..4fe71ba46d9 --- /dev/null +++ b/db/post_migrate/20230130102855_add_fk_index_to_ci_build_report_results_on_partition_id_and_build_id.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddFkIndexToCiBuildReportResultsOnPartitionIdAndBuildId < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + INDEX_NAME = :index_ci_build_report_results_on_partition_id_build_id + TABLE_NAME = :ci_build_report_results + COLUMNS = [:partition_id, :build_id] + + def up + add_concurrent_index(TABLE_NAME, COLUMNS, unique: true, name: INDEX_NAME) + end + + def down + remove_concurrent_index_by_name(TABLE_NAME, INDEX_NAME) + end +end diff --git a/db/post_migrate/20230130102856_add_fk_to_ci_build_report_results_on_partition_id_and_build_id.rb b/db/post_migrate/20230130102856_add_fk_to_ci_build_report_results_on_partition_id_and_build_id.rb new file mode 100644 index 00000000000..ef301af2c9f --- /dev/null +++ b/db/post_migrate/20230130102856_add_fk_to_ci_build_report_results_on_partition_id_and_build_id.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class AddFkToCiBuildReportResultsOnPartitionIdAndBuildId < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + SOURCE_TABLE_NAME = :ci_build_report_results + TARGET_TABLE_NAME = :ci_builds + COLUMN = :build_id + TARGET_COLUMN = :id + FK_NAME = :fk_rails_16cb1ff064_p + PARTITION_COLUMN = :partition_id + + def up + add_concurrent_foreign_key( + SOURCE_TABLE_NAME, + TARGET_TABLE_NAME, + column: [PARTITION_COLUMN, COLUMN], + target_column: [PARTITION_COLUMN, TARGET_COLUMN], + validate: false, + reverse_lock_order: true, + on_update: :cascade, + on_delete: :cascade, + name: FK_NAME + ) + end + + def down + with_lock_retries do + remove_foreign_key_if_exists( + SOURCE_TABLE_NAME, + TARGET_TABLE_NAME, + name: FK_NAME, + reverse_lock_order: true + ) + end + end +end diff --git a/db/post_migrate/20230201152525_schedule_fk_index_to_ci_build_needs_on_partition_id_and_build_id.rb b/db/post_migrate/20230201152525_schedule_fk_index_to_ci_build_needs_on_partition_id_and_build_id.rb new file mode 100644 index 00000000000..674d92295c3 --- /dev/null +++ b/db/post_migrate/20230201152525_schedule_fk_index_to_ci_build_needs_on_partition_id_and_build_id.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class ScheduleFkIndexToCiBuildNeedsOnPartitionIdAndBuildId < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + INDEX_NAME = :index_ci_build_needs_on_partition_id_build_id + TABLE_NAME = :ci_build_needs + COLUMNS = [:partition_id, :build_id] + + def up + prepare_async_index(TABLE_NAME, COLUMNS, name: INDEX_NAME) + end + + def down + unprepare_async_index_by_name(TABLE_NAME, INDEX_NAME) + end +end diff --git a/db/schema_migrations/20230127093353 b/db/schema_migrations/20230127093353 new file mode 100644 index 00000000000..903688f1608 --- /dev/null +++ b/db/schema_migrations/20230127093353 @@ -0,0 +1 @@ +7b6b30a2de12f145df5eb0814f584a117a421b1ae23c4dd45fea58fe0d883653
\ No newline at end of file diff --git a/db/schema_migrations/20230127101834 b/db/schema_migrations/20230127101834 new file mode 100644 index 00000000000..4d89984347a --- /dev/null +++ b/db/schema_migrations/20230127101834 @@ -0,0 +1 @@ +13aba72dc08069cf5585657a6c684495886f27c634cdb63c363ddd1ab6f7c58d
\ No newline at end of file diff --git a/db/schema_migrations/20230130102855 b/db/schema_migrations/20230130102855 new file mode 100644 index 00000000000..91f9164a254 --- /dev/null +++ b/db/schema_migrations/20230130102855 @@ -0,0 +1 @@ +1e6d539713dd9d6b6b8afd5fcb6db87e75eb96fccf91a94c00700760fb5e963f
\ No newline at end of file diff --git a/db/schema_migrations/20230130102856 b/db/schema_migrations/20230130102856 new file mode 100644 index 00000000000..f258d0e1eae --- /dev/null +++ b/db/schema_migrations/20230130102856 @@ -0,0 +1 @@ +4dc770e4a78c0f3e3aa5af43e017744a85b4974c1315508ac2244c7b12f4e0b3
\ No newline at end of file diff --git a/db/schema_migrations/20230201152525 b/db/schema_migrations/20230201152525 new file mode 100644 index 00000000000..51fd8eabe91 --- /dev/null +++ b/db/schema_migrations/20230201152525 @@ -0,0 +1 @@ +cfe3f77bf0615889a0fd1d55ef4f07f2bb9a1dbe1a6bb0fb5a36c017f9a5ca46
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 6321bfa3ab0..ddc4945a58f 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -234,6 +234,15 @@ BEGIN END; $$; +CREATE FUNCTION trigger_c7107f30d69d() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + NEW."id_convert_to_bigint" := NEW."id"; + RETURN NEW; +END; +$$; + CREATE FUNCTION unset_has_issues_on_vulnerability_reads() RETURNS trigger LANGUAGE plpgsql AS $$ @@ -17791,6 +17800,7 @@ CREATE TABLE merge_request_metrics ( added_lines integer, removed_lines integer, target_project_id integer, + id_convert_to_bigint bigint DEFAULT 0 NOT NULL, CONSTRAINT check_e03d0900bf CHECK ((target_project_id IS NOT NULL)) ); @@ -28982,6 +28992,8 @@ CREATE UNIQUE INDEX index_ci_build_pending_states_on_build_id ON ci_build_pendin CREATE INDEX index_ci_build_pending_states_on_partition_id_build_id ON ci_build_pending_states USING btree (partition_id, build_id); +CREATE UNIQUE INDEX index_ci_build_report_results_on_partition_id_build_id ON ci_build_report_results USING btree (partition_id, build_id); + CREATE INDEX index_ci_build_report_results_on_project_id ON ci_build_report_results USING btree (project_id); CREATE UNIQUE INDEX index_ci_build_trace_chunks_on_build_id_and_chunk_index ON ci_build_trace_chunks USING btree (build_id, chunk_index); @@ -33426,6 +33438,8 @@ CREATE TRIGGER projects_loose_fk_trigger AFTER DELETE ON projects REFERENCING OL CREATE TRIGGER trigger_1a857e8db6cd BEFORE INSERT OR UPDATE ON vulnerability_occurrences FOR EACH ROW EXECUTE FUNCTION trigger_1a857e8db6cd(); +CREATE TRIGGER trigger_c7107f30d69d BEFORE INSERT OR UPDATE ON merge_request_metrics FOR EACH ROW EXECUTE FUNCTION trigger_c7107f30d69d(); + CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace(); CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker(); @@ -34559,6 +34573,9 @@ ALTER TABLE ONLY users_security_dashboard_projects ALTER TABLE ONLY ci_build_report_results ADD CONSTRAINT fk_rails_16cb1ff064 FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE; +ALTER TABLE ONLY ci_build_report_results + ADD CONSTRAINT fk_rails_16cb1ff064_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; + ALTER TABLE ONLY project_deploy_tokens ADD CONSTRAINT fk_rails_170e03cbaf FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 994246b64e4..e82b5c71a9b 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -20700,6 +20700,7 @@ Represents a vulnerability. | <a id="vulnerabilityscanner"></a>`scanner` | [`VulnerabilityScanner`](#vulnerabilityscanner) | Scanner metadata for the vulnerability. | | <a id="vulnerabilityseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the vulnerability (INFO, UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL). | | <a id="vulnerabilitystate"></a>`state` | [`VulnerabilityState`](#vulnerabilitystate) | State of the vulnerability (DETECTED, CONFIRMED, RESOLVED, DISMISSED). | +| <a id="vulnerabilitystatecomment"></a>`stateComment` | [`String`](#string) | Comment given for the vulnerability state change. | | <a id="vulnerabilitytitle"></a>`title` | [`String`](#string) | Title of the vulnerability. | | <a id="vulnerabilityupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp of when the vulnerability was last updated. | | <a id="vulnerabilityusernotescount"></a>`userNotesCount` | [`Int!`](#int) | Number of user notes attached to the vulnerability. | diff --git a/doc/ci/yaml/artifacts_reports.md b/doc/ci/yaml/artifacts_reports.md index 38b0ab1f0a3..ced620195b4 100644 --- a/doc/ci/yaml/artifacts_reports.md +++ b/doc/ci/yaml/artifacts_reports.md @@ -15,9 +15,9 @@ Use [`artifacts:reports`](index.md#artifactsreports) to: - Pipeline views. - [Security dashboards](../../user/application_security/security_dashboard/index.md). -The test reports are collected regardless of the job results (success or failure). -You can use [`artifacts:expire_in`](index.md#artifactsexpire_in) to set up an expiration -date for their artifacts. +Artifacts created for `artifacts: reports` are always uploaded, regardless of the job results (success or failure). +You can use [`artifacts:expire_in`](index.md#artifactsexpire_in) to set an expiration +date for the artifacts. Some `artifacts:reports` types can be generated by multiple jobs in the same pipeline, and used by merge request or pipeline features from each job. diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index 663900006dd..8f02b502693 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -1002,9 +1002,9 @@ rspec: - Combining reports in parent pipelines using [artifacts from child pipelines](#needspipelinejob) is not supported. Track progress on adding support in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/215725). - To be able to browse the report output files, include the [`artifacts:paths`](#artifactspaths) keyword. This uploads and stores the artifact twice. -- The test reports are collected regardless of the job results (success or failure). - You can use [`artifacts:expire_in`](#artifactsexpire_in) to set up an expiration - date for artifacts reports. +- Artifacts created for `artifacts: reports` are always uploaded, regardless of the job results (success or failure). + You can use [`artifacts:expire_in`](#artifactsexpire_in) to set an expiration + date for the artifacts. #### `artifacts:untracked` @@ -1057,6 +1057,11 @@ job: when: on_failure ``` +**Additional details**: + +- The artifacts created for [`artifacts:reports`](#artifactsreports) are always uploaded, + regardless of the job results (success or failure). `artifacts:when` does not change this behavior. + ### `before_script` Use `before_script` to define an array of commands that should run before each job's diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md index 050148c2cec..a419ca4f3eb 100644 --- a/doc/security/two_factor_authentication.md +++ b/doc/security/two_factor_authentication.md @@ -139,7 +139,7 @@ FLAG: On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `two_factor_for_cli`. On GitLab.com, this feature is not available. The feature is not ready for production use. This feature flag also affects [session duration for Git Operations when 2FA is enabled](../user/admin_area/settings/account_and_limit_settings.md#customize-session-duration-for-git-operations-when-2fa-is-enabled). You can enforce 2FA for [Git over SSH operations](../development/gitlab_shell/features.md#git-operations). However, you should use -[ED25519_SK](../user/ssh.md#ed25519_sk-ssh-keys) or [ECDSA_SK](../user/ssh.md#ecdsa_sk-ssh-keys) SSH keys instead. +[ED25519_SK](../user/ssh.md#ed25519_sk-ssh-keys) or [ECDSA_SK](../user/ssh.md#ecdsa_sk-ssh-keys) SSH keys instead. 2FA is enforced for Git operations only, and internal commands such as [`personal_access_token`](../development/gitlab_shell/features.md#personal-access-token) are excluded. To perform one-time password (OTP) verification, run: diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md index 11ef1d79d3f..65951ce2dda 100644 --- a/doc/user/profile/index.md +++ b/doc/user/profile/index.md @@ -269,10 +269,7 @@ To change your commit email: ## Change your primary email -Your primary email: - -- Is the default email address for your login, commit email, and notification email. -- Must be already [linked to your user profile](#add-emails-to-your-user-profile). +Your primary email is the default email address for your login, commit email, and notification email. To change your primary email: @@ -280,6 +277,7 @@ To change your primary email: 1. Select **Edit profile**. 1. In the **Email** field, enter your new email address. 1. Select **Update profile settings**. +1. Optional. Select the confirmation email if you have not previously added this email to your GitLab.com account. ## Set your public email diff --git a/doc/user/project/members/index.md b/doc/user/project/members/index.md index 823a950e771..c7d45b0bd15 100644 --- a/doc/user/project/members/index.md +++ b/doc/user/project/members/index.md @@ -121,7 +121,12 @@ To add a user to a project: 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Project information > Members**. 1. Select **Invite members**. -1. Enter an email address and select a [role](../../permissions.md). +1. If the user: + + - Has a GitLab account, enter their username. + - Doesn't have a GitLab account, enter their email address. + +1. Select a [role](../../permissions.md). 1. Optional. Select an **Access expiration date**. From that date onward, the user can no longer access the project. @@ -131,16 +136,12 @@ To add a user to a project: to extend their own time in the Maintainer role. 1. Select **Invite**. + If you invited the user using their: -If the user has a GitLab account, they are added to the members list. -If you used an email address, the user receives an email. - -If the invitation is not accepted, GitLab sends reminder emails two, -five, and ten days later. Unaccepted invites are automatically -deleted after 90 days. - -If the user does not have a GitLab account, they are prompted to create an account -using the email address the invitation was sent to. + - GitLab username, they are added to the members list. + - Email address, an invitation is sent to their email address, and they are prompted to create an account. + If the invitation is not accepted, GitLab sends reminder emails two, five, and ten days later. + Unaccepted invites are automatically deleted after 90 days. ### Which roles you can assign diff --git a/doc/user/project/repository/vscode.md b/doc/user/project/repository/vscode.md index 4afdb3be0bd..257f98155d8 100644 --- a/doc/user/project/repository/vscode.md +++ b/doc/user/project/repository/vscode.md @@ -1,6 +1,6 @@ --- stage: Create -group: Code Review +group: Editor info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- diff --git a/lib/api/validations/validators/bulk_imports.rb b/lib/api/validations/validators/bulk_imports.rb index 8d49607f64c..4625f2f39cd 100644 --- a/lib/api/validations/validators/bulk_imports.rb +++ b/lib/api/validations/validators/bulk_imports.rb @@ -21,7 +21,7 @@ module API def validate_param!(attr_name, params) return if params[attr_name].blank? - unless params[attr_name] =~ Gitlab::Regex.bulk_import_namespace_path_regex # rubocop: disable Style/GuardClause + unless params[attr_name] =~ Gitlab::Regex.bulk_import_destination_namespace_path_regex # rubocop: disable Style/GuardClause raise Grape::Exceptions::Validation.new( params: [@scope.full_name(attr_name)], message: "cannot start with a dash or forward slash, or end with a period or forward slash. " \ @@ -34,7 +34,7 @@ module API class SourceFullPath < Grape::Validations::Base def validate_param!(attr_name, params) - unless params[attr_name] =~ Gitlab::Regex.bulk_import_namespace_path_regex # rubocop: disable Style/GuardClause + unless params[attr_name] =~ Gitlab::Regex.bulk_import_source_full_path_regex # rubocop: disable Style/GuardClause raise Grape::Exceptions::Validation.new( params: [@scope.full_name(attr_name)], message: "must be a relative path and not include protocol, sub-domain, or domain information. " \ diff --git a/lib/bulk_imports/groups/graphql/get_projects_query.rb b/lib/bulk_imports/groups/graphql/get_projects_query.rb index 4784baf225c..01d2d9776ec 100644 --- a/lib/bulk_imports/groups/graphql/get_projects_query.rb +++ b/lib/bulk_imports/groups/graphql/get_projects_query.rb @@ -22,6 +22,7 @@ module BulkImports nodes { id name + path full_path: fullPath } } diff --git a/lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb b/lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb index 026b2e55713..7d9d8120e6c 100644 --- a/lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb +++ b/lib/bulk_imports/groups/pipelines/project_entities_pipeline.rb @@ -13,7 +13,7 @@ module BulkImports { source_type: :project_entity, source_full_path: data['full_path'], - destination_name: data['name'], + destination_name: data['path'], destination_namespace: context.entity.group.full_path, parent_id: context.entity.id, source_xid: GlobalID.parse(data['id']).model_id diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml index 6884a9556b4..aa2356f6a34 100644 --- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.45.0' + DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.46.0' .dast-auto-deploy: image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${DAST_AUTO_DEPLOY_IMAGE_VERSION}" diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml index dc7e5f445d2..372b782c0a0 100644 --- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - AUTO_DEPLOY_IMAGE_VERSION: 'v2.45.0' + AUTO_DEPLOY_IMAGE_VERSION: 'v2.46.0' .auto-deploy: image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}" diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml index 9e15b07f5d1..feba2efcf22 100644 --- a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - AUTO_DEPLOY_IMAGE_VERSION: 'v2.45.0' + AUTO_DEPLOY_IMAGE_VERSION: 'v2.46.0' .auto-deploy: image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}" diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index ba02566e232..7bff41e9521 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -252,24 +252,48 @@ module Gitlab extend self extend Packages - def bulk_import_namespace_path_regex - # This regexp validates the string conforms to rules for a namespace path: - # i.e does not start with a non-alphanueric character except for periods or underscores, + def bulk_import_destination_namespace_path_regex + # This regexp validates the string conforms to rules for a destination_namespace path: + # i.e does not start with a non-alphanumeric character except for periods or underscores, + # contains only alphanumeric characters, forward slashes, periods, and underscores, + # does not end with a period or forward slash, and has a relative path structure + # with no http protocol chars or leading or trailing forward slashes + # eg 'source/full/path' or 'destination_namespace' not 'https://example.com/destination/namespace/path' + # the regex also allows for an empty string ('') to be accepted as this is allowed in + # a bulk_import POST request + @bulk_import_destination_namespace_path_regex ||= %r/((\A\z)|\A([.]?)[^\W](\/?[.]?[0-9a-z][-_]*)+\z)/i + end + + def bulk_import_source_full_path_regex + # This regexp validates the string conforms to rules for a source_full_path path: + # i.e does not start with a non-alphanumeric character except for periods or underscores, # contains only alphanumeric characters, forward slashes, periods, and underscores, # does not end with a period or forward slash, and has a relative path structure # with no http protocol chars or leading or trailing forward slashes # eg 'source/full/path' or 'destination_namespace' not 'https://example.com/source/full/path' - @bulk_import_namespace_path_regex ||= %r/^([.]?)[^\W](\/?[.]?[0-9a-z][-_]*)+$/i + @bulk_import_source_full_path_regex ||= %r/\A([.]?)[^\W](\/?[.]?[0-9a-z][-_]*)+\z/i + end + + def bulk_import_destination_namespace_path_regex_message + "cannot start with a non-alphanumeric character except for periods or underscores, " \ + "can contain only alphanumeric characters, forward slashes, periods, and underscores, " \ + "cannot end with a period or forward slash, and has a relative path structure " \ + "with no http protocol chars or leading or trailing forward slashes" \ end def group_path_regex # This regexp validates the string conforms to rules for a group slug: - # i.e does not start with a non-alphanueric character except for periods or underscores, + # i.e does not start with a non-alphanumeric character except for periods or underscores, # contains only alphanumeric characters, periods, and underscores, - # does not end with a period or forward slash, and has a relative path structure - # with no http protocol chars or leading or trailing forward slashes - # eg 'source/full/path' or 'destination_namespace' not 'https://example.com/source/full/path' - @group_path_regex ||= %r/^[.]?[^\W]([.]?[0-9a-z][-_]*)+$/i + # does not end with a period or forward slash, and has no leading or trailing forward slashes + # eg 'destination-path' or 'destination_pth' not 'example/com/destination/full/path' + @group_path_regex ||= %r/\A[.]?[^\W]([.]?[0-9a-z][-_]*)+\z/i + end + + def group_path_regex_message + "cannot start with a non-alphanumeric character except for periods or underscores, " \ + "can contain only alphanumeric characters, periods, and underscores, " \ + "cannot end with a period or forward slash, and has no leading or trailing forward slashes" \ end def project_name_regex diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml index 880db790602..861f3dd952d 100644 --- a/lib/gitlab/usage_data_counters/known_events/common.yml +++ b/lib/gitlab/usage_data_counters/known_events/common.yml @@ -244,6 +244,11 @@ category: issues_edit redis_slot: project_management aggregation: daily +# Runner group +- name: g_runner_fleet_read_jobs_statistics + category: runner + redis_slot: runner + aggregation: weekly # Secrets Management - name: i_snippets_show category: snippets diff --git a/locale/gitlab.pot b/locale/gitlab.pot index dbf11468589..a3ef32f3b7e 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -28966,6 +28966,9 @@ msgstr "" msgid "OnCallSchedules|Rotation length" msgstr "" +msgid "OnCallSchedules|Rotation length must be a positive number" +msgstr "" + msgid "OnCallSchedules|Rotation name cannot be empty" msgstr "" diff --git a/package.json b/package.json index 7cd85dec640..bb57680aa23 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@gitlab/favicon-overlay": "2.0.0", "@gitlab/fonts": "^1.2.0", "@gitlab/svgs": "3.18.0", - "@gitlab/ui": "54.1.2", + "@gitlab/ui": "54.2.3", "@gitlab/visual-review-tools": "1.7.3", "@gitlab/web-ide": "0.0.1-dev-20230120231236", "@rails/actioncable": "6.1.4-7", diff --git a/qa/qa/page/component/dropdown.rb b/qa/qa/page/component/dropdown.rb index 33ea1ee8d1b..7062c5c7132 100644 --- a/qa/qa/page/component/dropdown.rb +++ b/qa/qa/page/component/dropdown.rb @@ -9,26 +9,26 @@ module QA def select_item(item_text) return super if use_select2? - find('li.gl-dropdown-item', text: item_text, match: :prefer_exact).click + find('li.gl-new-dropdown-item', text: item_text, match: :prefer_exact).click end def has_item?(item_text) return super if use_select2? - has_css?('li.gl-dropdown-item', text: item_text, match: :prefer_exact) + has_css?('li.gl-new-dropdown-item', text: item_text, match: :prefer_exact) end def current_selection return super if use_select2? expand_select_list unless dropdown_open? - find('span.gl-dropdown-button-text').text + find('span.gl-new-dropdown-button-text').text end def all_items raise NotImplementedError if use_select2? - find_all("li.gl-dropdown-item").map(&:text) + find_all("li.gl-new-dropdown-item").map(&:text) end def clear_current_selection_if_present @@ -80,13 +80,13 @@ module QA raise QA::Page::Base::ElementNotFound, %(Couldn't find option named "#{item_text}") end - find('li.gl-dropdown-item span:nth-child(2)', text: item_text, exact_text: true).click + find('li.gl-new-dropdown-item span:nth-child(2)', text: item_text, exact_text: true).click end def expand_select_list return super if use_select2? - find('svg.dropdown-chevron').click + find('.gl-new-dropdown-toggle').click end def wait_for_search_to_complete @@ -101,7 +101,7 @@ module QA def dropdown_open? return super if use_select2? - has_css?('ul.gl-dropdown-contents', wait: 1) + has_css?('ul.gl-new-dropdown-contents', wait: 1) end def find_input_by_prefix_and_set(element_prefix, item_text) diff --git a/spec/factories/bulk_import/entities.rb b/spec/factories/bulk_import/entities.rb index 5d8d91ab07a..a662d42c7c9 100644 --- a/spec/factories/bulk_import/entities.rb +++ b/spec/factories/bulk_import/entities.rb @@ -8,7 +8,7 @@ FactoryBot.define do sequence(:source_full_path) { |n| "source-path-#{n}" } sequence(:destination_namespace) { |n| "destination-path-#{n}" } - destination_name { 'imported-entity' } + destination_slug { 'imported-entity' } sequence(:source_xid) migrate_projects { true } diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 975af84969d..07db0750074 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'Admin::Users', feature_category: :user_management do include Spec::Support::Helpers::Features::AdminUsersHelpers include Spec::Support::Helpers::ModalHelpers + include ListboxHelpers let_it_be(:user, reload: true) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') } let_it_be(:current_user) { create(:admin) } @@ -608,8 +609,8 @@ RSpec.describe 'Admin::Users', feature_category: :user_management do def sort_by(option) page.within('.filtered-search-block') do - find('.gl-dropdown').click - find('.gl-dropdown-item', text: option).click + find('.gl-new-dropdown').click + select_listbox_item(option) end end end diff --git a/spec/features/incidents/incident_timeline_events_spec.rb b/spec/features/incidents/incident_timeline_events_spec.rb index ffab23c58bc..7404ac64cc9 100644 --- a/spec/features/incidents/incident_timeline_events_spec.rb +++ b/spec/features/incidents/incident_timeline_events_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Incident timeline events', :js, feature_category: :incident_management do + include ListboxHelpers + let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user, developer_projects: [project]) } let_it_be(:incident) { create(:incident, project: project) } @@ -47,11 +49,7 @@ RSpec.describe 'Incident timeline events', :js, feature_category: :incident_mana # Add event click_button(s_('Incident|Add new timeline event')) - click_button _('Select tags') - page.within '.gl-dropdown-inner' do - expect(page).to have_content(_('Start time')) - page.find('.gl-dropdown-item-text-wrapper', text: _('Start time')).click - end + select_from_listbox('Start time', from: 'Select tags') complete_form('Event note goes here', '07', '25') @@ -64,11 +62,9 @@ RSpec.describe 'Incident timeline events', :js, feature_category: :incident_mana # Edit event trigger_dropdown_action(_('Edit')) - click_button _('Start time') - page.within '.gl-dropdown-inner' do - page.find('.gl-dropdown-item-text-wrapper', text: _('Start time')).click - end + select_from_listbox('Start time', from: 'Start time') + complete_form('Edited event note goes here', '08', '30') page.within '.timeline-event-note' do diff --git a/spec/features/issuables/sorting_list_spec.rb b/spec/features/issuables/sorting_list_spec.rb index b5362267309..9045124cc8c 100644 --- a/spec/features/issuables/sorting_list_spec.rb +++ b/spec/features/issuables/sorting_list_spec.rb @@ -2,6 +2,8 @@ require 'spec_helper' RSpec.describe 'Sort Issuable List', feature_category: :team_planning do + include ListboxHelpers + let(:project) { create(:project, :public) } let(:first_created_issuable) { issuables.order_created_asc.first } @@ -94,8 +96,7 @@ RSpec.describe 'Sort Issuable List', feature_category: :team_planning do it 'supports sorting in asc and desc order' do visit_merge_requests_with_state(project, 'open') - click_button('Created date') - find('.dropdown-item', text: 'Updated date').click + select_from_listbox('Updated date', from: 'Created date') expect(first_merge_request).to include(last_updated_issuable.title) expect(last_merge_request).to include(first_updated_issuable.title) @@ -209,7 +210,7 @@ RSpec.describe 'Sort Issuable List', feature_category: :team_planning do end def selected_sort_order - find('.filter-dropdown-container .dropdown button').text.downcase + find('.filter-dropdown-container .gl-new-dropdown button').text.downcase end def visit_merge_requests_with_state(project, state) diff --git a/spec/features/jira_connect/branches_spec.rb b/spec/features/jira_connect/branches_spec.rb index 8cf07f2ade2..c90c0d2dda9 100644 --- a/spec/features/jira_connect/branches_spec.rb +++ b/spec/features/jira_connect/branches_spec.rb @@ -20,8 +20,8 @@ RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integ sign_in(alice) end - def within_dropdown(&block) - within('.dropdown-menu', &block) + def within_project_listbox(&block) + within('#project-select', &block) end it 'select project and branch and submit the form' do @@ -35,16 +35,16 @@ RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integ click_on 'Select a project' - within_dropdown do - expect(page).to have_text('Alice / foo') - expect(page).to have_text('Alice / bar') - expect(page).not_to have_text('Bob /') + within_project_listbox do + expect_listbox_item('Alice / foo') + expect_listbox_item('Alice / bar') + expect_no_listbox_item('Bob /') fill_in 'Search', with: 'foo' - expect(page).not_to have_text('Alice / bar') + expect_no_listbox_item('Alice / bar') - find('span', text: 'Alice / foo', match: :first).click + select_listbox_item('Alice / foo') end expect(page).to have_field('Branch name', with: 'ACME-123-my-issue-title') @@ -61,9 +61,9 @@ RSpec.describe 'Create GitLab branches from Jira', :js, feature_category: :integ find('span', text: 'Alice / foo', match: :first).click - within_dropdown do + within_project_listbox do fill_in 'Search', with: '' - find('span', text: 'Alice / bar', match: :first).click + select_listbox_item('Alice / bar') end click_on 'master' diff --git a/spec/features/merge_request/user_creates_merge_request_spec.rb b/spec/features/merge_request/user_creates_merge_request_spec.rb index 6be0eee21fc..97b423f2cc2 100644 --- a/spec/features/merge_request/user_creates_merge_request_spec.rb +++ b/spec/features/merge_request/user_creates_merge_request_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'User creates a merge request', :js, feature_category: :code_review_workflow do include ProjectForksHelper + include ListboxHelpers shared_examples 'creates a merge request' do specify do @@ -155,7 +156,7 @@ RSpec.describe 'User creates a merge request', :js, feature_category: :code_revi wait_for_requests find('.gl-listbox-search-input').set(project.full_path) - first('.gl-dropdown-item', text: project.full_path).click + select_listbox_item(project.full_path) end def select_branch(selector, branch) @@ -164,6 +165,6 @@ RSpec.describe 'User creates a merge request', :js, feature_category: :code_revi wait_for_requests find('.gl-listbox-search-input').set(branch) - first('.gl-dropdown-item', text: branch).click + select_listbox_item(branch, exact_text: true) end end diff --git a/spec/features/merge_request/user_creates_mr_spec.rb b/spec/features/merge_request/user_creates_mr_spec.rb index cde1b71a7ee..6ee20a08a47 100644 --- a/spec/features/merge_request/user_creates_mr_spec.rb +++ b/spec/features/merge_request/user_creates_mr_spec.rb @@ -61,7 +61,7 @@ RSpec.describe 'Merge request > User creates MR', feature_category: :code_review find('.js-source-project').click find('.gl-listbox-search-input').set('source') - expect(first('.merge-request-select .dropdown-menu')).not_to have_content(source_project.name) + expect(first('.merge-request-select .gl-new-dropdown-panel')).not_to have_content(source_project.name) end end end diff --git a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb index f79821e9420..0de59ea21c5 100644 --- a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb +++ b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb @@ -3,13 +3,15 @@ require 'spec_helper' RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_category: :code_review_workflow do + include ListboxHelpers + let(:project) { create(:project, :public, :repository) } let(:user) { project.creator } def select_source_branch(branch_name) find('.js-source-branch', match: :first).click find('.gl-listbox-search-input').native.send_keys branch_name - find('.gl-dropdown-item', text: branch_name, match: :first).click + select_listbox_item(branch_name) end before do @@ -27,7 +29,7 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_ expect(page).to have_content('Target branch') first('.js-source-branch').click - find('.gl-dropdown-item', match: :first).click + find('.gl-new-dropdown-item', match: :first).click expect(page).to have_content "b83d6e3" end @@ -44,7 +46,7 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js, feature_ first('.js-target-branch').click find('.gl-listbox-search-input').native.send_keys 'v1.1.0' - find('.gl-dropdown-item', text: 'v1.1.0', match: :first).click + select_listbox_item('v1.1.0') expect(page).to have_content "b83d6e3" end diff --git a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb index cf99f2cb94a..58d796f8288 100644 --- a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb +++ b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb @@ -27,15 +27,15 @@ RSpec.describe 'User sorts merge requests', :js, feature_category: :code_review_ visit(merge_requests_dashboard_path(assignee_username: user.username)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') visit(project_merge_requests_path(project)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') visit(merge_requests_group_path(group)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') end it 'fallbacks to issuable_sort cookie key when remembering the sorting option' do @@ -43,7 +43,7 @@ RSpec.describe 'User sorts merge requests', :js, feature_category: :code_review_ visit(merge_requests_dashboard_path(assignee_username: user.username)) - expect(find('.filter-dropdown-container button.dropdown-toggle')).to have_content('Milestone') + expect(find('.filter-dropdown-container button.gl-new-dropdown-toggle')).to have_content('Milestone') end it 'separates remember sorting with issues', :js do diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 6a44f421249..b5f640f1cca 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -597,8 +597,8 @@ RSpec.describe 'Pipelines', :js, feature_category: :projects do it 'changes the Pipeline ID column for Pipeline IID' do page.find('[data-testid="pipeline-key-collapsible-box"]').click - within '.gl-dropdown-contents' do - dropdown_options = page.find_all '.gl-dropdown-item' + within '.gl-new-dropdown-contents' do + dropdown_options = page.find_all '.gl-new-dropdown-item' dropdown_options[1].click end @@ -675,7 +675,7 @@ RSpec.describe 'Pipelines', :js, feature_category: :projects do click_button project.default_branch wait_for_requests - find('.gl-dropdown-item', text: 'master').click + find('.gl-new-dropdown-item', text: 'master').click wait_for_requests end diff --git a/spec/frontend/ci/runner/components/runner_header_spec.js b/spec/frontend/ci/runner/components/runner_header_spec.js index a04011de1cd..abe3b47767e 100644 --- a/spec/frontend/ci/runner/components/runner_header_spec.js +++ b/spec/frontend/ci/runner/components/runner_header_spec.js @@ -6,7 +6,7 @@ import { GROUP_TYPE, STATUS_ONLINE, } from '~/ci/runner/constants'; -import { TYPE_CI_RUNNER } from '~/graphql_shared/constants'; +import { TYPENAME_CI_RUNNER } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; @@ -71,7 +71,7 @@ describe('RunnerHeader', () => { it('displays the runner id', () => { createComponent({ runner: { - id: convertToGraphQLId(TYPE_CI_RUNNER, 99), + id: convertToGraphQLId(TYPENAME_CI_RUNNER, 99), }, }); @@ -99,7 +99,7 @@ describe('RunnerHeader', () => { it('does not display runner creation time if "createdAt" is missing', () => { createComponent({ runner: { - id: convertToGraphQLId(TYPE_CI_RUNNER, 99), + id: convertToGraphQLId(TYPENAME_CI_RUNNER, 99), createdAt: null, }, }); diff --git a/spec/frontend/issues/show/components/description_spec.js b/spec/frontend/issues/show/components/description_spec.js index 9f36204139f..309930afa4d 100644 --- a/spec/frontend/issues/show/components/description_spec.js +++ b/spec/frontend/issues/show/components/description_spec.js @@ -261,7 +261,7 @@ describe('Description component', () => { }); }); - describe('with work_items_create_from_markdown feature flag enabled', () => { + describe('with work_items_mvc_2 feature flag enabled', () => { describe('empty description', () => { beforeEach(() => { createComponent({ @@ -270,7 +270,7 @@ describe('Description component', () => { }, provide: { glFeatures: { - workItemsCreateFromMarkdown: true, + workItemsMvc2: true, }, }, }); @@ -290,7 +290,7 @@ describe('Description component', () => { }, provide: { glFeatures: { - workItemsCreateFromMarkdown: true, + workItemsMvc2: true, }, }, }); @@ -330,7 +330,7 @@ describe('Description component', () => { 1. [ ] item 4;`; createComponent({ props: { descriptionText }, - provide: { glFeatures: { workItemsCreateFromMarkdown: true } }, + provide: { glFeatures: { workItemsMvc2: true } }, }); eventHub.$emit('delete-task-list-item', '4:4-5:19'); @@ -348,7 +348,7 @@ describe('Description component', () => { descriptionHtml: descriptionHtmlWithTask, }, provide: { - glFeatures: { workItemsCreateFromMarkdown: true }, + glFeatures: { workItemsMvc2: true }, }, }); return nextTick(); @@ -410,7 +410,7 @@ describe('Description component', () => { createComponent({ props: { descriptionHtml: descriptionHtmlWithTask }, - provide: { glFeatures: { workItemsCreateFromMarkdown: true } }, + provide: { glFeatures: { workItemsMvc2: true } }, }); expect(showDetailsModal).toHaveBeenCalledTimes(modalOpened); @@ -426,7 +426,7 @@ describe('Description component', () => { descriptionHtml: descriptionHtmlWithTask, }, provide: { - glFeatures: { workItemsCreateFromMarkdown: true }, + glFeatures: { workItemsMvc2: true }, }, }); return nextTick(); diff --git a/spec/frontend/language_switcher/components/app_spec.js b/spec/frontend/language_switcher/components/app_spec.js index effb71c2775..7f6fb138d89 100644 --- a/spec/frontend/language_switcher/components/app_spec.js +++ b/spec/frontend/language_switcher/components/app_spec.js @@ -28,7 +28,7 @@ describe('<LanguageSwitcher />', () => { wrapper.destroy(); }); - const getPreferredLanguage = () => wrapper.find('.gl-dropdown-button-text').text(); + const getPreferredLanguage = () => wrapper.find('.gl-new-dropdown-button-text').text(); const findLanguageDropdownItem = (code) => wrapper.findByTestId(`language_switcher_lang_${code}`); const findFooter = () => wrapper.findByTestId('footer'); diff --git a/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js b/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js index cb3bb7a4538..452240dd81b 100644 --- a/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js +++ b/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js @@ -7,7 +7,7 @@ import waitForPromises from 'helpers/wait_for_promises'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import CreateTimelogForm from '~/sidebar/components/time_tracking/create_timelog_form.vue'; import createTimelogMutation from '~/sidebar/queries/create_timelog.mutation.graphql'; -import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; const mockMutationErrorMessage = 'Example error message'; @@ -157,7 +157,7 @@ describe('Create Timelog Form', () => { it.each` issuableType | typeConstant - ${'issue'} | ${TYPE_ISSUE} + ${'issue'} | ${TYPENAME_ISSUE} ${'merge_request'} | ${TYPE_MERGE_REQUEST} `( 'calls the mutation with all the fields when the the form is submitted and issuable type is $issuableType', diff --git a/spec/helpers/snippets_helper_spec.rb b/spec/helpers/snippets_helper_spec.rb index 48f67a291c4..43e663464c8 100644 --- a/spec/helpers/snippets_helper_spec.rb +++ b/spec/helpers/snippets_helper_spec.rb @@ -80,10 +80,25 @@ RSpec.describe SnippetsHelper do context 'for Project Snippets' do let(:snippet) { public_project_snippet } + let(:project) { snippet.project } it 'returns copy button of embedded snippets' do expect(subject).to eq(copy_button(blob.id.to_s)) end + + describe 'path helpers' do + specify '#toggle_award_emoji_project_project_snippet_path' do + expect(toggle_award_emoji_project_project_snippet_path(project, snippet, a: 1)).to eq( + "/#{project.full_path}/-/snippets/#{snippet.id}/toggle_award_emoji?a=1" + ) + end + + specify '#toggle_award_emoji_project_project_snippet_url' do + expect(toggle_award_emoji_project_project_snippet_url(project, snippet, a: 1)).to eq( + "http://test.host/#{project.full_path}/-/snippets/#{snippet.id}/toggle_award_emoji?a=1" + ) + end + end end def copy_button(blob_id) diff --git a/spec/lib/bulk_imports/common/pipelines/boards_pipeline_spec.rb b/spec/lib/bulk_imports/common/pipelines/boards_pipeline_spec.rb index 241bd694a2c..badc4a45c86 100644 --- a/spec/lib/bulk_imports/common/pipelines/boards_pipeline_spec.rb +++ b/spec/lib/bulk_imports/common/pipelines/boards_pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Common::Pipelines::BoardsPipeline do +RSpec.describe BulkImports::Common::Pipelines::BoardsPipeline, feature_category: :importers do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } @@ -53,7 +53,7 @@ RSpec.describe BulkImports::Common::Pipelines::BoardsPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Group', + destination_slug: 'My-Destination-Group', destination_namespace: group.full_path ) end @@ -78,7 +78,7 @@ RSpec.describe BulkImports::Common::Pipelines::BoardsPipeline do group: group, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Group', + destination_slug: 'My-Destination-Group', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb b/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb index ac516418ce8..23368f38889 100644 --- a/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb +++ b/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Common::Pipelines::LabelsPipeline do +RSpec.describe BulkImports::Common::Pipelines::LabelsPipeline, feature_category: :importers do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:bulk_import) { create(:bulk_import, user: user) } @@ -13,7 +13,7 @@ RSpec.describe BulkImports::Common::Pipelines::LabelsPipeline do group: group, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Group', + destination_slug: 'My-Destination-Group', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/common/pipelines/milestones_pipeline_spec.rb b/spec/lib/bulk_imports/common/pipelines/milestones_pipeline_spec.rb index 902b29bc365..8a61e927712 100644 --- a/spec/lib/bulk_imports/common/pipelines/milestones_pipeline_spec.rb +++ b/spec/lib/bulk_imports/common/pipelines/milestones_pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Common::Pipelines::MilestonesPipeline do +RSpec.describe BulkImports::Common::Pipelines::MilestonesPipeline, feature_category: :importers do let(:user) { create(:user) } let(:group) { create(:group) } let(:bulk_import) { create(:bulk_import, user: user) } @@ -97,7 +97,7 @@ RSpec.describe BulkImports::Common::Pipelines::MilestonesPipeline do group: group, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Group', + destination_slug: 'My-Destination-Group', destination_namespace: group.full_path ) end @@ -119,7 +119,7 @@ RSpec.describe BulkImports::Common::Pipelines::MilestonesPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/common/pipelines/wiki_pipeline_spec.rb b/spec/lib/bulk_imports/common/pipelines/wiki_pipeline_spec.rb index 0eefb7390dc..30eef0b9f9e 100644 --- a/spec/lib/bulk_imports/common/pipelines/wiki_pipeline_spec.rb +++ b/spec/lib/bulk_imports/common/pipelines/wiki_pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Common::Pipelines::WikiPipeline do +RSpec.describe BulkImports::Common::Pipelines::WikiPipeline, feature_category: :importers do describe '#run' do let_it_be(:user) { create(:user) } let_it_be(:bulk_import) { create(:bulk_import, user: user) } @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Common::Pipelines::WikiPipeline do :project_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Wiki', + destination_slug: 'My-Destination-Wiki', destination_namespace: parent.full_path, project: parent ) diff --git a/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb index c07d27e973f..395f3568913 100644 --- a/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb +++ b/spec/lib/bulk_imports/groups/pipelines/project_entities_pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Groups::Pipelines::ProjectEntitiesPipeline do +RSpec.describe BulkImports::Groups::Pipelines::ProjectEntitiesPipeline, feature_category: :importers do let_it_be(:user) { create(:user) } let_it_be(:destination_group) { create(:group) } @@ -20,8 +20,9 @@ RSpec.describe BulkImports::Groups::Pipelines::ProjectEntitiesPipeline do let(:extracted_data) do BulkImports::Pipeline::ExtractedData.new(data: { 'id' => 'gid://gitlab/Project/1234567', - 'name' => 'project', - 'full_path' => 'group/project' + 'name' => 'My Project', + 'path' => 'my-project', + 'full_path' => 'group/my-project' }) end @@ -42,8 +43,9 @@ RSpec.describe BulkImports::Groups::Pipelines::ProjectEntitiesPipeline do project_entity = BulkImports::Entity.last expect(project_entity.source_type).to eq('project_entity') - expect(project_entity.source_full_path).to eq('group/project') - expect(project_entity.destination_name).to eq('project') + expect(project_entity.source_full_path).to eq('group/my-project') + expect(project_entity.destination_slug).to eq('my-project') + expect(project_entity.destination_name).to eq('my-project') expect(project_entity.destination_namespace).to eq(destination_group.full_path) expect(project_entity.source_xid).to eq(1234567) end diff --git a/spec/lib/bulk_imports/pipeline/context_spec.rb b/spec/lib/bulk_imports/pipeline/context_spec.rb index 83d6f494d53..0f1d00172cd 100644 --- a/spec/lib/bulk_imports/pipeline/context_spec.rb +++ b/spec/lib/bulk_imports/pipeline/context_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Pipeline::Context do create( :bulk_import_entity, source_full_path: 'source/full/path', - destination_name: 'My Destination Group', + destination_slug: 'My-Destination-Group', destination_namespace: group.full_path, group: group, bulk_import: bulk_import diff --git a/spec/lib/bulk_imports/projects/pipelines/auto_devops_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/auto_devops_pipeline_spec.rb index e2744a6a457..b35ba612197 100644 --- a/spec/lib/bulk_imports/projects/pipelines/auto_devops_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/auto_devops_pipeline_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::AutoDevopsPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/ci_pipelines_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/ci_pipelines_pipeline_spec.rb index 98a2e8b6a57..a78f524b227 100644 --- a/spec/lib/bulk_imports/projects/pipelines/ci_pipelines_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/ci_pipelines_pipeline_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::CiPipelinesPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/issues_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/issues_pipeline_spec.rb index 19e3a1fecc3..a0789522ea8 100644 --- a/spec/lib/bulk_imports/projects/pipelines/issues_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/issues_pipeline_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::IssuesPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/merge_requests_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/merge_requests_pipeline_spec.rb index e780cde4ae2..5b85b3eee79 100644 --- a/spec/lib/bulk_imports/projects/pipelines/merge_requests_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/merge_requests_pipeline_spec.rb @@ -15,7 +15,7 @@ RSpec.describe BulkImports::Projects::Pipelines::MergeRequestsPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/pipeline_schedules_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/pipeline_schedules_pipeline_spec.rb index 12713f008bb..0bfd9410808 100644 --- a/spec/lib/bulk_imports/projects/pipelines/pipeline_schedules_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/pipeline_schedules_pipeline_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::PipelineSchedulesPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb index 567a0a4fcc3..09385a261b6 100644 --- a/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/project_pipeline_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::ProjectPipeline do source_type: :project_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/releases_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/releases_pipeline_spec.rb index a376cdd712c..339ca727b57 100644 --- a/spec/lib/bulk_imports/projects/pipelines/releases_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/releases_pipeline_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::ReleasesPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/repository_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/repository_pipeline_spec.rb index a968104fc91..0cc8da80a61 100644 --- a/spec/lib/bulk_imports/projects/pipelines/repository_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/repository_pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Projects::Pipelines::RepositoryPipeline do +RSpec.describe BulkImports::Projects::Pipelines::RepositoryPipeline, feature_category: :importers do let_it_be(:user) { create(:user) } let_it_be(:parent) { create(:project) } let_it_be(:bulk_import) { create(:bulk_import, user: user) } @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::RepositoryPipeline do :project_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Repository', + destination_slug: 'My-Destination-Repository', destination_namespace: parent.full_path, project: parent ) diff --git a/spec/lib/bulk_imports/projects/pipelines/snippets_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/snippets_pipeline_spec.rb index dae879de998..41b3ea37804 100644 --- a/spec/lib/bulk_imports/projects/pipelines/snippets_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/snippets_pipeline_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Pipelines::SnippetsPipeline do project: project, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: group.full_path ) end diff --git a/spec/lib/bulk_imports/projects/pipelines/snippets_repository_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/snippets_repository_pipeline_spec.rb index dfd01cdf4bb..56c0f8c8807 100644 --- a/spec/lib/bulk_imports/projects/pipelines/snippets_repository_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/snippets_repository_pipeline_spec.rb @@ -15,7 +15,7 @@ RSpec.describe BulkImports::Projects::Pipelines::SnippetsRepositoryPipeline do project: project, bulk_import: bulk_import_configuration.bulk_import, source_full_path: 'source/full/path', - destination_name: 'My Destination Project', + destination_slug: 'My-Destination-Project', destination_namespace: project.full_path ) end diff --git a/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb index a62d82da35d..36dc63a9331 100644 --- a/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb +++ b/spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb @@ -14,7 +14,7 @@ RSpec.describe BulkImports::Projects::Transformers::ProjectAttributesTransformer source_type: :project_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_slug: 'Destination Project Name', + destination_slug: 'Destination-Project-Name', destination_namespace: destination_namespace ) end @@ -58,7 +58,7 @@ RSpec.describe BulkImports::Projects::Transformers::ProjectAttributesTransformer source_type: :project_entity, bulk_import: bulk_import, source_full_path: 'source/full/path', - destination_slug: 'Destination Project Name', + destination_slug: 'Destination-Project-Name', destination_namespace: '' ) diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb index 353b8eb7edb..0def40bd4e4 100644 --- a/spec/lib/gitlab/regex_spec.rb +++ b/spec/lib/gitlab/regex_spec.rb @@ -21,6 +21,7 @@ RSpec.describe Gitlab::Regex, feature_category: :tooling do it_behaves_like 'project/group name chars regex' it { is_expected.not_to match('?gitlab') } it { is_expected.not_to match("Users's something") } + it { is_expected.not_to match('users/something') } end shared_examples_for 'project name regex' do @@ -28,6 +29,7 @@ RSpec.describe Gitlab::Regex, feature_category: :tooling do it { is_expected.to match("Gitlab++") } it { is_expected.not_to match('?gitlab') } it { is_expected.not_to match("Users's something") } + it { is_expected.not_to match('users/something') } end describe '.project_name_regex' do @@ -72,8 +74,47 @@ RSpec.describe Gitlab::Regex, feature_category: :tooling do it { is_expected.to eq("can contain only letters, digits, emojis, '_', '.', dash, space, parenthesis. It must start with letter, digit, emoji or '_'.") } end - describe '.bulk_import_namespace_path_regex' do - subject { described_class.bulk_import_namespace_path_regex } + describe '.bulk_import_destination_namespace_path_regex_message' do + subject { described_class.bulk_import_destination_namespace_path_regex_message } + + it { + is_expected + .to eq("cannot start with a non-alphanumeric character except for periods or underscores, " \ + "can contain only alphanumeric characters, forward slashes, periods, and underscores, " \ + "cannot end with a period or forward slash, and has a relative path structure " \ + "with no http protocol chars or leading or trailing forward slashes") + } + end + + describe '.bulk_import_destination_namespace_path_regex' do + subject { described_class.bulk_import_destination_namespace_path_regex } + + it { is_expected.not_to match('?gitlab') } + it { is_expected.not_to match("Users's something") } + it { is_expected.not_to match('/source') } + it { is_expected.not_to match('http:') } + it { is_expected.not_to match('https:') } + it { is_expected.not_to match('example.com/?stuff=true') } + it { is_expected.not_to match('example.com:5000/?stuff=true') } + it { is_expected.not_to match('http://gitlab.example/gitlab-org/manage/import/gitlab-migration-test') } + it { is_expected.not_to match('_good_for_me!') } + it { is_expected.not_to match('good_for+you') } + it { is_expected.not_to match('source/') } + it { is_expected.not_to match('.source/full./path') } + + it { is_expected.to match('source') } + it { is_expected.to match('.source') } + it { is_expected.to match('_source') } + it { is_expected.to match('source/full') } + it { is_expected.to match('source/full/path') } + it { is_expected.to match('.source/.full/.path') } + it { is_expected.to match('domain_namespace') } + it { is_expected.to match('gitlab-migration-test') } + it { is_expected.to match('') } # it is possible to pass an empty string for destination_namespace in bulk_import POST request + end + + describe '.bulk_import_source_full_path_regex' do + subject { described_class.bulk_import_source_full_path_regex } it { is_expected.not_to match('?gitlab') } it { is_expected.not_to match("Users's something") } @@ -87,6 +128,7 @@ RSpec.describe Gitlab::Regex, feature_category: :tooling do it { is_expected.not_to match('good_for+you') } it { is_expected.not_to match('source/') } it { is_expected.not_to match('.source/full./path') } + it { is_expected.not_to match('') } it { is_expected.to match('source') } it { is_expected.to match('.source') } diff --git a/spec/models/bulk_imports/entity_spec.rb b/spec/models/bulk_imports/entity_spec.rb index dd947b5abb3..56796aa1fe4 100644 --- a/spec/models/bulk_imports/entity_spec.rb +++ b/spec/models/bulk_imports/entity_spec.rb @@ -17,6 +17,38 @@ RSpec.describe BulkImports::Entity, type: :model, feature_category: :importers d it { is_expected.to define_enum_for(:source_type).with_values(%i[group_entity project_entity]) } + context 'when formatting with regexes' do + subject { described_class.new(group: Group.new) } + + it { is_expected.to allow_values('namespace', 'parent/namespace', 'parent/group/subgroup', '').for(:destination_namespace) } + it { is_expected.not_to allow_values('parent/namespace/', '/namespace', 'parent group/subgroup', '@namespace').for(:destination_namespace) } + + it { is_expected.to allow_values('source', 'source/path', 'source/full/path').for(:source_full_path) } + it { is_expected.not_to allow_values('/source', 'http://source/path', 'sou rce/full/path', '').for(:source_full_path) } + + it { is_expected.to allow_values('destination', 'destination-slug', 'new-destination-slug').for(:destination_slug) } + + # it { is_expected.not_to allow_values('destination/slug', '/destination-slug', 'destination slug').for(:destination_slug) } <-- this test should + # succeed but it's failing possibly due to rspec caching. To ensure this case is covered see the more cumbersome test below: + context 'when destination_slug is invalid' do + let(:invalid_slugs) { ['destination/slug', '/destination-slug', 'destination slug'] } + let(:error_message) do + 'cannot start with a non-alphanumeric character except for periods or underscores, ' \ + 'can contain only alphanumeric characters, periods, and underscores, ' \ + 'cannot end with a period or forward slash, and has no ' \ + 'leading or trailing forward slashes' + end + + it 'raises an error' do + invalid_slugs.each do |slug| + entity = build(:bulk_import_entity, :group_entity, group: build(:group), project: nil, destination_slug: slug) + expect(entity).not_to be_valid + expect(entity.errors.errors[0].message).to include(error_message) + end + end + end + end + context 'when associated with a group and project' do it 'is invalid' do entity = build(:bulk_import_entity, group: build(:group), project: build(:project)) diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index a3982263de8..2b0791323ff 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -2,16 +2,16 @@ require 'spec_helper' -RSpec.describe Ci::Build, feature_category: :continuous_integration do +RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_default: :keep do include Ci::TemplateHelpers include AfterNextHelpers let_it_be(:user) { create(:user) } - let_it_be(:group, reload: true) { create(:group) } - let_it_be(:project, reload: true) { create(:project, :repository, group: group) } + let_it_be(:group, reload: true) { create_default(:group) } + let_it_be(:project, reload: true) { create_default(:project, :repository, group: group) } let_it_be(:pipeline, reload: true) do - create(:ci_pipeline, project: project, + create_default(:ci_pipeline, project: project, sha: project.commit.id, ref: project.default_branch, status: 'success') @@ -904,9 +904,7 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration do subject(:locked_artifacts) { build.locked_artifacts? } context 'when pipeline is artifacts_locked' do - before do - build.pipeline.artifacts_locked! - end + let(:pipeline) { create(:ci_pipeline, locked: :artifacts_locked) } context 'artifacts archive does not exist' do let(:build) { create(:ci_build, pipeline: pipeline) } @@ -922,9 +920,7 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration do end context 'when pipeline is unlocked' do - before do - build.pipeline.unlocked! - end + let(:pipeline) { create(:ci_pipeline, locked: :unlocked) } context 'artifacts archive does not exist' do let(:build) { create(:ci_build, pipeline: pipeline) } diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 7e4354221fa..1a255379098 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -3549,13 +3549,6 @@ RSpec.describe Group, feature_category: :subgroups do end end - describe '#work_items_create_from_markdown_feature_flag_enabled?' do - it_behaves_like 'checks self and root ancestor feature flag' do - let(:feature_flag) { :work_items_create_from_markdown } - let(:feature_flag_method) { :work_items_create_from_markdown_feature_flag_enabled? } - end - end - describe 'group shares' do let!(:sub_group) { create(:group, parent: group) } let!(:sub_sub_group) { create(:group, parent: sub_group) } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index f277dd054ee..9d6ab7d6137 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -8449,16 +8449,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do end end - describe '#work_items_create_from_markdown_feature_flag_enabled?' do - let_it_be(:group_project) { create(:project, :in_subgroup) } - - it_behaves_like 'checks parent group feature flag' do - let(:feature_flag_method) { :work_items_create_from_markdown_feature_flag_enabled? } - let(:feature_flag) { :work_items_create_from_markdown } - let(:subject_project) { group_project } - end - end - describe 'serialization' do let(:object) { build(:project) } diff --git a/spec/presenters/user_presenter_spec.rb b/spec/presenters/user_presenter_spec.rb index 883eec68304..d1124d73dbd 100644 --- a/spec/presenters/user_presenter_spec.rb +++ b/spec/presenters/user_presenter_spec.rb @@ -17,6 +17,14 @@ RSpec.describe UserPresenter do it { expect(presenter.web_url).to eq("http://localhost/#{user.username}") } end + describe '#can?' do + it 'forwards call to the given user' do + expect(user).to receive(:can?).with("a", b: 24) + + presenter.send(:can?, "a", b: 24) + end + end + context 'Gitpod' do let(:gitpod_url) { "https://gitpod.io" } let(:gitpod_application_enabled) { true } diff --git a/spec/services/bulk_imports/create_service_spec.rb b/spec/services/bulk_imports/create_service_spec.rb index 3086184c5b3..7f892cfe722 100644 --- a/spec/services/bulk_imports/create_service_spec.rb +++ b/spec/services/bulk_imports/create_service_spec.rb @@ -8,6 +8,7 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do let(:destination_group) { create(:group, path: 'destination1') } let(:migrate_projects) { true } let_it_be(:parent_group) { create(:group, path: 'parent-group') } + # note: destination_name and destination_slug are currently interchangable so we need to test for both possibilities let(:params) do [ { @@ -20,7 +21,7 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do { source_type: 'group_entity', source_full_path: 'full/path/to/group2', - destination_slug: 'destination-group-2', + destination_name: 'destination-group-2', destination_namespace: 'parent-group', migrate_projects: migrate_projects }, @@ -225,7 +226,12 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do expect(result).to be_a(ServiceResponse) expect(result).to be_error - expect(result.message).to eq("Validation failed: Source full path can't be blank") + expect(result.message).to eq("Validation failed: Source full path can't be blank, " \ + "Source full path cannot start with a non-alphanumeric character except " \ + "for periods or underscores, can contain only alphanumeric characters, " \ + "forward slashes, periods, and underscores, cannot end with " \ + "a period or forward slash, and has a relative path structure " \ + "with no http protocol chars or leading or trailing forward slashes") end describe '#user-role' do diff --git a/spec/support/helpers/features/sorting_helpers.rb b/spec/support/helpers/features/sorting_helpers.rb index 50b8083ebb3..504a9b764cf 100644 --- a/spec/support/helpers/features/sorting_helpers.rb +++ b/spec/support/helpers/features/sorting_helpers.rb @@ -26,8 +26,8 @@ module Spec # all of the dropdowns are converted, pajamas_sort_by can be renamed to sort_by # https://gitlab.com/groups/gitlab-org/-/epics/7551 def pajamas_sort_by(value) - find('.filter-dropdown-container .dropdown').click - find('.dropdown-item', text: value).click + find('.filter-dropdown-container .gl-new-dropdown').click + find('.gl-new-dropdown-item', text: value).click end end end diff --git a/spec/support/helpers/listbox_helpers.rb b/spec/support/helpers/listbox_helpers.rb index c23927bb0c0..e943790fc65 100644 --- a/spec/support/helpers/listbox_helpers.rb +++ b/spec/support/helpers/listbox_helpers.rb @@ -7,18 +7,18 @@ module ListboxHelpers end def select_listbox_item(text, exact_text: false) - find('.gl-dropdown-item[role="option"]', text: text, exact_text: exact_text).click + find('.gl-new-dropdown-item[role="option"]', text: text, exact_text: exact_text).click end def expect_listbox_item(text) - expect(page).to have_css('.gl-dropdown-item[role="option"]', text: text) + expect(page).to have_css('.gl-new-dropdown-item[role="option"]', text: text) end def expect_no_listbox_item(text) - expect(page).not_to have_css('.gl-dropdown-item[role="option"]', text: text) + expect(page).not_to have_css('.gl-new-dropdown-item[role="option"]', text: text) end def expect_listbox_items(items) - expect(find_all('.gl-dropdown-item[role="option"]').map(&:text)).to eq(items) + expect(find_all('.gl-new-dropdown-item[role="option"]').map(&:text)).to eq(items) end end diff --git a/spec/support/shared_examples/features/creatable_merge_request_shared_examples.rb b/spec/support/shared_examples/features/creatable_merge_request_shared_examples.rb index 3941a239c51..96e57980c68 100644 --- a/spec/support/shared_examples/features/creatable_merge_request_shared_examples.rb +++ b/spec/support/shared_examples/features/creatable_merge_request_shared_examples.rb @@ -2,6 +2,7 @@ RSpec.shared_examples 'a creatable merge request' do include WaitForRequests + include ListboxHelpers it 'creates new merge request', :js do find('.js-assignee-search').click @@ -64,7 +65,7 @@ RSpec.shared_examples 'a creatable merge request' do visit project_new_merge_request_path(source_project) first('.js-target-project').click - find('.gl-dropdown-item', text: target_project.full_path).click + select_listbox_item(target_project.full_path) wait_for_requests @@ -74,6 +75,6 @@ RSpec.shared_examples 'a creatable merge request' do wait_for_requests - expect(page).to have_selector('.gl-dropdown-item', text: 'a-brand-new-branch-to-test') + expect_listbox_item('a-brand-new-branch-to-test') end end diff --git a/yarn.lock b/yarn.lock index ad5d8588457..f97643431a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1347,10 +1347,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.18.0.tgz#d89364feb42404a35824a54d518b51af8c1e900f" integrity sha512-ni9TmhusXpt/3k/DZzovMEUeB/6UTXiDpuujI8HDBqR4Mwlah6FBco5ZfolkW6YjFL0YvtcLWhnwZA0iM3hfMw== -"@gitlab/ui@54.1.2": - version "54.1.2" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-54.1.2.tgz#c34ca7a34cb1c930e65435f993424f78f17aae50" - integrity sha512-CxtbFg6ULyzk1woLB+8ufOhgziPWVWgd5PMlRhQIWKR0WRfSa9tSii6qWa9vuUh9m8vs9SA9K1MjeLmaVrMB1A== +"@gitlab/ui@54.2.3": + version "54.2.3" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-54.2.3.tgz#8fbaa7de24d326094a6f2a509e38fe6a58bbc17a" + integrity sha512-cQcdO9nHRlgMcz661soOeTJWXEM8lADPxxFuMubkxJfRZcknhdR4RrSiHxQxZT05l2tfCpd7L6yt07r1bCIgLw== dependencies: "@popperjs/core" "^2.11.2" bootstrap-vue "2.20.1" |