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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-07-12 06:08:48 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-12 06:08:48 +0300
commitbb01b338bfbc6e17996696145e6c495694b8f745 (patch)
treea470ea44dca6b2975fe5b62f07558286652e8140
parent7abe3b23d1dc3267ac7ac4e1955c78c97d06485c (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/issue_templates/Geo Replicate a new Git repository type.md1
-rw-r--r--app/controllers/concerns/integrations/params.rb2
-rw-r--r--app/helpers/integrations_helper.rb8
-rw-r--r--app/models/group.rb7
-rw-r--r--app/models/integration.rb4
-rw-r--r--app/models/integrations/base_chat_notification.rb4
-rw-r--r--app/models/integrations/base_slack_notification.rb11
-rw-r--r--app/models/integrations/chat_message/group_mention_message.rb102
-rw-r--r--app/services/integrations/group_mention_service.rb59
-rw-r--r--app/services/issues/base_service.rb19
-rw-r--r--app/services/merge_requests/base_service.rb19
-rw-r--r--app/services/notes/post_process_service.rb11
-rw-r--r--app/workers/all_queues.yml9
-rw-r--r--app/workers/integrations/group_mention_worker.rb42
-rw-r--r--config/feature_flags/development/group_mentions.yml8
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--db/migrate/20230705155000_add_group_mention_events_to_integrations.rb8
-rw-r--r--db/schema_migrations/202307051550001
-rw-r--r--db/structure.sql2
-rw-r--r--doc/administration/admin_area.md489
-rw-r--r--doc/administration/audit_events.md2
-rw-r--r--doc/administration/auditor_users.md2
-rw-r--r--doc/administration/compliance.md2
-rw-r--r--doc/administration/configure.md2
-rw-r--r--doc/administration/dedicated/index.md2
-rw-r--r--doc/administration/gitaly/recovery.md10
-rw-r--r--doc/administration/img/export_permissions_v13_11.png (renamed from doc/user/admin_area/img/export_permissions_v13_11.png)bin11567 -> 11567 bytes
-rw-r--r--doc/administration/img/impersonate_user_button_v13_8.png (renamed from doc/user/admin_area/img/impersonate_user_button_v13_8.png)bin23707 -> 23707 bytes
-rw-r--r--doc/administration/img/index_runners_search_or_filter_v14_5.png (renamed from doc/user/admin_area/img/index_runners_search_or_filter_v14_5.png)bin13881 -> 13881 bytes
-rw-r--r--doc/administration/repository_storage_types.md2
-rw-r--r--doc/administration/user_settings.md2
-rw-r--r--doc/ci/jobs/job_control.md2
-rw-r--r--doc/ci/pipelines/cicd_minutes.md4
-rw-r--r--doc/integration/advanced_search/elasticsearch_troubleshooting.md2
-rw-r--r--doc/raketasks/user_management.md2
-rw-r--r--doc/security/unlock_user.md2
-rw-r--r--doc/subscriptions/self_managed/index.md4
-rw-r--r--doc/update/background_migrations.md2
-rw-r--r--doc/user/admin_area/index.md492
-rw-r--r--doc/user/admin_area/settings/account_and_limit_settings.md2
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md2
-rw-r--r--doc/user/group/saml_sso/troubleshooting_scim.md2
-rw-r--r--doc/user/group/subgroups/index.md2
-rw-r--r--doc/user/profile/account/delete_account.md2
-rw-r--r--doc/user/project/integrations/gitlab_slack_application.md2
-rw-r--r--doc/user/project/integrations/slack.md2
-rw-r--r--doc/user/project/repository/mirror/index.md2
-rw-r--r--doc/user/project/settings/index.md4
-rw-r--r--doc/user/project/working_with_projects.md2
-rw-r--r--doc/user/upgrade_email_bypass.md2
-rw-r--r--locale/gitlab.pot24
-rw-r--r--spec/models/group_spec.rb22
-rw-r--r--spec/models/integrations/chat_message/group_mention_message_spec.rb193
-rw-r--r--spec/services/integrations/group_mention_service_spec.rb143
-rw-r--r--spec/services/issues/create_service_spec.rb6
-rw-r--r--spec/services/issues/reopen_service_spec.rb6
-rw-r--r--spec/services/merge_requests/after_create_service_spec.rb6
-rw-r--r--spec/services/merge_requests/reopen_service_spec.rb4
-rw-r--r--spec/services/notes/post_process_service_spec.rb3
-rw-r--r--spec/workers/integrations/group_mention_worker_spec.rb65
60 files changed, 1309 insertions, 529 deletions
diff --git a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
index 24ccd4afd6d..b77247954de 100644
--- a/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
+++ b/.gitlab/issue_templates/Geo Replicate a new Git repository type.md
@@ -69,7 +69,6 @@ Geo secondary sites have a [Geo tracking database](https://gitlab.com/gitlab-org
t.integer :retry_count, default: 0, limit: 2, null: false
t.integer :verification_retry_count, default: 0, limit: 2, null: false
t.boolean :checksum_mismatch, default: false, null: false
- t.boolean :force_to_redownload, default: false, null: false
t.boolean :missing_on_primary, default: false, null: false
t.binary :verification_checksum
t.binary :verification_checksum_mismatched
diff --git a/app/controllers/concerns/integrations/params.rb b/app/controllers/concerns/integrations/params.rb
index 19e458307a1..53dd06ce638 100644
--- a/app/controllers/concerns/integrations/params.rb
+++ b/app/controllers/concerns/integrations/params.rb
@@ -43,6 +43,8 @@ module Integrations
:external_wiki_url,
:google_iap_service_account_json,
:google_iap_audience_client_id,
+ :group_confidential_mention_events,
+ :group_mention_events,
:incident_events,
:inherit_from_id,
# We're using `issues_events` and `merge_requests_events`
diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb
index ffea23bf55d..4b5fadf3397 100644
--- a/app/helpers/integrations_helper.rb
+++ b/app/helpers/integrations_helper.rb
@@ -30,6 +30,10 @@ module IntegrationsHelper
_("Alert")
when "incident"
_("Incident")
+ when "group_mention"
+ _("Group mention in public")
+ when "group_confidential_mention"
+ _("Group mention in private")
end
end
# rubocop:enable Metrics/CyclomaticComplexity
@@ -290,6 +294,10 @@ module IntegrationsHelper
s_("ProjectService|Trigger event when a new, unique alert is recorded.")
when "incident"
s_("ProjectService|Trigger event when an incident is created.")
+ when "group_mention"
+ s_("ProjectService|Trigger event when a group is mentioned in a public context.")
+ when "group_confidential_mention"
+ s_("ProjectService|Trigger event when a group is mentioned in a confidential context.")
end
end
# rubocop:enable Metrics/CyclomaticComplexity
diff --git a/app/models/group.rb b/app/models/group.rb
index 4e92bdab94c..c004d525fcd 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -813,8 +813,11 @@ class Group < Namespace
end
def execute_integrations(data, hooks_scope)
- # NOOP
- # TODO: group hooks https://gitlab.com/gitlab-org/gitlab/-/issues/216904
+ return unless Feature.enabled?(:group_mentions, self)
+
+ integrations.public_send(hooks_scope).each do |integration| # rubocop:disable GitlabSecurity/PublicSend
+ integration.async_execute(data)
+ end
end
def preload_shared_group_links
diff --git a/app/models/integration.rb b/app/models/integration.rb
index eae94f7cd5d..f823a385022 100644
--- a/app/models/integration.rb
+++ b/app/models/integration.rb
@@ -90,6 +90,8 @@ class Integration < ApplicationRecord
attribute :push_events, default: true
attribute :tag_push_events, default: true
attribute :wiki_page_events, default: true
+ attribute :group_mention_events, default: false
+ attribute :group_confidential_mention_events, default: false
after_initialize :initialize_properties
@@ -137,6 +139,8 @@ class Integration < ApplicationRecord
scope :alert_hooks, -> { where(alert_events: true, active: true) }
scope :incident_hooks, -> { where(incident_events: true, active: true) }
scope :deployment, -> { where(category: 'deployment') }
+ scope :group_mention_hooks, -> { where(group_mention_events: true, active: true) }
+ scope :group_confidential_mention_hooks, -> { where(group_confidential_mention_events: true, active: true) }
class << self
private
diff --git a/app/models/integrations/base_chat_notification.rb b/app/models/integrations/base_chat_notification.rb
index 4477f3d207f..c9de4d2b3bb 100644
--- a/app/models/integrations/base_chat_notification.rb
+++ b/app/models/integrations/base_chat_notification.rb
@@ -262,11 +262,11 @@ module Integrations
end
def project_name
- project.full_name
+ project.try(:full_name)
end
def project_url
- project.web_url
+ project.try(:web_url)
end
def update?(data)
diff --git a/app/models/integrations/base_slack_notification.rb b/app/models/integrations/base_slack_notification.rb
index c83a559e0da..29a20419809 100644
--- a/app/models/integrations/base_slack_notification.rb
+++ b/app/models/integrations/base_slack_notification.rb
@@ -7,6 +7,8 @@ module Integrations
].freeze
prop_accessor EVENT_CHANNEL['alert']
+ prop_accessor EVENT_CHANNEL['group_mention']
+ prop_accessor EVENT_CHANNEL['group_confidential_mention']
override :default_channel_placeholder
def default_channel_placeholder
@@ -16,15 +18,20 @@ module Integrations
override :get_message
def get_message(object_kind, data)
return Integrations::ChatMessage::AlertMessage.new(data) if object_kind == 'alert'
+ return Integrations::ChatMessage::GroupMentionMessage.new(data) if object_kind == 'group_mention'
super
end
override :supported_events
def supported_events
- additional = ['alert']
+ additional = %w[alert]
- super + additional
+ if group_level? && Feature.enabled?(:group_mentions, group)
+ additional += %w[group_mention group_confidential_mention]
+ end
+
+ (super + additional).freeze
end
override :configurable_channels?
diff --git a/app/models/integrations/chat_message/group_mention_message.rb b/app/models/integrations/chat_message/group_mention_message.rb
new file mode 100644
index 00000000000..a2bc00ddbd9
--- /dev/null
+++ b/app/models/integrations/chat_message/group_mention_message.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+module Integrations
+ module ChatMessage
+ class GroupMentionMessage < BaseMessage
+ ISSUE_KIND = 'issue'
+ MR_KIND = 'merge_request'
+ NOTE_KIND = 'note'
+
+ KNOWN_KINDS = [ISSUE_KIND, MR_KIND, NOTE_KIND].freeze
+
+ def initialize(params)
+ super
+ params = HashWithIndifferentAccess.new(params)
+
+ @group_name, @group_url = params[:mentioned].values_at(:name, :url)
+ @detail = nil
+
+ obj_attr = params[:object_attributes]
+ obj_kind = obj_attr[:object_kind]
+ raise NotImplementedError unless KNOWN_KINDS.include?(obj_kind)
+
+ case obj_kind
+ when 'issue'
+ @source_name, @title = get_source_for_issue(obj_attr)
+ @detail = obj_attr[:description]
+ when 'merge_request'
+ @source_name, @title = get_source_for_merge_request(obj_attr)
+ @detail = obj_attr[:description]
+ when 'note'
+ if params[:commit]
+ @source_name, @title = get_source_for_commit(params[:commit])
+ elsif params[:issue]
+ @source_name, @title = get_source_for_issue(params[:issue])
+ elsif params[:merge_request]
+ @source_name, @title = get_source_for_merge_request(params[:merge_request])
+ else
+ raise NotImplementedError
+ end
+
+ @detail = obj_attr[:note]
+ end
+
+ @source_url = obj_attr[:url]
+ end
+
+ def attachments
+ if markdown
+ detail
+ else
+ [{ text: format(detail), color: attachment_color }]
+ end
+ end
+
+ def activity
+ {
+ title: "Group #{group_link} was mentioned in #{source_link}",
+ subtitle: "of #{project_link}",
+ text: strip_markup(formatted_title),
+ image: user_avatar
+ }
+ end
+
+ private
+
+ attr_reader :group_name, :group_url, :source_name, :source_url, :title, :detail
+
+ def get_source_for_commit(params)
+ commit_sha = Commit.truncate_sha(params[:id])
+ ["commit #{commit_sha}", params[:title]]
+ end
+
+ def get_source_for_issue(params)
+ ["issue ##{params[:iid]}", params[:title]]
+ end
+
+ def get_source_for_merge_request(params)
+ ["merge request !#{params[:iid]}", params[:title]]
+ end
+
+ def message
+ "Group #{group_link} was mentioned in #{source_link} of #{project_link}: *#{formatted_title}*"
+ end
+
+ def formatted_title
+ strip_markup(title.lines.first.chomp)
+ end
+
+ def group_link
+ link(group_name, group_url)
+ end
+
+ def source_link
+ link(source_name, source_url)
+ end
+
+ def project_link
+ link(project_name, project_url)
+ end
+ end
+ end
+end
diff --git a/app/services/integrations/group_mention_service.rb b/app/services/integrations/group_mention_service.rb
new file mode 100644
index 00000000000..2389bf33432
--- /dev/null
+++ b/app/services/integrations/group_mention_service.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+# GroupMentionService class
+#
+# Used for sending group mention notifications
+#
+# Ex.
+# Integrations::GroupMentionService.new(mentionable, hook_data: data, is_confidential: true).execute
+#
+module Integrations
+ class GroupMentionService
+ def initialize(mentionable, hook_data:, is_confidential:)
+ @mentionable = mentionable
+ @hook_data = hook_data
+ @is_confidential = is_confidential
+ end
+
+ def execute
+ return ServiceResponse.success if mentionable.nil? || hook_data.nil?
+
+ @hook_data = hook_data.clone
+ # Fake a "group_mention" object kind so integrations can handle this as a separate class of event
+ hook_data[:object_attributes][:object_kind] = hook_data[:object_kind]
+ hook_data[:object_kind] = 'group_mention'
+
+ if confidential?
+ hook_data[:event_type] = 'group_confidential_mention'
+ hook_scope = :group_confidential_mention_hooks
+ else
+ hook_data[:event_type] = 'group_mention'
+ hook_scope = :group_mention_hooks
+ end
+
+ groups = mentionable.referenced_groups(mentionable.author)
+ groups.each do |group|
+ group_hook_data = hook_data.merge(
+ mentioned: {
+ object_kind: 'group',
+ name: group.full_path,
+ url: group.web_url
+ }
+ )
+ group.execute_integrations(group_hook_data, hook_scope)
+ end
+
+ ServiceResponse.success
+ end
+
+ private
+
+ attr_reader :mentionable, :hook_data, :is_confidential
+
+ def confidential?
+ return is_confidential if is_confidential.present?
+
+ mentionable.project.visibility_level != Gitlab::VisibilityLevel::PUBLIC
+ end
+ end
+end
diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb
index f982d66eb08..b9b7cd08b68 100644
--- a/app/services/issues/base_service.rb
+++ b/app/services/issues/base_service.rb
@@ -111,6 +111,10 @@ module Issues
issue.namespace.execute_integrations(issue_data, hooks_scope)
execute_incident_hooks(issue, issue_data) if issue.work_item_type&.incident?
+
+ return unless Feature.enabled?(:group_mentions, issue.project)
+
+ execute_group_mention_hooks(issue, issue_data) if action == 'open'
end
# We can remove this code after proposal in
@@ -121,6 +125,21 @@ module Issues
issue.namespace.execute_integrations(issue_data, :incident_hooks)
end
+ def execute_group_mention_hooks(issue, issue_data)
+ return unless issue.instance_of?(Issue)
+
+ args = {
+ mentionable_type: 'Issue',
+ mentionable_id: issue.id,
+ hook_data: issue_data,
+ is_confidential: issue.confidential?
+ }
+
+ issue.run_after_commit_or_now do
+ Integrations::GroupMentionWorker.perform_async(args)
+ end
+ end
+
def update_project_counter_caches?(issue)
super || issue.confidential_changed?
end
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index ec8a17162ca..aaa91548d19 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -36,6 +36,10 @@ module MergeRequests
execute_external_hooks(merge_request, merge_data)
+ if action == 'open' && Feature.enabled?(:group_mentions, merge_request.project)
+ execute_group_mention_hooks(merge_request, merge_data)
+ end
+
enqueue_jira_connect_messages_for(merge_request)
end
@@ -43,6 +47,21 @@ module MergeRequests
# Implemented in EE
end
+ def execute_group_mention_hooks(merge_request, merge_data)
+ return unless merge_request.instance_of?(MergeRequest)
+
+ args = {
+ mentionable_type: 'MergeRequest',
+ mentionable_id: merge_request.id,
+ hook_data: merge_data,
+ is_confidential: false
+ }
+
+ merge_request.run_after_commit_or_now do
+ Integrations::GroupMentionWorker.perform_async(args)
+ end
+ end
+
def handle_changes(merge_request, options)
old_associations = options.fetch(:old_associations, {})
old_assignees = old_associations.fetch(:assignees, [])
diff --git a/app/services/notes/post_process_service.rb b/app/services/notes/post_process_service.rb
index c9375fe14a1..9465b5218b0 100644
--- a/app/services/notes/post_process_service.rb
+++ b/app/services/notes/post_process_service.rb
@@ -36,10 +36,19 @@ module Notes
return unless note.project
note_data = hook_data
- hooks_scope = note.confidential?(include_noteable: true) ? :confidential_note_hooks : :note_hooks
+ is_confidential = note.confidential?(include_noteable: true)
+ hooks_scope = is_confidential ? :confidential_note_hooks : :note_hooks
note.project.execute_hooks(note_data, hooks_scope)
note.project.execute_integrations(note_data, hooks_scope)
+
+ return unless Feature.enabled?(:group_mentions, note.project)
+
+ execute_group_mention_hooks(note, note_data, is_confidential)
+ end
+
+ def execute_group_mention_hooks(note, note_data, is_confidential)
+ Integrations::GroupMentionService.new(note, hook_data: note_data, is_confidential: is_confidential).execute
end
end
end
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 316b11ad791..f4d94432842 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -2847,6 +2847,15 @@
:weight: 1
:idempotent: false
:tags: []
+- :name: integrations_group_mention
+ :worker_name: Integrations::GroupMentionWorker
+ :feature_category: :integrations
+ :has_external_dependencies: true
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: integrations_irker
:worker_name: Integrations::IrkerWorker
:feature_category: :integrations
diff --git a/app/workers/integrations/group_mention_worker.rb b/app/workers/integrations/group_mention_worker.rb
new file mode 100644
index 00000000000..6cde1657ccd
--- /dev/null
+++ b/app/workers/integrations/group_mention_worker.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Integrations
+ class GroupMentionWorker
+ include ApplicationWorker
+
+ idempotent!
+ feature_category :integrations
+ deduplicate :until_executed
+ data_consistency :delayed
+ urgency :low
+
+ worker_has_external_dependencies!
+
+ def perform(args)
+ args = args.with_indifferent_access
+
+ mentionable_type = args[:mentionable_type]
+ mentionable_id = args[:mentionable_id]
+ hook_data = args[:hook_data]
+ is_confidential = args[:is_confidential]
+
+ mentionable = case mentionable_type
+ when 'Issue'
+ Issue.find(mentionable_id)
+ when 'MergeRequest'
+ MergeRequest.find(mentionable_id)
+ end
+
+ if mentionable.nil?
+ Sidekiq.logger.error(
+ message: 'Integrations::GroupMentionWorker: mentionable not supported',
+ mentionable_type: mentionable_type,
+ mentionable_id: mentionable_id
+ )
+ return
+ end
+
+ Integrations::GroupMentionService.new(mentionable, hook_data: hook_data, is_confidential: is_confidential).execute
+ end
+ end
+end
diff --git a/config/feature_flags/development/group_mentions.yml b/config/feature_flags/development/group_mentions.yml
new file mode 100644
index 00000000000..4f536b2b583
--- /dev/null
+++ b/config/feature_flags/development/group_mentions.yml
@@ -0,0 +1,8 @@
+---
+name: group_mentions
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96684
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/414856
+milestone: '16.2'
+type: development
+group: group::import and integrate
+default_enabled: false
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 94504635972..18ae1d7c097 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -303,6 +303,8 @@
- 1
- - integrations_execute
- 1
+- - integrations_group_mention
+ - 1
- - integrations_irker
- 1
- - integrations_slack_event
diff --git a/db/migrate/20230705155000_add_group_mention_events_to_integrations.rb b/db/migrate/20230705155000_add_group_mention_events_to_integrations.rb
new file mode 100644
index 00000000000..82c2c714022
--- /dev/null
+++ b/db/migrate/20230705155000_add_group_mention_events_to_integrations.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class AddGroupMentionEventsToIntegrations < Gitlab::Database::Migration[2.1]
+ def change
+ add_column :integrations, :group_mention_events, :boolean, null: false, default: false
+ add_column :integrations, :group_confidential_mention_events, :boolean, null: false, default: false
+ end
+end
diff --git a/db/schema_migrations/20230705155000 b/db/schema_migrations/20230705155000
new file mode 100644
index 00000000000..e2f6d13e31e
--- /dev/null
+++ b/db/schema_migrations/20230705155000
@@ -0,0 +1 @@
+4f3d64c52ac1b46bab194be78cadeaa36abf3faf26de1c7d7ca3c03cc64b876f \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index f54bd4fc210..5efc4c0765f 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -17152,6 +17152,8 @@ CREATE TABLE integrations (
encrypted_properties bytea,
encrypted_properties_iv bytea,
incident_events boolean DEFAULT false NOT NULL,
+ group_mention_events boolean DEFAULT false NOT NULL,
+ group_confidential_mention_events boolean DEFAULT false NOT NULL,
CONSTRAINT check_a948a0aa7e CHECK ((char_length(type_new) <= 255))
);
diff --git a/doc/administration/admin_area.md b/doc/administration/admin_area.md
new file mode 100644
index 00000000000..65e437be487
--- /dev/null
+++ b/doc/administration/admin_area.md
@@ -0,0 +1,489 @@
+---
+stage: none
+group: unassigned
+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
+type: reference
+---
+
+# GitLab Admin Area **(FREE SELF)**
+
+The Admin Area provides a web UI to manage and configure features of GitLab
+self-managed instances. If you are an administrator,to access the Admin Area:
+
+- In GitLab 16.1 and later: on the left sidebar, expand the top-most chevron (**{chevron-down}**), then select **Admin Area**.
+- In GitLab 16.0 and earlier: on the top bar, select **Main menu > Admin**.
+
+NOTE:
+Only administrators can access the Admin Area.
+
+## Administering projects
+
+You can administer all projects in the GitLab instance from the Admin Area's Projects page.
+
+To access the Projects page:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Projects**.
+1. Select the **All**, **Private**, **Internal**, or **Public** tab to list only
+ projects of that criteria.
+
+By default, all projects are listed, in reverse order of when they were last updated. For each
+project, the following information is listed:
+
+- Name
+- Namespace
+- Description
+- Size, updated every 15 minutes at most
+
+Projects can be edited or deleted.
+
+To edit a project's name or description:
+
+1. In the Projects overview, next to the project you want to edit, select **Edit**.
+1. Edit the **Project name** or **Project description**.
+1. Select **Save Changes**.
+
+To delete a project:
+
+1. In the Projects overview, next to the project you want to delete, select **Delete**.
+
+The list of projects can be sorted by:
+
+- Updated date
+- Last created
+- Name
+- Most stars
+- Oldest created
+- Oldest updated
+- Largest repository
+
+A user can choose to hide or show archived projects in the list.
+
+In the **Filter by name** field, type the project name you want to find, and GitLab filters
+them as you type.
+
+To filter only projects in that namespace, select from the **Namespace** dropdown list.
+
+You can combine the filter options. For example, to list only public projects with `score` in their name:
+
+1. Select the **Public** tab.
+1. Enter `score` in the **Filter by name...** input box.
+
+## Administering users
+
+You can administer all users in the GitLab instance from the Admin Area's Users page:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Users**.
+
+To list users matching a specific criteria, select one of the following tabs on the **Users** page:
+
+- **Active**
+- **Admins**
+- **2FA Enabled**
+- **2FA Disabled**
+- **External**
+- **[Blocked](../user/admin_area/moderate_users.md#block-a-user)**
+- **[Deactivated](../user/admin_area/moderate_users.md#deactivate-a-user)**
+- **Without projects**
+
+For each user, the following are listed:
+
+1. Username
+1. Email address
+1. Project membership count
+1. Group membership count ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276215) in GitLab 13.12)
+1. Date of account creation
+1. Date of last activity
+
+To edit a user, in the user's row, select **Edit**. To delete the user, or delete the user and their contributions, select the cog dropdown list in
+that user's row, and select the desired option.
+
+To change the sort order:
+
+1. Select the sort dropdown list.
+1. Select the desired order.
+
+By default the sort dropdown list shows **Name**.
+
+To search for users, enter your criteria in the search field. The user search is case
+insensitive, and applies partial matching to name and username. To search for an email address,
+you must provide the complete email address.
+
+### User impersonation
+
+An administrator can "impersonate" any other user, including other administrators.
+This allows the administrator to "see what the user sees," and take actions on behalf of the user.
+You can impersonate a user in the following ways:
+
+- Through the UI:
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
+ 1. On the left sidebar, select **Overview > Users**.
+ 1. From the list of users, select a user.
+ 1. Select **Impersonate**.
+- With the API, using [impersonation tokens](../api/rest/index.md#impersonation-tokens).
+
+All impersonation activities are [captured with audit events](audit_events.md#user-impersonation).
+
+By default, impersonation is enabled. GitLab can be configured to [disable impersonation](../api/rest/index.md#disable-impersonation).
+
+![user impersonation button](img/impersonate_user_button_v13_8.png)
+
+### User identities
+
+> The ability to see a user's SCIM identity was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294608) in GitLab 15.3.
+
+When using authentication providers, administrators can see the identities for a user:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Users**.
+1. From the list of users, select a user.
+1. Select **Identities**.
+
+This list shows the user's identities, including SCIM identities. Administrators can use this information to troubleshoot SCIM-related issues and confirm
+the identities being used for an account.
+
+### User Permission Export **(PREMIUM SELF)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1772) in GitLab 13.8.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292436) in GitLab 13.9.
+
+An administrator can export user permissions for all users in the GitLab instance from the Admin Area's Users page.
+The export lists direct membership the users have in groups and projects.
+
+The following data is included in the export:
+
+- Username
+- Email
+- Type
+- Path
+- Access level ([Project](../user/permissions.md#project-members-permissions) and [Group](../user/permissions.md#group-members-permissions))
+- Date of last activity ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345388) in GitLab 14.6). For a list of activities that populate this column, see the [Users API documentation](../api/users.md#get-user-activities).
+
+Only the first 100,000 user accounts are exported.
+
+![user permission export button](img/export_permissions_v13_11.png)
+
+### Users statistics
+
+The **Users statistics** page provides an overview of user accounts by role. These statistics are
+calculated daily, so user changes made since the last update are not reflected.
+
+The following totals are also included:
+
+- Billable users
+- Blocked users
+- Total users
+
+GitLab billing is based on the number of [**Billable users**](../subscriptions/self_managed/index.md#billable-users).
+
+### Add email to user
+
+You must be an administrator to manually add emails to users:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Users**.
+1. Locate the user and select them.
+1. Select **Edit**.
+1. In **Email**, enter the new email address. This adds the new email address to the
+ user and sets the previous email address to be a secondary.
+1. Select **Save changes**.
+
+## User cohorts
+
+The [Cohorts](../user/admin_area/user_cohorts.md) tab displays the monthly cohorts of new users and their activities over time.
+
+## Prevent a user from creating groups
+
+By default, users can create groups. To prevent a user from creating a top level group:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Users**.
+1. Locate the user and select them.
+1. Select **Edit**.
+1. Clear the **Can create group** checkbox.
+1. Select **Save changes**.
+
+It is also possible to [limit which roles can create a subgroup within a group](../user/group/subgroups/index.md#change-who-can-create-subgroups).
+
+## Administering groups
+
+You can administer all groups in the GitLab instance from the Admin Area's Groups page.
+
+To access the Groups page:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Groups**.
+
+For each group, the page displays their name, description, size, number of projects in the group,
+number of members, and whether the group is private, internal, or public. To edit a group, in the group's row, select **Edit**. To delete the group, in the group's row, select **Delete**.
+
+To change the sort order, select the sort dropdown list and select the desired order. The default
+sort order is by **Last created**.
+
+To search for groups by name, enter your criteria in the search field. The group search is case
+insensitive, and applies partial matching.
+
+To [Create a new group](../user/group/index.md#create-a-group) select **New group**.
+
+## Administering topics
+
+- > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340920) in GitLab 14.4.
+- > Merging topics [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366884) in GitLab 15.5.
+
+[Topics](../user/project/working_with_projects.md#explore-topics) are used to categorize and find similar projects.
+
+### View all topics
+
+To view all topics in the GitLab instance:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Topics**.
+
+For each topic, the page displays its name and the number of projects labeled with the topic.
+
+### Search for topics
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Topics**.
+1. In the search box, enter your search criteria.
+ The topic search is case-insensitive and applies partial matching.
+
+### Create a topic
+
+To create a topic:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Topics**.
+1. Select **New topic**.
+1. Enter the **Topic slug (name)** and **Topic title**.
+1. Optional. Enter a **Description** and add a **Topic avatar**.
+1. Select **Save changes**.
+
+The created topics are displayed on the **Explore topics** page.
+
+NOTE:
+The assigned topics are visible only to everyone with access to the project,
+but everyone can see which topics exist on the GitLab instance.
+Do not include sensitive information in the name of a topic.
+
+### Edit a topic
+
+You can edit a topic's name, title, description, and avatar at any time.
+To edit a topic:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Topics**.
+1. Select **Edit** in that topic's row.
+1. Edit the topic slug (name), title, description, or avatar.
+1. Select **Save changes**.
+
+### Remove a topic
+
+If you no longer need a topic, you can permanently remove it.
+To remove a topic:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Topics**.
+1. To remove a topic, select **Remove** in that topic's row.
+
+### Merge topics
+
+You can move all projects assigned to a topic to another topic.
+The source topic is then permanently deleted.
+After a merged topic is deleted, you cannot restore it.
+
+To merge topics:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Topics**.
+1. Select **Merge topics**.
+1. From the **Source topic** dropdown list, select the topic you want to merge and remove.
+1. From the **Target topic** dropdown list, select the topic you want to merge the source topic into.
+1. Select **Merge**.
+
+## Administering Gitaly servers
+
+You can list all Gitaly servers in the GitLab instance from the Admin Area's **Gitaly Servers**
+page. For more details, see [Gitaly](gitaly/index.md).
+
+To access the **Gitaly Servers** page:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Gitaly Servers**.
+
+For each Gitaly server, the following details are listed:
+
+| Field | Description |
+|----------------|-------------|
+| Storage | Repository storage |
+| Address | Network address on which the Gitaly server is listening |
+| Server version | Gitaly version |
+| Git version | Version of Git installed on the Gitaly server |
+| Up to date | Indicates if the Gitaly server version is the latest version available. A green dot indicates the server is up to date. |
+
+## CI/CD section
+
+### Administering runners
+
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/340859) from **Overview > Runners** to **CI/CD > Runners** in GitLab 15.8.
+
+You can administer all runners in the GitLab instance from the Admin Area's **Runners** page. See
+[GitLab Runner](https://docs.gitlab.com/runner/) for more information.
+
+To access the **Runners** page:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Runners**.
+
+#### Search and filter runners
+
+To search runners' descriptions:
+
+1. In the **Search or filter results...** field, type the description of the runner you want to
+ find.
+1. Press <kbd>Enter</kbd>.
+
+You can also filter runners by status, type, and tag. To filter:
+
+1. Select a tab or the **Search or filter results...** field.
+1. Select any **Type**, or filter by **Status** or **Tags**.
+1. Select or enter your search criteria.
+
+![Attributes of a runner, with the **Search or filter results...** field active](img/index_runners_search_or_filter_v14_5.png)
+
+#### Bulk delete runners
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/370241) in GitLab 15.4.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/353981) in GitLab 15.5.
+
+You can delete multiple runners at the same time.
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **Overview > Runners**.
+1. To the left of the runners you want to delete, select the checkbox.
+ To select all of the runners on the page, select the checkbox above
+ the list.
+1. Select **Delete selected**.
+
+#### Runner attributes
+
+For each runner, the following attributes are listed:
+
+| Attribute | Description |
+|--------------|-------------|
+| Status | The status of the runner. In [GitLab 15.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22224), for the **Ultimate** tier, the upgrade status is available. |
+| Runner details | Information about the runner, including partial token and details about the computer the runner was registered from. |
+| Version | GitLab Runner version. |
+| Jobs | Total number of jobs run by the runner. |
+| Tags | Tags associated with the runner. |
+| Last contact | Timestamp indicating when the runner last contacted the GitLab instance. |
+
+You can also edit, pause, or remove each runner.
+
+### Administering Jobs
+
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/386311) from **Overview > Jobs** to **CI/CD > Jobs** in GitLab 15.8.
+
+You can administer all jobs in the GitLab instance from the Admin Area's Jobs page.
+
+To access the Jobs page:
+
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select **CI/CD > Jobs**. All jobs are listed, in descending order of job ID.
+1. Select the **All** tab to list all jobs. Select the **Pending**, **Running**, or **Finished**
+ tab to list only jobs of that status.
+
+For each job, the following details are listed:
+
+| Field | Description |
+|----------|-------------|
+| Status | Job status, either **passed**, **skipped**, or **failed**. |
+| Job | Includes links to the job, branch, and the commit that started the job. |
+| Pipeline | Includes a link to the specific pipeline. |
+| Project | Name of the project, and organization, to which the job belongs. |
+| Runner | Name of the CI runner assigned to execute the job. |
+| Stage | Stage that the job is declared in a `.gitlab-ci.yml` file. |
+| Name | Name of the job specified in a `.gitlab-ci.yml` file. |
+| Timing | Duration of the job, and how long ago the job completed. |
+| Coverage | Percentage of tests coverage. |
+
+## Monitoring section
+
+The following topics document the **Monitoring** section of the Admin Area.
+
+### System Information
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341248) in GitLab 15.2, support for relative time. "Uptime" statistic was renamed to "System started".
+
+The **System Info** page provides the following statistics:
+
+| Field | Description |
+|:---------------|:--------------------------------------------------|
+| CPU | Number of CPU cores available |
+| Memory Usage | Memory in use, and total memory available |
+| Disk Usage | Disk space in use, and total disk space available |
+| System started | When the system hosting GitLab was started. In GitLab 15.1 and earlier, this was an uptime statistic. |
+
+These statistics are updated only when you navigate to the **System Info** page, or you refresh the page in your browser.
+
+### Background Jobs
+
+The **Background Jobs** page displays the Sidekiq dashboard. Sidekiq is used by GitLab to
+perform processing in the background.
+
+The Sidekiq dashboard consists of the following elements:
+
+- A tab per jobs' status.
+- A breakdown of background job statistics.
+- A live graph of **Processed** and **Failed** jobs, with a selectable polling interval.
+- An historical graph of **Processed** and **Failed** jobs, with a selectable time span.
+- Redis statistics, including:
+ - Version number
+ - Uptime, measured in days
+ - Number of connections
+ - Current memory usage, measured in MB
+ - Peak memory usage, measured in MB
+
+### Logs
+
+Since GitLab 13.0, **Log** view has been removed from the Admin Area dashboard since the logging does not work in multi-node setups and could cause confusion for administrators by displaying partial information.
+
+For multi-node systems we recommend ingesting the logs into services like Elasticsearch and Splunk.
+
+| Log file | Contents |
+|:------------------------|:---------|
+| `application_json.log` | GitLab user activity |
+| `git_json.log` | Failed GitLab interaction with Git repositories |
+| `production.log` | Requests received from Puma, and the actions taken to serve those requests |
+| `sidekiq.log` | Background jobs |
+| `repocheck.log` | Repository activity |
+| `integrations_json.log` | Activity between GitLab and integrated systems |
+| `kubernetes.log` | Kubernetes activity |
+
+The contents of these log files can be useful when troubleshooting a problem.
+
+For details of these log files and their contents, see [Log system](logs/index.md).
+
+The content of each log file is listed in chronological order. To minimize performance issues, a maximum 2000 lines of each log file are shown.
+
+### Audit Events **(PREMIUM SELF)**
+
+The **Audit Events** page lists changes made within the GitLab server. With this information you can control, analyze, and track every change.
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index e47e1018159..3ea94f5e4be 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -140,7 +140,7 @@ From audit events pages, different filters are available depending on the page y
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/536) in GitLab 13.0.
> - Impersonation session events included in group audit events in GitLab 14.8.
-When a user is [impersonated](../user/admin_area/index.md#user-impersonation), their actions are logged as audit events
+When a user is [impersonated](../administration/admin_area.md#user-impersonation), their actions are logged as audit events
with additional details:
- Audit events include information about the impersonating administrator. These audit events are visible in audit event
diff --git a/doc/administration/auditor_users.md b/doc/administration/auditor_users.md
index 8482edaf7c6..e8ed0eb4313 100644
--- a/doc/administration/auditor_users.md
+++ b/doc/administration/auditor_users.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Users with auditor access have read-only access to all groups, projects, and other resources except:
-- The [Admin Area](../user/admin_area/index.md).
+- The [Admin Area](../administration/admin_area.md).
- Project and group settings.
For more information, see [Auditor user permissions and restrictions](#auditor-user-permissions-and-restrictions)
diff --git a/doc/administration/compliance.md b/doc/administration/compliance.md
index 79133d5a6c7..cc162e8ec53 100644
--- a/doc/administration/compliance.md
+++ b/doc/administration/compliance.md
@@ -68,7 +68,7 @@ These features can also help with compliance requirements:
| [Email all users of a project,<br/>group, or entire server](../user/admin_area/email_from_gitlab.md) | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Email groups of users based on project or group membership, or email everyone using the GitLab instance. These emails are great for scheduled maintenance or upgrades. |
| [Enforce ToS acceptance](../user/admin_area/settings/terms.md) | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Enforce your users accepting new terms of service by blocking GitLab traffic. |
| [External Status Checks](../user/project/merge_requests/status_checks.md) | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Interface with third-party systems you already use during development to ensure you remain compliant. |
-| [Generate reports on permission<br/>levels of users](../user/admin_area/index.md#user-permission-export) | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Generate a report listing all users' access permissions for groups and projects in the instance. |
+| [Generate reports on permission<br/>levels of users](../administration/admin_area.md#user-permission-export) | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Generate a report listing all users' access permissions for groups and projects in the instance. |
| [License compliance](../user/compliance/license_compliance/index.md) | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Search dependencies for their licenses. This lets you determine if the licenses of your project's dependencies are compatible with your project's license. |
| [Lock project membership to group](../user/group/access_and_permissions.md#prevent-members-from-being-added-to-projects-in-a-group) | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Group owners can prevent new members from being added to projects in a group. |
| [LDAP group sync](auth/ldap/ldap_synchronization.md#group-sync) | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Automatically synchronize groups and manage SSH keys, permissions, and authentication, so you can focus on building your product, not configuring your tools. |
diff --git a/doc/administration/configure.md b/doc/administration/configure.md
index d68e81ebf69..72ee7c3da77 100644
--- a/doc/administration/configure.md
+++ b/doc/administration/configure.md
@@ -11,7 +11,7 @@ Customize and configure your self-managed GitLab installation.
- [Authentication](auth/index.md)
- [CI/CD](../administration/cicd.md)
-- [Configuration](../user/admin_area/index.md)
+- [Configuration](../administration/admin_area.md)
- [Consul](../administration/consul.md)
- [Environment variables](../administration/environment_variables.md)
- [File hooks](../administration/file_hooks.md)
diff --git a/doc/administration/dedicated/index.md b/doc/administration/dedicated/index.md
index ac79280ddda..02a64ae60f4 100644
--- a/doc/administration/dedicated/index.md
+++ b/doc/administration/dedicated/index.md
@@ -14,7 +14,7 @@ The instructions on this page guide you through:
1. Onboarding and initial setup of your GitLab Dedicated instance.
1. Configuring your GitLab Dedicated instance including enabling and updating the settings for [available functionality](../../subscriptions/gitlab_dedicated/index.md#available-features).
-Any functionality in the GitLab application that is not controlled by the SaaS environment can be configured by using the [Admin Panel](../../user/admin_area/index.md).
+Any functionality in the GitLab application that is not controlled by the SaaS environment can be configured by using the [Admin Panel](../../administration/admin_area.md).
## Onboarding
diff --git a/doc/administration/gitaly/recovery.md b/doc/administration/gitaly/recovery.md
index 980b4c89145..aa487917ef0 100644
--- a/doc/administration/gitaly/recovery.md
+++ b/doc/administration/gitaly/recovery.md
@@ -433,8 +433,9 @@ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.t
> - [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5789) in GitLab 14.6, support for immediate replication.
WARNING:
-Manually adding repositories to the tracking database is broken with Praefect-generated replica paths (`@cluster`).
-The repository is not given the correct relative repository path.
+Because of a [known issue](https://gitlab.com/gitlab-org/gitaly/-/issues/5402), you can't add repositories to the
+Praefect tracking database with Praefect-generated replica paths (`@cluster`). These repositories are not associated with the repository path used by GitLab and are
+inaccessible.
The `track-repository` Praefect sub-command adds repositories on disk to the Praefect tracking database to be tracked.
@@ -489,8 +490,9 @@ This command fails if:
> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/6319) in GitLab 15.4.
WARNING:
-Manually adding repositories to the tracking database is broken with Praefect-generated replica paths (`@cluster`).
-The repository is not given the correct relative repository path.
+Because of a [known issue](https://gitlab.com/gitlab-org/gitaly/-/issues/5402), you can't add repositories to the
+Praefect tracking database with Praefect-generated replica paths (`@cluster`). These repositories are not associated with the repository path used by GitLab and are
+inaccessible.
Migrations using the API automatically add repositories to the Praefect tracking database.
diff --git a/doc/user/admin_area/img/export_permissions_v13_11.png b/doc/administration/img/export_permissions_v13_11.png
index d9bbe8c3daf..d9bbe8c3daf 100644
--- a/doc/user/admin_area/img/export_permissions_v13_11.png
+++ b/doc/administration/img/export_permissions_v13_11.png
Binary files differ
diff --git a/doc/user/admin_area/img/impersonate_user_button_v13_8.png b/doc/administration/img/impersonate_user_button_v13_8.png
index 475315a0c0f..475315a0c0f 100644
--- a/doc/user/admin_area/img/impersonate_user_button_v13_8.png
+++ b/doc/administration/img/impersonate_user_button_v13_8.png
Binary files differ
diff --git a/doc/user/admin_area/img/index_runners_search_or_filter_v14_5.png b/doc/administration/img/index_runners_search_or_filter_v14_5.png
index 10b8cc01103..10b8cc01103 100644
--- a/doc/user/admin_area/img/index_runners_search_or_filter_v14_5.png
+++ b/doc/administration/img/index_runners_search_or_filter_v14_5.png
Binary files differ
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index 3bd73b4df94..e1512038286 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -73,7 +73,7 @@ translate between the human-readable project name and the hashed storage path. Y
Administrators can look up a project's hashed path from its name or ID using:
-- The [Admin Area](../user/admin_area/index.md#administering-projects).
+- The [Admin Area](../administration/admin_area.md#administering-projects).
- A Rails console.
To look up a project's hash path in the Admin Area:
diff --git a/doc/administration/user_settings.md b/doc/administration/user_settings.md
index c4b00d05f9d..a1b901e0677 100644
--- a/doc/administration/user_settings.md
+++ b/doc/administration/user_settings.md
@@ -44,7 +44,7 @@ For self-compiled installations:
Administrators can:
-- Use the Admin Area to [prevent an existing user from creating top-level groups](../user/admin_area/index.md#prevent-a-user-from-creating-groups).
+- Use the Admin Area to [prevent an existing user from creating top-level groups](../administration/admin_area.md#prevent-a-user-from-creating-groups).
- Use the [modify an existing user API endpoint](../api/users.md#user-modification) to change the `can_create_group` setting.
## Prevent users from changing their usernames
diff --git a/doc/ci/jobs/job_control.md b/doc/ci/jobs/job_control.md
index 8e5014f5fbd..09c7500a883 100644
--- a/doc/ci/jobs/job_control.md
+++ b/doc/ci/jobs/job_control.md
@@ -1115,5 +1115,5 @@ to change this behavior.
To run protected manual jobs:
- Add the administrator as a direct member of the private project (any role)
-- [Impersonate a user](../../user/admin_area/index.md#user-impersonation) who is a
+- [Impersonate a user](../../administration/admin_area.md#user-impersonation) who is a
direct member of the project.
diff --git a/doc/ci/pipelines/cicd_minutes.md b/doc/ci/pipelines/cicd_minutes.md
index 70515c35ff4..6c7b00c827a 100644
--- a/doc/ci/pipelines/cicd_minutes.md
+++ b/doc/ci/pipelines/cicd_minutes.md
@@ -358,12 +358,12 @@ An administrator can reset the compute usage for a namespace for the current mon
### Reset usage for a personal namespace
-1. Find the [user in the admin area](../../user/admin_area/index.md#administering-users).
+1. Find the [user in the admin area](../../administration/admin_area.md#administering-users).
1. Select **Edit**.
1. In **Limits**, select **Reset compute usage**.
### Reset usage for a group namespace
-1. Find the [group in the admin area](../../user/admin_area/index.md#administering-groups).
+1. Find the [group in the admin area](../../administration/admin_area.md#administering-groups).
1. Select **Edit**.
1. In **Permissions and group features**, select **Reset compute usage**.
diff --git a/doc/integration/advanced_search/elasticsearch_troubleshooting.md b/doc/integration/advanced_search/elasticsearch_troubleshooting.md
index d3a065f1f99..e8634cf5ef9 100644
--- a/doc/integration/advanced_search/elasticsearch_troubleshooting.md
+++ b/doc/integration/advanced_search/elasticsearch_troubleshooting.md
@@ -487,7 +487,7 @@ $ jq --raw-output 'select(.severity == "ERROR") | [.error_class, .error_message]
sort | uniq -c
```
-`Elastic` workers and [Sidekiq jobs](../../user/admin_area/index.md#background-jobs) could also appear much more often
+`Elastic` workers and [Sidekiq jobs](../../administration/admin_area.md#background-jobs) could also appear much more often
because Elasticsearch frequently attempts to reindex if a previous job fails.
You can use [`fast-stats`](https://gitlab.com/gitlab-com/support/toolbox/fast-stats#usage)
or `jq` to count workers in the [Sidekiq logs](../../administration/logs/index.md#sidekiq-logs):
diff --git a/doc/raketasks/user_management.md b/doc/raketasks/user_management.md
index bb3f1f404b4..fa7d0813001 100644
--- a/doc/raketasks/user_management.md
+++ b/doc/raketasks/user_management.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# User management Rake tasks **(FREE SELF)**
GitLab provides Rake tasks for managing users. Administrators can also use the Admin Area to
-[manage users](../user/admin_area/index.md#administering-users).
+[manage users](../administration/admin_area.md#administering-users).
## Add user as a developer to all projects
diff --git a/doc/security/unlock_user.md b/doc/security/unlock_user.md
index e8215616e1b..5e21cad8f3e 100644
--- a/doc/security/unlock_user.md
+++ b/doc/security/unlock_user.md
@@ -12,7 +12,7 @@ type: howto
Users are locked after ten failed sign-in attempts. These users remain locked:
- For 10 minutes, after which time they are automatically unlocked.
-- Until an administrator unlocks them from the [Admin Area](../user/admin_area/index.md) or the command line in under 10 minutes.
+- Until an administrator unlocks them from the [Admin Area](../administration/admin_area.md) or the command line in under 10 minutes.
## GitLab.com users
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index 01a6bff0877..60430f87125 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/index.md
@@ -20,7 +20,7 @@ To subscribe to GitLab for a GitLab self-managed installation:
NOTE:
If you're purchasing a subscription for an existing **Free** GitLab self-managed
instance, ensure you're purchasing enough seats to
-[cover your users](../../user/admin_area/index.md#administering-users).
+[cover your users](../../administration/admin_area.md#administering-users).
### Subscription seats
@@ -121,7 +121,7 @@ GitLab has several features which can help you manage the number of users:
option. **Available in GitLab 13.7 and later**.
- [Disable new sign-ups](../../user/admin_area/settings/sign_up_restrictions.md), and instead manage new
users manually.
-- View a breakdown of users by role in the [Users statistics](../../user/admin_area/index.md#users-statistics) page.
+- View a breakdown of users by role in the [Users statistics](../../administration/admin_area.md#users-statistics) page.
## Subscription data synchronization
diff --git a/doc/update/background_migrations.md b/doc/update/background_migrations.md
index 5bdd40647f3..d83b653ce76 100644
--- a/doc/update/background_migrations.md
+++ b/doc/update/background_migrations.md
@@ -105,7 +105,7 @@ Batched background migrations are handled by Sidekiq and
so an instance can remain operational while the migrations are processed. However,
performance might degrade on larger instances that are heavily used while
batched background migrations are run. You should
-[Actively monitor the Sidekiq status](../user/admin_area/index.md#background-jobs)
+[Actively monitor the Sidekiq status](../administration/admin_area.md#background-jobs)
until all migrations are completed.
### Check the status of batched background migrations
diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md
index 8b2ef115298..a729cefa7b8 100644
--- a/doc/user/admin_area/index.md
+++ b/doc/user/admin_area/index.md
@@ -1,489 +1,11 @@
---
-stage: none
-group: unassigned
-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
-type: reference
+redirect_to: '../../administration/admin_area.md'
+remove_date: '2023-10-11'
---
-# GitLab Admin Area **(FREE SELF)**
+This document was moved to [another location](../../administration/admin_area.md).
-The Admin Area provides a web UI to manage and configure features of GitLab
-self-managed instances. If you are an administrator,to access the Admin Area:
-
-- In GitLab 16.1 and later: on the left sidebar, expand the top-most chevron (**{chevron-down}**), then select **Admin Area**.
-- In GitLab 16.0 and earlier: on the top bar, select **Main menu > Admin**.
-
-NOTE:
-Only administrators can access the Admin Area.
-
-## Administering projects
-
-You can administer all projects in the GitLab instance from the Admin Area's Projects page.
-
-To access the Projects page:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Projects**.
-1. Select the **All**, **Private**, **Internal**, or **Public** tab to list only
- projects of that criteria.
-
-By default, all projects are listed, in reverse order of when they were last updated. For each
-project, the following information is listed:
-
-- Name
-- Namespace
-- Description
-- Size, updated every 15 minutes at most
-
-Projects can be edited or deleted.
-
-To edit a project's name or description:
-
-1. In the Projects overview, next to the project you want to edit, select **Edit**.
-1. Edit the **Project name** or **Project description**.
-1. Select **Save Changes**.
-
-To delete a project:
-
-1. In the Projects overview, next to the project you want to delete, select **Delete**.
-
-The list of projects can be sorted by:
-
-- Updated date
-- Last created
-- Name
-- Most stars
-- Oldest created
-- Oldest updated
-- Largest repository
-
-A user can choose to hide or show archived projects in the list.
-
-In the **Filter by name** field, type the project name you want to find, and GitLab filters
-them as you type.
-
-To filter only projects in that namespace, select from the **Namespace** dropdown list.
-
-You can combine the filter options. For example, to list only public projects with `score` in their name:
-
-1. Select the **Public** tab.
-1. Enter `score` in the **Filter by name...** input box.
-
-## Administering users
-
-You can administer all users in the GitLab instance from the Admin Area's Users page:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Users**.
-
-To list users matching a specific criteria, select one of the following tabs on the **Users** page:
-
-- **Active**
-- **Admins**
-- **2FA Enabled**
-- **2FA Disabled**
-- **External**
-- **[Blocked](moderate_users.md#block-a-user)**
-- **[Deactivated](moderate_users.md#deactivate-a-user)**
-- **Without projects**
-
-For each user, the following are listed:
-
-1. Username
-1. Email address
-1. Project membership count
-1. Group membership count ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276215) in GitLab 13.12)
-1. Date of account creation
-1. Date of last activity
-
-To edit a user, in the user's row, select **Edit**. To delete the user, or delete the user and their contributions, select the cog dropdown list in
-that user's row, and select the desired option.
-
-To change the sort order:
-
-1. Select the sort dropdown list.
-1. Select the desired order.
-
-By default the sort dropdown list shows **Name**.
-
-To search for users, enter your criteria in the search field. The user search is case
-insensitive, and applies partial matching to name and username. To search for an email address,
-you must provide the complete email address.
-
-### User impersonation
-
-An administrator can "impersonate" any other user, including other administrators.
-This allows the administrator to "see what the user sees," and take actions on behalf of the user.
-You can impersonate a user in the following ways:
-
-- Through the UI:
- 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
- 1. Select **Admin Area**.
- 1. On the left sidebar, select **Overview > Users**.
- 1. From the list of users, select a user.
- 1. Select **Impersonate**.
-- With the API, using [impersonation tokens](../../api/rest/index.md#impersonation-tokens).
-
-All impersonation activities are [captured with audit events](../../administration/audit_events.md#user-impersonation).
-
-By default, impersonation is enabled. GitLab can be configured to [disable impersonation](../../api/rest/index.md#disable-impersonation).
-
-![user impersonation button](img/impersonate_user_button_v13_8.png)
-
-### User identities
-
-> The ability to see a user's SCIM identity was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294608) in GitLab 15.3.
-
-When using authentication providers, administrators can see the identities for a user:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Users**.
-1. From the list of users, select a user.
-1. Select **Identities**.
-
-This list shows the user's identities, including SCIM identities. Administrators can use this information to troubleshoot SCIM-related issues and confirm
-the identities being used for an account.
-
-### User Permission Export **(PREMIUM SELF)**
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1772) in GitLab 13.8.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292436) in GitLab 13.9.
-
-An administrator can export user permissions for all users in the GitLab instance from the Admin Area's Users page.
-The export lists direct membership the users have in groups and projects.
-
-The following data is included in the export:
-
-- Username
-- Email
-- Type
-- Path
-- Access level ([Project](../permissions.md#project-members-permissions) and [Group](../permissions.md#group-members-permissions))
-- Date of last activity ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345388) in GitLab 14.6). For a list of activities that populate this column, see the [Users API documentation](../../api/users.md#get-user-activities).
-
-Only the first 100,000 user accounts are exported.
-
-![user permission export button](img/export_permissions_v13_11.png)
-
-### Users statistics
-
-The **Users statistics** page provides an overview of user accounts by role. These statistics are
-calculated daily, so user changes made since the last update are not reflected.
-
-The following totals are also included:
-
-- Billable users
-- Blocked users
-- Total users
-
-GitLab billing is based on the number of [**Billable users**](../../subscriptions/self_managed/index.md#billable-users).
-
-### Add email to user
-
-You must be an administrator to manually add emails to users:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Users**.
-1. Locate the user and select them.
-1. Select **Edit**.
-1. In **Email**, enter the new email address. This adds the new email address to the
- user and sets the previous email address to be a secondary.
-1. Select **Save changes**.
-
-## User cohorts
-
-The [Cohorts](user_cohorts.md) tab displays the monthly cohorts of new users and their activities over time.
-
-## Prevent a user from creating groups
-
-By default, users can create groups. To prevent a user from creating a top level group:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Users**.
-1. Locate the user and select them.
-1. Select **Edit**.
-1. Clear the **Can create group** checkbox.
-1. Select **Save changes**.
-
-It is also possible to [limit which roles can create a subgroup within a group](../group/subgroups/index.md#change-who-can-create-subgroups).
-
-## Administering groups
-
-You can administer all groups in the GitLab instance from the Admin Area's Groups page.
-
-To access the Groups page:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Groups**.
-
-For each group, the page displays their name, description, size, number of projects in the group,
-number of members, and whether the group is private, internal, or public. To edit a group, in the group's row, select **Edit**. To delete the group, in the group's row, select **Delete**.
-
-To change the sort order, select the sort dropdown list and select the desired order. The default
-sort order is by **Last created**.
-
-To search for groups by name, enter your criteria in the search field. The group search is case
-insensitive, and applies partial matching.
-
-To [Create a new group](../group/index.md#create-a-group) select **New group**.
-
-## Administering topics
-
-- > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340920) in GitLab 14.4.
-- > Merging topics [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366884) in GitLab 15.5.
-
-[Topics](../project/working_with_projects.md#explore-topics) are used to categorize and find similar projects.
-
-### View all topics
-
-To view all topics in the GitLab instance:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Topics**.
-
-For each topic, the page displays its name and the number of projects labeled with the topic.
-
-### Search for topics
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Topics**.
-1. In the search box, enter your search criteria.
- The topic search is case-insensitive and applies partial matching.
-
-### Create a topic
-
-To create a topic:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Topics**.
-1. Select **New topic**.
-1. Enter the **Topic slug (name)** and **Topic title**.
-1. Optional. Enter a **Description** and add a **Topic avatar**.
-1. Select **Save changes**.
-
-The created topics are displayed on the **Explore topics** page.
-
-NOTE:
-The assigned topics are visible only to everyone with access to the project,
-but everyone can see which topics exist on the GitLab instance.
-Do not include sensitive information in the name of a topic.
-
-### Edit a topic
-
-You can edit a topic's name, title, description, and avatar at any time.
-To edit a topic:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Topics**.
-1. Select **Edit** in that topic's row.
-1. Edit the topic slug (name), title, description, or avatar.
-1. Select **Save changes**.
-
-### Remove a topic
-
-If you no longer need a topic, you can permanently remove it.
-To remove a topic:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Topics**.
-1. To remove a topic, select **Remove** in that topic's row.
-
-### Merge topics
-
-You can move all projects assigned to a topic to another topic.
-The source topic is then permanently deleted.
-After a merged topic is deleted, you cannot restore it.
-
-To merge topics:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Topics**.
-1. Select **Merge topics**.
-1. From the **Source topic** dropdown list, select the topic you want to merge and remove.
-1. From the **Target topic** dropdown list, select the topic you want to merge the source topic into.
-1. Select **Merge**.
-
-## Administering Gitaly servers
-
-You can list all Gitaly servers in the GitLab instance from the Admin Area's **Gitaly Servers**
-page. For more details, see [Gitaly](../../administration/gitaly/index.md).
-
-To access the **Gitaly Servers** page:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Gitaly Servers**.
-
-For each Gitaly server, the following details are listed:
-
-| Field | Description |
-|----------------|-------------|
-| Storage | Repository storage |
-| Address | Network address on which the Gitaly server is listening |
-| Server version | Gitaly version |
-| Git version | Version of Git installed on the Gitaly server |
-| Up to date | Indicates if the Gitaly server version is the latest version available. A green dot indicates the server is up to date. |
-
-## CI/CD section
-
-### Administering runners
-
-> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/340859) from **Overview > Runners** to **CI/CD > Runners** in GitLab 15.8.
-
-You can administer all runners in the GitLab instance from the Admin Area's **Runners** page. See
-[GitLab Runner](https://docs.gitlab.com/runner/) for more information.
-
-To access the **Runners** page:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Runners**.
-
-#### Search and filter runners
-
-To search runners' descriptions:
-
-1. In the **Search or filter results...** field, type the description of the runner you want to
- find.
-1. Press <kbd>Enter</kbd>.
-
-You can also filter runners by status, type, and tag. To filter:
-
-1. Select a tab or the **Search or filter results...** field.
-1. Select any **Type**, or filter by **Status** or **Tags**.
-1. Select or enter your search criteria.
-
-![Attributes of a runner, with the **Search or filter results...** field active](img/index_runners_search_or_filter_v14_5.png)
-
-#### Bulk delete runners
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/370241) in GitLab 15.4.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/353981) in GitLab 15.5.
-
-You can delete multiple runners at the same time.
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **Overview > Runners**.
-1. To the left of the runners you want to delete, select the checkbox.
- To select all of the runners on the page, select the checkbox above
- the list.
-1. Select **Delete selected**.
-
-#### Runner attributes
-
-For each runner, the following attributes are listed:
-
-| Attribute | Description |
-|--------------|-------------|
-| Status | The status of the runner. In [GitLab 15.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22224), for the **Ultimate** tier, the upgrade status is available. |
-| Runner details | Information about the runner, including partial token and details about the computer the runner was registered from. |
-| Version | GitLab Runner version. |
-| Jobs | Total number of jobs run by the runner. |
-| Tags | Tags associated with the runner. |
-| Last contact | Timestamp indicating when the runner last contacted the GitLab instance. |
-
-You can also edit, pause, or remove each runner.
-
-### Administering Jobs
-
-> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/386311) from **Overview > Jobs** to **CI/CD > Jobs** in GitLab 15.8.
-
-You can administer all jobs in the GitLab instance from the Admin Area's Jobs page.
-
-To access the Jobs page:
-
-1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
-1. Select **Admin Area**.
-1. Select **CI/CD > Jobs**. All jobs are listed, in descending order of job ID.
-1. Select the **All** tab to list all jobs. Select the **Pending**, **Running**, or **Finished**
- tab to list only jobs of that status.
-
-For each job, the following details are listed:
-
-| Field | Description |
-|----------|-------------|
-| Status | Job status, either **passed**, **skipped**, or **failed**. |
-| Job | Includes links to the job, branch, and the commit that started the job. |
-| Pipeline | Includes a link to the specific pipeline. |
-| Project | Name of the project, and organization, to which the job belongs. |
-| Runner | Name of the CI runner assigned to execute the job. |
-| Stage | Stage that the job is declared in a `.gitlab-ci.yml` file. |
-| Name | Name of the job specified in a `.gitlab-ci.yml` file. |
-| Timing | Duration of the job, and how long ago the job completed. |
-| Coverage | Percentage of tests coverage. |
-
-## Monitoring section
-
-The following topics document the **Monitoring** section of the Admin Area.
-
-### System Information
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341248) in GitLab 15.2, support for relative time. "Uptime" statistic was renamed to "System started".
-
-The **System Info** page provides the following statistics:
-
-| Field | Description |
-|:---------------|:--------------------------------------------------|
-| CPU | Number of CPU cores available |
-| Memory Usage | Memory in use, and total memory available |
-| Disk Usage | Disk space in use, and total disk space available |
-| System started | When the system hosting GitLab was started. In GitLab 15.1 and earlier, this was an uptime statistic. |
-
-These statistics are updated only when you navigate to the **System Info** page, or you refresh the page in your browser.
-
-### Background Jobs
-
-The **Background Jobs** page displays the Sidekiq dashboard. Sidekiq is used by GitLab to
-perform processing in the background.
-
-The Sidekiq dashboard consists of the following elements:
-
-- A tab per jobs' status.
-- A breakdown of background job statistics.
-- A live graph of **Processed** and **Failed** jobs, with a selectable polling interval.
-- An historical graph of **Processed** and **Failed** jobs, with a selectable time span.
-- Redis statistics, including:
- - Version number
- - Uptime, measured in days
- - Number of connections
- - Current memory usage, measured in MB
- - Peak memory usage, measured in MB
-
-### Logs
-
-Since GitLab 13.0, **Log** view has been removed from the Admin Area dashboard since the logging does not work in multi-node setups and could cause confusion for administrators by displaying partial information.
-
-For multi-node systems we recommend ingesting the logs into services like Elasticsearch and Splunk.
-
-| Log file | Contents |
-|:------------------------|:---------|
-| `application_json.log` | GitLab user activity |
-| `git_json.log` | Failed GitLab interaction with Git repositories |
-| `production.log` | Requests received from Puma, and the actions taken to serve those requests |
-| `sidekiq.log` | Background jobs |
-| `repocheck.log` | Repository activity |
-| `integrations_json.log` | Activity between GitLab and integrated systems |
-| `kubernetes.log` | Kubernetes activity |
-
-The contents of these log files can be useful when troubleshooting a problem.
-
-For details of these log files and their contents, see [Log system](../../administration/logs/index.md).
-
-The content of each log file is listed in chronological order. To minimize performance issues, a maximum 2000 lines of each log file are shown.
-
-### Audit Events **(PREMIUM SELF)**
-
-The **Audit Events** page lists changes made within the GitLab server. With this information you can control, analyze, and track every change.
+<!-- This redirect file can be deleted after <2023-10-11>. -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/admin_area/settings/account_and_limit_settings.md b/doc/user/admin_area/settings/account_and_limit_settings.md
index e244c2de4f0..7a0e4f29a4f 100644
--- a/doc/user/admin_area/settings/account_and_limit_settings.md
+++ b/doc/user/admin_area/settings/account_and_limit_settings.md
@@ -323,7 +323,7 @@ To do this:
NOTE:
When this ability is disabled, GitLab administrators can still use the
-[Admin Area](../index.md#administering-users) or the
+[Admin Area](../../../administration/admin_area.md#administering-users) or the
[API](../../../api/users.md#user-modification) to update usernames.
## Prevent new users from creating top-level groups
diff --git a/doc/user/admin_area/settings/visibility_and_access_controls.md b/doc/user/admin_area/settings/visibility_and_access_controls.md
index dd53efaf518..c6fda579396 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -114,7 +114,7 @@ Alternatively, projects that are marked for removal can be deleted immediately.
1. [Restore the project](../../project/settings/index.md#restore-a-project).
1. Delete the project as described in the
- [Administering Projects page](../../admin_area/index.md#administering-projects).
+ [Administering Projects page](../../../administration/admin_area.md#administering-projects).
## Configure project visibility defaults
diff --git a/doc/user/group/saml_sso/troubleshooting_scim.md b/doc/user/group/saml_sso/troubleshooting_scim.md
index 33343c9b339..b592ca31490 100644
--- a/doc/user/group/saml_sso/troubleshooting_scim.md
+++ b/doc/user/group/saml_sso/troubleshooting_scim.md
@@ -38,7 +38,7 @@ The following are possible solutions for problems where users cannot sign in:
To check if a user's SAML `NameId` matches their SCIM `externalId`:
-- Administrators can use the Admin Area to [list SCIM identities for a user](../../admin_area/index.md#user-identities).
+- Administrators can use the Admin Area to [list SCIM identities for a user](../../../administration/admin_area.md#user-identities).
- Group owners can see the list of users and the identifier stored for each user in the group SAML SSO Settings page.
- You can use the [SCIM API](../../../api/scim.md) to manually retrieve the `external_uid` GitLab has stored for users and compare the value for each user from the [SAML API](../../../api/saml.md) .
- Have the user use a [SAML Tracer](troubleshooting.md#saml-debugging-tools) and compare the `external_uid` to
diff --git a/doc/user/group/subgroups/index.md b/doc/user/group/subgroups/index.md
index 81e972bf73b..84902a5cbe9 100644
--- a/doc/user/group/subgroups/index.md
+++ b/doc/user/group/subgroups/index.md
@@ -77,7 +77,7 @@ Prerequisites:
- At least the Maintainer role for a group to create subgroups for it.
- The [role determined by a setting](#change-who-can-create-subgroups). These users can create
subgroups even if group creation is
- [disabled by an Administrator](../../admin_area/index.md#prevent-a-user-from-creating-groups) in the user's settings.
+ [disabled by an Administrator](../../../administration/admin_area.md#prevent-a-user-from-creating-groups) in the user's settings.
NOTE:
You cannot host a GitLab Pages subgroup website with a top-level domain name. For example, `subgroupname.example.io`.
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index 029b421ff4f..9d63a1abd6d 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -89,7 +89,7 @@ ERROR: null value in column "user_id" violates not-null constraint
```
The error can be found in the [PostgreSQL log](../../../administration/logs/index.md#postgresql-logs) and
-in the **Retries** section of the [background jobs view](../../admin_area/index.md#background-jobs) in the Admin Area.
+in the **Retries** section of the [background jobs view](../../../administration/admin_area.md#background-jobs) in the Admin Area.
If the user being deleted used the [iterations](../../group/iterations/index.md) feature, such
as adding an issue to an iteration, you must use
diff --git a/doc/user/project/integrations/gitlab_slack_application.md b/doc/user/project/integrations/gitlab_slack_application.md
index baf598e35c3..993a9389638 100644
--- a/doc/user/project/integrations/gitlab_slack_application.md
+++ b/doc/user/project/integrations/gitlab_slack_application.md
@@ -147,6 +147,8 @@ The following events are available for Slack notifications:
| **Wiki page** | A wiki page is created or updated. |
| **Deployment** | A deployment starts or finishes. |
| **Alert** | A new, unique alert is recorded. |
+| **Group mention in public** | A group is mentioned in a public context. |
+| **Group mention in private** | A group is mentioned in a confidential context. |
| [**Vulnerability**](../../application_security/vulnerabilities/index.md) | A new, unique vulnerability is recorded. |
## Troubleshooting
diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md
index 14183a47625..55000a0a992 100644
--- a/doc/user/project/integrations/slack.md
+++ b/doc/user/project/integrations/slack.md
@@ -79,6 +79,8 @@ The following triggers are available for Slack notifications:
| **Wiki page** | A wiki page is created or updated. |
| **Deployment** | A deployment starts or finishes. |
| **Alert** | A new, unique alert is recorded. |
+| **Group mention in public** | A group is mentioned in a public context. |
+| **Group mention in private** | A group is mentioned in a confidential context. |
| [**Vulnerability**](../../application_security/vulnerabilities/index.md) | A new, unique vulnerability is recorded. |
## Troubleshooting
diff --git a/doc/user/project/repository/mirror/index.md b/doc/user/project/repository/mirror/index.md
index 80b1c00bfa9..2eee17840da 100644
--- a/doc/user/project/repository/mirror/index.md
+++ b/doc/user/project/repository/mirror/index.md
@@ -325,7 +325,7 @@ fail nor succeed. They also do not leave a clear log. To check for this problem:
end
```
-1. After you run the command, the [background jobs page](../../../admin_area/index.md#background-jobs)
+1. After you run the command, the [background jobs page](../../../../administration/admin_area.md#background-jobs)
should show new mirroring jobs being scheduled, especially when
[triggered manually](#update-a-mirror).
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 52f274be1ba..4a7e7d2fe7d 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -41,7 +41,7 @@ To assign topics to a project:
1. Select **Save changes**.
If you're an instance administrator, you can administer all project topics from the
-[Admin Area's Topics page](../../admin_area/index.md#administering-topics).
+[Admin Area's Topics page](../../../administration/admin_area.md#administering-topics).
NOTE:
The assigned topics are visible only to users with access to the project, but everyone can see which topics exist on the GitLab instance. Do not include sensitive information in the name of a topic.
@@ -278,7 +278,7 @@ To transfer a project:
You are redirected to the project's new page and GitLab applies a redirect. For more information about repository redirects, see [What happens when a repository path changes](../repository/index.md#what-happens-when-a-repository-path-changes).
NOTE:
-If you are an administrator, you can also use the [administration interface](../../admin_area/index.md#administering-projects)
+If you are an administrator, you can also use the [administration interface](../../../administration/admin_area.md#administering-projects)
to move any project to any namespace.
### Transferring a GitLab SaaS project to a different subscription tier
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index 69e50553aed..472bbb81648 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -124,7 +124,7 @@ You can assign topics to a project on the [Project Settings page](settings/index
### Administer topics
Instance administrators can administer all project topics from the
-[Admin Area's Topics page](../admin_area/index.md#administering-topics).
+[Admin Area's Topics page](../../administration/admin_area.md#administering-topics).
## Star a project
diff --git a/doc/user/upgrade_email_bypass.md b/doc/user/upgrade_email_bypass.md
index afbdcbcdf09..99f2caf775d 100644
--- a/doc/user/upgrade_email_bypass.md
+++ b/doc/user/upgrade_email_bypass.md
@@ -83,7 +83,7 @@ You have the following options to help your users:
- They can confirm their address through the email that they received.
- They can confirm the subject email address themselves by navigating to `https://gitlab.example.com/users/confirmation/new`.
-As an administrator, you may also confirm a user in the [Admin Area](admin_area/index.md#administering-users).
+As an administrator, you may also confirm a user in the [Admin Area](../administration/admin_area.md#administering-users).
## What do you do if you are an administrator and you're locked out?
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d102db78a9f..d01da0c4ea9 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -13945,6 +13945,9 @@ msgstr ""
msgid "DORA4Metrics|Accept testing terms of use?"
msgstr ""
+msgid "DORA4Metrics|All labels"
+msgstr ""
+
msgid "DORA4Metrics|Average (last %{days}d)"
msgstr ""
@@ -13996,6 +13999,9 @@ msgstr ""
msgid "DORA4Metrics|Failed to load comparison chart for Namespace: %{fullPath}"
msgstr ""
+msgid "DORA4Metrics|Filtered by"
+msgstr ""
+
msgid "DORA4Metrics|Forecast"
msgstr ""
@@ -19930,9 +19936,6 @@ msgstr ""
msgid "Geo|%{label} should be between 1-999"
msgstr ""
-msgid "Geo|%{name} is scheduled for forced re-download"
-msgstr ""
-
msgid "Geo|%{name} is scheduled for re-sync"
msgstr ""
@@ -20206,9 +20209,6 @@ msgstr ""
msgid "Geo|Re-verification interval"
msgstr ""
-msgid "Geo|Redownload"
-msgstr ""
-
msgid "Geo|Remove"
msgstr ""
@@ -21520,6 +21520,12 @@ msgstr ""
msgid "Group membership expiration date removed"
msgstr ""
+msgid "Group mention in private"
+msgstr ""
+
+msgid "Group mention in public"
+msgstr ""
+
msgid "Group milestone"
msgstr ""
@@ -35901,6 +35907,12 @@ msgstr ""
msgid "ProjectService|Trigger event when a deployment starts or finishes."
msgstr ""
+msgid "ProjectService|Trigger event when a group is mentioned in a confidential context."
+msgstr ""
+
+msgid "ProjectService|Trigger event when a group is mentioned in a public context."
+msgstr ""
+
msgid "ProjectService|Trigger event when a merge request is created, updated, or merged."
msgstr ""
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 8385468756f..61c64a82296 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -852,6 +852,28 @@ RSpec.describe Group, feature_category: :groups_and_projects do
end
end
+ describe '.execute_integrations' do
+ let(:integration) { create(:integrations_slack, :group, group: group) }
+ let(:test_data) { { 'foo' => 'bar' } }
+
+ before do
+ allow(group.integrations).to receive(:public_send).and_return([])
+ allow(group.integrations).to receive(:public_send).with(:push_hooks).and_return([integration])
+ end
+
+ it 'executes integrations with a matching scope' do
+ expect(integration).to receive(:async_execute).with(test_data)
+
+ group.execute_integrations(test_data, :push_hooks)
+ end
+
+ it 'ignores integrations without a matching scope' do
+ expect(integration).not_to receive(:async_execute).with(test_data)
+
+ group.execute_integrations(test_data, :note_hooks)
+ end
+ end
+
describe '.public_or_visible_to_user' do
let!(:private_group) { create(:group, :private) }
let!(:private_subgroup) { create(:group, :private, parent: private_group) }
diff --git a/spec/models/integrations/chat_message/group_mention_message_spec.rb b/spec/models/integrations/chat_message/group_mention_message_spec.rb
new file mode 100644
index 00000000000..6fa486f3dc3
--- /dev/null
+++ b/spec/models/integrations/chat_message/group_mention_message_spec.rb
@@ -0,0 +1,193 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integrations::ChatMessage::GroupMentionMessage, feature_category: :integrations do
+ subject { described_class.new(args) }
+
+ let(:color) { '#345' }
+ let(:args) do
+ {
+ object_kind: 'group_mention',
+ mentioned: {
+ object_kind: 'group',
+ name: 'test/group',
+ url: 'http://test/group'
+ },
+ user: {
+ name: 'Test User',
+ username: 'test.user',
+ avatar_url: 'http://avatar'
+ },
+ project_name: 'Test Project',
+ project_url: 'http://project'
+ }
+ end
+
+ context 'for issue descriptions' do
+ let(:attachments) { [{ text: "Issue\ndescription\n123", color: color }] }
+
+ before do
+ args[:object_attributes] = {
+ object_kind: 'issue',
+ iid: '42',
+ title: 'Test Issue',
+ description: "Issue\ndescription\n123",
+ url: 'http://issue'
+ }
+ end
+
+ it 'returns the appropriate message' do
+ expect(subject.pretext).to eq(
+ 'Group <http://test/group|test/group> was mentioned ' \
+ 'in <http://issue|issue #42> ' \
+ 'of <http://project|Test Project>: ' \
+ '*Test Issue*'
+ )
+ expect(subject.attachments).to eq(attachments)
+ end
+
+ context 'with markdown' do
+ before do
+ args[:markdown] = true
+ end
+
+ it 'returns the appropriate message' do
+ expect(subject.pretext).to eq(
+ 'Group [test/group](http://test/group) was mentioned ' \
+ 'in [issue #42](http://issue) ' \
+ 'of [Test Project](http://project): ' \
+ '*Test Issue*'
+ )
+ expect(subject.attachments).to eq("Issue\ndescription\n123")
+ expect(subject.activity).to eq(
+ {
+ title: 'Group [test/group](http://test/group) was mentioned in [issue #42](http://issue)',
+ subtitle: 'of [Test Project](http://project)',
+ text: 'Test Issue',
+ image: 'http://avatar'
+ }
+ )
+ end
+ end
+ end
+
+ context 'for merge request descriptions' do
+ let(:attachments) { [{ text: "MR\ndescription\n123", color: color }] }
+
+ before do
+ args[:object_attributes] = {
+ object_kind: 'merge_request',
+ iid: '42',
+ title: 'Test MR',
+ description: "MR\ndescription\n123",
+ url: 'http://merge_request'
+ }
+ end
+
+ it 'returns the appropriate message' do
+ expect(subject.pretext).to eq(
+ 'Group <http://test/group|test/group> was mentioned ' \
+ 'in <http://merge_request|merge request !42> ' \
+ 'of <http://project|Test Project>: ' \
+ '*Test MR*'
+ )
+ expect(subject.attachments).to eq(attachments)
+ end
+ end
+
+ context 'for notes' do
+ let(:attachments) { [{ text: 'Test Comment', color: color }] }
+
+ before do
+ args[:object_attributes] = {
+ object_kind: 'note',
+ note: 'Test Comment',
+ url: 'http://note'
+ }
+ end
+
+ context 'on commits' do
+ before do
+ args[:commit] = {
+ id: '5f163b2b95e6f53cbd428f5f0b103702a52b9a23',
+ title: 'Test Commit',
+ message: "Commit\nmessage\n123\n"
+ }
+ end
+
+ it 'returns the appropriate message' do
+ expect(subject.pretext).to eq(
+ 'Group <http://test/group|test/group> was mentioned ' \
+ 'in <http://note|commit 5f163b2b> ' \
+ 'of <http://project|Test Project>: ' \
+ '*Test Commit*'
+ )
+ expect(subject.attachments).to eq(attachments)
+ end
+ end
+
+ context 'on issues' do
+ before do
+ args[:issue] = {
+ iid: '42',
+ title: 'Test Issue'
+ }
+ end
+
+ it 'returns the appropriate message' do
+ expect(subject.pretext).to eq(
+ 'Group <http://test/group|test/group> was mentioned ' \
+ 'in <http://note|issue #42> ' \
+ 'of <http://project|Test Project>: ' \
+ '*Test Issue*'
+ )
+ expect(subject.attachments).to eq(attachments)
+ end
+ end
+
+ context 'on merge requests' do
+ before do
+ args[:merge_request] = {
+ iid: '42',
+ title: 'Test MR'
+ }
+ end
+
+ it 'returns the appropriate message' do
+ expect(subject.pretext).to eq(
+ 'Group <http://test/group|test/group> was mentioned ' \
+ 'in <http://note|merge request !42> ' \
+ 'of <http://project|Test Project>: ' \
+ '*Test MR*'
+ )
+ expect(subject.attachments).to eq(attachments)
+ end
+ end
+ end
+
+ context 'for unsupported object types' do
+ before do
+ args[:object_attributes] = { object_kind: 'unsupported' }
+ end
+
+ it 'raises an error' do
+ expect { described_class.new(args) }.to raise_error(NotImplementedError)
+ end
+ end
+
+ context 'for notes on unsupported object types' do
+ before do
+ args[:object_attributes] = {
+ object_kind: 'note',
+ note: 'Test Comment',
+ url: 'http://note'
+ }
+ # Not adding a supported object type's attributes
+ end
+
+ it 'raises an error' do
+ expect { described_class.new(args) }.to raise_error(NotImplementedError)
+ end
+ end
+end
diff --git a/spec/services/integrations/group_mention_service_spec.rb b/spec/services/integrations/group_mention_service_spec.rb
new file mode 100644
index 00000000000..72d53ce6d06
--- /dev/null
+++ b/spec/services/integrations/group_mention_service_spec.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integrations::GroupMentionService, feature_category: :integrations do
+ subject(:execute) { described_class.new(mentionable, hook_data: hook_data, is_confidential: is_confidential).execute }
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+
+ before do
+ allow(mentionable).to receive(:referenced_groups).with(user).and_return([group])
+ end
+
+ shared_examples 'group_mention_hooks' do
+ specify do
+ expect(group).to receive(:execute_integrations).with(anything, :group_mention_hooks)
+ expect(execute).to be_success
+ end
+ end
+
+ shared_examples 'group_confidential_mention_hooks' do
+ specify do
+ expect(group).to receive(:execute_integrations).with(anything, :group_confidential_mention_hooks)
+ expect(execute).to be_success
+ end
+ end
+
+ context 'for issue descriptions' do
+ let(:hook_data) { mentionable.to_hook_data(user) }
+ let(:is_confidential) { mentionable.confidential? }
+
+ context 'in public projects' do
+ let_it_be(:project) { create(:project, :public) }
+
+ context 'in public issues' do
+ let(:mentionable) do
+ create(:issue, confidential: false, project: project, author: user, description: "@#{group.full_path}")
+ end
+
+ it_behaves_like 'group_mention_hooks'
+ end
+
+ context 'in confidential issues' do
+ let(:mentionable) do
+ create(:issue, confidential: true, project: project, author: user, description: "@#{group.full_path}")
+ end
+
+ it_behaves_like 'group_confidential_mention_hooks'
+ end
+ end
+
+ context 'in private projects' do
+ let_it_be(:project) { create(:project, :private) }
+
+ context 'in public issues' do
+ let(:mentionable) do
+ create(:issue, confidential: false, project: project, author: user, description: "@#{group.full_path}")
+ end
+
+ it_behaves_like 'group_confidential_mention_hooks'
+ end
+
+ context 'in confidential issues' do
+ let(:mentionable) do
+ create(:issue, confidential: true, project: project, author: user, description: "@#{group.full_path}")
+ end
+
+ it_behaves_like 'group_confidential_mention_hooks'
+ end
+ end
+ end
+
+ context 'for merge request descriptions' do
+ let(:hook_data) { mentionable.to_hook_data(user) }
+ let(:is_confidential) { false }
+ let(:mentionable) do
+ create(:merge_request, source_project: project, target_project: project, author: user,
+ description: "@#{group.full_path}")
+ end
+
+ context 'in public projects' do
+ let_it_be(:project) { create(:project, :public) }
+
+ it_behaves_like 'group_mention_hooks'
+ end
+
+ context 'in private projects' do
+ let_it_be(:project) { create(:project, :private) }
+
+ it_behaves_like 'group_confidential_mention_hooks'
+ end
+ end
+
+ context 'for issue notes' do
+ let(:hook_data) { Gitlab::DataBuilder::Note.build(mentionable, mentionable.author) }
+ let(:is_confidential) { mentionable.confidential?(include_noteable: true) }
+
+ context 'in public projects' do
+ let_it_be(:project) { create(:project, :public) }
+
+ context 'in public issues' do
+ let(:issue) do
+ create(:issue, confidential: false, project: project, author: user, description: "@#{group.full_path}")
+ end
+
+ context 'for public notes' do
+ let(:mentionable) { create(:note_on_issue, noteable: issue, project: project, author: user) }
+
+ it_behaves_like 'group_mention_hooks'
+ end
+
+ context 'for internal notes' do
+ let(:mentionable) { create(:note_on_issue, :confidential, noteable: issue, project: project, author: user) }
+
+ it_behaves_like 'group_confidential_mention_hooks'
+ end
+ end
+ end
+
+ context 'in private projects' do
+ let_it_be(:project) { create(:project, :private) }
+
+ context 'in public issues' do
+ let(:issue) do
+ create(:issue, confidential: false, project: project, author: user, description: "@#{group.full_path}")
+ end
+
+ context 'for public notes' do
+ let(:mentionable) { create(:note_on_issue, noteable: issue, project: project, author: user) }
+
+ it_behaves_like 'group_confidential_mention_hooks'
+ end
+
+ context 'for internal notes' do
+ let(:mentionable) { create(:note_on_issue, :confidential, noteable: issue, project: project, author: user) }
+
+ it_behaves_like 'group_confidential_mention_hooks'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 3dfc9571c9c..95f19bd6f00 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -149,6 +149,12 @@ RSpec.describe Issues::CreateService, feature_category: :team_planning do
issue
end
+ it 'calls GroupMentionWorker' do
+ expect(Integrations::GroupMentionWorker).to receive(:perform_async)
+
+ issue
+ end
+
context 'when a build_service is provided' do
let(:result) { described_class.new(container: project, current_user: user, params: opts, build_service: build_service).execute }
diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb
index bb1151dfac7..377efdb3f9f 100644
--- a/spec/services/issues/reopen_service_spec.rb
+++ b/spec/services/issues/reopen_service_spec.rb
@@ -68,6 +68,12 @@ RSpec.describe Issues::ReopenService, feature_category: :team_planning do
expect { execute }.not_to change { issue.incident_management_timeline_events.count }
end
+ it 'does not call GroupMentionWorker' do
+ expect(Integrations::GroupMentionWorker).not_to receive(:perform_async)
+
+ issue
+ end
+
context 'issue is incident type' do
let(:issue) { create(:incident, :closed, project: project) }
let(:current_user) { user }
diff --git a/spec/services/merge_requests/after_create_service_spec.rb b/spec/services/merge_requests/after_create_service_spec.rb
index 7255d19ef8a..1126539b25a 100644
--- a/spec/services/merge_requests/after_create_service_spec.rb
+++ b/spec/services/merge_requests/after_create_service_spec.rb
@@ -75,6 +75,12 @@ RSpec.describe MergeRequests::AfterCreateService, feature_category: :code_review
execute_service
end
+ it 'calls GroupMentionWorker' do
+ expect(Integrations::GroupMentionWorker).to receive(:perform_async)
+
+ execute_service
+ end
+
it_behaves_like 'records an onboarding progress action', :merge_request_created do
let(:namespace) { merge_request.target_project.namespace }
end
diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb
index 7399b29d06e..e173cd382f2 100644
--- a/spec/services/merge_requests/reopen_service_spec.rb
+++ b/spec/services/merge_requests/reopen_service_spec.rb
@@ -40,6 +40,10 @@ RSpec.describe MergeRequests::ReopenService, feature_category: :code_review_work
.with(merge_request, 'reopen')
end
+ it 'does not call GroupMentionWorker' do
+ expect(Integrations::GroupMentionWorker).not_to receive(:perform_async)
+ end
+
it 'sends email to user2 about reopen of merge_request', :sidekiq_might_not_need_inline do
email = ActionMailer::Base.deliveries.last
expect(email.to.first).to eq(user2.email)
diff --git a/spec/services/notes/post_process_service_spec.rb b/spec/services/notes/post_process_service_spec.rb
index 0bcfd6b63d2..35d3620e429 100644
--- a/spec/services/notes/post_process_service_spec.rb
+++ b/spec/services/notes/post_process_service_spec.rb
@@ -22,6 +22,9 @@ RSpec.describe Notes::PostProcessService, feature_category: :team_planning do
it do
expect(project).to receive(:execute_hooks)
expect(project).to receive(:execute_integrations)
+ expect_next_instance_of(Integrations::GroupMentionService) do |group_mention_service|
+ expect(group_mention_service).to receive(:execute)
+ end
described_class.new(@note).execute
end
diff --git a/spec/workers/integrations/group_mention_worker_spec.rb b/spec/workers/integrations/group_mention_worker_spec.rb
new file mode 100644
index 00000000000..111e3f5a107
--- /dev/null
+++ b/spec/workers/integrations/group_mention_worker_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integrations::GroupMentionWorker, :clean_gitlab_redis_shared_state, feature_category: :integrations do
+ describe '#perform' do
+ let(:worker) { described_class.new }
+ let(:service_class) { Integrations::GroupMentionService }
+
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:user) { create(:user) }
+
+ let(:issue) { create(:issue, confidential: false, project: project, author: user) }
+ let(:hook_data) { issue.to_hook_data(user) }
+ let(:is_confidential) { issue.confidential? }
+
+ let(:args) do
+ {
+ mentionable_type: 'Issue',
+ mentionable_id: issue.id,
+ hook_data: hook_data,
+ is_confidential: is_confidential
+ }
+ end
+
+ it 'executes the service' do
+ expect_next_instance_of(service_class, issue, hook_data: hook_data, is_confidential: is_confidential) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ worker.perform(args)
+ end
+
+ it_behaves_like 'an idempotent worker' do
+ let(:job_args) { [args] }
+ end
+
+ context 'when mentionable_type is not supported' do
+ let(:args) do
+ {
+ mentionable_type: 'Unsupported',
+ mentionable_id: 23,
+ hook_data: {},
+ is_confidential: false
+ }
+ end
+
+ it 'does not execute the service' do
+ expect(service_class).not_to receive(:new)
+
+ worker.perform(args)
+ end
+
+ it 'logs an error' do
+ expect(Sidekiq.logger).to receive(:error).with({
+ message: 'Integrations::GroupMentionWorker: mentionable not supported',
+ mentionable_type: 'Unsupported',
+ mentionable_id: 23
+ })
+
+ worker.perform(args)
+ end
+ end
+ end
+end