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:
-rw-r--r--app/assets/javascripts/breadcrumb.js2
-rw-r--r--app/assets/stylesheets/framework/breadcrumbs.scss8
-rw-r--r--app/helpers/button_helper.rb10
-rw-r--r--app/helpers/groups_helper.rb6
-rw-r--r--app/helpers/merge_requests_helper.rb5
-rw-r--r--app/helpers/projects_helper.rb2
-rw-r--r--app/services/issuable/common_system_notes_service.rb15
-rw-r--r--app/services/work_items/callbacks/current_user_todos.rb35
-rw-r--r--app/services/work_items/widgets/current_user_todos_service/update_service.rb37
-rw-r--r--db/migrate/20240105000000_rename_workspace_url_domain_to_dns_zone.rb14
-rw-r--r--db/post_migrate/20231219132423_remove_epic_id_column_from_vulnerabilities.rb21
-rw-r--r--db/post_migrate/20240105000001_cleanup_workspaces_url_domain_to_dns_zone_rename.rb15
-rw-r--r--db/post_migrate/20240108181808_remove_package_registry_duplicated_indexes.rb36
-rw-r--r--db/schema_migrations/202312191324231
-rw-r--r--db/schema_migrations/202401050000001
-rw-r--r--db/schema_migrations/202401050000011
-rw-r--r--db/schema_migrations/202401081818081
-rw-r--r--db/structure.sql16
-rw-r--r--doc/api/merge_requests.md4
-rw-r--r--doc/architecture/blueprints/gitlab_housekeeper/index.md132
-rw-r--r--doc/development/feature_flags/index.md2
-rw-r--r--doc/solutions/cloud/aws/gitlab_aws_integration.md24
-rw-r--r--spec/features/projects/show/redirects_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_git_instructions_spec.rb2
-rw-r--r--spec/services/issuable/common_system_notes_service_spec.rb4
-rw-r--r--spec/services/work_items/callbacks/current_user_todos_spec.rb (renamed from spec/services/work_items/widgets/current_user_todos_service/update_service_spec.rb)20
-rw-r--r--spec/support/helpers/database/duplicate_indexes.yml13
-rw-r--r--spec/support/shared_examples/services/common_system_notes_shared_examples.rb6
28 files changed, 318 insertions, 117 deletions
diff --git a/app/assets/javascripts/breadcrumb.js b/app/assets/javascripts/breadcrumb.js
index 0dacd5af5cc..b06a6f8b141 100644
--- a/app/assets/javascripts/breadcrumb.js
+++ b/app/assets/javascripts/breadcrumb.js
@@ -34,7 +34,7 @@ export default () => {
$('li.expander').remove();
// set focus on first breadcrumb item
- $('.breadcrumb-item-text').first().focus();
+ $('.js-breadcrumb-item-text').first().focus();
});
}
};
diff --git a/app/assets/stylesheets/framework/breadcrumbs.scss b/app/assets/stylesheets/framework/breadcrumbs.scss
index 2ed611f7ba9..b71382f5570 100644
--- a/app/assets/stylesheets/framework/breadcrumbs.scss
+++ b/app/assets/stylesheets/framework/breadcrumbs.scss
@@ -11,11 +11,3 @@
vertical-align: sub;
}
}
-
-.breadcrumb-item-text {
- text-decoration: inherit;
-
- @include media-breakpoint-down(xs) {
- @include str-truncated(128px);
- }
-}
diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb
index e6212ee7d8d..851de133a38 100644
--- a/app/helpers/button_helper.rb
+++ b/app/helpers/button_helper.rb
@@ -8,7 +8,9 @@ module ButtonHelper
# :gfm - GitLab Flavored Markdown to copy, if different from `text` (optional)
# :target - Selector for target element to copy from (optional)
# :class - CSS classes to be applied to the button (optional)
- # :title - Button's title attribute (used for the tooltip) (optional)
+ # :title - Button's title attribute (used for the tooltip) (optional, default: Copy)
+ # :aria_label - Button's aria-label attribute (optional)
+ # :aria_keyshortcuts - Button's aria-keyshortcuts attribute (optional)
# :button_text - Button's displayed label (optional)
# :hide_tooltip - Whether the tooltip should be hidden (optional, default: false)
# :hide_button_icon - Whether the icon should be hidden (optional, default: false)
@@ -31,6 +33,8 @@ module ButtonHelper
def clipboard_button(data = {})
css_class = data.delete(:class)
title = data.delete(:title) || _('Copy')
+ aria_keyshortcuts = data.delete(:aria_keyshortcuts) || nil
+ aria_label = data.delete(:aria_label) || title
button_text = data[:button_text] || nil
hide_tooltip = data[:hide_tooltip] || false
hide_button_icon = data[:hide_button_icon] || false
@@ -54,7 +58,7 @@ module ButtonHelper
data[:clipboard_target] = target if target
unless hide_tooltip
- data = { toggle: 'tooltip', placement: 'bottom', container: 'body' }.merge(data)
+ data = { toggle: 'tooltip', placement: 'bottom', container: 'body', html: 'true' }.merge(data)
end
render ::Pajamas::ButtonComponent.new(
@@ -62,7 +66,7 @@ module ButtonHelper
variant: variant,
category: category,
size: size,
- button_options: { class: css_class, title: title, aria: { label: title, live: 'polite' }, data: data, itemprop: item_prop }) do
+ button_options: { class: css_class, title: title, aria: { keyshortcuts: aria_keyshortcuts, label: aria_label, live: 'polite' }, data: data, itemprop: item_prop }) do
button_text
end
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 25a2cc8a5ae..8b5d05b6408 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -57,7 +57,7 @@ module GroupsHelper
push_to_schema_breadcrumb(simple_sanitize(group.name), group_path(group))
if name
- full_title << ' &middot; '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path breadcrumb-item-text js-breadcrumb-item-text')
+ full_title << ' &middot; '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path js-breadcrumb-item-text')
push_to_schema_breadcrumb(simple_sanitize(name), url)
end
@@ -241,8 +241,8 @@ module GroupsHelper
private
- def group_title_link(group, hidable: false, show_avatar: false, for_dropdown: false)
- link_to(group_path(group), class: "group-path #{'breadcrumb-item-text' unless for_dropdown} js-breadcrumb-item-text #{'hidable' if hidable}") do
+ def group_title_link(group, hidable: false, show_avatar: false)
+ link_to(group_path(group), class: "group-path js-breadcrumb-item-text #{'hidable' if hidable}") do
icon = render Pajamas::AvatarComponent.new(group, alt: group.name, class: "avatar-tile", size: 16) if group.try(:avatar_url) || show_avatar
[icon, simple_sanitize(group.name)].join.html_safe
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 100b9349df6..767838df076 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -275,7 +275,10 @@ module MergeRequestsHelper
def merge_request_header(project, merge_request)
link_to_author = link_to_member(project, merge_request.author, size: 24, extra_class: 'gl-font-weight-bold gl-mr-2', avatar: false)
- copy_button = clipboard_button(text: merge_request.source_branch, title: _('Copy branch name'), class: 'gl-display-none! gl-md-display-inline-block! js-source-branch-copy')
+ copy_action_description = _('Copy branch name')
+ copy_action_shortcut = 'b'
+ copy_button_title = "#{copy_action_description} <kbd class='flat ml-1'>#{copy_action_shortcut}</kbd>"
+ copy_button = clipboard_button(text: merge_request.source_branch, title: copy_button_title, aria_keyshortcuts: copy_action_shortcut, aria_label: copy_action_description, class: 'gl-display-none! gl-md-display-inline-block! js-source-branch-copy')
target_branch = link_to merge_request.target_branch, project_tree_path(merge_request.target_project, merge_request.target_branch), title: merge_request.target_branch, class: 'ref-container gl-display-inline-block gl-text-truncate gl-max-w-26 gl-mx-2'
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index cbc2db9e79f..cb8c86a7d29 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -791,7 +791,7 @@ module ProjectsHelper
link_to project_path(project) do
icon = render Pajamas::AvatarComponent.new(project, alt: project.name, size: 16, class: 'avatar-tile') if project.avatar_url && !Rails.env.test?
- [icon, content_tag("span", project_name, class: "breadcrumb-item-text js-breadcrumb-item-text")].join.html_safe
+ [icon, content_tag("span", project_name, class: "js-breadcrumb-item-text")].join.html_safe
end
end
diff --git a/app/services/issuable/common_system_notes_service.rb b/app/services/issuable/common_system_notes_service.rb
index db28be864a7..a0fa1616f7b 100644
--- a/app/services/issuable/common_system_notes_service.rb
+++ b/app/services/issuable/common_system_notes_service.rb
@@ -2,10 +2,11 @@
module Issuable
class CommonSystemNotesService < ::BaseProjectService
- attr_reader :issuable
+ attr_reader :issuable, :is_update
def execute(issuable, old_labels: [], old_milestone: nil, is_update: true)
@issuable = issuable
+ @is_update = is_update
# We disable touch so that created system notes do not update
# the noteable's updated_at field
@@ -17,10 +18,10 @@ module Issuable
handle_description_change_note
- handle_time_tracking_note if issuable.is_a?(TimeTrackable)
create_discussion_lock_note if issuable.previous_changes.include?('discussion_locked')
end
+ handle_time_tracking_note if issuable.is_a?(TimeTrackable)
handle_start_date_or_due_date_change_note
create_milestone_change_event(old_milestone) if issuable.previous_changes.include?('milestone_id')
create_labels_note(old_labels) if old_labels && issuable.labels != old_labels
@@ -37,13 +38,11 @@ module Issuable
end
def handle_time_tracking_note
- if issuable.previous_changes.include?('time_estimate')
- create_time_estimate_note
- end
+ estimate_updated = is_update && issuable.previous_changes.include?('time_estimate')
+ estimate_set = !is_update && issuable.time_estimate != 0
- if issuable.time_spent?
- create_time_spent_note
- end
+ create_time_estimate_note if estimate_updated || estimate_set
+ create_time_spent_note if issuable.time_spent?
end
def handle_description_change_note
diff --git a/app/services/work_items/callbacks/current_user_todos.rb b/app/services/work_items/callbacks/current_user_todos.rb
new file mode 100644
index 00000000000..c6c74a5ce3d
--- /dev/null
+++ b/app/services/work_items/callbacks/current_user_todos.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module WorkItems
+ module Callbacks
+ class CurrentUserTodos < Base
+ def before_update
+ return unless params.present? && params.key?(:action)
+
+ case params[:action]
+ when "add"
+ add_todo
+ when "mark_as_done"
+ mark_as_done(params[:todo_id])
+ end
+ end
+
+ private
+
+ def add_todo
+ return unless has_permission?(:create_todo)
+
+ TodoService.new.mark_todo(work_item, current_user)&.first
+ end
+
+ def mark_as_done(todo_id)
+ todos = TodosFinder.new(current_user, state: :pending, target_id: work_item.id).execute
+ todos = todo_id ? todos.id_in(todo_id) : todos
+
+ return if todos.empty?
+
+ TodoService.new.resolve_todos(todos, current_user, resolved_by_action: :api_done)
+ end
+ end
+ end
+end
diff --git a/app/services/work_items/widgets/current_user_todos_service/update_service.rb b/app/services/work_items/widgets/current_user_todos_service/update_service.rb
deleted file mode 100644
index 38e2ae4de32..00000000000
--- a/app/services/work_items/widgets/current_user_todos_service/update_service.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-module WorkItems
- module Widgets
- module CurrentUserTodosService
- class UpdateService < WorkItems::Widgets::BaseService
- def before_update_in_transaction(params:)
- return unless params.present? && params.key?(:action)
-
- case params[:action]
- when "add"
- add_todo
- when "mark_as_done"
- mark_as_done(params[:todo_id])
- end
- end
-
- private
-
- def add_todo
- return unless has_permission?(:create_todo)
-
- TodoService.new.mark_todo(work_item, current_user)&.first
- end
-
- def mark_as_done(todo_id)
- todos = TodosFinder.new(current_user, state: :pending, target_id: work_item.id).execute
- todos = todo_id ? todos.id_in(todo_id) : todos
-
- return if todos.empty?
-
- TodoService.new.resolve_todos(todos, current_user, resolved_by_action: :api_done)
- end
- end
- end
- end
-end
diff --git a/db/migrate/20240105000000_rename_workspace_url_domain_to_dns_zone.rb b/db/migrate/20240105000000_rename_workspace_url_domain_to_dns_zone.rb
new file mode 100644
index 00000000000..72e7ea566a8
--- /dev/null
+++ b/db/migrate/20240105000000_rename_workspace_url_domain_to_dns_zone.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class RenameWorkspaceUrlDomainToDnsZone < Gitlab::Database::Migration[2.2]
+ milestone '16.8'
+ disable_ddl_transaction!
+
+ def up
+ rename_column_concurrently :workspaces, :url_domain, :dns_zone
+ end
+
+ def down
+ undo_rename_column_concurrently :workspaces, :url_domain, :dns_zone
+ end
+end
diff --git a/db/post_migrate/20231219132423_remove_epic_id_column_from_vulnerabilities.rb b/db/post_migrate/20231219132423_remove_epic_id_column_from_vulnerabilities.rb
new file mode 100644
index 00000000000..fa6379a409a
--- /dev/null
+++ b/db/post_migrate/20231219132423_remove_epic_id_column_from_vulnerabilities.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class RemoveEpicIdColumnFromVulnerabilities < Gitlab::Database::Migration[2.2]
+ disable_ddl_transaction!
+
+ milestone '16.8'
+
+ def up
+ with_lock_retries do
+ remove_column :vulnerabilities, :epic_id
+ end
+ end
+
+ def down
+ add_column :vulnerabilities, :epic_id, :bigint unless column_exists?(:vulnerabilities, :epic_id)
+
+ # Add back index and constraint that were dropped in `up`
+ add_concurrent_index(:vulnerabilities, :epic_id)
+ add_concurrent_foreign_key(:vulnerabilities, :epics, column: :epic_id, on_delete: :nullify)
+ end
+end
diff --git a/db/post_migrate/20240105000001_cleanup_workspaces_url_domain_to_dns_zone_rename.rb b/db/post_migrate/20240105000001_cleanup_workspaces_url_domain_to_dns_zone_rename.rb
new file mode 100644
index 00000000000..d37d0c9a5af
--- /dev/null
+++ b/db/post_migrate/20240105000001_cleanup_workspaces_url_domain_to_dns_zone_rename.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CleanupWorkspacesUrlDomainToDnsZoneRename < Gitlab::Database::Migration[2.2]
+ milestone '16.8'
+
+ disable_ddl_transaction!
+
+ def up
+ cleanup_concurrent_column_rename :workspaces, :url_domain, :dns_zone
+ end
+
+ def down
+ undo_cleanup_concurrent_column_rename :workspaces, :url_domain, :dns_zone
+ end
+end
diff --git a/db/post_migrate/20240108181808_remove_package_registry_duplicated_indexes.rb b/db/post_migrate/20240108181808_remove_package_registry_duplicated_indexes.rb
new file mode 100644
index 00000000000..96380b94d50
--- /dev/null
+++ b/db/post_migrate/20240108181808_remove_package_registry_duplicated_indexes.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+class RemovePackageRegistryDuplicatedIndexes < Gitlab::Database::Migration[2.2]
+ disable_ddl_transaction!
+ milestone '16.8'
+
+ DUPLICATED_INDEXES = [
+ {
+ name: :index_packages_debian_group_distributions_on_group_id,
+ table: :packages_debian_group_distributions,
+ column: :group_id
+ },
+ {
+ name: :index_packages_debian_project_distributions_on_project_id,
+ table: :packages_debian_project_distributions,
+ column: :project_id
+ },
+ {
+ name: :index_packages_tags_on_package_id,
+ table: :packages_tags,
+ column: :package_id
+ }
+ ]
+
+ def up
+ DUPLICATED_INDEXES.each do |index|
+ remove_concurrent_index_by_name(index[:table], index[:name])
+ end
+ end
+
+ def down
+ DUPLICATED_INDEXES.each do |index|
+ add_concurrent_index(index[:table], index[:column], name: index[:name])
+ end
+ end
+end
diff --git a/db/schema_migrations/20231219132423 b/db/schema_migrations/20231219132423
new file mode 100644
index 00000000000..82fb1923c91
--- /dev/null
+++ b/db/schema_migrations/20231219132423
@@ -0,0 +1 @@
+ed2b44c085d02dfb5e361f3f33dd62b9b5fed0e3ae570ff79936feadad66561a \ No newline at end of file
diff --git a/db/schema_migrations/20240105000000 b/db/schema_migrations/20240105000000
new file mode 100644
index 00000000000..5d7b53970b7
--- /dev/null
+++ b/db/schema_migrations/20240105000000
@@ -0,0 +1 @@
+5fd81c2408e7e4ae564b719702b69e7645fb84822e77d2aee9eb284a68daf1dd \ No newline at end of file
diff --git a/db/schema_migrations/20240105000001 b/db/schema_migrations/20240105000001
new file mode 100644
index 00000000000..45bc8d78c16
--- /dev/null
+++ b/db/schema_migrations/20240105000001
@@ -0,0 +1 @@
+7a53aa32b606bb1ae2b2816fe50d2ef57eb899fefc7dfd1ad558da36898a3155 \ No newline at end of file
diff --git a/db/schema_migrations/20240108181808 b/db/schema_migrations/20240108181808
new file mode 100644
index 00000000000..542a576fdf1
--- /dev/null
+++ b/db/schema_migrations/20240108181808
@@ -0,0 +1 @@
+688603d4b31b17d1eeb133e293876aae77ab68b80f656fb9b902ca38d4c7beed \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 82417b9b6be..31a1dd8ae30 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -25201,7 +25201,6 @@ ALTER SEQUENCE vs_code_settings_id_seq OWNED BY vs_code_settings.id;
CREATE TABLE vulnerabilities (
id bigint NOT NULL,
- epic_id bigint,
project_id bigint NOT NULL,
author_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -26014,12 +26013,12 @@ CREATE TABLE workspaces (
config_version integer DEFAULT 1 NOT NULL,
force_include_all_resources boolean DEFAULT true NOT NULL,
url_prefix text,
- url_domain text,
url_query_string text,
- CONSTRAINT check_03c5d442fd CHECK ((char_length(url_domain) <= 256)),
+ dns_zone text,
CONSTRAINT check_15543fb0fa CHECK ((char_length(name) <= 64)),
CONSTRAINT check_157d5f955c CHECK ((char_length(namespace) <= 64)),
CONSTRAINT check_2b401b0034 CHECK ((char_length(deployment_resource_version) <= 64)),
+ CONSTRAINT check_67c4c93554 CHECK ((char_length(dns_zone) <= 256)),
CONSTRAINT check_77d1a2ff50 CHECK ((char_length(processed_devfile) <= 65535)),
CONSTRAINT check_8a0ab61b6b CHECK ((char_length(url_query_string) <= 256)),
CONSTRAINT check_8e363ee3ad CHECK ((char_length(devfile_ref) <= 256)),
@@ -34529,14 +34528,10 @@ CREATE INDEX index_packages_debian_group_component_files_on_component_id ON pack
CREATE INDEX index_packages_debian_group_distributions_on_creator_id ON packages_debian_group_distributions USING btree (creator_id);
-CREATE INDEX index_packages_debian_group_distributions_on_group_id ON packages_debian_group_distributions USING btree (group_id);
-
CREATE INDEX index_packages_debian_project_component_files_on_component_id ON packages_debian_project_component_files USING btree (component_id);
CREATE INDEX index_packages_debian_project_distributions_on_creator_id ON packages_debian_project_distributions USING btree (creator_id);
-CREATE INDEX index_packages_debian_project_distributions_on_project_id ON packages_debian_project_distributions USING btree (project_id);
-
CREATE INDEX index_packages_debian_publications_on_distribution_id ON packages_debian_publications USING btree (distribution_id);
CREATE UNIQUE INDEX index_packages_debian_publications_on_package_id ON packages_debian_publications USING btree (package_id);
@@ -34613,8 +34608,6 @@ CREATE INDEX index_packages_rpm_metadata_on_package_id ON packages_rpm_metadata
CREATE INDEX index_packages_rpm_repository_files_on_project_id_and_file_name ON packages_rpm_repository_files USING btree (project_id, file_name);
-CREATE INDEX index_packages_tags_on_package_id ON packages_tags USING btree (package_id);
-
CREATE INDEX index_packages_tags_on_package_id_and_updated_at ON packages_tags USING btree (package_id, updated_at DESC);
CREATE INDEX index_packages_tags_on_project_id ON packages_tags USING btree (project_id);
@@ -35685,8 +35678,6 @@ CREATE INDEX index_vulnerabilities_on_detected_at_and_id ON vulnerabilities USIN
CREATE INDEX index_vulnerabilities_on_dismissed_by_id ON vulnerabilities USING btree (dismissed_by_id);
-CREATE INDEX index_vulnerabilities_on_epic_id ON vulnerabilities USING btree (epic_id);
-
CREATE INDEX index_vulnerabilities_on_finding_id ON vulnerabilities USING btree (finding_id);
CREATE INDEX index_vulnerabilities_on_project_id_and_id ON vulnerabilities USING btree (project_id, id);
@@ -38098,9 +38089,6 @@ ALTER TABLE ONLY project_statistics
ALTER TABLE ONLY agent_project_authorizations
ADD CONSTRAINT fk_1d30bb4987 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY vulnerabilities
- ADD CONSTRAINT fk_1d37cddf91 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE SET NULL;
-
ALTER TABLE ONLY boards
ADD CONSTRAINT fk_1e9a074a35 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index a852c7c0b96..02407b5e650 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -2014,7 +2014,9 @@ This API returns specific HTTP status codes:
| HTTP Status | Message | Reason |
|-------------|--------------------------------------------|--------|
| `202` | *(no message)* | Successfully enqueued. |
-| `403` | <ul><li>`Source branch does not exist`</li><li>`Cannot push to source branch`</li><li>`Source branch is protected from force push`</li></ul> | You don't have permission to push to the merge request's source branch. |
+| `403` | `Cannot push to source branch` | You don't have permission to push to the merge request's source branch. |
+| `403` | `Source branch does not exist` | You don't have permission to push to the merge request's source branch. |
+| `403` | `Source branch is protected from force push` | You don't have permission to push to the merge request's source branch. |
| `409` | `Failed to enqueue the rebase operation` | A long-lived transaction might have blocked your request. |
If the request is enqueued successfully, the response contains:
diff --git a/doc/architecture/blueprints/gitlab_housekeeper/index.md b/doc/architecture/blueprints/gitlab_housekeeper/index.md
new file mode 100644
index 00000000000..76ff032bbcf
--- /dev/null
+++ b/doc/architecture/blueprints/gitlab_housekeeper/index.md
@@ -0,0 +1,132 @@
+---
+status: implemented
+creation-date: "2023-10-18"
+authors: [ "@DylanGriffith" ]
+coach:
+approvers: [ "@rymai", "@tigerwnz" ]
+owning-stage: "~devops::tenant scale"
+participating-stages: []
+---
+
+<!-- vale gitlab.FutureTense = NO -->
+
+# GitLab Housekeeper - automating merge requests
+
+## Summary
+
+This blueprint documents the philosophy behind the "GitLab Housekeeper" gem
+which was introduced in
+<https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139492> and has already
+been used to create many merge requests.
+
+The tool should be used to save developers from mundane repetitive tasks that
+can be automated. The tool is scoped to any task where a developer needs to
+create a straightforward merge request and is known ahead of time.
+
+This tool should be useful for at least the following kinds of mundane MRs
+we create:
+
+1. Remove a feature flag after X date
+1. Remove an unused index where the unused index is identified by some
+ automation
+1. Remove an `ignore_column` after X date (part of renaming/removing columns
+ multi-step procedure)
+1. Populate sharding keys for organizations/cells on tables that are missing a
+ sharding key
+
+## Motivation
+
+We've observed there are many cases where developers are doing a lot of
+manual work for tasks that are entirely predictable and automatable. Often
+these manual tasks are done after waiting some known period of time. As such we
+usually create an issue and set the future milestone. Then in the future the
+developer remembers to followup on that issue and opens an MR to make the
+manual change.
+
+The biggest examples we've seen lately are:
+
+1. Feature flag removal: <https://gitlab.com/groups/gitlab-org/-/epics/5325>. We
+ have many opportunities for automation with feature flags but this blueprint
+ focuses on removing the feature flag after it's fully rolled out. A step
+ that is often forgotten leading to growing technical debt.
+1. Removing duplicated or unused indexes in Postgres:
+ <https://gitlab.com/gitlab-org/gitlab/-/issues/385701>. For now we're
+ developing automation that creates issues and assigns them to groups to
+ follow up and manually open MRs to remove them. This blueprint would take it
+ a step further and the automation would just create the MRs to remove them
+ once we have identified them.
+1. Removing out of date `ignore_column` references:
+ <https://docs.gitlab.com/ee/development/database/avoiding_downtime_in_migrations.html#removing-the-ignore-rule-release-m2>
+ . For now we leave a note in our code telling us the date it needs to be
+ removed and often create an issue as a reminder. This blueprint proposes
+ that automation just reads this note and opens the MR to remove it after the
+ date.
+1. Adding and backfilling sharding keys for organizations for Cells:
+ <https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133796>. The cells
+ architecture depends on all tables having a sharding key that is attributed
+ to an organization. We will need to backfill this for ~300 tables. Much of
+ this will be repetitive and mundane work that we can automate provided that
+ groups just identify what the name of the sharding key should be and how we
+ will backfill it. As such we can automate the creation of MRs that guess the
+ sharding key and owning groups can check and correct those MRs. Then we can
+ automate the MR creation for adding the columns and backfilling the data.
+ Some kind of automation like this will be necessary to finish this work in a
+ reasonable timeframe.
+
+### Goals
+
+1. Identify the common tasks that take development time and automate them.
+1. Focus on MR creation rather than issue creation as MRs are the results we
+ want and issues are a process for reminding us to get those results.
+1. Improve developer job satisfication by knowing that automation is doing the
+ busy work while we get to do the challenging and creative work.
+1. Developers should be encouraged to contribute to the automation framework
+ when they see a pattern rather than documenting the manual work for future
+ developers to do it again.
+1. Automation MRs should be very easily identified and reviewed and merged much
+ more quickly than other MRs. If our automation MRs cause too much effort for
+ reviewers we maybe will outweigh the benefits. This might mean that some
+ automations get disabled when they are just noisy.
+
+## Solution
+
+The
+[GitLab Housekeeper gem](https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper)
+should be used to automate creation of mundane merge requests.
+
+Using this tool reflects our
+[bias for action](https://handbook.gitlab.com/handbook/values/#bias-for-action)
+subvalue. As such, developers should preference contributing a new
+[keep](https://gitlab.com/gitlab-org/gitlab/-/tree/master/keeps) over the following:
+
+1. Documenting a process that involves creating several merge requests over a
+ period of time
+1. Setting up periodic reminders for developers (in Slack or issues) to create
+ some merge request
+
+The keeps may sometimes take more work to implement than documentation or
+reminders so judgement should be used to assess the likely time savings from
+using automation. The `gitlab-housekeeper` gem will evolve over time with many
+utilities that make it simpler to contribute new keeps and it is expected that
+over time the cost to implementing a keep should be small enough that we will
+mostly prefer this whenever developers need to do a repeatable task more than a
+few times.
+
+## Design and implementation details
+
+The key details for this architecture is:
+
+1. The design of this tool is like a combination of `rubocop -a` and Renovate
+ bot. It extends on `rubocop -a` to understand when things need to be removed
+ after certain deadlines as well as creating a steady stream of manageable
+ merge requests for the reviewer rather than leaving those decisions to the
+ developer. Like the renovate bot it attempts to create MRs periodically and
+ assign them to the right people to review.
+1. The keeps live in the GitLab repo which means that there are no
+ dependencies to update and the keeps can use code inside the
+ GitLab codebase.
+1. The script can be run locally by a developer or can be run periodically
+ in some automated way.
+1. The keeps are able to use any data sources (eg. local code, Prometheus,
+ Postgres database archive, logs) needed to determine whether and how to make
+ the change.
diff --git a/doc/development/feature_flags/index.md b/doc/development/feature_flags/index.md
index 59c796ca331..bea42d6340d 100644
--- a/doc/development/feature_flags/index.md
+++ b/doc/development/feature_flags/index.md
@@ -244,7 +244,7 @@ created using the [Experiment Tracking template](https://gitlab.com/gitlab-org/g
the worker name itself, for example, `run_sidekiq_jobs_AuthorizedProjectsWorker`. Some examples for using `worker` type feature
flags can be found in [deferring Sidekiq jobs](#deferring-sidekiq-jobs).
-### [Deprecated]`development` type
+### (Deprecated) `development` type
The `development` type is deprecated in favor of the `gitlab_com_derisk`, `wip`, and `beta` feature flag types.
diff --git a/doc/solutions/cloud/aws/gitlab_aws_integration.md b/doc/solutions/cloud/aws/gitlab_aws_integration.md
index 31459fca747..fddb5ccfa38 100644
--- a/doc/solutions/cloud/aws/gitlab_aws_integration.md
+++ b/doc/solutions/cloud/aws/gitlab_aws_integration.md
@@ -37,16 +37,16 @@ These integrations have to do with using GitLab to build application workloads a
[12/28/2023 AWS Release Announcement for Self-Managed / Dedicated](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)
-**AWS CodeStar Connections** - enables SCM connections to multiple AWS Services. [Configure GitLab](https://docs.aws.amazon.com/dtconsole/latest/userguide/connections-create-gitlab.html). [Supported Providers](https://docs.aws.amazon.com/dtconsole/latest/userguide/supported-versions-connections.html). [Supported AWS Services](https://docs.aws.amazon.com/dtconsole/latest/userguide/integrations-connections.html) - each one may have to make updates to support GitLab, so here is the subset that support GitLab. This works with GitLab.com SaaS, GitLab Self-Managed and GitLab Dedicated. AWS CodeStar connections are not available in all AWS regions - the exclusion list is [documented here](https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html). [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Built]`
+**AWS CodeStar Connections** - enables SCM connections to multiple AWS Services. [Configure GitLab](https://docs.aws.amazon.com/dtconsole/latest/userguide/connections-create-gitlab.html). [Supported Providers](https://docs.aws.amazon.com/dtconsole/latest/userguide/supported-versions-connections.html). [Supported AWS Services](https://docs.aws.amazon.com/dtconsole/latest/userguide/integrations-connections.html) - each one may have to make updates to support GitLab, so here is the subset that support GitLab. This works with GitLab.com SaaS, GitLab Self-Managed and GitLab Dedicated. AWS CodeStar connections are not available in all AWS regions - the exclusion list is [documented here](https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html). ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Built]`
[Video Explanation of AWS CodeStar Connection Integration for AWS (1 min)](https://youtu.be/f7qTSa_bNig)
AWS Services that are supported directly by a CodeStar Connection in an AWS account:
-- **Amazon CodeWhisperer Customization Capability** [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] [can connect to a GitLab repository](https://aws.amazon.com/blogs/aws/new-customization-capability-in-amazon-codewhisperer-generates-even-better-suggestions-preview/). `[AWS Built]`
-- **AWS Service Catalog** directly inherits CodeStar Connections, there is not any specific documentation about GitLab because it just uses any GitLab CodeStar Connection that has been created in the account. [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Built]`
-- **AWS Proton** directly inherits CodeStar Connections, there is not any specific documentation about GitLab since it just uses any GitLab CodeStar Connection that has been created in the account. [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Built]`
-- **AWS Glue Notebook Jobs** directly inherit CodeStar Connections, there is not any specific documentation about GitLab because it just uses any GitLab CodeStar Connection that has been created in the account. [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Built]`
+- **Amazon CodeWhisperer Customization Capability** ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) [can connect to a GitLab repository](https://aws.amazon.com/blogs/aws/new-customization-capability-in-amazon-codewhisperer-generates-even-better-suggestions-preview/). `[AWS Built]`
+- **AWS Service Catalog** directly inherits CodeStar Connections, there is not any specific documentation about GitLab because it just uses any GitLab CodeStar Connection that has been created in the account. ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Built]`
+- **AWS Proton** directly inherits CodeStar Connections, there is not any specific documentation about GitLab since it just uses any GitLab CodeStar Connection that has been created in the account. ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Built]`
+- **AWS Glue Notebook Jobs** directly inherit CodeStar Connections, there is not any specific documentation about GitLab because it just uses any GitLab CodeStar Connection that has been created in the account. ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Built]`
Documentation and References:
@@ -59,8 +59,8 @@ Documentation and References:
AWS Services that are supported by an AWS CodePipeline integration:
-- **AWS CodeBuild Integration** - through CodePipeline support. [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Built]`
-- **Amazon SageMaker MLOps Projects** are created via CodePipeline ([as noted here](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-projects-walkthrough-3rdgit.html#sagemaker-proejcts-walkthrough-connect-3rdgit)), there is not any specific documentation about GitLab since it just uses any GitLab CodeStar Connection that has been created in the account. [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Built]`
+- **AWS CodeBuild Integration** - through CodePipeline support. ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Built]`
+- **Amazon SageMaker MLOps Projects** are created via CodePipeline ([as noted here](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-projects-walkthrough-3rdgit.html#sagemaker-proejcts-walkthrough-connect-3rdgit)), there is not any specific documentation about GitLab since it just uses any GitLab CodeStar Connection that has been created in the account. ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Built]`
Documentation and References:
@@ -75,12 +75,12 @@ Documentation and References:
#### Custom GitLab Integration in AWS Services
-- **Amazon SageMaker Notebooks** [allow Git repositories to be specified by the Git clone URL](https://docs.aws.amazon.com/sagemaker/latest/dg/nbi-git-resource.html) and configuration of a secret - so GitLab is configurable. [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Configuration]`
+- **Amazon SageMaker Notebooks** [allow Git repositories to be specified by the Git clone URL](https://docs.aws.amazon.com/sagemaker/latest/dg/nbi-git-resource.html) and configuration of a secret - so GitLab is configurable. ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Configuration]`
- **AWS Amplify** - [uses a Git integration mechanism designed by the AWS Amplify team](https://docs.aws.amazon.com/amplify/latest/userguide/getting-started.html). `[AWS Built]`
#### Other SCM Integration Options
-- [GitLab Push Mirroring to CodeCommit](../../../user/project/repository/mirror/push.md#set-up-a-push-mirror-from-gitlab-to-aws-codecommit) Workaround enables GitLab repositories to leverage CodePipeline SCM Triggers. GitLab can already leverage S3 and Container Triggers for CodePipeline. This work around enabled CodePipeline capabilities since it was documented. [06/06/2020] `[GitLab Configuration]`
+- [GitLab Push Mirroring to CodeCommit](../../../user/project/repository/mirror/push.md#set-up-a-push-mirror-from-gitlab-to-aws-codecommit) Workaround enables GitLab repositories to leverage CodePipeline SCM Triggers. GitLab can already leverage S3 and Container Triggers for CodePipeline. This work around enabled CodePipeline capabilities since it was documented. (06/06/2020) `[GitLab Configuration]`
See [CD and Operations Integrations](#cd-and-operations-integrations) below for Continuous Deployment (CD) specific integrations that are also available.
@@ -88,12 +88,12 @@ See [CD and Operations Integrations](#cd-and-operations-integrations) below for
- **Direct CI Integrations That Use Keys, IAM or OIDC/JWT to Authenticate to AWS Services from GitLab Runners**
- **Amazon CodeGuru Reviewer CI workflows using GitLab CI** - can be done, not yet documented.`[AWS Solution]` `[CI Solution]`
-- [Amazon CodeGuru Secure Scanning using GitLab CI](https://docs.aws.amazon.com/codeguru/latest/security-ug/get-started-gitlab.html) [[06/13/2022](https://aws.amazon.com/about-aws/whats-new/2023/06/amazon-codeguru-security-available-preview/)] `[AWS Solution]` `[CI Solution]`
+- [Amazon CodeGuru Secure Scanning using GitLab CI](https://docs.aws.amazon.com/codeguru/latest/security-ug/get-started-gitlab.html) ([06/13/2022](https://aws.amazon.com/about-aws/whats-new/2023/06/amazon-codeguru-security-available-preview/)) `[AWS Solution]` `[CI Solution]`
### CD and Operations Integrations
-- **AWS CodeDeploy Integration** - through CodePipeline support dicussed above in SCM integrations. This capability allows GitLab to interface with [this list of advanced deployment subsystems in AWS](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-deploy). [[12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)] `[AWS Built]`
-- **AWS SAM Pipelines** - [pipelines support for GitLab](https://aws.amazon.com/about-aws/whats-new/2021/07/simplify-ci-cd-configuration-serverless-applications-your-favorite-ci-cd-system-public-preview). [7/31/2021]
+- **AWS CodeDeploy Integration** - through CodePipeline support discussed above in SCM integrations. This capability allows GitLab to interface with [this list of advanced deployment subsystems in AWS](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-deploy). ([12/28/2023](https://aws.amazon.com/about-aws/whats-new/2023/12/codepipeline-gitlab-self-managed/)) `[AWS Built]`
+- **AWS SAM Pipelines** - [pipelines support for GitLab](https://aws.amazon.com/about-aws/whats-new/2021/07/simplify-ci-cd-configuration-serverless-applications-your-favorite-ci-cd-system-public-preview). (7/31/2021)
- [Integrate EKS clusters for application deployment](../../../user/infrastructure/clusters/connect/new_eks_cluster.md). `[GitLab Built]`
- [GitLab pushing a build Artifact to a CodePipeline monitored S3 location](https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-about-starting.html#change-detection-methods) `[AWS Built]`
- [GitLab Pushing a container to a CodePipeline monitored AWS ECR](https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-about-starting.html#change-detection-methods) `[AWS Built]`
diff --git a/spec/features/projects/show/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb
index ef326b92b98..a0424831973 100644
--- a/spec/features/projects/show/redirects_spec.rb
+++ b/spec/features/projects/show/redirects_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'Projects > Show > Redirects', feature_category: :groups_and_proj
it 'shows public project page' do
visit project_path(public_project)
- page.within '.breadcrumbs .breadcrumb-item-text' do
+ page.within '.breadcrumbs .js-breadcrumb-item-text' do
expect(page).to have_content(public_project.name)
end
end
diff --git a/spec/features/projects/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb
index 4933b3f239c..40549beae9f 100644
--- a/spec/features/projects/show/user_sees_git_instructions_spec.rb
+++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe 'Projects > Show > User sees Git instructions', feature_category:
let(:user_has_ssh_key) { false }
it 'shows details' do
- page.within('.breadcrumbs .breadcrumb-item-text') do
+ page.within('.breadcrumbs .js-breadcrumb-item-text') do
expect(page).to have_content(project.title)
end
diff --git a/spec/services/issuable/common_system_notes_service_spec.rb b/spec/services/issuable/common_system_notes_service_spec.rb
index 3d83c9ec9c2..fb2292bfe64 100644
--- a/spec/services/issuable/common_system_notes_service_spec.rb
+++ b/spec/services/issuable/common_system_notes_service_spec.rb
@@ -142,5 +142,9 @@ RSpec.describe Issuable::CommonSystemNotesService, feature_category: :team_plann
context 'when changing dates' do
it_behaves_like 'system note for issuable date changes'
end
+
+ context 'when setting an estimae' do
+ it_behaves_like 'system note creation', { time_estimate: 5 }, 'changed time estimate', false
+ end
end
end
diff --git a/spec/services/work_items/widgets/current_user_todos_service/update_service_spec.rb b/spec/services/work_items/callbacks/current_user_todos_spec.rb
index aa7257e9e62..0f16687e620 100644
--- a/spec/services/work_items/widgets/current_user_todos_service/update_service_spec.rb
+++ b/spec/services/work_items/callbacks/current_user_todos_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe WorkItems::Widgets::CurrentUserTodosService::UpdateService, feature_category: :team_planning do
+RSpec.describe WorkItems::Callbacks::CurrentUserTodos, feature_category: :team_planning do
let_it_be(:reporter) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:current_user) { reporter }
@@ -25,16 +25,16 @@ RSpec.describe WorkItems::Widgets::CurrentUserTodosService::UpdateService, featu
create(:todo, state: :pending, target: work_item, target_type: work_item.class.name, user: create(:user))
end
- let(:widget) { work_item.widgets.find { |widget| widget.is_a?(WorkItems::Widgets::CurrentUserTodos) } }
+ let(:widget) { work_item.widgets.find { |widget| widget.is_a?(WorkItems::Callbacks::CurrentUserTodos) } }
before_all do
project.add_reporter(reporter)
end
describe '#before_update_in_transaction' do
- subject do
- described_class.new(widget: widget, current_user: current_user)
- .before_update_in_transaction(params: params)
+ subject(:service) do
+ described_class.new(issuable: work_item, current_user: current_user, params: params)
+ .before_update
end
context 'when adding a todo' do
@@ -44,7 +44,7 @@ RSpec.describe WorkItems::Widgets::CurrentUserTodosService::UpdateService, featu
let(:current_user) { create(:user) }
it 'does add a todo' do
- expect { subject }.not_to change { Todo.count }
+ expect { service }.not_to change { Todo.count }
end
end
@@ -52,7 +52,7 @@ RSpec.describe WorkItems::Widgets::CurrentUserTodosService::UpdateService, featu
let(:params) { { action: "add" } }
it 'creates a new todo for the user and the work item' do
- expect { subject }.to change { current_user.todos.count }.by(1)
+ expect { service }.to change { current_user.todos.count }.by(1)
todo = current_user.todos.last
@@ -69,7 +69,7 @@ RSpec.describe WorkItems::Widgets::CurrentUserTodosService::UpdateService, featu
let(:current_user) { create(:user) }
it 'does not change todo status' do
- subject
+ service
expect(pending_todo1.reload).to be_pending
expect(pending_todo2.reload).to be_pending
@@ -80,7 +80,7 @@ RSpec.describe WorkItems::Widgets::CurrentUserTodosService::UpdateService, featu
context 'when resolving all todos of the work item', :aggregate_failures do
it 'resolves todos of the user for the work item' do
- subject
+ service
expect(pending_todo1.reload).to be_done
expect(pending_todo2.reload).to be_done
@@ -93,7 +93,7 @@ RSpec.describe WorkItems::Widgets::CurrentUserTodosService::UpdateService, featu
let(:params) { { action: "mark_as_done", todo_id: pending_todo1.id } }
it 'resolves todos of the user for the work item' do
- subject
+ service
expect(pending_todo1.reload).to be_done
expect(pending_todo2.reload).to be_pending
diff --git a/spec/support/helpers/database/duplicate_indexes.yml b/spec/support/helpers/database/duplicate_indexes.yml
index 87a1e0c2c50..acfda313020 100644
--- a/spec/support/helpers/database/duplicate_indexes.yml
+++ b/spec/support/helpers/database/duplicate_indexes.yml
@@ -105,19 +105,6 @@ ml_models:
p_ci_runner_machine_builds:
index_p_ci_runner_machine_builds_on_runner_machine_id:
- index_ci_runner_machine_builds_on_runner_machine_id
-packages_debian_group_distributions:
- uniq_pkgs_debian_group_distributions_group_id_and_codename:
- - index_packages_debian_group_distributions_on_group_id
- uniq_pkgs_debian_group_distributions_group_id_and_suite:
- - index_packages_debian_group_distributions_on_group_id
-packages_debian_project_distributions:
- uniq_pkgs_debian_project_distributions_project_id_and_codename:
- - index_packages_debian_project_distributions_on_project_id
- uniq_pkgs_debian_project_distributions_project_id_and_suite:
- - index_packages_debian_project_distributions_on_project_id
-packages_tags:
- index_packages_tags_on_package_id_and_updated_at:
- - index_packages_tags_on_package_id
pages_domains:
index_pages_domains_on_project_id_and_enabled_until:
- index_pages_domains_on_project_id
diff --git a/spec/support/shared_examples/services/common_system_notes_shared_examples.rb b/spec/support/shared_examples/services/common_system_notes_shared_examples.rb
index 1887b38b50e..14b0aa1ab08 100644
--- a/spec/support/shared_examples/services/common_system_notes_shared_examples.rb
+++ b/spec/support/shared_examples/services/common_system_notes_shared_examples.rb
@@ -1,7 +1,9 @@
# frozen_string_literal: true
-RSpec.shared_examples 'system note creation' do |update_params, note_text|
- subject { described_class.new(project: project, current_user: user).execute(issuable, old_labels: []) }
+RSpec.shared_examples 'system note creation' do |update_params, note_text, is_update = true|
+ subject do
+ described_class.new(project: project, current_user: user).execute(issuable, old_labels: [], is_update: is_update)
+ end
before do
issuable.assign_attributes(update_params)