Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-07-12 09:37:35 +00:00
parent c005943e3b
commit f2288ffc90
57 changed files with 982 additions and 276 deletions

View File

@ -1,6 +1,5 @@
<script>
import { GlTabs, GlTab } from '@gitlab/ui';
import API from '~/api';
import { mergeUrlParams, updateHistory, getParameterValues } from '~/lib/utils/url_utility';
import { InternalEvents } from '~/tracking';
import PipelineCharts from './pipeline_charts.vue';
@ -22,8 +21,8 @@ export default {
piplelinesTabEvent: 'p_analytics_ci_cd_pipelines',
deploymentFrequencyTabEvent: 'p_analytics_ci_cd_deployment_frequency',
leadTimeTabEvent: 'p_analytics_ci_cd_lead_time',
timeToRestoreServiceTabEvent: 'p_analytics_ci_cd_time_to_restore_service',
changeFailureRateTabEvent: 'p_analytics_ci_cd_change_failure_rate',
timeToRestoreServiceTabEvent: 'visit_ci_cd_time_to_restore_service_tab',
changeFailureRateTabEvent: 'visit_ci_cd_failure_rate_tab',
mixins: [InternalEvents.mixin()],
inject: {
shouldRenderDoraCharts: {
@ -77,13 +76,6 @@ export default {
updateHistory({ url: path, title: window.title });
}
},
trackTabClick(event, trackWithInternalEvents = false) {
if (trackWithInternalEvents) {
this.trackEvent(event);
return;
}
API.trackRedisHllUserEvent(event);
},
},
};
</script>
@ -93,7 +85,7 @@ export default {
<gl-tab
:title="__('Pipelines')"
data-testid="pipelines-tab"
@click="trackTabClick($options.piplelinesTabEvent, true)"
@click="trackEvent($options.piplelinesTabEvent)"
>
<pipeline-charts />
</gl-tab>
@ -101,28 +93,28 @@ export default {
<gl-tab
:title="__('Deployment frequency')"
data-testid="deployment-frequency-tab"
@click="trackTabClick($options.deploymentFrequencyTabEvent, true)"
@click="trackEvent($options.deploymentFrequencyTabEvent)"
>
<deployment-frequency-charts />
</gl-tab>
<gl-tab
:title="__('Lead time')"
data-testid="lead-time-tab"
@click="trackTabClick($options.leadTimeTabEvent, true)"
@click="trackEvent($options.leadTimeTabEvent)"
>
<lead-time-charts />
</gl-tab>
<gl-tab
:title="s__('DORA4Metrics|Time to restore service')"
data-testid="time-to-restore-service-tab"
@click="trackTabClick($options.timeToRestoreServiceTabEvent)"
@click="trackEvent($options.timeToRestoreServiceTabEvent)"
>
<time-to-restore-service-charts />
</gl-tab>
<gl-tab
:title="s__('DORA4Metrics|Change failure rate')"
data-testid="change-failure-rate-tab"
@click="trackTabClick($options.changeFailureRateTabEvent)"
@click="trackEvent($options.changeFailureRateTabEvent)"
>
<change-failure-rate-charts />
</gl-tab>

View File

@ -17,7 +17,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
before_action :authorize_read_group_member!, only: :index
before_action only: [:index] do
push_frontend_feature_flag(:bulk_import_user_mapping, @group)
push_frontend_feature_flag(:bulk_import_user_mapping, current_user)
push_frontend_feature_flag(:service_accounts_crud, @group)
push_frontend_feature_flag(:webui_members_inherited_users, current_user)
end

View File

@ -38,8 +38,8 @@ class Projects::PipelinesController < Projects::ApplicationController
track_internal_event :charts, name: 'p_analytics_ci_cd_pipelines', conditions: -> { should_track_ci_cd_pipelines? }
track_internal_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', conditions: -> { should_track_ci_cd_deployment_frequency? }
track_internal_event :charts, name: 'p_analytics_ci_cd_lead_time', conditions: -> { should_track_ci_cd_lead_time? }
track_event :charts, name: 'p_analytics_ci_cd_time_to_restore_service', conditions: -> { should_track_ci_cd_time_to_restore_service? }
track_event :charts, name: 'p_analytics_ci_cd_change_failure_rate', conditions: -> { should_track_ci_cd_change_failure_rate? }
track_internal_event :charts, name: 'visit_ci_cd_time_to_restore_service_tab', conditions: -> { should_track_visit_ci_cd_time_to_restore_service_tab? }
track_internal_event :charts, name: 'visit_ci_cd_failure_rate_tab', conditions: -> { should_track_visit_ci_cd_change_failure_tab? }
wrap_parameters Ci::Pipeline
@ -357,11 +357,11 @@ class Projects::PipelinesController < Projects::ApplicationController
params[:chart] == 'lead-time'
end
def should_track_ci_cd_time_to_restore_service?
def should_track_visit_ci_cd_time_to_restore_service_tab?
params[:chart] == 'time-to-restore-service'
end
def should_track_ci_cd_change_failure_rate?
def should_track_visit_ci_cd_change_failure_tab?
params[:chart] == 'change-failure-rate'
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
module Mutations
module WorkItems
module SharedArguments
extend ActiveSupport::Concern
included do
argument :assignees_widget,
::Types::WorkItems::Widgets::AssigneesInputType,
required: false,
description: 'Input for assignees widget.'
argument :confidential,
GraphQL::Types::Boolean,
required: false,
description: 'Sets the work item confidentiality.'
argument :description_widget,
::Types::WorkItems::Widgets::DescriptionInputType,
required: false,
description: 'Input for description widget.'
argument :milestone_widget,
::Types::WorkItems::Widgets::MilestoneInputType,
required: false,
description: 'Input for milestone widget.'
end
end
end
end

View File

@ -1,62 +0,0 @@
# frozen_string_literal: true
module Mutations
module WorkItems
module UpdateArguments
extend ActiveSupport::Concern
included do
argument :id, ::Types::GlobalIDType[::WorkItem],
required: true,
description: 'Global ID of the work item.'
argument :state_event, Types::WorkItems::StateEventEnum,
description: 'Close or reopen a work item.',
required: false
argument :title, GraphQL::Types::String,
required: false,
description: copy_field_description(Types::WorkItemType, :title)
argument :confidential, GraphQL::Types::Boolean,
required: false,
description: 'Sets the work item confidentiality.'
argument :description_widget, ::Types::WorkItems::Widgets::DescriptionInputType,
required: false,
description: 'Input for description widget.'
argument :assignees_widget, ::Types::WorkItems::Widgets::AssigneesInputType,
required: false,
description: 'Input for assignees widget.'
argument :hierarchy_widget, ::Types::WorkItems::Widgets::HierarchyUpdateInputType,
required: false,
description: 'Input for hierarchy widget.'
argument :start_and_due_date_widget, ::Types::WorkItems::Widgets::StartAndDueDateUpdateInputType,
required: false,
description: 'Input for start and due date widget.'
argument :labels_widget, ::Types::WorkItems::Widgets::LabelsUpdateInputType,
required: false,
description: 'Input for labels widget.'
argument :milestone_widget, ::Types::WorkItems::Widgets::MilestoneInputType,
required: false,
description: 'Input for milestone widget.'
argument :notifications_widget,
::Types::WorkItems::Widgets::NotificationsUpdateInputType,
required: false,
description: 'Input for notifications widget.'
argument :current_user_todos_widget,
::Types::WorkItems::Widgets::CurrentUserTodosInputType,
required: false,
description: 'Input for to-dos widget.'
argument :award_emoji_widget,
::Types::WorkItems::Widgets::AwardEmojiUpdateInputType,
required: false,
description: 'Input for emoji reactions widget.'
argument :notes_widget,
::Types::WorkItems::Widgets::NotesInputType,
required: false,
description: 'Input for notes widget.'
argument :time_tracking_widget,
::Types::WorkItems::Widgets::TimeTracking::TimeTrackingInputType,
required: false,
description: 'Input for time tracking widget.'
end
end
end
end

View File

@ -7,6 +7,7 @@ module Mutations
include Mutations::SpamProtection
include FindsNamespace
include Mutations::WorkItems::SharedArguments
include Mutations::WorkItems::Widgetable
description "Creates a work item."
@ -16,44 +17,39 @@ module Mutations
MUTUALLY_EXCLUSIVE_ARGUMENTS_ERROR = 'Please provide either projectPath or namespacePath argument, but not both.'
DISABLED_FF_ERROR = 'create_group_level_work_items feature flag is disabled. Only project paths allowed.'
argument :assignees_widget, ::Types::WorkItems::Widgets::AssigneesInputType,
required: false,
description: 'Input for assignees widget.'
argument :confidential, GraphQL::Types::Boolean,
required: false,
description: 'Sets the work item confidentiality.'
argument :description, GraphQL::Types::String,
required: false,
description: copy_field_description(Types::WorkItemType, :description),
deprecated: { milestone: '16.9', reason: 'use description widget instead' }
argument :description_widget, ::Types::WorkItems::Widgets::DescriptionInputType,
required: false,
description: 'Input for description widget.'
argument :hierarchy_widget, ::Types::WorkItems::Widgets::HierarchyCreateInputType,
required: false,
description: 'Input for hierarchy widget.'
argument :labels_widget, ::Types::WorkItems::Widgets::LabelsCreateInputType,
required: false,
description: 'Input for labels widget.'
argument :milestone_widget, ::Types::WorkItems::Widgets::MilestoneInputType,
required: false,
description: 'Input for milestone widget.'
argument :namespace_path, GraphQL::Types::ID,
required: false,
description: 'Full path of the namespace(project or group) the work item is created in.'
argument :project_path, GraphQL::Types::ID,
required: false,
description: 'Full path of the project the work item is associated with.',
deprecated: {
reason: 'Please use namespace_path instead. That will cover for both projects and groups',
milestone: '15.10'
}
argument :title, GraphQL::Types::String,
required: true,
description: copy_field_description(Types::WorkItemType, :title)
argument :work_item_type_id, ::Types::GlobalIDType[::WorkItems::Type],
required: true,
description: 'Global ID of a work item type.'
argument :description,
GraphQL::Types::String,
required: false,
description: copy_field_description(Types::WorkItemType, :description),
deprecated: { milestone: '16.9', reason: 'use description widget instead' }
argument :hierarchy_widget,
::Types::WorkItems::Widgets::HierarchyCreateInputType,
required: false,
description: 'Input for hierarchy widget.'
argument :labels_widget,
::Types::WorkItems::Widgets::LabelsCreateInputType,
required: false,
description: 'Input for labels widget.'
argument :namespace_path,
GraphQL::Types::ID,
required: false,
description: 'Full path of the namespace(project or group) the work item is created in.'
argument :project_path,
GraphQL::Types::ID,
required: false,
description: 'Full path of the project the work item is associated with.',
deprecated: {
reason: 'Please use namespace_path instead. That will cover for both projects and groups',
milestone: '15.10'
}
argument :title,
GraphQL::Types::String,
required: true,
description: copy_field_description(Types::WorkItemType, :title)
argument :work_item_type_id,
::Types::GlobalIDType[::WorkItems::Type],
required: true,
description: 'Global ID of a work item type.'
field :work_item, Types::WorkItemType,
null: true,

View File

@ -7,11 +7,56 @@ module Mutations
description "Updates a work item by Global ID."
include Mutations::SpamProtection
include Mutations::WorkItems::UpdateArguments
include Mutations::WorkItems::SharedArguments
include Mutations::WorkItems::Widgetable
authorize :read_work_item
argument :award_emoji_widget,
::Types::WorkItems::Widgets::AwardEmojiUpdateInputType,
required: false,
description: 'Input for emoji reactions widget.'
argument :current_user_todos_widget,
::Types::WorkItems::Widgets::CurrentUserTodosInputType,
required: false,
description: 'Input for to-dos widget.'
argument :hierarchy_widget,
::Types::WorkItems::Widgets::HierarchyUpdateInputType,
required: false,
description: 'Input for hierarchy widget.'
argument :id,
::Types::GlobalIDType[::WorkItem],
required: true,
description: 'Global ID of the work item.'
argument :labels_widget,
::Types::WorkItems::Widgets::LabelsUpdateInputType,
required: false,
description: 'Input for labels widget.'
argument :notes_widget,
::Types::WorkItems::Widgets::NotesInputType,
required: false,
description: 'Input for notes widget.'
argument :notifications_widget,
::Types::WorkItems::Widgets::NotificationsUpdateInputType,
required: false,
description: 'Input for notifications widget.'
argument :start_and_due_date_widget,
::Types::WorkItems::Widgets::StartAndDueDateUpdateInputType,
required: false,
description: 'Input for start and due date widget.'
argument :state_event,
Types::WorkItems::StateEventEnum,
description: 'Close or reopen a work item.',
required: false
argument :time_tracking_widget,
::Types::WorkItems::Widgets::TimeTracking::TimeTrackingInputType,
required: false,
description: 'Input for time tracking widget.'
argument :title,
GraphQL::Types::String,
required: false,
description: copy_field_description(Types::WorkItemType, :title)
field :work_item, Types::WorkItemType,
null: true,
description: 'Updated work item.'

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
module VirtualRegistries
module Packages
module Maven
def self.table_name_prefix
'virtual_registries_packages_maven_'
end
end
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
module VirtualRegistries
module Packages
module Maven
class Registry < ApplicationRecord
belongs_to :group
has_one :registry_upstream,
class_name: 'VirtualRegistries::Packages::Maven::RegistryUpstream',
inverse_of: :registry
has_one :upstream, class_name: 'VirtualRegistries::Packages::Maven::Upstream', through: :registry_upstream
validates :group, top_level_group: true, presence: true, uniqueness: true
validates :cache_validity_hours, numericality: { greater_than_or_equal_to: 0, only_integer: true }
end
end
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
module VirtualRegistries
module Packages
module Maven
class RegistryUpstream < ApplicationRecord
belongs_to :group
belongs_to :registry, class_name: 'VirtualRegistries::Packages::Maven::Registry', inverse_of: :registry_upstream
belongs_to :upstream, class_name: 'VirtualRegistries::Packages::Maven::Upstream', inverse_of: :registry_upstream
validates :registry_id, :upstream_id, uniqueness: true
validates :group, top_level_group: true, presence: true
end
end
end
end

View File

@ -0,0 +1,45 @@
# frozen_string_literal: true
module VirtualRegistries
module Packages
module Maven
class Upstream < ApplicationRecord
belongs_to :group
has_one :registry_upstream,
class_name: 'VirtualRegistries::Packages::Maven::RegistryUpstream',
inverse_of: :upstream
has_one :registry, class_name: 'VirtualRegistries::Packages::Maven::Registry', through: :registry_upstream
attr_encrypted :credentials,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_32,
algorithm: 'aes-256-gcm',
marshal: true,
marshaler: ::Gitlab::Json,
encode: false,
encode_iv: false
attribute :username, :string, default: nil
attribute :password, :string, default: nil
validates :group, top_level_group: true, presence: true
validates :url, addressable_url: { allow_localhost: false, allow_local_network: false }, presence: true
validates :username, presence: true, if: :password?
validates :password, presence: true, if: :username?
validates :url, :username, :password, length: { maximum: 255 }
after_initialize :read_credentials
before_save :write_credentials
private
def read_credentials
self.username, self.password = (credentials || {}).values_at('username', 'password')
end
def write_credentials
self.credentials = (credentials || {}).merge('username' => username, 'password' => password)
end
end
end
end
end

View File

@ -2,6 +2,7 @@
module Projects
class UpdatePagesService < BaseService
include Gitlab::InternalEventsTracking
include Gitlab::Utils::StrongMemoize
# old deployment can be cached by pages daemon
@ -33,6 +34,22 @@ module Projects
break error('The uploaded artifact size does not match the expected value') unless deployment
break error(deployment_validations.errors.first.full_message) unless deployment_validations.valid?
track_internal_event(
'create_pages_deployment',
project: project,
namespace: project.namespace,
user: build.user
)
if deployment.path_prefix.present?
track_internal_event(
'create_pages_extra_deployment',
project: project,
namespace: project.namespace,
user: build.user
)
end
deactive_old_deployments(deployment)
success
end

View File

@ -38,7 +38,7 @@ module BulkImports
log_extra_metadata_on_done(:batched, true)
BatchedRelationExportService.new(user, portable, relation, jid).execute
elsif config.user_contributions_relation?(relation)
return if Feature.disabled?(:bulk_import_user_mapping, portable)
return if Feature.disabled?(:bulk_import_user_mapping, user)
log_extra_metadata_on_done(:batched, false)
UserContributionsExportWorker.perform_async(portable_id, portable_class, user_id)

View File

@ -118,7 +118,7 @@ domains:
- dependency_management
DependencyProxy:
description:
description: Dependency Proxy for container images.
feature_categories:
- virtual_registry
- package_registry
@ -227,7 +227,7 @@ domains:
- cell
Packages:
description:
description: Package registry implementation for each supported format (such as Maven, NPM, NuGet, ...).
feature_categories:
- package_registry
- mlops
@ -310,6 +310,11 @@ domains:
feature_categories:
- consumables_cost_management
VirtualRegistries:
description: Virtual registries implementation that manage artifacts (packages or container images) from external upstreams.
feature_categories:
- virtual_registry
Vulnerabilities:
description: Vulnerability management
feature_categories:

View File

@ -0,0 +1,18 @@
---
description: GitLab Pages deployment created
internal_events: true
action: create_pages_deployment
identifiers:
- project
- namespace
- user
product_group: knowledge
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157474
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,18 @@
---
description: "Visits to the project level CI/CD Analytics Change failure rate tab"
internal_events: true
action: visit_ci_cd_failure_rate_tab
identifiers:
- project
- namespace
- user
product_group: optimize
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156593
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,18 @@
---
description: Tracks visits to the project level CI/CD Analytics Time to Restore Service tab
internal_events: true
action: visit_ci_cd_time_to_restore_service_tab
identifiers:
- project
- namespace
- user
product_group: optimize
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156593
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -49,8 +49,12 @@ events:
unique: user.id
- name: p_analytics_ci_cd_lead_time
unique: user.id
- name: visit_ci_cd_time_to_restore_service_tab
unique: user.id
- name: p_analytics_ci_cd_time_to_restore_service
unique: user.id
- name: visit_ci_cd_failure_rate_tab
unique: user.id
- name: p_analytics_ci_cd_change_failure_rate
unique: user.id
- name: g_analytics_ci_cd_release_statistics

View File

@ -7,9 +7,8 @@ status: active
milestone: "15.2"
introduced_by_url:
time_frame: 28d
data_source: redis_hll
data_source: internal_events
data_category: operational
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
@ -17,6 +16,6 @@ distribution:
tier:
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_time_to_restore_service
events:
- name: visit_ci_cd_time_to_restore_service_tab
unique: user.id

View File

@ -7,9 +7,8 @@ status: active
milestone: "15.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91726
time_frame: 28d
data_source: redis_hll
data_source: internal_events
data_category: operational
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
@ -17,6 +16,6 @@ distribution:
tier:
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_change_failure_rate
events:
- name: visit_ci_cd_failure_rate_tab
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_project_id_from_create_pages_deployment_monthly
description: Monthly count of unique projects where a Pages deployment was created
product_group: knowledge
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157474
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: create_pages_deployment
unique: project.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_create_pages_deployment_monthly
description: Monthly count of unique users who created a Pages deployment
product_group: knowledge
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157474
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: create_pages_deployment
unique: user.id

View File

@ -7,9 +7,8 @@ status: active
milestone: "15.2"
introduced_by_url:
time_frame: 7d
data_source: redis_hll
data_source: internal_events
data_category: operational
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
@ -17,6 +16,6 @@ distribution:
tier:
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_time_to_restore_service
events:
- name: visit_ci_cd_time_to_restore_service_tab
unique: user.id

View File

@ -7,9 +7,8 @@ status: active
milestone: "15.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91726
time_frame: 7d
data_source: redis_hll
data_source: internal_events
data_category: operational
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
@ -17,6 +16,6 @@ distribution:
tier:
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_change_failure_rate
events:
- name: visit_ci_cd_failure_rate_tab
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_project_id_from_create_pages_deployment_weekly
description: Weekly count of unique projects where a Pages deployment was created
product_group: knowledge
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157474
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: create_pages_deployment
unique: project.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_create_pages_deployment_weekly
description: Weekly count of unique users who created a Pages deployment
product_group: knowledge
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157474
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: create_pages_deployment
unique: user.id

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_create_pages_deployment
description: Total count of Pages deployments created
product_group: knowledge
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157474
time_frame: all
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: create_pages_deployment

View File

@ -0,0 +1,12 @@
---
table_name: virtual_registries_packages_maven_registries
classes:
- VirtualRegistries::Packages::Maven::Registry
feature_categories:
- virtual_registry
description: A virtual registry object for a packages of kind Maven.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156930
milestone: '17.2'
gitlab_schema: gitlab_main_cell
sharding_key:
group_id: namespaces

View File

@ -0,0 +1,12 @@
---
table_name: virtual_registries_packages_maven_registry_upstreams
classes:
- VirtualRegistries::Packages::Maven::RegistryUpstream
feature_categories:
- virtual_registry
description: Link a Maven Registry with a Maven Upstream.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156930
milestone: '17.2'
gitlab_schema: gitlab_main_cell
sharding_key:
group_id: namespaces

View File

@ -0,0 +1,12 @@
---
table_name: virtual_registries_packages_maven_upstreams
classes:
- VirtualRegistries::Packages::Maven::Upstream
feature_categories:
- virtual_registry
description: Upstream object for Maven Virtual Registries.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156930
milestone: '17.2'
gitlab_schema: gitlab_main_cell
sharding_key:
group_id: namespaces

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class CreateVirtualRegistriesPackagesMavenRegistries < Gitlab::Database::Migration[2.2]
milestone '17.2'
disable_ddl_transaction!
TABLE_NAME = :virtual_registries_packages_maven_registries
INDEX_NAME = 'virtual_registries_pkgs_maven_registries_on_unique_group_ids'
def up
with_lock_retries do
create_table TABLE_NAME, if_not_exists: true do |t|
t.references :group,
null: false,
index: { unique: true, name: INDEX_NAME },
foreign_key: { to_table: :namespaces, on_delete: :cascade }
t.timestamps_with_timezone null: false
t.integer :cache_validity_hours, limit: 2, null: false, default: 1
end
end
constraint = check_constraint_name(TABLE_NAME.to_s, 'cache_validity_hours', 'zero_or_positive')
add_check_constraint(TABLE_NAME, 'cache_validity_hours >= 0', constraint)
end
def down
drop_table TABLE_NAME
end
end

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
class CreateVirtualRegistriesPackagesMavenUpstreams < Gitlab::Database::Migration[2.2]
milestone '17.2'
disable_ddl_transaction!
TABLE_NAME = :virtual_registries_packages_maven_upstreams
def up
with_lock_retries do
create_table TABLE_NAME, if_not_exists: true do |t|
t.references :group,
null: false,
index: { name: 'index_virtual_reg_pkgs_maven_upstreams_on_group_id' },
foreign_key: { to_table: :namespaces, on_delete: :cascade }
t.timestamps_with_timezone null: false
t.text :url, null: false, limit: 255
t.binary :encrypted_credentials, null: true
t.binary :encrypted_credentials_iv, null: true
end
end
constraint = check_constraint_name(TABLE_NAME.to_s, 'encrypted_credentials', 'max_length')
add_check_constraint(TABLE_NAME, 'octet_length(encrypted_credentials) <= 1020', constraint)
constraint = check_constraint_name(TABLE_NAME.to_s, 'encrypted_credentials_iv', 'max_length')
add_check_constraint(TABLE_NAME, 'octet_length(encrypted_credentials_iv) <= 1020', constraint)
end
def down
drop_table TABLE_NAME
end
end

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
class CreateVirtualRegistriesPackagesMavenRegistryUpstreams < Gitlab::Database::Migration[2.2]
milestone '17.2'
disable_ddl_transaction!
TABLE_NAME = :virtual_registries_packages_maven_registry_upstreams
def up
with_lock_retries do
create_table TABLE_NAME, if_not_exists: true do |t|
t.references :group,
null: false,
index: { name: 'index_virtual_reg_pkgs_maven_reg_upstreams_on_group_id' },
foreign_key: { to_table: :namespaces, on_delete: :cascade }
t.references :registry,
null: false,
index: { unique: true, name: 'virtual_reg_packages_maven_reg_upstreams_on_unique_reg_ids' },
foreign_key: { to_table: :virtual_registries_packages_maven_registries, on_delete: :cascade }
t.references :upstream,
null: false,
index: { unique: true, name: 'virtual_reg_packages_maven_reg_upstreams_on_unique_upstream_ids' },
foreign_key: { to_table: :virtual_registries_packages_maven_upstreams, on_delete: :cascade }
t.timestamps_with_timezone null: false
end
end
end
def down
drop_table TABLE_NAME
end
end

View File

@ -0,0 +1 @@
16b265699f55b815bd1ac4e9b71242ac9b3ccfa06b91426168912fac45d6c019

View File

@ -0,0 +1 @@
aca6b5cc21a8b5f1dff79352b2a6f851fd07069af22d84925cc618a73dd49d98

View File

@ -0,0 +1 @@
39a0c550cd99b1c52e980c31f04723ba353f241474fb8d9efcb9453c695d4ed9

View File

@ -18900,6 +18900,64 @@ CREATE SEQUENCE value_stream_dashboard_counts_id_seq
ALTER SEQUENCE value_stream_dashboard_counts_id_seq OWNED BY value_stream_dashboard_counts.id;
CREATE TABLE virtual_registries_packages_maven_registries (
id bigint NOT NULL,
group_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
cache_validity_hours smallint DEFAULT 1 NOT NULL,
CONSTRAINT check_b3fbe8eb62 CHECK ((cache_validity_hours >= 0))
);
CREATE SEQUENCE virtual_registries_packages_maven_registries_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE virtual_registries_packages_maven_registries_id_seq OWNED BY virtual_registries_packages_maven_registries.id;
CREATE TABLE virtual_registries_packages_maven_registry_upstreams (
id bigint NOT NULL,
group_id bigint NOT NULL,
registry_id bigint NOT NULL,
upstream_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL
);
CREATE SEQUENCE virtual_registries_packages_maven_registry_upstreams_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE virtual_registries_packages_maven_registry_upstreams_id_seq OWNED BY virtual_registries_packages_maven_registry_upstreams.id;
CREATE TABLE virtual_registries_packages_maven_upstreams (
id bigint NOT NULL,
group_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
url text NOT NULL,
encrypted_credentials bytea,
encrypted_credentials_iv bytea,
CONSTRAINT check_26c0572777 CHECK ((char_length(url) <= 255)),
CONSTRAINT check_4af2999ab8 CHECK ((octet_length(encrypted_credentials_iv) <= 1020)),
CONSTRAINT check_b9e3bfa31a CHECK ((octet_length(encrypted_credentials) <= 1020))
);
CREATE SEQUENCE virtual_registries_packages_maven_upstreams_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE virtual_registries_packages_maven_upstreams_id_seq OWNED BY virtual_registries_packages_maven_upstreams.id;
CREATE TABLE vs_code_settings (
id bigint NOT NULL,
user_id bigint NOT NULL,
@ -21564,6 +21622,12 @@ ALTER TABLE ONLY users_statistics ALTER COLUMN id SET DEFAULT nextval('users_sta
ALTER TABLE ONLY value_stream_dashboard_counts ALTER COLUMN id SET DEFAULT nextval('value_stream_dashboard_counts_id_seq'::regclass);
ALTER TABLE ONLY virtual_registries_packages_maven_registries ALTER COLUMN id SET DEFAULT nextval('virtual_registries_packages_maven_registries_id_seq'::regclass);
ALTER TABLE ONLY virtual_registries_packages_maven_registry_upstreams ALTER COLUMN id SET DEFAULT nextval('virtual_registries_packages_maven_registry_upstreams_id_seq'::regclass);
ALTER TABLE ONLY virtual_registries_packages_maven_upstreams ALTER COLUMN id SET DEFAULT nextval('virtual_registries_packages_maven_upstreams_id_seq'::regclass);
ALTER TABLE ONLY vs_code_settings ALTER COLUMN id SET DEFAULT nextval('vs_code_settings_id_seq'::regclass);
ALTER TABLE ONLY vulnerabilities ALTER COLUMN id SET DEFAULT nextval('vulnerabilities_id_seq'::regclass);
@ -24266,6 +24330,15 @@ ALTER TABLE ONLY value_stream_dashboard_counts
ALTER TABLE ONLY verification_codes
ADD CONSTRAINT verification_codes_pkey PRIMARY KEY (created_at, visitor_id_code, code, phone);
ALTER TABLE ONLY virtual_registries_packages_maven_registries
ADD CONSTRAINT virtual_registries_packages_maven_registries_pkey PRIMARY KEY (id);
ALTER TABLE ONLY virtual_registries_packages_maven_registry_upstreams
ADD CONSTRAINT virtual_registries_packages_maven_registry_upstreams_pkey PRIMARY KEY (id);
ALTER TABLE ONLY virtual_registries_packages_maven_upstreams
ADD CONSTRAINT virtual_registries_packages_maven_upstreams_pkey PRIMARY KEY (id);
ALTER TABLE ONLY vs_code_settings
ADD CONSTRAINT vs_code_settings_pkey PRIMARY KEY (id);
@ -29535,6 +29608,10 @@ CREATE UNIQUE INDEX index_verification_codes_on_phone_and_visitor_id_code ON ONL
COMMENT ON INDEX index_verification_codes_on_phone_and_visitor_id_code IS 'JiHu-specific index';
CREATE INDEX index_virtual_reg_pkgs_maven_reg_upstreams_on_group_id ON virtual_registries_packages_maven_registry_upstreams USING btree (group_id);
CREATE INDEX index_virtual_reg_pkgs_maven_upstreams_on_group_id ON virtual_registries_packages_maven_upstreams USING btree (group_id);
CREATE UNIQUE INDEX index_vuln_findings_on_uuid_including_vuln_id_1 ON vulnerability_occurrences USING btree (uuid) INCLUDE (vulnerability_id);
CREATE UNIQUE INDEX index_vuln_historical_statistics_on_project_id_and_date ON vulnerability_historical_statistics USING btree (project_id, date);
@ -30091,6 +30168,12 @@ CREATE UNIQUE INDEX unique_zoekt_shards_uuid ON zoekt_shards USING btree (uuid);
CREATE INDEX user_follow_users_followee_id_idx ON user_follow_users USING btree (followee_id);
CREATE UNIQUE INDEX virtual_reg_packages_maven_reg_upstreams_on_unique_reg_ids ON virtual_registries_packages_maven_registry_upstreams USING btree (registry_id);
CREATE UNIQUE INDEX virtual_reg_packages_maven_reg_upstreams_on_unique_upstream_ids ON virtual_registries_packages_maven_registry_upstreams USING btree (upstream_id);
CREATE UNIQUE INDEX virtual_registries_pkgs_maven_registries_on_unique_group_ids ON virtual_registries_packages_maven_registries USING btree (group_id);
CREATE UNIQUE INDEX vulnerability_occurrence_pipelines_on_unique_keys ON vulnerability_occurrence_pipelines USING btree (occurrence_id, pipeline_id);
CREATE INDEX wi_colors_namespace_id_index ON work_item_colors USING btree (namespace_id);
@ -33775,6 +33858,9 @@ ALTER TABLE ONLY wiki_page_slugs
ALTER TABLE ONLY board_labels
ADD CONSTRAINT fk_rails_362b0600a3 FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
ALTER TABLE ONLY virtual_registries_packages_maven_upstreams
ADD CONSTRAINT fk_rails_3649ef6e9a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY merge_request_blocks
ADD CONSTRAINT fk_rails_364d4bea8b FOREIGN KEY (blocked_merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
@ -33817,6 +33903,9 @@ ALTER TABLE ONLY cluster_groups
ALTER TABLE ONLY note_diff_files
ADD CONSTRAINT fk_rails_3d66047aeb FOREIGN KEY (diff_note_id) REFERENCES notes(id) ON DELETE CASCADE;
ALTER TABLE ONLY virtual_registries_packages_maven_registry_upstreams
ADD CONSTRAINT fk_rails_3dc6bd8333 FOREIGN KEY (upstream_id) REFERENCES virtual_registries_packages_maven_upstreams(id) ON DELETE CASCADE;
ALTER TABLE ONLY snippet_user_mentions
ADD CONSTRAINT fk_rails_3e00189191 FOREIGN KEY (snippet_id) REFERENCES snippets(id) ON DELETE CASCADE;
@ -33991,6 +34080,9 @@ ALTER TABLE ONLY geo_node_namespace_links
ALTER TABLE ONLY abuse_events
ADD CONSTRAINT fk_rails_55101e588c FOREIGN KEY (abuse_report_id) REFERENCES abuse_reports(id);
ALTER TABLE ONLY virtual_registries_packages_maven_registries
ADD CONSTRAINT fk_rails_555e85e52c FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY issuable_metric_images
ADD CONSTRAINT fk_rails_56417a5a7f FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
@ -34324,6 +34416,9 @@ ALTER TABLE ONLY group_wiki_repository_states
ALTER TABLE ONLY cluster_enabled_grants
ADD CONSTRAINT fk_rails_8336ce35af FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY virtual_registries_packages_maven_registry_upstreams
ADD CONSTRAINT fk_rails_838d054752 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY dast_site_profiles
ADD CONSTRAINT fk_rails_83e309d69e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@ -34738,6 +34833,9 @@ ALTER TABLE ONLY packages_composer_cache_files
ALTER TABLE ONLY abuse_trust_scores
ADD CONSTRAINT fk_rails_b903079eb4 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE ONLY virtual_registries_packages_maven_registry_upstreams
ADD CONSTRAINT fk_rails_b991fff0be FOREIGN KEY (registry_id) REFERENCES virtual_registries_packages_maven_registries(id) ON DELETE CASCADE;
ALTER TABLE ONLY dora_configurations
ADD CONSTRAINT fk_rails_b9b8d90ddb FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;

View File

@ -395,7 +395,7 @@ You can't define Gitaly servers with some as a local Gitaly server
server (with `gitaly_address`) unless you use
[mixed configuration](#mixed-configuration).
Configure Gitaly clients in one of two ways:
Configure Gitaly clients in one of two ways. These instructions are for unencrypted connections but you can also enable [TLS support](tls_support.md):
::Tabs

View File

@ -92,7 +92,7 @@ If neither approach fixes the error, you may need a different internet service p
**If pushing over SSH**, first check your SSH configuration as 'Broken pipe'
errors can sometimes be caused by underlying issues with SSH (such as
authentication). Make sure that SSH is correctly configured by following the
instructions in the [SSH troubleshooting](../../user/ssh.md#password-prompt-with-git-clone) documentation.
instructions in the [SSH troubleshooting](../../user/ssh_troubleshooting.md#password-prompt-with-git-clone) documentation.
If you're a GitLab administrator with server access, you can also prevent
session timeouts by configuring SSH `keep-alive` on the client or the server.

View File

@ -49,6 +49,8 @@ GitLab calculates the deployment frequency from the number of finished deploymen
The calculation takes into account the production `environment tier` or the environments named `production/prod`. The environment must be part of the production deployment tier for its deployment information to appear on the graphs.
You can configure DORA metrics for different environments by specifying `other` under the `environment_tiers` parameter in the [`.gitlab/insights.yml` file](../project/insights/index.md#insights-configuration-file).
### How to improve deployment frequency
The first step is to benchmark the cadence of code releases between groups and projects. Next, you should consider:

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -50,7 +50,7 @@ DETAILS:
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
To assign multiple reviewers to a merge request, in a text area in
the merge request, use the `/assign_reviewer @user`
the merge request, use the `/assign_reviewer @user1 @user2`
[quick action](../../quick_actions.md#issues-merge-requests-and-epics), or:
1. On the left sidebar, select **Search or go to** and find your project.
@ -123,7 +123,7 @@ To submit your completed review, you can:
- Use the `/submit_review` [quick action](../../quick_actions.md) in the text of a non-review comment.
- Select **Finish review**, then select **Submit review** at the bottom of the dialog.
In the dialog, you can supply a **Summary comment**, approve the merge request, and
In the dialog, you can supply a **Summary comment**, approve (or reject) the merge request, and
include quick actions:
![Finish review with comment](img/mr_summary_comment_v16_9.png)
@ -137,8 +137,8 @@ When you submit your review, GitLab:
- Optional. Shows whether you have also approved or requested changes:
- **Comment**: Leave general feedback without explicit approval.
- **Approve**: Leave feedback and approve the changes.
- **Request changes**: Leave feedback the author should address before merging.
You can use this status to block the merge request from merging.
- **Request changes**: Block the merge request from merging until the author
addresses your feedback.
### Prevent merge when you request changes
@ -147,17 +147,24 @@ DETAILS:
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/430728) in GitLab 16.11 [with a flag](../../../../administration/feature_flags.md) named `mr_reviewer_requests_changes`. Disabled by default.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/451211) in GitLab 17.2.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158226) in GitLab 17.2 by default.
> - Enabled by default [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/451211) and [self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158226) in GitLab 17.2.
Any reviewer [requesting changes](#submit-a-review) blocks the merge request.
In the merge request reports area, it shows the message **The change requests must be completed or resolved.**
The request for changes is resolved when the reviewer who requested changes is asked
to [re-review](#re-request-a-review) and then approves the merge request.
A reviewer [requesting changes](#submit-a-review) blocks a merge request from merging.
When this happens, the merge request reports area shows the message
**The change requests must be completed or resolved.** To unblock the merge request,
the reviewer who requested changes should [re-review and approve](#re-request-a-review) the merge request.
If the user who has previously requested changes is unable to re-review or provide an approval,
users with permission to merge the merge request can override this check in the
merge request reports area by selecting **Bypass**.
If the user who requested changes is unable to re-review or provide an approval,
another user with permission to merge the merge request can override this check in the
merge request reports area by selecting **Bypass**:
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Code > Merge requests** and find your merge request.
1. Select the title of the merge request to view it.
1. On the merge request **Overview**, scroll to the merge request reports area.
1. Next to **The change requests must be completed or resolved**, select **Bypass**:
![A merge request that has been blocked by a user requesting changes](img/bypass_17_2.png)
### See how reviewers map to approval rules

View File

@ -80,7 +80,7 @@ Available documentation suggests ED25519 is more secure than RSA.
If you use an RSA key, the US National Institute of Standards and Technology in
[Publication 800-57 Part 3 (PDF)](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57Pt3r1.pdf)
recommends a key size of at least 2048 bits. Due to limitations in Go,
RSA keys [cannot exceed 8192 bits](#tls-server-sent-certificate-containing-rsa-key-larger-than-8192-bits).
RSA keys [cannot exceed 8192 bits](ssh_troubleshooting.md#tls-server-sent-certificate-containing-rsa-key-larger-than-8192-bits).
The default key size depends on your version of `ssh-keygen`.
Review the `man` page for your installed `ssh-keygen` command for details.
@ -559,68 +559,3 @@ chmod 700 /var/opt/gitlab/.ssh/
chmod 600 /var/opt/gitlab/.ssh/authorized_keys
chmod 644 /var/opt/gitlab/.ssh/authorized_keys.lock
```
## Troubleshooting
### TLS: server sent certificate containing RSA key larger than 8192 bits
In GitLab 16.3 and later, Go limits RSA keys to a maximum of 8192 bits.
To check the length of a key:
```shell
openssl rsa -in <your-key-file> -text -noout | grep "Key:"
```
Replace any key longer than 8192 bits with a shorter key.
### Password prompt with `git clone`
When you run `git clone`, you may be prompted for a password, like `git@gitlab.example.com's password:`.
This indicates that something is wrong with your SSH setup.
- Ensure that you generated your SSH key pair correctly and added the public SSH
key to your GitLab profile.
- Try to manually register your private SSH key by using `ssh-agent`.
- Try to debug the connection by running `ssh -Tv git@example.com`.
Replace `example.com` with your GitLab URL.
- Ensure you followed all the instructions in [Use SSH on Microsoft Windows](#use-ssh-on-microsoft-windows).
- Ensure that you have [Verify GitLab SSH ownership and permissions](#verify-gitlab-ssh-ownership-and-permissions). If you have several hosts ensure that permissions are correct in all hosts.
### `Could not resolve hostname` error
You may receive the following error when [verifying that you can connect](#verify-that-you-can-connect):
```shell
ssh: Could not resolve hostname gitlab.example.com: nodename nor servname provided, or not known
```
If you receive this error, restart your terminal and try the command again.
### `Key enrollment failed: invalid format` error
You may receive the following error when [generating an SSH key pair for a FIDO2 hardware security key](#generate-an-ssh-key-pair-for-a-fido2-hardware-security-key):
```shell
Key enrollment failed: invalid format
```
You can troubleshoot this by trying the following:
- Run the `ssh-keygen` command using `sudo`.
- Verify your FIDO2 hardware security key supports
the key type provided.
- Verify the version of OpenSSH is 8.2 or greater by
running `ssh -V`.
### Error: `SSH host keys are not available on this system.`
If GitLab does not have access to the host SSH keys, when you visit `gitlab.example/help/instance_configuration`, you see the following error message under the **SSH host key fingerprints** header instead of the instance SSH fingerprint:
```plaintext
SSH host keys are not available on this system. Please use ssh-keyscan command or contact your GitLab administrator for more information.
```
To resolve this error:
- On Helm chart (Kubernetes) deployments, update the `values.yaml` to set [`sshHostKeys.mount`](https://docs.gitlab.com/charts/charts/gitlab/webservice/) to `true` under the `webservice` section.
- On GitLab self-managed installations, check the `/etc/ssh` directory for the host keys.

View File

@ -0,0 +1,72 @@
---
stage: Govern
group: Authentication
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Troubleshooting SSH
When working with SSH keys, you might encounter the following issues.
## TLS: server sent certificate containing RSA key larger than 8192 bits
In GitLab 16.3 and later, Go limits RSA keys to a maximum of 8192 bits.
To check the length of a key:
```shell
openssl rsa -in <your-key-file> -text -noout | grep "Key:"
```
Replace any key longer than 8192 bits with a shorter key.
## Password prompt with `git clone`
When you run `git clone`, you may be prompted for a password, like `git@gitlab.example.com's password:`.
This indicates that something is wrong with your SSH setup.
- Ensure that you generated your SSH key pair correctly and added the public SSH
key to your GitLab profile.
- Try to manually register your private SSH key by using `ssh-agent`.
- Try to debug the connection by running `ssh -Tv git@example.com`.
Replace `example.com` with your GitLab URL.
- Ensure you followed all the instructions in [Use SSH on Microsoft Windows](ssh.md#use-ssh-on-microsoft-windows).
- Ensure that you have [Verify GitLab SSH ownership and permissions](ssh.md#verify-gitlab-ssh-ownership-and-permissions). If you have several hosts ensure that permissions are correct in all hosts.
## `Could not resolve hostname` error
You may receive the following error when [verifying that you can connect](ssh.md#verify-that-you-can-connect):
```shell
ssh: Could not resolve hostname gitlab.example.com: nodename nor servname provided, or not known
```
If you receive this error, restart your terminal and try the command again.
### `Key enrollment failed: invalid format` error
You may receive the following error when [generating an SSH key pair for a FIDO2 hardware security key](ssh.md#generate-an-ssh-key-pair-for-a-fido2-hardware-security-key):
```shell
Key enrollment failed: invalid format
```
You can troubleshoot this by trying the following:
- Run the `ssh-keygen` command using `sudo`.
- Verify your FIDO2 hardware security key supports
the key type provided.
- Verify the version of OpenSSH is 8.2 or greater by
running `ssh -V`.
## Error: `SSH host keys are not available on this system.`
If GitLab does not have access to the host SSH keys, when you visit `gitlab.example/help/instance_configuration`, you see the following error message under the **SSH host key fingerprints** header instead of the instance SSH fingerprint:
```plaintext
SSH host keys are not available on this system. Please use ssh-keyscan command or contact your GitLab administrator for more information.
```
To resolve this error:
- On Helm chart (Kubernetes) deployments, update the `values.yaml` to set [`sshHostKeys.mount`](https://docs.gitlab.com/charts/charts/gitlab/webservice/) to `true` under the `webservice` section.
- On GitLab self-managed installations, check the `/etc/ssh` directory for the host keys.

View File

@ -257,7 +257,7 @@ module Gitlab
end
def after_read_callback(record)
if Feature.enabled?(:bulk_import_user_mapping, exportable)
if Feature.enabled?(:bulk_import_user_mapping, current_user)
user_contributions_export_mapper.cache_user_contributions_on_record(record)
end

View File

@ -177,3 +177,13 @@ value_streams_dashboard_metric_link_clicked-user: value_streams_dashboard_metric
value_streams_dashboard_time_to_restore_service_link_clicked-user: value_streams_dashboard_time_to_restore_service_link_clicked
value_streams_dashboard_vulnerability_critical_link_clicked-user: value_streams_dashboard_vulnerability_critical_link_clicked
value_streams_dashboard_vulnerability_high_link_clicked-user: value_streams_dashboard_vulnerability_high_link_clicked
'view_merge_request_widget-filter:[label:accessibility]-user': i_code_review_merge_request_widget_accessibility_view
'view_merge_request_widget-filter:[label:code_quality]-user': i_code_review_merge_request_widget_code_quality_view
'view_merge_request_widget-filter:[label:license_compliance]-user': i_code_review_merge_request_widget_license_compliance_view
'view_merge_request_widget-filter:[label:status_checks]-user': i_code_review_merge_request_widget_status_checks_view
'view_merge_request_widget-filter:[label:terraform]-user': i_code_review_merge_request_widget_terraform_view
'view_merge_request_widget-filter:[label:test_summary]-user': i_code_review_merge_request_widget_test_summary_view
'view_merge_request_widget-filter:[label:metrics]-user': i_code_review_merge_request_widget_metrics_view
'view_merge_request_widget-filter:[label:security_reports]-user': i_code_review_merge_request_widget_security_reports_view
visit_ci_cd_failure_rate_tab-user: p_analytics_ci_cd_change_failure_rate
visit_ci_cd_time_to_restore_service_tab-user: p_analytics_ci_cd_time_to_restore_service

View File

@ -355,8 +355,6 @@
- merge_request_action
- o_pipeline_authoring_unique_users_committing_ciconfigfile
- o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile
- p_analytics_ci_cd_change_failure_rate
- p_analytics_ci_cd_time_to_restore_service
- p_analytics_code_reviews
- p_analytics_insights
- p_analytics_issues

View File

@ -74,7 +74,7 @@ namespace :dev do
databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
namespace :copy_db do
ALLOWED_DATABASES = %w[ci].freeze
ALLOWED_DATABASES = %w[ci sec].freeze
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
next unless ALLOWED_DATABASES.include?(name)

View File

@ -768,27 +768,17 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
[
{
chart_param: 'time-to-restore-service',
event: 'p_analytics_ci_cd_time_to_restore_service'
event: 'visit_ci_cd_time_to_restore_service_tab'
},
{
chart_param: 'change-failure-rate',
event: 'p_analytics_ci_cd_change_failure_rate'
event: 'visit_ci_cd_failure_rate_tab'
}
].each do |tab|
it_behaves_like 'tracking unique visits', :charts do
let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
let(:target_id) { ['p_analytics_pipelines', tab[:event]] }
end
it 'tracks internal events' do
request_params = { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] }
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
subject { get :charts, params: request_params, format: :html }
let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
let(:category) { described_class.name }
let(:action) { 'perform_analytics_usage_action' }
let(:namespace) { project.namespace }
let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' }
let(:property) { 'p_analytics_pipelines' }
expect { get :charts, params: request_params, format: :html }.to trigger_internal_events(tab[:event])
end
end

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
FactoryBot.define do
factory :virtual_registries_packages_maven_registry, class: 'VirtualRegistries::Packages::Maven::Registry' do
group
cache_validity_hours { 1 }
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
FactoryBot.define do
factory :virtual_registries_packages_maven_registry_upstream,
class: 'VirtualRegistries::Packages::Maven::RegistryUpstream' do
group { registry.group }
registry { association(:virtual_registries_packages_maven_registry) }
upstream do
association(
:virtual_registries_packages_maven_upstream,
group: registry.group,
registry: registry,
registry_upstream: nil
)
end
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
FactoryBot.define do
factory :virtual_registries_packages_maven_upstream, class: 'VirtualRegistries::Packages::Maven::Upstream' do
url { 'http://local.test/maven' }
username { 'user' }
password { 'password' }
registry { association(:virtual_registries_packages_maven_registry) }
group { registry.group }
after(:build) do |entry, _|
entry.registry_upstream.group = entry.group if entry.registry_upstream
end
end
end

View File

@ -123,28 +123,14 @@ describe('ProjectsPipelinesChartsApp', () => {
});
describe('event tracking', () => {
describe('RedisHLL events', () => {
it.each`
testId | event
${'time-to-restore-service-tab'} | ${'p_analytics_ci_cd_time_to_restore_service'}
${'change-failure-rate-tab'} | ${'p_analytics_ci_cd_change_failure_rate'}
`('tracks the $event event when clicked', ({ testId, event }) => {
const trackApiSpy = jest.spyOn(API, 'trackRedisHllUserEvent');
expect(trackApiSpy).not.toHaveBeenCalled();
wrapper.findByTestId(testId).vm.$emit('click');
expect(trackApiSpy).toHaveBeenCalledWith(event);
});
});
describe('Internal Events RedisHLL events', () => {
it.each`
testId | event
${'pipelines-tab'} | ${'p_analytics_ci_cd_pipelines'}
${'deployment-frequency-tab'} | ${'p_analytics_ci_cd_deployment_frequency'}
${'lead-time-tab'} | ${'p_analytics_ci_cd_lead_time'}
testId | event
${'pipelines-tab'} | ${'p_analytics_ci_cd_pipelines'}
${'deployment-frequency-tab'} | ${'p_analytics_ci_cd_deployment_frequency'}
${'lead-time-tab'} | ${'p_analytics_ci_cd_lead_time'}
${'time-to-restore-service-tab'} | ${'visit_ci_cd_time_to_restore_service_tab'}
${'change-failure-rate-tab'} | ${'visit_ci_cd_failure_rate_tab'}
`('tracks the $event event when clicked', ({ testId, event }) => {
const trackApiSpy = jest.spyOn(API, 'trackInternalEvent');
@ -177,18 +163,6 @@ describe('ProjectsPipelinesChartsApp', () => {
},
});
});
it.each`
tab
${'time-to-restore-service-tab'}
${'change-failure-rate-tab'}
`('does not track when tab $tab is clicked', ({ tab }) => {
const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
wrapper.findByTestId(tab).vm.$emit('click');
expect(trackingSpy).not.toHaveBeenCalled();
});
});
});
});

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe VirtualRegistries::Packages::Maven::Registry, type: :model, feature_category: :virtual_registry do
subject(:registry) { build(:virtual_registries_packages_maven_registry) }
describe 'associations' do
it { is_expected.to belong_to(:group) }
it do
is_expected.to have_one(:registry_upstream)
.class_name('VirtualRegistries::Packages::Maven::RegistryUpstream')
.inverse_of(:registry)
end
it do
is_expected.to have_one(:upstream)
.through(:registry_upstream)
.class_name('VirtualRegistries::Packages::Maven::Upstream')
end
end
describe 'validations' do
it { is_expected.to validate_uniqueness_of(:group) }
it { is_expected.to validate_presence_of(:group) }
it { is_expected.to validate_numericality_of(:cache_validity_hours).only_integer.is_greater_than_or_equal_to(0) }
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe VirtualRegistries::Packages::Maven::RegistryUpstream, type: :model, feature_category: :virtual_registry do
subject(:registry_upstream) { build(:virtual_registries_packages_maven_registry_upstream) }
describe 'associations' do
it { is_expected.to belong_to(:group) }
it do
is_expected.to belong_to(:registry)
.class_name('VirtualRegistries::Packages::Maven::Registry')
.inverse_of(:registry_upstream)
end
it do
is_expected.to belong_to(:upstream)
.class_name('VirtualRegistries::Packages::Maven::Upstream')
.inverse_of(:registry_upstream)
end
end
describe 'validations' do
it { is_expected.to validate_presence_of(:group) }
it { is_expected.to validate_uniqueness_of(:registry_id) }
it { is_expected.to validate_uniqueness_of(:upstream_id) }
end
end

View File

@ -0,0 +1,106 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe VirtualRegistries::Packages::Maven::Upstream, type: :model, feature_category: :virtual_registry do
using RSpec::Parameterized::TableSyntax
subject(:upstream) { build(:virtual_registries_packages_maven_upstream) }
describe 'associations' do
it do
is_expected.to have_one(:registry_upstream)
.class_name('VirtualRegistries::Packages::Maven::RegistryUpstream')
.inverse_of(:upstream)
end
it do
is_expected.to have_one(:registry)
.through(:registry_upstream)
.class_name('VirtualRegistries::Packages::Maven::Registry')
end
end
describe 'validations' do
it { is_expected.to validate_presence_of(:group) }
it { is_expected.to validate_presence_of(:url) }
it { is_expected.to validate_presence_of(:username) }
it { is_expected.to validate_presence_of(:password) }
it { is_expected.to validate_length_of(:url).is_at_most(255) }
it { is_expected.to validate_length_of(:username).is_at_most(255) }
it { is_expected.to validate_length_of(:password).is_at_most(255) }
context 'for url' do
where(:url, :valid, :error_messages) do
'http://test.maven' | true | nil
'https://test.maven' | true | nil
'git://test.maven' | false | ['Url is blocked: Only allowed schemes are http, https']
nil | false | ["Url can't be blank", 'Url must be a valid URL']
'' | false | ["Url can't be blank", 'Url must be a valid URL']
"http://#{'a' * 255}" | false | 'Url is too long (maximum is 255 characters)'
'http://127.0.0.1' | false | 'Url is blocked: Requests to localhost are not allowed'
'maven.local' | false | 'Url is blocked: Only allowed schemes are http, https'
'http://192.168.1.2' | false | 'Url is blocked: Requests to the local network are not allowed'
end
with_them do
before do
upstream.url = url
end
if params[:valid]
it { expect(upstream).to be_valid }
else
it do
expect(upstream).not_to be_valid
expect(upstream.errors).to contain_exactly(*error_messages)
end
end
end
end
context 'for credentials' do
where(:username, :password, :valid, :error_message) do
'user' | 'password' | true | nil
'' | '' | true | nil
'' | nil | true | nil
nil | '' | true | nil
nil | 'password' | false | "Username can't be blank"
'user' | nil | false | "Password can't be blank"
'' | 'password' | false | "Username can't be blank"
'user' | '' | false | "Password can't be blank"
('a' * 256) | 'password' | false | 'Username is too long (maximum is 255 characters)'
'user' | ('a' * 256) | false | 'Password is too long (maximum is 255 characters)'
end
with_them do
before do
upstream.username = username
upstream.password = password
end
if params[:valid]
it { expect(upstream).to be_valid }
else
it do
expect(upstream).not_to be_valid
expect(upstream.errors).to contain_exactly(error_message)
end
end
end
end
end
context 'for credentials persistance' do
it 'persists and reads back credentials properly' do
upstream.username = 'test'
upstream.password = 'test'
upstream.save!
upstream_read = upstream.reload
expect(upstream_read.username).to eq('test')
expect(upstream_read.password).to eq('test')
end
end
end

View File

@ -160,6 +160,14 @@ RSpec.describe Projects::UpdatePagesService, feature_category: :pages do
.by(1)
end
it_behaves_like 'internal event tracking' do
let(:event) { 'create_pages_deployment' }
let(:category) { 'Projects::UpdatePagesService' }
let(:namespace) { project.namespace }
subject(:track_event) { service.execute }
end
context 'when archive does not have pages directory' do
let(:file) { empty_file }
let(:metadata_filename) { empty_metadata_filename }