From c6d99422d907eaae28c0a6508cd83d21df7977cc Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 14 Mar 2025 21:13:11 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .eslint_todo/vue-no-unused-properties.mjs | 12 -- .rubocop_todo/gitlab/bounded_contexts.yml | 1 - .../gitlab/feature_available_usage.yml | 1 - .rubocop_todo/layout/line_length.yml | 2 - .rubocop_todo/style/if_unless_modifier.yml | 1 - .../admin_runner_show_app.vue | 8 -- .../components/cells/runner_summary_cell.vue | 12 +- .../registration/registration_dropdown.vue | 3 - .../runner_instructions_modal.vue | 3 + .../components/runner_delete_button.vue | 5 - .../runner/components/runner_delete_modal.vue | 2 + .../runner/components/runner_pause_action.vue | 5 - .../ci/runner/components/runner_type_tabs.vue | 1 + .../runner/components/stat/runner_count.vue | 1 + .../group_new_runner/group_new_runner_app.vue | 7 +- .../group_runner_show_app.vue | 8 -- .../project_new_runner_app.vue | 8 +- .../reviewers/sidebar_reviewers.vue | 8 +- .../vue_shared/components/markdown/header.vue | 121 ++++++++++++++++-- .../admin/impersonation_tokens_controller.rb | 2 +- .../concerns/render_access_tokens.rb | 2 +- .../projects/triggers_controller.rb | 6 +- app/models/concerns/reactive_caching.rb | 2 +- app/models/personal_access_token.rb | 9 +- .../groups/mark_for_deletion_service.rb | 17 +++ .../projects/mark_for_deletion_service.rb | 17 +++ .../merge_requests/creations/new.html.haml | 2 +- config/initializers/irb.rb | 2 + ...48_remove_replicas_with_evicted_indices.rb | 25 ++++ db/schema_migrations/20250314113948 | 1 + doc/administration/cells.md | 67 ++++++++++ doc/administration/credentials_inventory.md | 14 +- .../gitlab_duo_self_hosted/troubleshooting.md | 6 + .../credentials_inventory_gpg_keys_v14_9.png | Bin 16956 -> 0 bytes ...inventory_personal_access_tokens_v14_9.png | Bin 34445 -> 0 bytes ..._inventory_project_access_tokens_v14_9.png | Bin 19849 -> 0 bytes .../credentials_inventory_ssh_keys_v14_9.png | Bin 29612 -> 0 bytes doc/api/group_access_tokens.md | 2 +- doc/api/group_service_accounts.md | 1 + doc/api/personal_access_tokens.md | 2 +- doc/api/project_access_tokens.md | 2 +- doc/policy/development_stages_support.md | 2 + doc/user/duo_amazon_q/_index.md | 16 ++- doc/user/gitlab_duo/troubleshooting.md | 6 + doc/user/gitlab_duo_chat/troubleshooting.md | 12 +- doc/user/group/credentials_inventory.md | 4 - ...inventory_personal_access_tokens_v17_5.png | Bin 24010 -> 0 bytes ...p_credentials_inventory_ssh_keys_v17_5.png | Bin 14209 -> 0 bytes doc/user/project/file_lock.md | 94 +++++++------- .../code_suggestions/troubleshooting.md | 6 + doc/user/project/repository/web_editor.md | 2 +- lib/web_ide/extension_marketplace_preset.rb | 2 +- lib/web_ide/settings_sync.rb | 4 +- locale/gitlab.pot | 3 + scripts/frontend/quarantined_vue3_specs.txt | 1 - spec/factories/ci/bridge.rb | 4 +- ...creates_confidential_merge_request_spec.rb | 2 + .../work_items_list_filters_spec.rb | 3 - .../reviewers/sidebar_reviewers_spec.js | 10 +- .../components/markdown/header_spec.js | 69 +++++++++- .../extension_marketplace_preset_spec.rb | 2 +- .../extension_marketplace_validator_spec.rb | 2 +- .../settings/settings_integration_spec.rb | 8 +- spec/lib/web_ide/settings_sync_spec.rb | 11 +- ...move_replicas_with_evicted_indices_spec.rb | 59 +++++++++ spec/models/ci/bridge_spec.rb | 62 +++++++++ spec/models/personal_access_token_spec.rb | 38 +++++- .../organizations_controller_spec.rb | 28 ++-- .../groups/mark_for_deletion_service_spec.rb | 34 +++++ .../mark_for_deletion_service_spec.rb | 34 +++++ .../helpers/reactive_caching_helpers.rb | 2 +- .../helpers/work_item_feedback_helpers.rb | 11 -- .../rolled_up_dates_drawer_shared_examples.rb | 4 - .../rolledup_dates_shared_examples.rb | 4 - 74 files changed, 700 insertions(+), 227 deletions(-) create mode 100644 app/services/groups/mark_for_deletion_service.rb create mode 100644 app/services/projects/mark_for_deletion_service.rb create mode 100644 db/post_migrate/20250314113948_remove_replicas_with_evicted_indices.rb create mode 100644 db/schema_migrations/20250314113948 delete mode 100644 doc/administration/img/credentials_inventory_gpg_keys_v14_9.png delete mode 100644 doc/administration/img/credentials_inventory_personal_access_tokens_v14_9.png delete mode 100644 doc/administration/img/credentials_inventory_project_access_tokens_v14_9.png delete mode 100644 doc/administration/img/credentials_inventory_ssh_keys_v14_9.png delete mode 100644 doc/user/group/img/group_credentials_inventory_personal_access_tokens_v17_5.png delete mode 100644 doc/user/group/img/group_credentials_inventory_ssh_keys_v17_5.png create mode 100644 spec/migrations/db/post_migrate/20250314113948_remove_replicas_with_evicted_indices_spec.rb create mode 100644 spec/services/groups/mark_for_deletion_service_spec.rb create mode 100644 spec/services/projects/mark_for_deletion_service_spec.rb delete mode 100644 spec/support/helpers/work_item_feedback_helpers.rb diff --git a/.eslint_todo/vue-no-unused-properties.mjs b/.eslint_todo/vue-no-unused-properties.mjs index 7419aafde70..6a0bf5f0f06 100644 --- a/.eslint_todo/vue-no-unused-properties.mjs +++ b/.eslint_todo/vue-no-unused-properties.mjs @@ -61,18 +61,6 @@ export default { 'app/assets/javascripts/ci/pipelines_page/components/pipelines_artifacts.vue', 'app/assets/javascripts/ci/pipelines_page/pipelines.vue', 'app/assets/javascripts/ci/reports/components/report_section.vue', - 'app/assets/javascripts/ci/runner/admin_runner_show/admin_runner_show_app.vue', - 'app/assets/javascripts/ci/runner/components/cells/runner_summary_cell.vue', - 'app/assets/javascripts/ci/runner/components/registration/registration_dropdown.vue', - 'app/assets/javascripts/ci/runner/components/registration/runner_instructions/runner_instructions_modal.vue', - 'app/assets/javascripts/ci/runner/components/runner_delete_button.vue', - 'app/assets/javascripts/ci/runner/components/runner_delete_modal.vue', - 'app/assets/javascripts/ci/runner/components/runner_pause_action.vue', - 'app/assets/javascripts/ci/runner/components/runner_type_tabs.vue', - 'app/assets/javascripts/ci/runner/components/stat/runner_count.vue', - 'app/assets/javascripts/ci/runner/group_new_runner/group_new_runner_app.vue', - 'app/assets/javascripts/ci/runner/group_runner_show/group_runner_show_app.vue', - 'app/assets/javascripts/ci/runner/project_new_runner/project_new_runner_app.vue', 'app/assets/javascripts/clusters_list/components/agents.vue', 'app/assets/javascripts/clusters_list/components/delete_agent_button.vue', 'app/assets/javascripts/clusters_list/components/install_agent_modal.vue', diff --git a/.rubocop_todo/gitlab/bounded_contexts.yml b/.rubocop_todo/gitlab/bounded_contexts.yml index e0bd78dca46..215141b8d5b 100644 --- a/.rubocop_todo/gitlab/bounded_contexts.yml +++ b/.rubocop_todo/gitlab/bounded_contexts.yml @@ -3240,7 +3240,6 @@ Gitlab/BoundedContexts: - 'ee/app/services/groups/enterprise_users/base_service.rb' - 'ee/app/services/groups/enterprise_users/disassociate_service.rb' - 'ee/app/services/groups/epics_count_service.rb' - - 'ee/app/services/groups/mark_for_deletion_service.rb' - 'ee/app/services/groups/restore_service.rb' - 'ee/app/services/groups/schedule_bulk_repository_shard_moves_service.rb' - 'ee/app/services/groups/seat_usage_export_service.rb' diff --git a/.rubocop_todo/gitlab/feature_available_usage.yml b/.rubocop_todo/gitlab/feature_available_usage.yml index 38c54bf4193..b860dfe440f 100644 --- a/.rubocop_todo/gitlab/feature_available_usage.yml +++ b/.rubocop_todo/gitlab/feature_available_usage.yml @@ -82,7 +82,6 @@ Gitlab/FeatureAvailableUsage: - 'ee/app/services/iterations/create_service.rb' - 'ee/app/services/iterations/update_service.rb' - 'ee/app/services/merge_requests/update_blocks_service.rb' - - 'ee/app/services/projects/mark_for_deletion_service.rb' - 'ee/app/services/requirements_management/process_test_reports_service.rb' - 'ee/app/services/security/store_scans_service.rb' - 'ee/app/workers/analytics/code_review_metrics_worker.rb' diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml index 9d3605f51a2..65b8dbb2be1 100644 --- a/.rubocop_todo/layout/line_length.yml +++ b/.rubocop_todo/layout/line_length.yml @@ -14,7 +14,6 @@ Layout/LineLength: - 'app/controllers/projects/settings/ci_cd_controller.rb' - 'app/controllers/projects/settings/repository_controller.rb' - 'app/controllers/projects/templates_controller.rb' - - 'app/controllers/projects/triggers_controller.rb' - 'app/controllers/projects/web_ide_schemas_controller.rb' - 'app/controllers/projects_controller.rb' - 'app/controllers/registrations_controller.rb' @@ -718,7 +717,6 @@ Layout/LineLength: - 'ee/app/services/jira/requests/issues/list_service.rb' - 'ee/app/services/merge_requests/create_from_vulnerability_data_service.rb' - 'ee/app/services/merge_trains/refresh_merge_request_service.rb' - - 'ee/app/services/projects/mark_for_deletion_service.rb' - 'ee/app/services/projects/update_mirror_service.rb' - 'ee/app/services/security/ingestion/finding_map.rb' - 'ee/app/services/security/ingestion/tasks/ingest_remediations.rb' diff --git a/.rubocop_todo/style/if_unless_modifier.yml b/.rubocop_todo/style/if_unless_modifier.yml index 17ea871c0fa..58bc09eaa36 100644 --- a/.rubocop_todo/style/if_unless_modifier.yml +++ b/.rubocop_todo/style/if_unless_modifier.yml @@ -313,7 +313,6 @@ Style/IfUnlessModifier: - 'ee/app/services/iterations/delete_service.rb' - 'ee/app/services/merge_requests/update_blocks_service.rb' - 'ee/app/services/merge_trains/refresh_merge_request_service.rb' - - 'ee/app/services/projects/mark_for_deletion_service.rb' - 'ee/app/services/projects/update_mirror_service.rb' - 'ee/app/services/security/security_orchestration_policies/policy_configuration_validation_service.rb' - 'ee/app/services/security/security_orchestration_policies/process_policy_service.rb' 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 d63d1fcf7aa..b8eaca6d8b0 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 @@ -50,14 +50,6 @@ export default { }, }, }, - computed: { - canUpdate() { - return this.runner.userPermissions?.updateRunner; - }, - canDelete() { - return this.runner.userPermissions?.deleteRunner; - }, - }, methods: { reportToSentry(error) { captureException({ error, component: this.$options.name }); diff --git a/app/assets/javascripts/ci/runner/components/cells/runner_summary_cell.vue b/app/assets/javascripts/ci/runner/components/cells/runner_summary_cell.vue index a13f7919a33..c42e04f89e3 100644 --- a/app/assets/javascripts/ci/runner/components/cells/runner_summary_cell.vue +++ b/app/assets/javascripts/ci/runner/components/cells/runner_summary_cell.vue @@ -1,6 +1,6 @@ diff --git a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue index 09ae9a38cdf..aeeb2654836 100644 --- a/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue +++ b/app/assets/javascripts/sidebar/components/reviewers/sidebar_reviewers.vue @@ -7,6 +7,7 @@ import { GlButton } from '@gitlab/ui'; import { createAlert } from '~/alert'; import { TYPE_ISSUE } from '~/issues/constants'; import { __ } from '~/locale'; +import { InternalEvents } from '~/tracking'; import { isGid, getIdFromGraphQLId } from '~/graphql_shared/utils'; import { fetchUserCounts } from '~/super_sidebar/user_counts_fetch'; import ReviewerDrawer from '~/merge_requests/components/reviewers/reviewer_drawer.vue'; @@ -35,6 +36,7 @@ export default { ApprovalSummary: () => import('ee_component/merge_requests/components/reviewers/approval_summary.vue'), }, + mixins: [InternalEvents.mixin()], props: { mediator: { type: Object, @@ -191,6 +193,10 @@ export default { }, toggleDrawerOpen(drawerOpen = !this.drawerOpen) { this.drawerOpen = drawerOpen; + + if (drawerOpen) { + this.trackEvent('open_reviewer_sidebar_panel_in_mr'); + } }, }, }; @@ -213,7 +219,7 @@ export default { category="tertiary" variant="confirm" class="gl-ml-2 !gl-text-sm" - data-testid="sidebar-reviewers-assign-buton" + data-testid="sidebar-reviewers-assign-button" @click="toggleDrawerOpen()" > {{ __('Assign') }} diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index 6a984542355..c2c2c2c9dc2 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -117,10 +117,10 @@ export default { return { tag: '> ', suggestPopoverVisible: false, - shouldShowFindAndReplaceBar: false, findAndReplace: { find: '', replace: '', + shouldShowBar: false, }, modifierKey, shiftKey: modifierKey === '⌘' ? '⇧' : 'Shift+', @@ -181,14 +181,14 @@ export default { mounted() { $(document).on('markdown-preview:show.vue', this.showMarkdownPreview); $(document).on('markdown-preview:hide.vue', this.hideMarkdownPreview); - $(document).on('markdown-editor:find-and-replace:show', this.showFindAndReplaceBar); + $(document).on('markdown-editor:find-and-replace:show', this.findAndReplace_show); this.updateSuggestPopoverVisibility(); }, beforeDestroy() { $(document).off('markdown-preview:show.vue', this.showMarkdownPreview); $(document).off('markdown-preview:hide.vue', this.hideMarkdownPreview); - $(document).off('markdown-editor:find-and-replace:show', this.showFindAndReplaceBar); + $(document).off('markdown-editor:find-and-replace:show', this.findAndReplace_show); }, methods: { async updateSuggestPopoverVisibility() { @@ -233,8 +233,12 @@ export default { }) .catch(() => {}); }, + getCurrentTextArea() { + return this.$el.closest('.md-area')?.querySelector('textarea'); + }, insertIntoTextarea(text) { - const textArea = this.$el.closest('.md-area')?.querySelector('textarea'); + const textArea = this.getCurrentTextArea(); + if (textArea) { updateText({ textArea, @@ -289,20 +293,112 @@ export default { this.$el.closest('.md-area')?.querySelector('textarea')?.focus(); }, 500); }, - showFindAndReplaceBar(_, form) { + findAndReplace_show(_, form) { if (!this.isValid(form)) return; - this.shouldShowFindAndReplaceBar = true; + this.findAndReplace.shouldShowBar = true; }, - handleKeyDown(e) { + findAndReplace_handleKeyDown(e) { if (e.key === 'Enter') { e.preventDefault(); + } else if (e.key === 'Escape') { + this.findAndReplace.shouldShowBar = false; + this.getCurrentTextArea()?.removeEventListener('scroll', this.findAndReplace_syncScroll); + this.cloneDiv?.parentElement.removeChild(this.cloneDiv); + this.cloneDiv = undefined; + } + }, + findAndReplace_handleKeyUp(e) { + this.findAndReplace_highlightMatchingText(e.target.value); + }, + findAndReplace_syncScroll() { + const textArea = this.getCurrentTextArea(); + this.cloneDiv.scrollTop = textArea.scrollTop; + }, + findAndReplace_safeReplace(textArea, textToFind) { + const regex = new RegExp(`(${textToFind})`, 'g'); + const segments = textArea.value.split(regex); + + // Clear previous contents + this.cloneDiv.innerHTML = ''; + + segments.forEach((segment) => { + // If the segment matches the text we're highlighting + if (segment === textToFind) { + const span = document.createElement('span'); + span.classList.add('js-highlight'); + span.style.backgroundColor = 'orange'; + span.style.display = 'inline-block'; + span.textContent = segment; // Use textContent for safe text insertion + this.cloneDiv.appendChild(span); + } else { + // Otherwise, just append the plain text + const textNode = document.createTextNode(segment); + this.cloneDiv.appendChild(textNode); + } + }); + }, + async findAndReplace_highlightMatchingText(text) { + const textArea = this.getCurrentTextArea(); + + if (!textArea) { return; } - if (e.key === 'Escape') { - this.shouldShowFindAndReplaceBar = false; + // Make sure we got the right zIndex + textArea.style.position = 'relative'; + textArea.style.zIndex = 2; + + await this.findAndReplace_attachCloneDivIfNotExists(textArea); + + this.findAndReplace_safeReplace(textArea, text); + }, + async findAndReplace_attachCloneDivIfNotExists(textArea) { + if (this.cloneDiv) { + return; } + + this.cloneDiv = document.createElement('div'); + this.cloneDiv.dataset.testid = 'find-and-replace-clone'; + this.cloneDiv.textContent = textArea.value; + + const computedStyle = window.getComputedStyle(textArea); + const propsToCopy = [ + 'width', + 'height', + 'padding', + 'border', + 'font-family', + 'font-size', + 'line-height', + 'background-color', + 'color', + 'overflow', + 'white-space', + 'word-wrap', + 'resize', + 'margin', + ]; + + propsToCopy.forEach((prop) => { + this.cloneDiv.style[prop] = computedStyle[prop]; + }); + + // Additional required styles for div + this.cloneDiv.style.whiteSpace = 'pre-wrap'; + this.cloneDiv.style.overflowY = 'auto'; + this.cloneDiv.style.position = 'absolute'; + this.cloneDiv.style.zIndex = 1; + this.cloneDiv.style.color = 'transparent'; + + textArea.addEventListener('scroll', this.findAndReplace_syncScroll); + + textArea.parentElement.insertBefore(this.cloneDiv, textArea); + + await this.$nextTick(); + + // Required to align the clone div + this.cloneDiv.scrollTop = textArea.scrollTop; }, }, shortcuts: { @@ -620,8 +716,8 @@ export default {
diff --git a/app/controllers/admin/impersonation_tokens_controller.rb b/app/controllers/admin/impersonation_tokens_controller.rb index 0ba04a3416a..4e22f0d6cce 100644 --- a/app/controllers/admin/impersonation_tokens_controller.rb +++ b/app/controllers/admin/impersonation_tokens_controller.rb @@ -73,7 +73,7 @@ class Admin::ImpersonationTokensController < Admin::ApplicationController end def active_impersonation_tokens - tokens = finder(state: 'active', sort: 'expires_at_asc_id_desc').execute + tokens = finder(state: 'active', sort: 'expires_asc').execute ::ImpersonationAccessTokenSerializer.new.represent(tokens) end diff --git a/app/controllers/concerns/render_access_tokens.rb b/app/controllers/concerns/render_access_tokens.rb index 056e81c7f99..e82ec877035 100644 --- a/app/controllers/concerns/render_access_tokens.rb +++ b/app/controllers/concerns/render_access_tokens.rb @@ -4,7 +4,7 @@ module RenderAccessTokens extend ActiveSupport::Concern def active_access_tokens - tokens = finder(state: 'active', sort: 'expires_at_asc_id_desc').execute.preload_users + tokens = finder(state: 'active', sort: 'expires_asc').execute.preload_users size = tokens.size tokens = tokens.page(page) diff --git a/app/controllers/projects/triggers_controller.rb b/app/controllers/projects/triggers_controller.rb index 5ec0db457f9..277c260cb19 100644 --- a/app/controllers/projects/triggers_controller.rb +++ b/app/controllers/projects/triggers_controller.rb @@ -36,10 +36,12 @@ class Projects::TriggersController < Projects::ApplicationController end def update - response = ::Ci::PipelineTriggers::UpdateService.new(user: current_user, trigger: trigger, description: trigger_params[:description]).execute + response = ::Ci::PipelineTriggers::UpdateService.new(user: current_user, trigger: trigger, + description: trigger_params[:description]).execute if response.success? - redirect_to project_settings_ci_cd_path(@project, anchor: 'js-pipeline-triggers'), notice: _('Trigger token was successfully updated.') + redirect_to project_settings_ci_cd_path(@project, anchor: 'js-pipeline-triggers'), + notice: _('Trigger token was successfully updated.') else render action: "edit" end diff --git a/app/models/concerns/reactive_caching.rb b/app/models/concerns/reactive_caching.rb index 62300f95be4..82c6653b12b 100644 --- a/app/models/concerns/reactive_caching.rb +++ b/app/models/concerns/reactive_caching.rb @@ -151,7 +151,7 @@ module ReactiveCaching def enqueuing_update(*args) yield - worker_class.perform_in(self.class.reactive_cache_refresh_interval, self.class, id, *args) + worker_class.perform_in(self.class.reactive_cache_refresh_interval, self.class.name, id, *args) end def worker_class diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 8043f79dad1..9f8b25f6998 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -65,6 +65,9 @@ class PersonalAccessToken < ApplicationRecord scope :for_organization, ->(organization) { where(organization_id: organization) } scope :preload_users, -> { preload(:user) } scope :order_expires_at_asc_id_desc, -> { reorder(expires_at: :asc, id: :desc) } + scope :order_expires_at_desc_id_desc, -> { reorder(expires_at: :desc, id: :desc) } + scope :order_last_used_at_asc_id_desc, -> { reorder(last_used_at: :asc, id: :desc) } + scope :order_last_used_at_desc_id_desc, -> { reorder(last_used_at: :desc, id: :desc) } scope :project_access_token, -> { includes(:user).references(:user).merge(User.project_bot) } scope :owner_is_human, -> { includes(:user).references(:user).merge(User.human) } scope :last_used_before, ->(date) { where("last_used_at <= ?", date) } @@ -95,7 +98,11 @@ class PersonalAccessToken < ApplicationRecord def self.simple_sorts super.merge( { - 'expires_at_asc_id_desc' => -> { order_expires_at_asc_id_desc } + 'expires_asc' => -> { order_expires_at_asc_id_desc }, + 'expires_at_asc_id_desc' => -> { order_expires_at_asc_id_desc }, # Keep for backward compatibility + 'expires_desc' => -> { order_expires_at_desc_id_desc }, + 'last_used_asc' => -> { order_last_used_at_asc_id_desc }, + 'last_used_desc' => -> { order_last_used_at_desc_id_desc } } ) end diff --git a/app/services/groups/mark_for_deletion_service.rb b/app/services/groups/mark_for_deletion_service.rb new file mode 100644 index 00000000000..9c77774c262 --- /dev/null +++ b/app/services/groups/mark_for_deletion_service.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Groups # rubocop:disable Gitlab/BoundedContexts -- existing top-level module + class MarkForDeletionService < Groups::BaseService + # rubocop:disable Gitlab/NoCodeCoverageComment -- Tested in FOSS and fully overridden and tested in EE + # :nocov + def execute(async: true) + service = ::Groups::DestroyService.new(group, current_user, params) + + async ? service.async_execute : service.execute + end + # :nocov: + # rubocop:enable Gitlab/NoCodeCoverageComment + end +end + +Groups::MarkForDeletionService.prepend_mod diff --git a/app/services/projects/mark_for_deletion_service.rb b/app/services/projects/mark_for_deletion_service.rb new file mode 100644 index 00000000000..e304096b3c9 --- /dev/null +++ b/app/services/projects/mark_for_deletion_service.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Projects + class MarkForDeletionService < BaseService + # rubocop:disable Gitlab/NoCodeCoverageComment -- Tested in FOSS and fully overridden and tested in EE + # :nocov: + def execute(async: true) + service = ::Projects::DestroyService.new(project, current_user, params) + + async ? service.async_execute : service.execute + end + # :nocov: + # rubocop:enable Gitlab/NoCodeCoverageComment + end +end + +Projects::MarkForDeletionService.prepend_mod diff --git a/app/views/projects/merge_requests/creations/new.html.haml b/app/views/projects/merge_requests/creations/new.html.haml index 4f722ba901d..facb6727946 100644 --- a/app/views/projects/merge_requests/creations/new.html.haml +++ b/app/views/projects/merge_requests/creations/new.html.haml @@ -1,5 +1,5 @@ - add_to_breadcrumbs _("Merge requests"), project_merge_requests_path(@project) -- breadcrumb_title _("New") +- breadcrumb_title _("New merge request") - page_title _("New merge request") - add_page_specific_style 'page_bundles/pipelines' - add_page_specific_style 'page_bundles/ci_status' diff --git a/config/initializers/irb.rb b/config/initializers/irb.rb index 89c1bedfcc8..1e12d53429b 100644 --- a/config/initializers/irb.rb +++ b/config/initializers/irb.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true if Gitlab::Runtime.console? + require "irb" + # Stop irb from writing a history file by default. module IrbNoHistory def init_config(*) diff --git a/db/post_migrate/20250314113948_remove_replicas_with_evicted_indices.rb b/db/post_migrate/20250314113948_remove_replicas_with_evicted_indices.rb new file mode 100644 index 00000000000..cb994840069 --- /dev/null +++ b/db/post_migrate/20250314113948_remove_replicas_with_evicted_indices.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class RemoveReplicasWithEvictedIndices < Gitlab::Database::Migration[2.2] + disable_ddl_transaction! + restrict_gitlab_migration gitlab_schema: :gitlab_main + milestone '17.10' + BATCH_SIZE = 500 + EVICTED_STATE = 225 + SCOPE_SQL = ['state = ? AND zoekt_replica_id IS NOT NULL', EVICTED_STATE] + + def up + each_batch_range('zoekt_indices', scope: ->(table) { table.where(SCOPE_SQL) }, of: BATCH_SIZE) do |min, max| + execute <<~SQL + DELETE FROM zoekt_replicas + USING zoekt_indices + WHERE zoekt_indices.zoekt_replica_id = zoekt_replicas.id + AND zoekt_indices.id BETWEEN #{min} AND #{max} + SQL + end + end + + def down + # no-op + end +end diff --git a/db/schema_migrations/20250314113948 b/db/schema_migrations/20250314113948 new file mode 100644 index 00000000000..a4a0e521dc7 --- /dev/null +++ b/db/schema_migrations/20250314113948 @@ -0,0 +1 @@ +15688b6b3dd8adc421d7d41159ef6b448dc9948cf922e2deed022ab46c622657 \ No newline at end of file diff --git a/doc/administration/cells.md b/doc/administration/cells.md index f7d42448fd7..3a42fc0370b 100644 --- a/doc/administration/cells.md +++ b/doc/administration/cells.md @@ -30,6 +30,12 @@ This page explains how to configure the GitLab Rails console for cell functional ## Configuration +To configure your GitLab instance as a Cell instance: + +{{< tabs >}} + +{{< tab title="Self-compiled (source)" >}} + The cells related configuration in `config/gitlab.yml` is in this format: ```yaml @@ -45,6 +51,67 @@ The cells related configuration in `config/gitlab.yml` is in this format: private_key_file: /home/git/gitlab/config/topology-service-key.pem ``` +{{< /tab >}} + +{{< tab title="Linux Package (Omnibus)" >}} + +1. Edit `/etc/gitlab/gitlab.rb` and add the following lines: + + ```ruby + gitlab_rails['cell'] = { + enabled: true, + id: 1, + database: { + skip_sequence_alteration: false + }, + topology_service_client: { + enabled: true, + address: 'topology-service.gitlab.example.com:443', + ca_file: 'path/to/your/ca/.pem', + certificate_file: 'path/to/your/cert/.pem', + private_key_file: 'path/to/your/key/.pem' + } + } + ``` + +1. Reconfigure and restart GitLab: + + ```shell + sudo gitlab-ctl reconfigure + sudo gitlab-ctl restart + ``` + +{{< /tab >}} + +{{< tab title="Helm chart" >}} + +1. Edit `gitlab_values.yaml`: + + ```yaml + global: + appConfig: + cell: + enabled: true + id: 1 + database: + skipSequenceAlteration: false + topologyServiceClient: + address: "topology-service.gitlab.example.com:443" + caFile: "path/to/your/ca/.pem" + privateKeyFile: "path/to/your/key/.pem" + certificateFile: "path/to/your/certificate/.pem" + ``` + +1. Save the file and apply the new values: + + ```shell + helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab + ``` + +{{< /tab >}} + +{{< /tabs >}} + | Configuration | Default value | Description | |--------------------------------------------|-------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `cell.enabled` | `false` | To configure whether the instance is a Cell or not. `false` means all Cell features are disabled. `session_cookie_prefix_token` is not affected, and can be set separately. | diff --git a/doc/administration/credentials_inventory.md b/doc/administration/credentials_inventory.md index 9650a402767..8ae4994a443 100644 --- a/doc/administration/credentials_inventory.md +++ b/doc/administration/credentials_inventory.md @@ -28,7 +28,7 @@ Use the credentials inventory to monitor and control access to your GitLab self- As an administrator, you can: -- Revoke personal or project access tokens. +- Revoke personal, project, or group access tokens. - Delete SSH keys. - Review credential details including: - Ownership. @@ -48,21 +48,17 @@ To revoke a personal access token in your instance: The access token is revoked and the user is notified by email. -![The credentials inventory page listing personal access tokens.](img/credentials_inventory_personal_access_tokens_v14_9.png) - -## Revoke project access tokens +## Revoke project or group access tokens To revoke a project access token in your instance: 1. On the left sidebar, at the bottom, select **Admin**. 1. Select **Credentials**. -1. Select the **Project access tokens** tab. +1. Select the **Project and group access tokens** tab. 1. Next to the project access token, select **Revoke**. The access token is revoked and a background process begins to delete the associated project bot user. -![The credentials inventory page listing project access tokens.](img/credentials_inventory_project_access_tokens_v14_9.png) - ## Delete SSH keys To delete an SSH key in your instance: @@ -74,8 +70,6 @@ To delete an SSH key in your instance: The SSH key is deleted and the user is notified. -![The credentials inventory page listing SSH keys.](img/credentials_inventory_ssh_keys_v14_9.png) - ## View GPG keys You can see details for each GPG key including the owner, ID, and [verification status](../user/project/repository/signed_commits/gpg.md). @@ -85,5 +79,3 @@ To view information about GPG keys in your instance: 1. On the left sidebar, at the bottom, select **Admin**. 1. Select **Credentials**. 1. Select the **GPG Keys** tab. - -![The credentials inventory page listing GPG keys.](img/credentials_inventory_gpg_keys_v14_9.png) diff --git a/doc/administration/gitlab_duo_self_hosted/troubleshooting.md b/doc/administration/gitlab_duo_self_hosted/troubleshooting.md index e6ea15e9d49..035d9cade19 100644 --- a/doc/administration/gitlab_duo_self_hosted/troubleshooting.md +++ b/doc/administration/gitlab_duo_self_hosted/troubleshooting.md @@ -40,6 +40,12 @@ Before you begin troubleshooting, you should: Now, requests and responses from GitLab to the AI gateway are logged to [`llm.log`](../logs/_index.md#llmlog) +For more information on troubleshooting GitLab Duo, see: + +- [Troubleshooting GitLab Duo](../../user/gitlab_duo/troubleshooting.md). +- [Troubleshooting Code Suggestions](../../user/project/repository/code_suggestions/troubleshooting.md). +- [GitLab Duo Chat troubleshooting](../../user/gitlab_duo_chat/troubleshooting.md). + ## Use debugging scripts We provide two debugging scripts to help administrators verify their self-hosted model configuration. diff --git a/doc/administration/img/credentials_inventory_gpg_keys_v14_9.png b/doc/administration/img/credentials_inventory_gpg_keys_v14_9.png deleted file mode 100644 index 6c4c8f30df6b54c528f07621020349a3dceee59f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16956 zcmb7r1ymft(k>DuNPyt(34|=co#5`W_y%{EAPWQu?(PJ4mLS0w2+l$Xy12W;Vhanr z-23Z$|GDp+f6knl?yCB_rmB1Tv{Xl^smS7Bkz=8uq2b8ONok;=VS>=m&;ws!{-xA# z-Le0DJ+Ts37Dq$-5%&sZ^7L;W-AzMQ0I7p_&5CzGJu};pCaydBJ{e-YP6D0t`@Ys zA2>d6(2HWx($WgMnp+BLNXh&={BKT#-rC*WSr7pD^5x5iFI*p-T&(~f1q1{D9Gn17 zPWHbN>~7wU?j~OBj&2P9R>*&pBW2-c=4#{YZsX)g`;T%>Or1R3Md<1Oq3A!afBQ}g zFPs0;L!3|CIk9 zod44J-;lchh2-bu`tQj9#`%Ad+HMxEl1>hPRl196nz>s1Rc-C${_o)b&ir?vFyJ4S z|2I$ko16bh{p)8@EMdTZ)|n{Q{a5WgG&GERH6<w|-Xi;Ii<`}-e1ex#?T+u7L_6%{!-Idyh+hK7c2 zZEgK+8OO)RLPA3I_4RA(YpbiP4h{~nv9bC2`P3G@5C~*rV`Fx9HYzF#3@h0|U#-%2ZXAthGJuCA^QFOLM43x;jxp=s}Lf#{;QNTFcu1#1k{A4-8_wnX>=klP1gFOFaQg5?f#8;zr zxhJisc>VUgaiOaYu^99tK_%SGHV-_#j_6U~MczGpAFi(I-<`QWNb1T@Z`ss}p8T~n z;`r0uZ3k+-)so+}<5&<7RJn52SScT36x){F)z!u4sr=qS0=9TA`BnG(Xi<1i?ANYP z#r3L&k%J?|?QTJ8@$b4hKgZ8CR(>@xS;ynp*w~(hi;Fu~VTXg;$H;mHY`2n-DOWSU zvgMJhozR-qaa;Yvitih#kry2eOb!Dlb!9cvE#Xb66%#)PG(TBpeeo`jc;_^Dzp-*Z zJ8{3d(7!fhWo5noFxyH>6Ps#bZeB+1S;u z>^v7WN7kmo4=fB`qyMwV{2ve0ib2hyJ}LX#m3lzjHMH^D(A~@xF5ax$yf)wirZ5}e zrYjf0;#3{$c8%EwmGDsupT1eTtYiVz=-CZUtk239zgQ3Is!v>ByE~VLhDC}v8dlX* zhwrWfH`zW~;TnX1yAhj{e0o<-K%J!=c@2(f2(N9cacN+Pj>^sDLvXBVcLq2Y%Uk4o zJfQ4=OXbBzqn9Dg zVc~6yu1M`U&$&!?n2XV>H>rGc)`k?~J_DFt^wp=f&ljLGyJHFot2g4xk2OWF8Q1`) z*pyfs(PXGKWiL%RJ{=+9;XAj%lI|Ni>{^8N-|gB6ux>D^?5gJT@#-wen$~i&G@Qb$ z|7?(?SmbX%D|E~NT=&}=k$f;D^&-Z2rywi0hBaO_0{mLmEN}c^y=9kSDC}ODetD;E z?&2as2XAS7c(z1X8%J+9CcT0zqea1<)9VmIhL{lA1RXH0f)hFWq3ar(1EkuvBC>h6 z^$m3fMEy*(um#-AaZ35#wV+`D(`>tEC2|B9YaO6pbE%6=bW)@2)E>DN8DlPHp?};y zhNY>7WP>jWc|vS>Sy3;dr2fvXS9fp^rU-)zsdI)@GA3kGy_iVG^Z{?a6 zti5bFmtJPqrd%EFa*J0Q5|gE|cG5Xm4?}Fd;R?u8i}QP>NB)}?FxB6&!Z&gfwr72j zlmdubP59g(%521x+YpDan~TlBZk2rf4M3a>-8Morva+I7b(syI0>~x4_qV_W-J6*8%t| z-|hutWZ%jE_$mHx!k?#TV$U2|{%_*H%$=_6%)IHl?saJYn8qb^Tja2$5Vc?&3-N=u z__9XLOu^w+xuL2*QV%nn+-3%G)?rG;Nx1#TX>bzxi4%E3nq165+(}4MCtM-=4%0D~aS7C^nFjdnd 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 KRE@;vp#KBmmXW{! diff --git a/doc/administration/img/credentials_inventory_personal_access_tokens_v14_9.png b/doc/administration/img/credentials_inventory_personal_access_tokens_v14_9.png deleted file mode 100644 index 254d520d538cf9d178ce4c3e08a267c237b014c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34445 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 Hl+XkKk61?c diff --git a/doc/administration/img/credentials_inventory_project_access_tokens_v14_9.png b/doc/administration/img/credentials_inventory_project_access_tokens_v14_9.png deleted file mode 100644 index ae204ac09effbddcd3b7463325d266c19e88ee20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19849 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%0D79{C2j)>oEbyjSR#3^wI2Oq^ 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 diff --git a/doc/administration/img/credentials_inventory_ssh_keys_v14_9.png b/doc/administration/img/credentials_inventory_ssh_keys_v14_9.png deleted file mode 100644 index 8f2f11515eb38823290ff2114ea97f1d71c6c8e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29612 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 diff --git a/doc/api/group_access_tokens.md b/doc/api/group_access_tokens.md index eedf01f2f14..0a0c75c4a2e 100644 --- a/doc/api/group_access_tokens.md +++ b/doc/api/group_access_tokens.md @@ -40,7 +40,7 @@ GET /groups/:id/access_tokens?state=inactive | `last_used_before` | datetime (ISO 8601) | No | If defined, returns tokens last used before the specified time. | | `revoked` | boolean | No | If `true`, only returns revoked tokens. | | `search` | string | No | If defined, returns tokens that include the specified value in the name. | -| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `name_asc`, `name_desc`. | +| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `expires_asc`, `expires_desc`, `last_used_asc`, `last_used_desc`, `name_asc`, `name_desc`.| | `state` | string | No | If defined, returns tokens with the specified state. Possible values: `active` and `inactive`. | ```shell diff --git a/doc/api/group_service_accounts.md b/doc/api/group_service_accounts.md index d90ed60efe4..e565856b682 100644 --- a/doc/api/group_service_accounts.md +++ b/doc/api/group_service_accounts.md @@ -223,6 +223,7 @@ Parameters: | `id` | integer/string | yes | ID or [URL-encoded path](rest/_index.md#namespaced-paths) of a top-level group. | | `user_id` | integer | yes | ID of service account user. | | `name` | string | yes | Name of personal access token. | +| `description` | string | no | Description of personal access token. | | `scopes` | array | yes | Array of approved scopes. For a list of possible values, see [Personal access token scopes](../user/profile/personal_access_tokens.md#personal-access-token-scopes). | | `expires_at` | date | no | Expiration date of the access token in ISO format (`YYYY-MM-DD`). If not specified, the date is set to the [maximum allowable lifetime limit](../user/profile/personal_access_tokens.md#access-token-expiration). | diff --git a/doc/api/personal_access_tokens.md b/doc/api/personal_access_tokens.md index f1443c65613..01bdac88521 100644 --- a/doc/api/personal_access_tokens.md +++ b/doc/api/personal_access_tokens.md @@ -50,7 +50,7 @@ Supported attributes: | `last_used_before` | datetime (ISO 8601) | No | If defined, returns tokens last used before the specified time. | | `revoked` | boolean | No | If `true`, only returns revoked tokens. | | `search` | string | No | If defined, returns tokens that include the specified value in the name. | -| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `name_asc`, `name_desc`. | +| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `expires_asc`, `expires_desc`, `last_used_asc`, `last_used_desc`, `name_asc`, `name_desc`. | | `state` | string | No | If defined, returns tokens with the specified state. Possible values: `active` and `inactive`. | | `user_id` | integer or string | No | If defined, returns tokens owned by the specified user. Non-administrators can only filter their own tokens. | diff --git a/doc/api/project_access_tokens.md b/doc/api/project_access_tokens.md index ca3cff3c284..411a51e014f 100644 --- a/doc/api/project_access_tokens.md +++ b/doc/api/project_access_tokens.md @@ -40,7 +40,7 @@ GET projects/:id/access_tokens?state=inactive | `last_used_before` | datetime (ISO 8601) | No | If defined, returns tokens last used before the specified time. | | `revoked` | boolean | No | If `true`, only returns revoked tokens. | | `search` | string | No | If defined, returns tokens that include the specified value in the name. | -| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `name_asc`, `name_desc`. | +| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `expires_asc`, `expires_desc`, `last_used_asc`, `last_used_desc`, `name_asc`, `name_desc`.| | `state` | string | No | If defined, returns tokens with the specified state. Possible values: `active` and `inactive`. | ```shell diff --git a/doc/policy/development_stages_support.md b/doc/policy/development_stages_support.md index 0da9db6275b..e6f24a67901 100644 --- a/doc/policy/development_stages_support.md +++ b/doc/policy/development_stages_support.md @@ -61,6 +61,7 @@ Both types are production-ready, but have different scopes. Limited availability features: - Are ready for production use at a reduced scale. +- Can be initially available on one or more GitLab platforms (GitLab.com, GitLab Self-Managed, GitLab Dedicated). - Might initially be free, then become paid when generally available. - Might be offered at a discount before becoming generally available. - Might have commercial terms that change for new contracts when generally available. @@ -74,6 +75,7 @@ Generally available features: - Are ready for production use at any scale. - Are [fully supported](https://about.gitlab.com/support/statement-of-support/) and documented. - Have a complete user experience aligned with GitLab design standards. +- Must be available on all GitLab platforms (GitLab.com, GitLab Self-Managed, GitLab Dedicated). ## Development guidelines diff --git a/doc/user/duo_amazon_q/_index.md b/doc/user/duo_amazon_q/_index.md index e520e511069..a835980c16b 100644 --- a/doc/user/duo_amazon_q/_index.md +++ b/doc/user/duo_amazon_q/_index.md @@ -125,12 +125,24 @@ Amazon Q can reply to these comments with suggested fixes. Amazon Q proposes fixes for the issue in the comment. -### Create test coverage +### Generate unit tests Generate new unit tests while you're having your merge request reviewed. Amazon Q surfaces any missing unit test coverage in the proposed code changes. -To create test coverage: +To generate unit tests for all code changes: + +1. Open your merge request. +1. On the **Overview** tab, in a comment, type `/q test`. +1. Select **Comment**. + +Amazon Q populates a comment with the suggested tests. + +### Create test coverage for selected lines + +Generate new unit tests for specific lines of code in your merge request. + +To create test coverage for selected lines: 1. Open your merge request. 1. On the **Changes** tab, select the lines you want to test. diff --git a/doc/user/gitlab_duo/troubleshooting.md b/doc/user/gitlab_duo/troubleshooting.md index 2e32bf6d969..7c373cae7ca 100644 --- a/doc/user/gitlab_duo/troubleshooting.md +++ b/doc/user/gitlab_duo/troubleshooting.md @@ -10,6 +10,12 @@ When working with GitLab Duo, you might encounter issues. Start by [running a health check](setup.md#run-a-health-check-for-gitlab-duo) to determine if your instance meets the requirements to use GitLab Duo. +For more information on troubleshooting GitLab Duo, see: + +- [Troubleshooting Code Suggestions](../project/repository/code_suggestions/troubleshooting.md). +- [GitLab Duo Chat troubleshooting](../gitlab_duo_chat/troubleshooting.md). +- [Troubleshooting GitLab Duo Self-Hosted](../../administration/gitlab_duo_self_hosted/troubleshooting.md). + If the health check does not resolve your problem, review these troubleshooting steps. ## GitLab Duo features do not work on self-managed diff --git a/doc/user/gitlab_duo_chat/troubleshooting.md b/doc/user/gitlab_duo_chat/troubleshooting.md index 0b2f9e9f296..de5b1a6eaf7 100644 --- a/doc/user/gitlab_duo_chat/troubleshooting.md +++ b/doc/user/gitlab_duo_chat/troubleshooting.md @@ -21,11 +21,13 @@ button to appear. If this does not work, you can also check the following troubleshooting documentation: -- [GitLab Duo Code Suggestions](../project/repository/code_suggestions/troubleshooting.md) -- [VS Code](../../editor_extensions/visual_studio_code/troubleshooting.md) -- [Microsoft Visual Studio](../../editor_extensions/visual_studio/visual_studio_troubleshooting.md) -- [JetBrains IDEs](../../editor_extensions/jetbrains_ide/jetbrains_troubleshooting.md) -- [Neovim](../../editor_extensions/neovim/neovim_troubleshooting.md) +- [GitLab Duo Code Suggestions](../project/repository/code_suggestions/troubleshooting.md). +- [VS Code](../../editor_extensions/visual_studio_code/troubleshooting.md). +- [Microsoft Visual Studio](../../editor_extensions/visual_studio/visual_studio_troubleshooting.md). +- [JetBrains IDEs](../../editor_extensions/jetbrains_ide/jetbrains_troubleshooting.md). +- [Neovim](../../editor_extensions/neovim/neovim_troubleshooting.md). +- [Troubleshooting GitLab Duo](../gitlab_duo/troubleshooting.md). +- [Troubleshooting GitLab Duo Self-Hosted](../../administration/gitlab_duo_self_hosted/troubleshooting.md). ## `Error M2000` diff --git a/doc/user/group/credentials_inventory.md b/doc/user/group/credentials_inventory.md index 25367596a3f..5fac4fbf077 100644 --- a/doc/user/group/credentials_inventory.md +++ b/doc/user/group/credentials_inventory.md @@ -48,8 +48,6 @@ To revoke personal access tokens for enterprise users in your group: The access token is revoked and the user is notified by email. -![The credentials inventory page listing personal access tokens.](img/group_credentials_inventory_personal_access_tokens_v17_5.png) - ## Delete SSH keys To delete SSH keys for enterprise users in your group: @@ -61,8 +59,6 @@ To delete SSH keys for enterprise users in your group: The SSH key is deleted and the user is notified. -![The credentials inventory page listing SSH keys.](img/group_credentials_inventory_ssh_keys_v17_5.png) - ## Revoke project or group access tokens You cannot view or revoke project or group access tokens using the credentials inventory on GitLab.com. diff --git a/doc/user/group/img/group_credentials_inventory_personal_access_tokens_v17_5.png b/doc/user/group/img/group_credentials_inventory_personal_access_tokens_v17_5.png deleted file mode 100644 index 0eba417cb0efdbbc6c2bfd3b0815c3e5bd325cb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24010 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 diff --git a/doc/user/group/img/group_credentials_inventory_ssh_keys_v17_5.png b/doc/user/group/img/group_credentials_inventory_ssh_keys_v17_5.png deleted file mode 100644 index c2f33bac7ade18b138d28f8c845c22279223b06e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14209 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 Z3m|!tn@qyzLi!Ktla!KVnYi)y{|7FXm!bdw diff --git a/doc/user/project/file_lock.md b/doc/user/project/file_lock.md index 7b6077c3a30..8a822fe0e02 100644 --- a/doc/user/project/file_lock.md +++ b/doc/user/project/file_lock.md @@ -2,7 +2,7 @@ stage: Create group: Source Code info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments -title: File Locking +title: File locking --- {{< details >}} @@ -12,39 +12,23 @@ title: File Locking {{< /details >}} -Preventing wasted work caused by unresolvable merge conflicts requires -a different way of working. This means explicitly requesting write permissions, -and verifying no one else is editing the same file before you start. +File locking prevents multiple people from editing the same file simultaneously, which helps avoid +merge conflicts. File locking is especially valuable for binary files that cannot be merged like +design files, videos, and other non-text content. -Although branching strategies typically work well enough for source code and -plain text because different versions can be merged together, they do not work -for binary files. +GitLab supports two different types of file locking: -When file locking is setup, lockable files are **read-only** by default. - -When a file is locked, only the user who locked the file may modify it. This -user is said to "hold the lock" or have "taken the lock", because only one user -can lock a file at a time. When a file or directory is unlocked, the user is -said to have "released the lock". - -GitLab supports two different modes of file locking: - -- [Exclusive file locks](../../topics/git/file_management.md#file-locks) for binary files: done - **through the command line** with Git LFS and `.gitattributes`, it prevents locked - files from being modified on any branch. -- [Default branch locks](#default-branch-file-and-directory-locks): done - **through the GitLab UI**, it prevents locked files and directories being - modified on the default branch. +- [Exclusive file locks](../../topics/git/file_management.md#file-locks): Applied through the + command line with Git LFS and `.gitattributes`. + These locks prevent modifications to locked files on any branch. +- [Default branch file and directory locks](#default-branch-file-and-directory-locks): Applied + through the GitLab UI. These locks prevent modifications to files and directories on the + default branch only. ## Permissions -Locks can be created by any person who has at least -Developer role for the repository. - -Only the user who locked the file or directory can edit locked files. Other -users are prevented from modifying locked files by pushing, merging, -or any other means, and are shown an error like: -`'.gitignore' is locked by @Administrator`. +You can create file locks if you have at least the Developer role for the project. +For more information, see [Roles and permissions](../../user/permissions.md). ## Default branch file and directory locks @@ -55,40 +39,52 @@ or any other means, and are shown an error like: {{< /details >}} -This process allows you to lock one file at a time through the GitLab UI and -requires access to the [GitLab Premium or Ultimate tier](https://about.gitlab.com/pricing/). +Default branch locks apply only to the [default branch](repository/branches/default.md) set in your +project's settings. These locks help maintain stability in your default branch without blocking +collaborator workflows in other branches. -Default branch file and directory locks only apply to the -[default branch](repository/branches/default.md) set in the project's settings. +When a file or directory is locked by a user: -Changes to locked files on the default branch are blocked, including merge -requests that modify locked files. Unlock the file to allow changes. +- Only the user who created the lock can modify the file or directory on the default branch. +- For other users, the locked file or directory is **read-only** on the default branch. +- Direct changes to locked files or directories on the default branch are blocked. +- Merge requests that modify locked files or directories cannot be merged to the default branch. -### Lock a file or a directory +{{< alert type="note" >}} -To lock a file: +On non-default branches, all users can still modify locked files and directories. +A **Lock** status is visible on these files and directories. This helps team members +to be aware of in-flight work without restricting their workflow on other branches. -1. Open the file or directory in GitLab. -1. In the upper-right corner, above the file, select **Lock**. +{{< /alert >}} + +## Lock a file or directory + +To lock a file or directory: + +1. On the left sidebar, select **Search or go to** and find your project. +1. Go to the file or directory you want to lock. +1. In the upper-right corner, select **Lock**. 1. On the confirmation dialog, select **OK**. -If you do not have permission to lock the file, the button is not enabled. +If **Lock** is not enabled, you don't have the required permissions to lock the file. -To view the user who locked a directory (if it was not you), hover over the button. Reinstatement of -similar functionality for locked files is discussed in -[issue 376222](https://gitlab.com/gitlab-org/gitlab/-/issues/376222). +To see who locked a directory, if it wasn't you, hover over the **Lock**. For a similar function +for locked files, see [issue 4623](https://gitlab.com/gitlab-org/gitlab/-/issues/4623). -### View and remove existing locks +## View and remove locks -To view and remove file locks: +Locks can be removed by: + +- The user who created the lock. +- Any user with at least the Maintainer role for the project. + +To view and manage file locks: 1. On the left sidebar, select **Search or go to** and find your project. 1. Select **Code > Locked files**. -This list shows all the files locked either through LFS or GitLab UI. - -Locks can be removed by their author, or any user -with at least the Maintainer role. +This list displays all files locked either through Git LFS exclusive locks or the GitLab UI. ## Related topics diff --git a/doc/user/project/repository/code_suggestions/troubleshooting.md b/doc/user/project/repository/code_suggestions/troubleshooting.md index be9fbe8c95b..e7823ef41a1 100644 --- a/doc/user/project/repository/code_suggestions/troubleshooting.md +++ b/doc/user/project/repository/code_suggestions/troubleshooting.md @@ -23,6 +23,12 @@ When working with GitLab Duo Code Suggestions, you might encounter the following You can run a [health check](../../../gitlab_duo/turn_on_off.md) to test if your instance meets the requirements to run Code Suggestions. +For more information on troubleshooting GitLab Duo, see: + +- [Troubleshooting GitLab Duo](../../../../user/gitlab_duo/troubleshooting.md). +- [GitLab Duo Chat troubleshooting](../../../gitlab_duo_chat/troubleshooting.md). +- [Troubleshooting GitLab Duo Self-Hosted](../../../../administration/gitlab_duo_self_hosted/troubleshooting.md). + ## Suggestions are not displayed If suggestions are not displayed, ensure that you: diff --git a/doc/user/project/repository/web_editor.md b/doc/user/project/repository/web_editor.md index c2aa0f87b2b..55dff8869aa 100644 --- a/doc/user/project/repository/web_editor.md +++ b/doc/user/project/repository/web_editor.md @@ -20,7 +20,7 @@ local setup. You can: - Create new files and directories. - Upload and replace files. - Create branches and tags for version control. -- [Lock files](../file_lock.md#lock-a-file-or-a-directory) to prevent concurrent editing conflicts. +- [Lock files](../file_lock.md#lock-a-file-or-directory) to prevent concurrent editing conflicts. - Contribute to projects without setting up Git locally. GitLab uses your [primary email address](../../profile/_index.md#change-the-email-displayed-on-your-commits) diff --git a/lib/web_ide/extension_marketplace_preset.rb b/lib/web_ide/extension_marketplace_preset.rb index 0a42371669a..09b452a983a 100644 --- a/lib/web_ide/extension_marketplace_preset.rb +++ b/lib/web_ide/extension_marketplace_preset.rb @@ -16,7 +16,7 @@ module WebIde # See https://open-vsx.org/swagger-ui/index.html?urls.primaryName=VSCode%20Adapter for OpenVSX Swagger API service_url: "https://open-vsx.org/vscode/gallery", item_url: "https://open-vsx.org/vscode/item", - resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}" + resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}" ) end diff --git a/lib/web_ide/settings_sync.rb b/lib/web_ide/settings_sync.rb index 829c36c5320..e81d92cd29c 100644 --- a/lib/web_ide/settings_sync.rb +++ b/lib/web_ide/settings_sync.rb @@ -11,8 +11,10 @@ module WebIde # 2e0d3e8c1107f9ccc5ea is the hash of "web_ide_https://open-vsx.org/vscode/gallery_https://open-vsx.org/vscode/item_" # e36c431c0e2e1ee82c86 is the hash of "web_ide_https://open-vsx.org/vscode/gallery_https://open-vsx.org/vscode/item_https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}" # 55b10685e181429abe78 is the hash of "web_ide_https://open-vsx.org/vscode/gallery_https://open-vsx.org/vscode/item_https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}" + # 372ad9a36594931b612d is the hash of "web_ide_https://open-vsx.org/vscode/gallery_https://open-vsx.org/vscode/item_https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}" "e36c431c0e2e1ee82c86" => "2e0d3e8c1107f9ccc5ea", - "55b10685e181429abe78" => "2e0d3e8c1107f9ccc5ea" + "55b10685e181429abe78" => "2e0d3e8c1107f9ccc5ea", + "372ad9a36594931b612d" => "2e0d3e8c1107f9ccc5ea" }.freeze def settings_context_hash(extension_marketplace_settings:) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e91c65ff1ba..29f5655025e 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6263,6 +6263,9 @@ msgstr "" msgid "AmazonQ|Create unit tests for selected lines of code in Java or Python files (Beta)" msgstr "" +msgid "AmazonQ|Create unit tests for this merge request (Beta)" +msgstr "" + msgid "AmazonQ|Delete the IAM identity provider created for AI gateway." msgstr "" diff --git a/scripts/frontend/quarantined_vue3_specs.txt b/scripts/frontend/quarantined_vue3_specs.txt index 138e6cc47d2..eba4a77239c 100644 --- a/scripts/frontend/quarantined_vue3_specs.txt +++ b/scripts/frontend/quarantined_vue3_specs.txt @@ -74,7 +74,6 @@ ee/spec/frontend/security_dashboard/components/shared/vulnerability_report/vulne ee/spec/frontend/sidebar/components/sidebar_dropdown_widget_spec.js ee/spec/frontend/status_checks/components/modal_create_spec.js ee/spec/frontend/status_checks/mount_spec.js -ee/spec/frontend/tracing/details/tracing_details_spec.js ee/spec/frontend/tracing/details/tracing_header_spec.js ee/spec/frontend/usage_quotas/transfer/components/usage_by_month_spec.js ee/spec/frontend/users/identity_verification/components/international_phone_input_spec.js diff --git a/spec/factories/ci/bridge.rb b/spec/factories/ci/bridge.rb index e5a03d98e8e..fca3724764c 100644 --- a/spec/factories/ci/bridge.rb +++ b/spec/factories/ci/bridge.rb @@ -25,13 +25,13 @@ FactoryBot.define do bridge.project ||= bridge.pipeline.project if evaluator.downstream.present? - bridge.options = bridge.options.to_h.merge( + bridge.options = bridge.options.to_h.deep_merge( trigger: { project: evaluator.downstream.full_path } ) end if evaluator.upstream.present? - bridge.options = bridge.options.to_h.merge( + bridge.options = bridge.options.to_h.deep_merge( bridge_needs: { pipeline: evaluator.upstream.full_path } ) end diff --git a/spec/features/issues/user_creates_confidential_merge_request_spec.rb b/spec/features/issues/user_creates_confidential_merge_request_spec.rb index 23fef5fa46e..12eff36a3af 100644 --- a/spec/features/issues/user_creates_confidential_merge_request_spec.rb +++ b/spec/features/issues/user_creates_confidential_merge_request_spec.rb @@ -50,6 +50,8 @@ RSpec.describe 'User creates confidential merge request on issue page', :js, fea click_button 'Create confidential merge request' end + click_button 'Show more breadcrumbs' + expect(page).to have_content(forked_project.namespace.name) end end diff --git a/spec/features/work_items/work_items_list_filters_spec.rb b/spec/features/work_items/work_items_list_filters_spec.rb index 383556b6518..854bfa264bc 100644 --- a/spec/features/work_items/work_items_list_filters_spec.rb +++ b/spec/features/work_items/work_items_list_filters_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' RSpec.describe 'Work items list filters', :js, feature_category: :team_planning do - include WorkItemFeedbackHelpers include FilteredSearchHelpers let_it_be(:user1) { create(:user) } @@ -48,8 +47,6 @@ RSpec.describe 'Work items list filters', :js, feature_category: :team_planning before do sign_in(user1) visit group_work_items_path(group) - - close_work_item_feedback_popover_if_present end describe 'assignee' do diff --git a/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js b/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js index 2e9126da815..c541f0357bc 100644 --- a/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js +++ b/spec/frontend/sidebar/components/reviewers/sidebar_reviewers_spec.js @@ -1,9 +1,9 @@ -import { shallowMount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; import axios from 'axios'; import AxiosMockAdapter from 'axios-mock-adapter'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import SidebarReviewers from '~/sidebar/components/reviewers/sidebar_reviewers.vue'; import SidebarService from '~/sidebar/services/sidebar_service'; import SidebarMediator from '~/sidebar/sidebar_mediator'; @@ -21,8 +21,10 @@ describe('sidebar reviewers', () => { let mediator; let axiosMock; + const findAssignButton = () => wrapper.findByTestId('sidebar-reviewers-assign-button'); + const createComponent = (props) => { - wrapper = shallowMount(SidebarReviewers, { + wrapper = shallowMountExtended(SidebarReviewers, { apolloProvider: apolloMock, propsData: { issuableIid: '1', @@ -67,7 +69,7 @@ describe('sidebar reviewers', () => { ${'shows'} | ${true} | ${true} ${'does not show'} | ${false} | ${false} `('$copy Assign button when canUpdate is $canUpdate', ({ canUpdate, expected }) => { - wrapper = shallowMount(SidebarReviewers, { + wrapper = shallowMountExtended(SidebarReviewers, { apolloProvider: apolloMock, propsData: { issuableIid: '1', @@ -93,7 +95,7 @@ describe('sidebar reviewers', () => { }, }); - expect(wrapper.find('[data-testid="sidebar-reviewers-assign-buton"]').exists()).toBe(expected); + expect(findAssignButton().exists()).toBe(expected); }); it('calls the mediator when it saves the reviewers', () => { diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js index 4fb5cbc46b5..d8054af925f 100644 --- a/spec/frontend/vue_shared/components/markdown/header_spec.js +++ b/spec/frontend/vue_shared/components/markdown/header_spec.js @@ -1,13 +1,18 @@ import $ from 'jquery'; import { nextTick } from 'vue'; import { GlToggle, GlButton } from '@gitlab/ui'; +import { createWrapper as createVueTestWrapper } from '@vue/test-utils'; import HeaderComponent from '~/vue_shared/components/markdown/header.vue'; import HeaderDividerComponent from '~/vue_shared/components/markdown/header_divider.vue'; import CommentTemplatesModal from '~/vue_shared/components/markdown/comment_templates_modal.vue'; import ToolbarButton from '~/vue_shared/components/markdown/toolbar_button.vue'; import ToolbarTableButton from '~/content_editor/components/toolbar_table_button.vue'; import DrawioToolbarButton from '~/vue_shared/components/markdown/drawio_toolbar_button.vue'; -import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { + mountExtended, + shallowMountExtended, + extendedWrapper, +} from 'helpers/vue_test_utils_helper'; import { updateText } from '~/lib/utils/text_markdown'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; @@ -352,24 +357,38 @@ describe('Markdown field header component', () => { describe('find and replace', () => { let form; + let formWrapper; const createParentForm = () => { form = document.createElement('form'); const field = document.createElement('div'); const root = document.createElement('div'); + const textarea = document.createElement('textarea'); + textarea.value = 'lorem ipsum dolor sit amet '; field.classList = 'js-vue-markdown-field'; + form.classList = 'md-area'; + form.appendChild(textarea); form.appendChild(field); field.appendChild(root); document.body.appendChild(form); + formWrapper = extendedWrapper(createVueTestWrapper(form)); return root; }; + const findFindInput = () => wrapper.findByTestId('find-btn'); + const findCloneDiv = () => formWrapper.findByTestId('find-and-replace-clone'); + const showFindAndReplace = async () => { $(document).triggerHandler('markdown-editor:find-and-replace:show', [$('form')]); await nextTick(); }; - const findFindInput = () => wrapper.findByTestId('find-btn'); + const closeFindAndReplace = async () => { + const preventDefault = jest.fn(); + findFindInput().vm.$emit('keydown', { preventDefault, key: 'Escape' }); + await nextTick(); + expect(preventDefault).not.toHaveBeenCalled(); + }; beforeEach(() => { createWrapper({ attachTo: createParentForm() }); @@ -403,11 +422,49 @@ describe('Markdown field header component', () => { it('closes the find-and-replace bar when Escape key is pressed', async () => { await showFindAndReplace(); - const preventDefault = jest.fn(); - findFindInput().vm.$emit('keydown', { preventDefault, key: 'Escape' }); - await nextTick(); - expect(preventDefault).not.toHaveBeenCalled(); + expect(wrapper.findByTestId('find-and-replace').exists()).toBe(true); + await closeFindAndReplace(); expect(wrapper.findByTestId('find-and-replace').exists()).toBe(false); }); + + it('embeds a clone to div to color highlighted text', async () => { + await showFindAndReplace(); + + findFindInput().vm.$emit('keyup', { target: { value: 'my-text' } }); + + await nextTick(); + expect(findCloneDiv().exists()).toBe(true); + + // Wait till the highlighting is complete + await nextTick(); + + // Check that closing the find and replace removes the clone div + await closeFindAndReplace(); + expect(findCloneDiv().exists()).toBe(false); + }); + + it('highlights text when text matches', async () => { + await showFindAndReplace(); + + // Text that does not match + await findFindInput().vm.$emit('keyup', { target: { value: 'my-text' } }); + + expect(formWrapper.element.querySelector('.js-highlight')).toBe(null); + + // Text that matches + await findFindInput().vm.$emit('keyup', { target: { value: 'lorem' } }); + + expect(formWrapper.element.querySelector('.js-highlight').innerHTML).toBe('lorem'); + }); + + it('is not vulnerable to XSS', async () => { + await showFindAndReplace(); + await findFindInput().vm.$emit('keyup', { target: { value: 'prompt' } }); + await nextTick(); + + expect(findCloneDiv().element.innerHTML).toBe( + 'lorem ipsum dolor sit amet <img src="prompt">', + ); + }); }); }); diff --git a/spec/lib/web_ide/extension_marketplace_preset_spec.rb b/spec/lib/web_ide/extension_marketplace_preset_spec.rb index a1d85b86f82..8eb7b4eb23b 100644 --- a/spec/lib/web_ide/extension_marketplace_preset_spec.rb +++ b/spec/lib/web_ide/extension_marketplace_preset_spec.rb @@ -19,7 +19,7 @@ RSpec.describe WebIde::ExtensionMarketplacePreset, feature_category: :web_ide do values: { service_url: "https://open-vsx.org/vscode/gallery", item_url: "https://open-vsx.org/vscode/item", - resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}" + resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}" } ) end diff --git a/spec/lib/web_ide/settings/extension_marketplace_validator_spec.rb b/spec/lib/web_ide/settings/extension_marketplace_validator_spec.rb index 8fa1e69b001..b07102aac0c 100644 --- a/spec/lib/web_ide/settings/extension_marketplace_validator_spec.rb +++ b/spec/lib/web_ide/settings/extension_marketplace_validator_spec.rb @@ -7,7 +7,7 @@ RSpec.describe WebIde::Settings::ExtensionMarketplaceValidator, feature_category let(:service_url) { "https://open-vsx.org/vscode/gallery" } let(:item_url) { "https://open-vsx.org/vscode/item" } - let(:resource_url_template) { "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}" } + let(:resource_url_template) { "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}" } let(:vscode_extension_marketplace) do { service_url: service_url, diff --git a/spec/lib/web_ide/settings/settings_integration_spec.rb b/spec/lib/web_ide/settings/settings_integration_spec.rb index ddf8c8f526f..93846ba9ba1 100644 --- a/spec/lib/web_ide/settings/settings_integration_spec.rb +++ b/spec/lib/web_ide/settings/settings_integration_spec.rb @@ -9,7 +9,7 @@ RSpec.describe ::WebIde::Settings, feature_category: :web_ide do # rubocop:disab { service_url: "https://open-vsx.org/vscode/gallery", item_url: "https://open-vsx.org/vscode/item", - resource_url_template: 'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}' + resource_url_template: 'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}' } end @@ -69,7 +69,7 @@ RSpec.describe ::WebIde::Settings, feature_category: :web_ide do # rubocop:disab stub_env("GITLAB_WEB_IDE_VSCODE_EXTENSION_MARKETPLACE", '{"service_url":"https://OVERRIDE.org/vscode/gallery",' \ '"item_url":"https://OVERRIDE.org/vscode/item",' \ - '"resource_url_template":"https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}"}' + '"resource_url_template":"https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}"}' ) end @@ -78,7 +78,7 @@ RSpec.describe ::WebIde::Settings, feature_category: :web_ide do # rubocop:disab { service_url: "https://OVERRIDE.org/vscode/gallery", item_url: "https://OVERRIDE.org/vscode/item", - resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}" + resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}" } ) end @@ -99,7 +99,7 @@ RSpec.describe ::WebIde::Settings, feature_category: :web_ide do # rubocop:disab it "uses default value" do expected_value = { item_url: "https://open-vsx.org/vscode/item", - resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}", + resource_url_template: "https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{versionRaw}/{path}", service_url: "https://open-vsx.org/vscode/gallery" } diff --git a/spec/lib/web_ide/settings_sync_spec.rb b/spec/lib/web_ide/settings_sync_spec.rb index 71f8da8e551..5b316d16e75 100644 --- a/spec/lib/web_ide/settings_sync_spec.rb +++ b/spec/lib/web_ide/settings_sync_spec.rb @@ -24,7 +24,12 @@ RSpec.describe WebIde::SettingsSync, feature_category: :web_ide do }, expectation: 'c6620244fe72864fa8d8' }, - "default vscode settings" => { + "default vscode settings (openvsx)" => { + enabled: true, + vscode_settings: ::WebIde::ExtensionMarketplacePreset.open_vsx.values, + expectation: '2e0d3e8c1107f9ccc5ea' + }, + "default vscode settings (openvsx compat without versionRaw)" => { enabled: true, vscode_settings: { service_url: 'https://open-vsx.org/vscode/gallery', @@ -33,7 +38,7 @@ RSpec.describe WebIde::SettingsSync, feature_category: :web_ide do }, expectation: '2e0d3e8c1107f9ccc5ea' }, - "default vscode settings (compatability)" => { + "default vscode settings (openvsx compat with vscode/asset)" => { enabled: true, vscode_settings: { service_url: 'https://open-vsx.org/vscode/gallery', @@ -42,7 +47,7 @@ RSpec.describe WebIde::SettingsSync, feature_category: :web_ide do }, expectation: '2e0d3e8c1107f9ccc5ea' }, - "default vscode settings (compatability after bug fix)" => { + "default vscode settings (openvsx compat without resource_url_template)" => { # This is the default vscode settings that creates the same # hash as default_vscode_settings to avoid breaking-changes. # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178491 diff --git a/spec/migrations/db/post_migrate/20250314113948_remove_replicas_with_evicted_indices_spec.rb b/spec/migrations/db/post_migrate/20250314113948_remove_replicas_with_evicted_indices_spec.rb new file mode 100644 index 00000000000..b2df5dc50c4 --- /dev/null +++ b/spec/migrations/db/post_migrate/20250314113948_remove_replicas_with_evicted_indices_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RemoveReplicasWithEvictedIndices, migration: :gitlab_main, feature_category: :global_search do + let(:zoekt_nodes) { table(:zoekt_nodes) } + let(:zoekt_node) { zoekt_nodes.create!(uuid: SecureRandom.uuid, index_base_url: 'i_url', search_base_url: 's_url') } + let(:organizations) { table(:organizations) } + let(:organization) { organizations.create!(path: 'path') } + let(:namespaces) { table(:namespaces) } + let(:namespace) { namespaces.create!(name: 'name', path: 'path', type: 'Group', organization_id: organization.id) } + let(:zoekt_indices) { table(:zoekt_indices) } + let!(:evicted_index_without_zoekt_replica) do + zoekt_indices.create!( + state: described_class::EVICTED_STATE, + zoekt_node_id: zoekt_node.id, + namespace_id: namespace.id + ) + end + + let(:zoekt_replicas) { table(:zoekt_replicas) } + let(:zoekt_enabled_namespaces) { table(:zoekt_enabled_namespaces) } + let(:zoekt_enabled_namespace) { zoekt_enabled_namespaces.create!(root_namespace_id: namespace.id) } + let(:zoekt_replica) do + zoekt_replicas.create!(zoekt_enabled_namespace_id: zoekt_enabled_namespace.id, namespace_id: namespace.id) + end + + let!(:evicted_index_with_zoekt_replica) do + zoekt_indices.create!( + state: described_class::EVICTED_STATE, + zoekt_node_id: zoekt_node.id, + namespace_id: namespace.id, + zoekt_replica_id: zoekt_replica.id + ) + end + + let(:zoekt_replica2) do + zoekt_replicas.create!(zoekt_enabled_namespace_id: zoekt_enabled_namespace.id, namespace_id: namespace.id) + end + + let!(:pending_eviction_index_with_zoekt_replica) do + zoekt_indices.create!( + state: 220, + zoekt_node_id: zoekt_node.id, + namespace_id: namespace.id, + zoekt_replica_id: zoekt_replica2.id + ) + end + + describe '#up' do + it 'deletes the zoekt_replicas of the evicted indices' do + expect(zoekt_replicas.exists?(id: evicted_index_with_zoekt_replica.zoekt_replica_id)).to be true + migrate! + expect(zoekt_replicas.exists?(id: evicted_index_with_zoekt_replica.zoekt_replica_id)).to be false + expect(pending_eviction_index_with_zoekt_replica.reload.zoekt_replica_id).not_to be_nil + end + end +end diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb index cff97ac9318..dbd334e6068 100644 --- a/spec/models/ci/bridge_spec.rb +++ b/spec/models/ci/bridge_spec.rb @@ -82,6 +82,68 @@ RSpec.describe Ci::Bridge, feature_category: :continuous_integration do end end + describe '#downstream_pipeline_params' do + it 'returns an empty hash' do + expect(bridge.downstream_pipeline_params).to eq({}) + end + + context 'when there is a downstream project present' do + it 'returns cross project params' do + downstream_project = create(:project) + options = { trigger: { project: 'our/project', inputs: {} } } + bridge = create(:ci_bridge, status: :created, options: options, downstream: downstream_project) + + cross_project_params = { + project: downstream_project, + source: :pipeline, + target_revision: { + ref: downstream_project.default_branch, + variables_attributes: [] + }, + execute_params: { + ignore_skip_ci: true, + bridge: bridge, + inputs: {} + } + } + + expect(bridge.downstream_pipeline_params).to eq(cross_project_params) + end + end + + context 'when a child pipeline is triggered' do + let(:options) do + { + trigger: { + include: 'path/to/child.yml' + } + } + end + + it 'returns child params' do + child_params = { + project: project, + source: :parent_pipeline, + target_revision: { + ref: pipeline.ref, + checkout_sha: pipeline.sha, + before: pipeline.before_sha, + source_sha: pipeline.source_sha, + target_sha: pipeline.target_sha, + variables_attributes: bridge.downstream_variables + }, + execute_params: { + ignore_skip_ci: true, + bridge: bridge, + merge_request: pipeline.merge_request + } + } + + expect(bridge.downstream_pipeline_params).to eq(child_params) + end + end + end + describe '#tags' do it 'only has a bridge tag' do expect(bridge.tags).to eq [:bridge] diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb index 326b5d0bb39..899b219ec8c 100644 --- a/spec/models/personal_access_token_spec.rb +++ b/spec/models/personal_access_token_spec.rb @@ -648,7 +648,13 @@ RSpec.describe PersonalAccessToken, feature_category: :system_access do describe '.simple_sorts' do it 'includes overridden keys' do - expect(described_class.simple_sorts.keys).to include(*%w[expires_at_asc_id_desc]) + expect(described_class.simple_sorts.keys).to include(*%w[expires_asc expires_at_asc_id_desc expires_desc last_used_asc last_used_desc]) + end + + it 'returns a valid ActiveRecord::Relation for each sort' do + described_class.simple_sorts.each_value do |blk| + expect(blk.call).to be_a(ActiveRecord::Relation) + end end end @@ -679,6 +685,36 @@ RSpec.describe PersonalAccessToken, feature_category: :system_access do expect(described_class.order_expires_at_asc_id_desc).to eq [earlier_token_2, earlier_token, later_token] end end + + describe '.order_expires_at_desc_id_desc' do + let_it_be(:earlier_token_2) { create(:personal_access_token, expires_at: 2.days.ago) } + + it 'returns ordered list in combination of expires_at descending and id descending' do + expect(described_class.order_expires_at_desc_id_desc).to eq [later_token, earlier_token_2, earlier_token] + end + end + end + + describe 'ordering by last_used_at' do + let_it_be(:two_days_ago) { 2.days.ago } + let_it_be(:earlier_token) { create(:personal_access_token, last_used_at: two_days_ago) } + let_it_be(:later_token) { create(:personal_access_token, last_used_at: 1.day.ago) } + + describe '.order_last_used_at_asc_id_desc' do + let_it_be(:earlier_token_2) { create(:personal_access_token, last_used_at: two_days_ago) } + + it 'returns ordered list in combination of last_used_at ascending and id descending' do + expect(described_class.order_last_used_at_asc_id_desc).to eq [earlier_token_2, earlier_token, later_token] + end + end + + describe '.order_last_used_at_desc_id_desc' do + let_it_be(:earlier_token_2) { create(:personal_access_token, last_used_at: 2.days.ago) } + + it 'returns ordered list in combination of expires_at descending and id descending' do + expect(described_class.order_last_used_at_desc_id_desc).to eq [later_token, earlier_token_2, earlier_token] + end + end end it_behaves_like 'TokenAuthenticatable' do diff --git a/spec/requests/organizations/organizations_controller_spec.rb b/spec/requests/organizations/organizations_controller_spec.rb index bc2b26cd44c..3a49ea78853 100644 --- a/spec/requests/organizations/organizations_controller_spec.rb +++ b/spec/requests/organizations/organizations_controller_spec.rb @@ -208,30 +208,30 @@ RSpec.describe Organizations::OrganizationsController, feature_category: :cell d end end - context 'when organization has multiple projects', - quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/524222' do - let_it_be(:stale_project) do - create(:project, :public, organization: organization, last_activity_at: 3.days.ago) - .tap { |project| create(:project_member, :developer, user:, project:) } - end - - let_it_be(:recently_updated_project) do - create(:project, :public, organization: organization, last_activity_at: Date.current) - .tap { |project| create(:project_member, :developer, user:, project:) } - end + context 'when organization has multiple projects' do + let_it_be(:stale_project) { create(:project, organization: organization, developers: [user]) } + let_it_be(:recently_updated_project) { create(:project, organization: organization, developers: [user]) } before_all do + stale_project.update!(last_activity_at: 3.days.ago) + sign_in(user) end - it 'returns events from the projects with the most recent activities' do + it 'returns events from the projects with the most recent activities', :aggregate_failures do stub_const("#{described_class}::DEFAULT_RESOURCE_LIMIT", 1) get activity_organization_path(organization, format: :json) + resource_parent_path = json_response['events'].first["resource_parent"]["full_path"] + expect(json_response['events'].size).to eq(1) - expect(json_response['events'].first["resource_parent"]["full_path"]) - .to eq(recently_updated_project.full_path) + expect(resource_parent_path).to eq(recently_updated_project.full_path), <<~ERROR.squish + Expected project with path #{recently_updated_project.full_path} + (last_activity_at: #{recently_updated_project.last_activity_at}), + but got #{resource_parent_path || 'nil'}. + Stale project: #{stale_project.full_path} last_activity_at: #{stale_project.last_activity_at}). + ERROR end end diff --git a/spec/services/groups/mark_for_deletion_service_spec.rb b/spec/services/groups/mark_for_deletion_service_spec.rb new file mode 100644 index 00000000000..1e6ae15bd26 --- /dev/null +++ b/spec/services/groups/mark_for_deletion_service_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Groups::MarkForDeletionService, feature_category: :groups_and_projects do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let(:params) { { param: true } } + let(:service) { described_class.new(group, user, params) } + + context 'when in FOSS', unless: Gitlab.ee? do + describe '#execute' do + context 'when async is true' do + it 'executes the Groups::DestroyService with the same parameters asychronously' do + expect_next_instance_of(Groups::DestroyService, group, user, params) do |destroy_service| + expect(destroy_service).to receive(:async_execute) + end + + service.execute + end + end + + context 'when async is false' do + it 'executes the Groups::DestroyService with the same parameters sychronously' do + expect_next_instance_of(Groups::DestroyService, group, user, params) do |destroy_service| + expect(destroy_service).to receive(:execute) + end + + service.execute(async: false) + end + end + end + end +end diff --git a/spec/services/projects/mark_for_deletion_service_spec.rb b/spec/services/projects/mark_for_deletion_service_spec.rb new file mode 100644 index 00000000000..74957284909 --- /dev/null +++ b/spec/services/projects/mark_for_deletion_service_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::MarkForDeletionService, feature_category: :groups_and_projects do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + let(:params) { { param: true } } + let(:service) { described_class.new(project, user, params) } + + context 'when in FOSS', unless: Gitlab.ee? do + describe '#execute' do + context 'when async is true' do + it 'executes the Projects::DestroyService with the same parameters asychronously' do + expect_next_instance_of(Projects::DestroyService, project, user, params) do |destroy_service| + expect(destroy_service).to receive(:async_execute) + end + + service.execute + end + end + + context 'when async is false' do + it 'executes the Projects::DestroyService with the same parameters sychronously' do + expect_next_instance_of(Projects::DestroyService, project, user, params) do |destroy_service| + expect(destroy_service).to receive(:execute) + end + + service.execute(async: false) + end + end + end + end +end diff --git a/spec/support/helpers/reactive_caching_helpers.rb b/spec/support/helpers/reactive_caching_helpers.rb index 0b0b0622696..00192a5d587 100644 --- a/spec/support/helpers/reactive_caching_helpers.rb +++ b/spec/support/helpers/reactive_caching_helpers.rb @@ -48,6 +48,6 @@ module ReactiveCachingHelpers def expect_reactive_cache_update_queued(subject, worker_klass: ReactiveCachingWorker) expect(worker_klass) .to receive(:perform_in) - .with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id) + .with(subject.class.reactive_cache_refresh_interval, subject.class.name, subject.id) end end diff --git a/spec/support/helpers/work_item_feedback_helpers.rb b/spec/support/helpers/work_item_feedback_helpers.rb deleted file mode 100644 index 3934e51d879..00000000000 --- a/spec/support/helpers/work_item_feedback_helpers.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module WorkItemFeedbackHelpers - def close_work_item_feedback_popover_if_present - return unless page.has_css?("[data-testid='work-item-feedback-popover']") - - page.within("[data-testid='work-item-feedback-popover']") do - page.find("[data-testid='close-button']").click - end - end -end diff --git a/spec/support/shared_examples/features/work_items/rolled_up_dates_drawer_shared_examples.rb b/spec/support/shared_examples/features/work_items/rolled_up_dates_drawer_shared_examples.rb index 59d63c41224..1083ad41560 100644 --- a/spec/support/shared_examples/features/work_items/rolled_up_dates_drawer_shared_examples.rb +++ b/spec/support/shared_examples/features/work_items/rolled_up_dates_drawer_shared_examples.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true RSpec.shared_examples 'work items due dates in drawer' do - include WorkItemFeedbackHelpers - let(:work_item_due_dates_selector) { '[data-testid="work-item-due-dates"]' } let(:work_item_start_due_dates_selector) { '[data-testid="work-item-start-due-dates"]' } let(:work_item_milestone_selector) { '[data-testid="work-item-milestone"]' } @@ -13,8 +11,6 @@ RSpec.shared_examples 'work items due dates in drawer' do page.refresh wait_for_all_requests - - close_work_item_feedback_popover_if_present end it 'passes axe automated accessibility testing in closed state' do diff --git a/spec/support/shared_examples/features/work_items/rolledup_dates_shared_examples.rb b/spec/support/shared_examples/features/work_items/rolledup_dates_shared_examples.rb index 807e43efd1c..25405da2b95 100644 --- a/spec/support/shared_examples/features/work_items/rolledup_dates_shared_examples.rb +++ b/spec/support/shared_examples/features/work_items/rolledup_dates_shared_examples.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true RSpec.shared_examples 'work items rolled up dates' do - include WorkItemFeedbackHelpers - let(:work_item_due_dates_selector) { '[data-testid="work-item-due-dates"]' } let(:work_item_milestone_selector) { '[data-testid="work-item-milestone"]' } @@ -28,8 +26,6 @@ RSpec.shared_examples 'work items rolled up dates' do page.refresh wait_for_all_requests - - close_work_item_feedback_popover_if_present end context 'when using inheritable dates', :sidekiq_inline do