Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
32f67dc214
commit
50b7d6cec7
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,11 +11,3 @@
|
|||
vertical-align: sub;
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-item-text {
|
||||
text-decoration: inherit;
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
@include str-truncated(128px);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ module GroupsHelper
|
|||
push_to_schema_breadcrumb(simple_sanitize(group.name), group_path(group))
|
||||
|
||||
if name
|
||||
full_title << ' · '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path breadcrumb-item-text js-breadcrumb-item-text')
|
||||
full_title << ' · '.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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
ed2b44c085d02dfb5e361f3f33dd62b9b5fed0e3ae570ff79936feadad66561a
|
||||
|
|
@ -0,0 +1 @@
|
|||
5fd81c2408e7e4ae564b719702b69e7645fb84822e77d2aee9eb284a68daf1dd
|
||||
|
|
@ -0,0 +1 @@
|
|||
7a53aa32b606bb1ae2b2816fe50d2ef57eb899fefc7dfd1ad558da36898a3155
|
||||
|
|
@ -0,0 +1 @@
|
|||
688603d4b31b17d1eeb133e293876aae77ab68b80f656fb9b902ca38d4c7beed
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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]`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue