Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
24ed1c84da
commit
50c3e72072
2
Gemfile
2
Gemfile
|
|
@ -47,7 +47,7 @@ gem 'responders', '~> 3.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
|||
|
||||
gem 'sprockets', '~> 3.7.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
gem 'view_component', '~> 3.6.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
gem 'view_component', '~> 3.7.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
# Supported DBs
|
||||
gem 'pg', '~> 1.5.4' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
|
|
|||
|
|
@ -678,7 +678,7 @@
|
|||
{"name":"validates_hostname","version":"1.0.13","platform":"ruby","checksum":"eac40178cc0b4f727df9cc6a5cb5bc2550718ad8d9bb3728df9aba6354bdda19"},
|
||||
{"name":"version_gem","version":"1.1.0","platform":"ruby","checksum":"6b009518020db57f51ec7b410213fae2bf692baea9f1b51770db97fbc93d9a80"},
|
||||
{"name":"version_sorter","version":"2.3.0","platform":"ruby","checksum":"2147f2a1a3804fbb8f60d268b7d7c1ec717e6dd727ffe2c165b4e05e82efe1da"},
|
||||
{"name":"view_component","version":"3.6.0","platform":"ruby","checksum":"7aa45c11b4fd51583bd63b10fbc6b1a87f088182e4f026e5f4f6a9211e5a42a3"},
|
||||
{"name":"view_component","version":"3.7.0","platform":"ruby","checksum":"648909bde6c188621d607732d64a82515b03e69761c8098a0fe4336166d7e403"},
|
||||
{"name":"virtus","version":"2.0.0","platform":"ruby","checksum":"8841dae4eb7fcc097320ba5ea516bf1839e5d056c61ee27138aa4bddd6e3d1c2"},
|
||||
{"name":"vite_rails","version":"3.0.15","platform":"ruby","checksum":"b8ec528aedf7e24b54f222b449cd9250810ea2456d5f8dd4ef87f06b475cf860"},
|
||||
{"name":"vite_ruby","version":"3.3.4","platform":"ruby","checksum":"025e438385a6dc2320c8c148dff453f5bb1d4f056ce69c3386f47d4c388ad80c"},
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ PATH
|
|||
PATH
|
||||
remote: vendor/gems/sidekiq-reliable-fetch
|
||||
specs:
|
||||
gitlab-sidekiq-fetcher (0.9.0)
|
||||
gitlab-sidekiq-fetcher (0.10.0)
|
||||
json (>= 2.5)
|
||||
sidekiq (~> 6.1)
|
||||
|
||||
|
|
@ -1670,7 +1670,7 @@ GEM
|
|||
activesupport (>= 3.0)
|
||||
version_gem (1.1.0)
|
||||
version_sorter (2.3.0)
|
||||
view_component (3.6.0)
|
||||
view_component (3.7.0)
|
||||
activesupport (>= 5.2.0, < 8.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
method_source (~> 1.0)
|
||||
|
|
@ -2038,7 +2038,7 @@ DEPENDENCIES
|
|||
valid_email (~> 0.1)
|
||||
validates_hostname (~> 1.0.13)
|
||||
version_sorter (~> 2.3)
|
||||
view_component (~> 3.6.0)
|
||||
view_component (~> 3.7.0)
|
||||
vite_rails
|
||||
vmstat (~> 2.3.0)
|
||||
warning (~> 1.3.0)
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ export default class UserTabs {
|
|||
this.loadActivityCalendar();
|
||||
|
||||
UserTabs.renderMostRecentBlocks('#js-overview .activities-block', {
|
||||
requestParams: { limit: 10 },
|
||||
requestParams: { limit: 15 },
|
||||
});
|
||||
UserTabs.renderMostRecentBlocks('#js-overview .projects-block', {
|
||||
requestParams: { limit: 10, skip_pagination: true, skip_namespace: true, compact_mode: true },
|
||||
|
|
|
|||
|
|
@ -10,16 +10,13 @@ $icon-size-diff: $avatar-icon-size - $system-note-icon-size;
|
|||
$system-note-icon-m-top: $avatar-m-top + $icon-size-diff - 1.3rem;
|
||||
$system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio;
|
||||
|
||||
@mixin vertical-line($left) {
|
||||
&::before {
|
||||
content: '';
|
||||
border-left: 2px solid var(--gray-50, $gray-50);
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
bottom: 0;
|
||||
left: calc(#{$left} - 1px);
|
||||
height: calc(100% + 20px);
|
||||
}
|
||||
@mixin vertical-line($top, $left) {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
left: $left;
|
||||
top: $top;
|
||||
height: calc(100% - #{$top});
|
||||
}
|
||||
|
||||
@mixin outline-comment() {
|
||||
|
|
@ -32,12 +29,7 @@ $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio;
|
|||
.limited-width-notes {
|
||||
.main-notes-list::before,
|
||||
.timeline-entry:last-child::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
left: 15px;
|
||||
top: 15px;
|
||||
height: calc(100% - 15px);
|
||||
@include vertical-line(15px, 15px);
|
||||
}
|
||||
|
||||
.main-notes-list::before {
|
||||
|
|
@ -1143,6 +1135,24 @@ $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio;
|
|||
}
|
||||
}
|
||||
|
||||
.user-activity-content {
|
||||
&::before {
|
||||
@include vertical-line(80px, 25px);
|
||||
background: var(--gray-50, $gray-50);
|
||||
}
|
||||
|
||||
.system-note-image {
|
||||
@include gl--flex-center;
|
||||
top: 14px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
|
||||
svg {
|
||||
fill: $gray-600 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This needs to be deleted when Snippet/Commit comments are convered to Vue
|
||||
// See https://gitlab.com/gitlab-org/gitlab-foss/issues/53918#note_117038785
|
||||
.unstyled-comments {
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ module Repositories
|
|||
|
||||
def access_actor
|
||||
return user if user
|
||||
return :ci if ci?
|
||||
|
||||
:ci if ci?
|
||||
end
|
||||
|
||||
def access_check
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ module EventsHelper
|
|||
'deleted' => 'remove',
|
||||
'destroyed' => 'remove',
|
||||
'imported' => 'import',
|
||||
'joined' => 'users'
|
||||
'joined' => 'users',
|
||||
'approved' => 'check',
|
||||
'added' => 'upload',
|
||||
'removed' => 'remove'
|
||||
}.freeze
|
||||
|
||||
def localized_action_name_map
|
||||
|
|
@ -242,7 +245,7 @@ module EventsHelper
|
|||
|
||||
def event_wiki_title_html(event)
|
||||
capture do
|
||||
concat content_tag(:span, _('wiki page'), class: "event-target-type gl-mr-2")
|
||||
concat content_tag(:span, _('wiki page'), class: "event-target-type gl-mr-2 #{user_profile_activity_classes}")
|
||||
concat link_to(
|
||||
event.target_title,
|
||||
event_wiki_page_target_url(event),
|
||||
|
|
@ -254,7 +257,7 @@ module EventsHelper
|
|||
|
||||
def event_design_title_html(event)
|
||||
capture do
|
||||
concat content_tag(:span, _('design'), class: "event-target-type gl-mr-2")
|
||||
concat content_tag(:span, _('design'), class: "event-target-type gl-mr-2 #{user_profile_activity_classes}")
|
||||
concat link_to(
|
||||
event.design.reference_link_text,
|
||||
design_url(event.design),
|
||||
|
|
@ -271,7 +274,7 @@ module EventsHelper
|
|||
def event_note_title_html(event)
|
||||
if event.note_target
|
||||
capture do
|
||||
concat content_tag(:span, event.note_target_type_name, class: "event-target-type gl-mr-2")
|
||||
concat content_tag(:span, event.note_target_type_name, class: "event-target-type gl-mr-2 #{user_profile_activity_classes}")
|
||||
concat link_to(event.note_target_reference, event_note_target_url(event), title: event.target_title, class: 'has-tooltip event-target-link gl-mr-2')
|
||||
end
|
||||
else
|
||||
|
|
@ -303,19 +306,16 @@ module EventsHelper
|
|||
end
|
||||
|
||||
def icon_for_profile_event(event)
|
||||
if current_path?('users#show')
|
||||
content_tag :div, class: "system-note-image #{event.action_name.parameterize}-icon" do
|
||||
icon_for_event(event.action_name)
|
||||
end
|
||||
else
|
||||
content_tag :div, class: 'system-note-image user-avatar' do
|
||||
author_avatar(event, size: 32)
|
||||
end
|
||||
end
|
||||
base_class = 'system-note-image'
|
||||
|
||||
classes = current_path?('users#activity') ? "#{event.action_name.parameterize}-icon gl-rounded-full gl-bg-gray-50 gl-line-height-0" : "user-avatar"
|
||||
content = current_path?('users#activity') ? icon_for_event(event.action_name, size: 14) : author_avatar(event, size: 32)
|
||||
|
||||
tag.div(class: "#{base_class} #{classes}") { content }
|
||||
end
|
||||
|
||||
def inline_event_icon(event)
|
||||
unless current_path?('users#show')
|
||||
unless current_path?('users#activity')
|
||||
content_tag :span, class: "system-note-image-inline d-none d-sm-flex gl-mr-2 #{event.action_name.parameterize}-icon align-self-center" do
|
||||
next design_event_icon(event.action, size: 14) if event.design?
|
||||
|
||||
|
|
@ -325,13 +325,19 @@ module EventsHelper
|
|||
end
|
||||
|
||||
def event_user_info(event)
|
||||
content_tag(:div, class: "event-user-info") do
|
||||
concat content_tag(:span, link_to_author(event), class: "author-name")
|
||||
concat " ".html_safe
|
||||
concat content_tag(:span, event.author.to_reference, class: "username")
|
||||
return if current_path?('users#activity')
|
||||
|
||||
tag.div(class: 'event-user-info') do
|
||||
concat tag.span(link_to_author(event), class: 'author-name')
|
||||
concat ' '.html_safe
|
||||
concat tag.span(event.author.to_reference, class: 'username')
|
||||
end
|
||||
end
|
||||
|
||||
def user_profile_activity_classes
|
||||
current_path?('users#activity') ? ' gl-font-weight-semibold gl-text-black-normal' : ''
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def design_url(design, opts = {})
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class User < MainClusterwide::ApplicationRecord
|
|||
|
||||
# Associations with dependent: option
|
||||
cross_database_ignore_tables(
|
||||
%w[namespaces projects project_authorizations issues merge_requests merge_requests issues issues merge_requests],
|
||||
%w[namespaces projects project_authorizations issues merge_requests merge_requests issues issues merge_requests events],
|
||||
url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/424285',
|
||||
on: :destroy
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
- event = event.present
|
||||
|
||||
- if event.visible_to_user?(current_user)
|
||||
.event-item
|
||||
.event-item{ class: current_path?('users#activity') ? 'user-profile-activity gl-border-bottom-0 gl-pl-7! gl-pb-3' : '' }
|
||||
.event-item-timestamp.gl-font-sm
|
||||
#{time_ago_with_tooltip(event.created_at)}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
.event-title.d-flex.flex-wrap
|
||||
= inline_event_icon(event)
|
||||
- if event.target
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name }
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes }
|
||||
= localized_action_name(event)
|
||||
%span.event-target-type.gl-mr-2= event.target_type_name
|
||||
%span.event-target-type.gl-mr-2{ class: user_profile_activity_classes }= event.target_type_name
|
||||
= link_to event_target_path(event), class: 'has-tooltip event-target-link gl-mr-2', title: event.target_title do
|
||||
= event.target.reference_link_text
|
||||
- unless event.milestone?
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
.event-title.d-flex.flex-wrap
|
||||
= inline_event_icon(event)
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name }
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes }
|
||||
= event.action_name
|
||||
= event_design_title_html(event)
|
||||
= render "events/event_scope", event: event
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
.event-title.d-flex.flex-wrap
|
||||
= inline_event_icon(event)
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name }
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes }
|
||||
= event.action_name
|
||||
= event_note_title_html(event)
|
||||
- title = note_target_title(event.target)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
.event-title.d-flex.flex-wrap
|
||||
= inline_event_icon(event)
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name }
|
||||
%span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes }
|
||||
= event.action_name
|
||||
= event_wiki_title_html(event)
|
||||
= render "events/event_scope", event: event
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- activity_pane_class = Feature.enabled?(:security_auto_fix) && @user.bot? ? "col-12" : "col-md-12 col-lg-6"
|
||||
- activity_pane_class = Feature.enabled?(:security_auto_fix) && @user.bot? ? "col-12" : "col-md-12 col-lg-6 gl-align-self-start"
|
||||
|
||||
.row.d-none.d-sm-flex
|
||||
.col-12.calendar-block.gl-my-3
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
%h4.gl-flex-grow-1
|
||||
= Feature.enabled?(:security_auto_fix) && @user.bot? ? s_('UserProfile|Bot activity') : s_('UserProfile|Activity')
|
||||
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
|
||||
.overview-content-list{ data: { href: user_activity_path, testid: 'user-activity-content' } }
|
||||
.overview-content-list.user-activity-content{ data: { href: user_activity_path, testid: 'user-activity-content' } }
|
||||
= gl_loading_icon(size: 'md', css_class: 'loading')
|
||||
|
||||
- unless Feature.enabled?(:security_auto_fix) && @user.bot?
|
||||
|
|
|
|||
|
|
@ -171,13 +171,15 @@
|
|||
|
||||
- if profile_tab?(:activity)
|
||||
#activity.tab-pane
|
||||
.flash-container
|
||||
- if can?(current_user, :read_cross_project)
|
||||
%h4.prepend-top-20
|
||||
= s_('UserProfile|Most Recent Activity')
|
||||
.content_list{ data: { href: user_activity_path } }
|
||||
.loading
|
||||
= gl_loading_icon(size: 'md')
|
||||
.row
|
||||
.col-12
|
||||
.flash-container
|
||||
- if can?(current_user, :read_cross_project)
|
||||
%h4.prepend-top-20
|
||||
= s_('UserProfile|Most Recent Activity')
|
||||
.content_list.user-activity-content{ data: { href: user_activity_path } }
|
||||
.loading
|
||||
= gl_loading_icon(size: 'md')
|
||||
- unless @user.bot?
|
||||
- if profile_tab?(:groups)
|
||||
#groups.tab-pane
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ module Gitlab
|
|||
module StageMethods
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
MAX_RETRIES_AFTER_INTERRUPTION = 20
|
||||
|
||||
included do
|
||||
include ApplicationWorker
|
||||
|
||||
|
|
@ -18,6 +20,29 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
class_methods do
|
||||
# We can increase the number of times a GitHubImport::Stage worker is retried
|
||||
# after being interrupted if the importer it executes can restart exactly
|
||||
# from where it left off.
|
||||
#
|
||||
# It is not safe to call this method if the importer loops over its data from
|
||||
# the beginning when restarted, even if it skips data that is already imported
|
||||
# inside the loop, as there is a possibility the importer will never reach
|
||||
# the end of the loop.
|
||||
#
|
||||
# Examples of stage workers that call this method are ones that execute services that:
|
||||
#
|
||||
# - Continue paging an endpoint from where it left off:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/487521cc/lib/gitlab/github_import/parallel_scheduling.rb#L114-117
|
||||
# - Continue their loop from where it left off:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/024235ec/lib/gitlab/github_import/importer/pull_requests/review_requests_importer.rb#L15
|
||||
def resumes_work_when_interrupted!
|
||||
return unless Feature.enabled?(:github_importer_raise_max_interruptions)
|
||||
|
||||
sidekiq_options max_retries_after_interruption: MAX_RETRIES_AFTER_INTERRUPTION
|
||||
end
|
||||
end
|
||||
|
||||
# project_id - The ID of the GitLab project to import the data into.
|
||||
def perform(project_id)
|
||||
info(project_id, message: 'starting stage')
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
# Importer::LfsObjectsImporter can resume work when interrupted as
|
||||
# it uses Projects::LfsPointers::LfsObjectDownloadListService which excludes LFS objects that already exist.
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/blob/eabf0800/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb#L69-71
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
def perform(project_id)
|
||||
return unless (project = find_project(project_id))
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Gitlab
|
|||
include GithubImport::Queue
|
||||
include StageMethods
|
||||
|
||||
resumes_work_when_interrupted!
|
||||
|
||||
# client - An instance of Gitlab::GithubImport::Client.
|
||||
# project - An instance of Project.
|
||||
def import(client, project)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: github_importer_raise_max_interruptions
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134949
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/429306
|
||||
milestone: '16.6'
|
||||
type: development
|
||||
group: group::import and integrate
|
||||
default_enabled: false
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(Gitlab::Database::SchemaCacheWithRenamedTable)
|
||||
if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('7.1')
|
||||
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(Gitlab::Database::SchemaCacheWithRenamedTable)
|
||||
else
|
||||
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(Gitlab::Database::SchemaCacheWithRenamedTableLegacy)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ feature_categories:
|
|||
description: Stores events created by users interacting with various product features
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/a847501fd2ffc1c4becc7d0d352d80168d9b3568
|
||||
milestone: "2.2"
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ feature_categories:
|
|||
description: Keeps track of counters scoped to a certain context, e.g. a project-wide counter for issues.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17580
|
||||
milestone: '10.7'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ feature_categories:
|
|||
description: User default email for commits from the GitLab UI
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101832
|
||||
milestone: '15.6'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ feature_categories:
|
|||
description: Stores topics that can be assigned to projects
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67574
|
||||
milestone: '14.3'
|
||||
gitlab_schema: gitlab_main
|
||||
gitlab_schema: gitlab_main_cell
|
||||
|
|
|
|||
|
|
@ -35,7 +35,10 @@ to community resources (such as IRC or forums) to seek help from other users.
|
|||
|
||||
## Prerequisites
|
||||
|
||||
Docker is required. See the [official installation documentation](https://docs.docker.com/get-docker/).
|
||||
To use the GitLab Docker images:
|
||||
|
||||
- You must install Docker.
|
||||
- You must use a valid externally-accessible hostname. Do not use `localhost`.
|
||||
|
||||
## Set up the volumes location
|
||||
|
||||
|
|
|
|||
|
|
@ -17,20 +17,20 @@ module Gitlab
|
|||
clear_renamed_tables_cache!
|
||||
end
|
||||
|
||||
def primary_keys(table_name)
|
||||
super(underlying_table(table_name))
|
||||
def primary_keys(connection, table_name)
|
||||
super(connection, underlying_table(table_name))
|
||||
end
|
||||
|
||||
def columns(table_name)
|
||||
super(underlying_table(table_name))
|
||||
def columns(connection, table_name)
|
||||
super(connection, underlying_table(table_name))
|
||||
end
|
||||
|
||||
def columns_hash(table_name)
|
||||
super(underlying_table(table_name))
|
||||
def columns_hash(connection, table_name)
|
||||
super(connection, underlying_table(table_name))
|
||||
end
|
||||
|
||||
def indexes(table_name)
|
||||
super(underlying_table(table_name))
|
||||
def indexes(connection, table_name)
|
||||
super(connection, underlying_table(table_name))
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -40,7 +40,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def renamed_tables_cache
|
||||
@renamed_tables ||= Gitlab::Database::TABLES_TO_BE_RENAMED.select do |old_name, new_name|
|
||||
@renamed_tables ||= Gitlab::Database::TABLES_TO_BE_RENAMED.select do |old_name, _new_name|
|
||||
connection.view_exists?(old_name)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Database
|
||||
# This is a legacy extension targeted at Rails versions prior to 7.1
|
||||
# In Rails 7.1, the method parameters have been changed to (connection, table_name)
|
||||
module SchemaCacheWithRenamedTableLegacy
|
||||
# Override methods in ActiveRecord::ConnectionAdapters::SchemaCache
|
||||
|
||||
def clear!
|
||||
super
|
||||
|
||||
clear_renamed_tables_cache!
|
||||
end
|
||||
|
||||
def clear_data_source_cache!(name)
|
||||
super(name)
|
||||
|
||||
clear_renamed_tables_cache!
|
||||
end
|
||||
|
||||
def primary_keys(table_name)
|
||||
super(underlying_table(table_name))
|
||||
end
|
||||
|
||||
def columns(table_name)
|
||||
super(underlying_table(table_name))
|
||||
end
|
||||
|
||||
def columns_hash(table_name)
|
||||
super(underlying_table(table_name))
|
||||
end
|
||||
|
||||
def indexes(table_name)
|
||||
super(underlying_table(table_name))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def underlying_table(table_name)
|
||||
renamed_tables_cache.fetch(table_name, table_name)
|
||||
end
|
||||
|
||||
def renamed_tables_cache
|
||||
@renamed_tables ||= Gitlab::Database::TABLES_TO_BE_RENAMED.select do |old_name, _new_name|
|
||||
connection.view_exists?(old_name)
|
||||
end
|
||||
end
|
||||
|
||||
def clear_renamed_tables_cache!
|
||||
@renamed_tables = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Detect user based on identifier like
|
||||
# Detect user or keys based on identifier like
|
||||
# key-13 or user-36
|
||||
module Gitlab
|
||||
module Identifier
|
||||
|
|
@ -35,6 +35,13 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
# Tries to identify a deploy key using a SSH key identifier (e.g. "key-123").
|
||||
def identify_using_deploy_key(identifier)
|
||||
key_id = identifier.gsub("key-", "")
|
||||
|
||||
DeployKey.find_by_id(key_id)
|
||||
end
|
||||
|
||||
def identify_with_cache(category, key)
|
||||
if identification_cache[category].key?(key)
|
||||
identification_cache[category][key]
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
"@cubejs-client/core": "^0.34.9",
|
||||
"@cubejs-client/vue": "^0.34.9",
|
||||
"@floating-ui/dom": "^1.2.9",
|
||||
"@gitlab/application-sdk-browser": "^0.2.8",
|
||||
"@gitlab/application-sdk-browser": "^0.2.9",
|
||||
"@gitlab/at.js": "1.5.7",
|
||||
"@gitlab/cluster-client": "^2.1.0",
|
||||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
|
|
|
|||
|
|
@ -60,15 +60,15 @@ RSpec.describe 'Overview tab on a user profile', :js, feature_category: :user_pr
|
|||
end
|
||||
end
|
||||
|
||||
describe 'user has 11 activities' do
|
||||
describe 'user has 15 activities' do
|
||||
before do
|
||||
11.times { push_code_contribution }
|
||||
16.times { push_code_contribution }
|
||||
end
|
||||
|
||||
include_context 'visit overview tab'
|
||||
|
||||
it 'displays 10 entries in the list of activities' do
|
||||
expect(find('#js-overview')).to have_selector('.event-item', count: 10)
|
||||
it 'displays 15 entries in the list of activities' do
|
||||
expect(find('#js-overview')).to have_selector('.event-item', count: 15)
|
||||
end
|
||||
|
||||
it 'shows a link to the activity list' do
|
||||
|
|
|
|||
|
|
@ -41,6 +41,69 @@ RSpec.describe EventsHelper, factory_default: :keep, feature_category: :user_pro
|
|||
end
|
||||
end
|
||||
|
||||
describe '#icon_for_profile_event' do
|
||||
let(:event) { build(:event, :joined) }
|
||||
let(:users_activity_page?) { true }
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:current_path?).and_call_original
|
||||
allow(helper).to receive(:current_path?).with('users#activity').and_return(users_activity_page?)
|
||||
end
|
||||
|
||||
context 'when on users activity page' do
|
||||
it 'gives an icon with specialized classes' do
|
||||
result = helper.icon_for_profile_event(event)
|
||||
|
||||
expect(result).to include('joined-icon')
|
||||
expect(result).to include('<svg')
|
||||
end
|
||||
|
||||
context 'with an unsupported event action_name' do
|
||||
let(:event) { build(:event, :expired) }
|
||||
|
||||
it 'does not have an icon' do
|
||||
result = helper.icon_for_profile_event(event)
|
||||
|
||||
expect(result).not_to include('<svg')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not on users activity page' do
|
||||
let(:users_activity_page?) { false }
|
||||
|
||||
it 'gives an icon with specialized classes' do
|
||||
result = helper.icon_for_profile_event(event)
|
||||
|
||||
expect(result).not_to include('joined-icon')
|
||||
expect(result).not_to include('<svg')
|
||||
expect(result).to include('<img')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#event_user_info' do
|
||||
let(:event) { build(:event) }
|
||||
let(:users_activity_page?) { true }
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:current_path?).and_call_original
|
||||
allow(helper).to receive(:current_path?).with('users#activity').and_return(users_activity_page?)
|
||||
end
|
||||
|
||||
subject { helper.event_user_info(event) }
|
||||
|
||||
context 'when on users activity page' do
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when not on users activity page' do
|
||||
let(:users_activity_page?) { false }
|
||||
|
||||
it { is_expected.to include('<div') }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#event_target_path' do
|
||||
subject { helper.event_target_path(event.present) }
|
||||
|
||||
|
|
@ -270,12 +333,26 @@ RSpec.describe EventsHelper, factory_default: :keep, feature_category: :user_pro
|
|||
|
||||
describe '#event_wiki_title_html' do
|
||||
let(:event) { create(:wiki_page_event) }
|
||||
let(:url) { helper.event_wiki_page_target_url(event) }
|
||||
let(:title) { event.target_title }
|
||||
|
||||
it 'produces a suitable title chunk' do
|
||||
url = helper.event_wiki_page_target_url(event)
|
||||
title = event.target_title
|
||||
html = [
|
||||
"<span class=\"event-target-type gl-mr-2\">wiki page</span>",
|
||||
"<span class=\"event-target-type gl-mr-2 \">wiki page</span>",
|
||||
"<a title=\"#{title}\" class=\"has-tooltip event-target-link gl-mr-2\" href=\"#{url}\">",
|
||||
title,
|
||||
"</a>"
|
||||
].join
|
||||
|
||||
expect(helper.event_wiki_title_html(event)).to eq(html)
|
||||
end
|
||||
|
||||
it 'produces a suitable title chunk on the user profile' do
|
||||
allow(helper).to receive(:user_profile_activity_classes).and_return(
|
||||
'gl-font-weight-semibold gl-text-black-normal')
|
||||
|
||||
html = [
|
||||
"<span class=\"event-target-type gl-mr-2 gl-font-weight-semibold gl-text-black-normal\">wiki page</span>",
|
||||
"<a title=\"#{title}\" class=\"has-tooltip event-target-link gl-mr-2\" href=\"#{url}\">",
|
||||
title,
|
||||
"</a>"
|
||||
|
|
@ -443,5 +520,28 @@ RSpec.describe EventsHelper, factory_default: :keep, feature_category: :user_pro
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#user_profile_activity_classes' do
|
||||
let(:users_activity_page?) { true }
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:current_path?).and_call_original
|
||||
allow(helper).to receive(:current_path?).with('users#activity').and_return(users_activity_page?)
|
||||
end
|
||||
|
||||
context 'when on the user activity page' do
|
||||
it 'returns the expected class names' do
|
||||
expect(helper.user_profile_activity_classes).to eq(' gl-font-weight-semibold gl-text-black-normal')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not on the user activity page' do
|
||||
let(:users_activity_page?) { false }
|
||||
|
||||
it 'returns an empty string' do
|
||||
expect(helper.user_profile_activity_classes).to eq('')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable RSpec/FactoryBot/AvoidCreate
|
||||
|
|
|
|||
|
|
@ -443,10 +443,10 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers,
|
|||
|
||||
describe '#ensure_batched_background_migration_is_finished' do
|
||||
let(:job_class_name) { 'CopyColumnUsingBackgroundMigrationJob' }
|
||||
let(:table_name) { 'events' }
|
||||
let(:table_name) { '_test_table' }
|
||||
let(:column_name) { :id }
|
||||
let(:job_arguments) { [["id"], ["id_convert_to_bigint"], nil] }
|
||||
let(:gitlab_schema) { Gitlab::Database::GitlabSchema.table_schema!(table_name) }
|
||||
let(:gitlab_schema) { :gitlab_main }
|
||||
|
||||
let(:configuration) do
|
||||
{
|
||||
|
|
@ -484,7 +484,7 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers,
|
|||
"\n\n" \
|
||||
"Finalize it manually by running the following command in a `bash` or `sh` shell:" \
|
||||
"\n\n" \
|
||||
"\tsudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,events,id,'[[\"id\"]\\,[\"id_convert_to_bigint\"]\\,null]']" \
|
||||
"\tsudo gitlab-rake gitlab:background_migrations:finalize[CopyColumnUsingBackgroundMigrationJob,_test_table,id,'[[\"id\"]\\,[\"id_convert_to_bigint\"]\\,null]']" \
|
||||
"\n\n" \
|
||||
"For more information, check the documentation" \
|
||||
"\n\n" \
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ RSpec.describe 'cross-database foreign keys' do
|
|||
# should be added as a comment along with the name of the column.
|
||||
let!(:allowed_cross_database_foreign_keys) do
|
||||
[
|
||||
'events.author_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/429803
|
||||
'gitlab_subscriptions.hosted_plan_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/422012
|
||||
'group_import_states.user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/421210
|
||||
'identities.saml_provider_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/422010
|
||||
|
|
@ -22,6 +23,8 @@ RSpec.describe 'cross-database foreign keys' do
|
|||
'merge_requests.updated_by_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/422080
|
||||
'merge_requests.merge_user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/422080
|
||||
'merge_requests.author_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/422080
|
||||
'namespace_commit_emails.email_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/429804
|
||||
'namespace_commit_emails.user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/429804
|
||||
'path_locks.user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/429380
|
||||
'project_authorizations.user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/422044
|
||||
'security_orchestration_policy_configurations.bot_user_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/429438
|
||||
|
|
|
|||
|
|
@ -185,4 +185,30 @@ RSpec.describe Gitlab::GithubImport::StageMethods, feature_category: :importers
|
|||
expect(worker.find_project(-1)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '.resumes_work_when_interrupted!' do
|
||||
subject(:sidekiq_options) { worker.class.sidekiq_options }
|
||||
|
||||
it 'does not set the `max_retries_after_interruption` if not called' do
|
||||
is_expected.not_to have_key('max_retries_after_interruption')
|
||||
end
|
||||
|
||||
it 'sets the `max_retries_after_interruption`' do
|
||||
worker.class.resumes_work_when_interrupted!
|
||||
|
||||
is_expected.to include('max_retries_after_interruption' => 20)
|
||||
end
|
||||
|
||||
context 'when the flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(github_importer_raise_max_interruptions: false)
|
||||
end
|
||||
|
||||
it 'does not set `max_retries_after_interruption`' do
|
||||
worker.class.resumes_work_when_interrupted!
|
||||
|
||||
is_expected.not_to have_key('max_retries_after_interruption')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
gitlab-sidekiq-fetcher (0.9.0)
|
||||
gitlab-sidekiq-fetcher (0.10.0)
|
||||
json (>= 2.5)
|
||||
sidekiq (~> 6.1)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Gem::Specification.new do |s|
|
||||
s.name = 'gitlab-sidekiq-fetcher'
|
||||
s.version = '0.9.0'
|
||||
s.version = '0.10.0'
|
||||
s.authors = ['TEA', 'GitLab']
|
||||
s.email = 'valery@gitlab.com'
|
||||
s.license = 'LGPL-3.0'
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ module Sidekiq
|
|||
max_retries_after_interruption = nil
|
||||
|
||||
max_retries_after_interruption ||= begin
|
||||
Object.const_get(worker_class).sidekiq_options[:max_retries_after_interruption]
|
||||
Object.const_get(worker_class).sidekiq_options['max_retries_after_interruption']
|
||||
rescue NameError
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,19 @@ describe Sidekiq::BaseReliableFetch do
|
|||
expect(queue2.size).to eq 1
|
||||
expect(Sidekiq::InterruptedSet.new.size).to eq 0
|
||||
end
|
||||
|
||||
it 'does not put jobs into interrupted queue if it is disabled on the worker' do
|
||||
stub_const('Bob', double(sidekiq_options: { 'max_retries_after_interruption' => -1 }))
|
||||
|
||||
uow = described_class::UnitOfWork
|
||||
interrupted_job = Sidekiq.dump_json(class: 'Bob', args: [1, 2, 'foo'], interrupted_count: 3)
|
||||
jobs = [ uow.new('queue:foo', interrupted_job), uow.new('queue:foo', job), uow.new('queue:bar', job) ]
|
||||
described_class.new(options).bulk_requeue(jobs, nil)
|
||||
|
||||
expect(queue1.size).to eq 2
|
||||
expect(queue2.size).to eq 1
|
||||
expect(Sidekiq::InterruptedSet.new.size).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
it 'sets heartbeat' do
|
||||
|
|
|
|||
|
|
@ -1211,10 +1211,10 @@
|
|||
dependencies:
|
||||
"@floating-ui/core" "^1.2.6"
|
||||
|
||||
"@gitlab/application-sdk-browser@^0.2.8":
|
||||
version "0.2.8"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/application-sdk-browser/-/application-sdk-browser-0.2.8.tgz#d4c824e44f033a4af5a11e63e18350de6b7c9228"
|
||||
integrity sha512-jVE11bWHrMHVc4B+t/QD2z1rzUP1rgSP15hHDiM48219I3uahmA5ZMeuYqldaJzimTMEEkV+bdWIA4eNiJXVFA==
|
||||
"@gitlab/application-sdk-browser@^0.2.9":
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/application-sdk-browser/-/application-sdk-browser-0.2.9.tgz#fc9069350452ce73b7409affd1615ee4d62ed728"
|
||||
integrity sha512-FnUbsyan/LTh2I9NWcfnfYLAp928FnXN4rlcitMIU2FKhhFXcVDtDaOolECBLtMM+c12teWIDn6eRzYtEd23TA==
|
||||
dependencies:
|
||||
"@snowplow/browser-plugin-client-hints" "^3.9.0"
|
||||
"@snowplow/browser-plugin-error-tracking" "^3.9.0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue