Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-03-29 03:12:19 +00:00
parent 8c9cb9bb57
commit 7d8cc770b1
147 changed files with 2063 additions and 521 deletions

View File

@ -123,6 +123,7 @@ detect-tests:
tooling/bin/partial_to_views_mappings ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_VIEWS_INCLUDING_PARTIALS_PATH};
tooling/bin/find_tests ${RSPEC_VIEWS_INCLUDING_PARTIALS_PATH} ${RSPEC_MATCHING_TESTS_PATH};
tooling/bin/js_to_system_specs_mappings ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_MATCHING_TESTS_PATH};
tooling/bin/graphql_base_type_mappings ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_MATCHING_TESTS_PATH};
tooling/bin/find_changes ${RSPEC_CHANGED_FILES_PATH} ${RSPEC_MATCHING_TESTS_PATH} ${FRONTEND_FIXTURES_MAPPING_PATH};
filter_rspec_matched_foss_tests ${RSPEC_MATCHING_TESTS_PATH} ${RSPEC_MATCHING_TESTS_FOSS_PATH};
filter_rspec_matched_ee_tests ${RSPEC_MATCHING_TESTS_PATH} ${RSPEC_MATCHING_TESTS_EE_PATH};

View File

@ -1 +1 @@
28a95b4b97a1f2b2187cccfa05feebf073d0696b
0c5b7fc851773654a7e2dedf195eb55409967284

View File

@ -1 +1 @@
v15.10.0
v15.11.0-rc1

View File

@ -1,16 +1,18 @@
<script>
import { debounce, uniq } from 'lodash';
import { GlDropdownDivider, GlDropdownItem, GlCollapsibleListbox } from '@gitlab/ui';
import { GlDropdownDivider, GlDropdownItem, GlCollapsibleListbox, GlSprintf } from '@gitlab/ui';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { __, s__, sprintf } from '~/locale';
import { convertEnvironmentScope } from '../utils';
import { ENVIRONMENT_QUERY_LIMIT } from '../constants';
export default {
name: 'CiEnvironmentsDropdown',
components: {
GlCollapsibleListbox,
GlDropdownDivider,
GlDropdownItem,
GlCollapsibleListbox,
GlSprintf,
},
mixins: [glFeatureFlagsMixin()],
props: {
@ -95,9 +97,10 @@ export default {
this.selectEnvironment(this.searchTerm);
},
},
ENVIRONMENT_QUERY_LIMIT,
i18n: {
maxEnvsNote: s__(
'CiVariable|Maximum of 20 environments listed. For more environments, enter a search query.',
'CiVariable|Maximum of %{limit} environments listed. For more environments, enter a search query.',
),
},
};
@ -117,9 +120,11 @@ export default {
<gl-dropdown-divider v-if="shouldRenderDivider" />
<div v-if="isEnvScopeLimited" data-testid="max-envs-notice">
<gl-dropdown-item class="gl-list-style-none" disabled>
<span class="gl-font-sm">
{{ $options.i18n.maxEnvsNote }}
</span>
<gl-sprintf :message="$options.i18n.maxEnvsNote" class="gl-font-sm">
<template #limit>
{{ $options.ENVIRONMENT_QUERY_LIMIT }}
</template>
</gl-sprintf>
</gl-dropdown-item>
</div>
<div v-if="shouldRenderCreateButton">

View File

@ -1,7 +1,7 @@
import { __, s__ } from '~/locale';
export const ADD_CI_VARIABLE_MODAL_ID = 'add-ci-variable';
export const ENVIRONMENT_QUERY_LIMIT = 20;
export const ENVIRONMENT_QUERY_LIMIT = 30;
export const SORT_DIRECTIONS = {
ASC: 'KEY_ASC',

View File

@ -21,7 +21,7 @@ export default {
editCommentLabel: __('Edit comment'),
deleteCommentLabel: __('Delete comment'),
moreActionsLabel: __('More actions'),
reportAbuse: __('Report abuse to administrator'),
reportAbuse: __('Report abuse'),
},
name: 'NoteActions',
components: {

View File

@ -27,7 +27,7 @@ export default {
<template>
<div
class="gl-display-flex gl-sm-align-items-center gl-flex-direction-column gl-sm-flex-direction-row gl-justify-content-space-between gl-pt-5"
class="gl-display-flex gl-sm-align-items-center gl-flex-direction-column gl-sm-flex-direction-row gl-justify-content-space-between gl-pt-5 gl-pb-3"
>
<h2 class="gl-font-size-h1 gl-m-0">{{ __('Activity') }}</h2>
<div class="gl-display-flex gl-gap-3 gl-w-full gl-sm-w-auto gl-mt-3 gl-sm-mt-0">

View File

@ -1,3 +1,5 @@
import { initLinkToSpam } from '~/abuse_reports';
import initFilePickers from '~/file_pickers';
initLinkToSpam();
initFilePickers();

View File

@ -106,7 +106,7 @@ export default {
v-if="userPermissions.canMerge"
size="small"
variant="confirm"
category="secondary"
category="tertiary"
data-testid="merge-locally-button"
class="js-check-out-modal-trigger gl-align-self-start"
>

View File

@ -983,8 +983,8 @@ $tabs-holder-z-index: 250;
.merge-request-overview {
@include media-breakpoint-up(lg) {
display: grid;
grid-template-columns: calc(95% - 285px) auto;
grid-gap: 5%;
grid-template-columns: calc(97% - 285px) auto;
grid-gap: 3%;
}
}

View File

@ -55,7 +55,7 @@ class AbuseReportsController < ApplicationController
private
def report_params
params.require(:abuse_report).permit(:message, :user_id, :category, :reported_from_url, links_to_spam: [])
params.require(:abuse_report).permit(:message, :user_id, :category, :reported_from_url, :screenshot, links_to_spam: [])
end
# rubocop: disable CodeReuse/ActiveRecord

View File

@ -10,6 +10,7 @@ module Admin
def index
@relations_by_tab = {
'queued' => batched_migration_class.queued.queue_order,
'finalizing' => batched_migration_class.finalizing.queue_order,
'failed' => batched_migration_class.with_status(:failed).queue_order,
'finished' => batched_migration_class.with_status(:finished).queue_order.reverse_order
}

View File

@ -5,7 +5,7 @@ module UploadsActions
include Gitlab::Utils::StrongMemoize
include SendFileUpload
UPLOAD_MOUNTS = %w[avatar attachment file logo pwa_icon header_logo favicon].freeze
UPLOAD_MOUNTS = %w[avatar attachment file logo pwa_icon header_logo favicon screenshot].freeze
included do
prepend_before_action :set_request_format_from_path_extension

View File

@ -16,6 +16,7 @@ class UploadsController < ApplicationController
"projects/topic" => Projects::Topic,
'alert_management_metric_image' => ::AlertManagement::MetricImage,
"achievements/achievement" => Achievements::Achievement,
"abuse_report" => AbuseReport,
nil => PersonalSnippet
}.freeze

View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
module DataTransfer
class GroupDataTransferFinder
def initialize(group:, from:, to:, user:)
@group = group
@from = from
@to = to
@user = user
end
def execute
return ::Projects::DataTransfer.none unless Ability.allowed?(user, :read_usage_quotas, group)
::Projects::DataTransfer
.with_namespace_between_dates(group, from, to)
.select('SUM(repository_egress
+ artifacts_egress
+ packages_egress
+ registry_egress
) as total_egress,
SUM(repository_egress) as repository_egress,
SUM(artifacts_egress) as artifacts_egress,
SUM(packages_egress) as packages_egress,
SUM(registry_egress) as registry_egress,
date,
namespace_id')
end
private
attr_reader :group, :from, :to, :user
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
# Mocked data for data transfer
# Follow this epic for recent progress: https://gitlab.com/groups/gitlab-org/-/epics/9330
module DataTransfer
class MockedTransferFinder
def execute
start_date = Date.new(2023, 0o1, 0o1)
date_for_index = ->(i) { (start_date + i.months).strftime('%Y-%m-%d') }
0.upto(11).map do |i|
{
date: date_for_index.call(i),
repository_egress: rand(70000..550000),
artifacts_egress: rand(70000..550000),
packages_egress: rand(70000..550000),
registry_egress: rand(70000..550000)
}.tap do |hash|
hash[:total_egress] = hash
.slice(:repository_egress, :artifacts_egress, :packages_egress, :registry_egress)
.values
.sum
end
end
end
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
module DataTransfer
class ProjectDataTransferFinder
def initialize(project:, from:, to:, user:)
@project = project
@from = from
@to = to
@user = user
end
def execute
return ::Projects::DataTransfer.none unless Ability.allowed?(user, :read_usage_quotas, project)
::Projects::DataTransfer
.with_project_between_dates(project, from, to)
.select(:project_id, :date, :repository_egress, :artifacts_egress, :packages_egress, :registry_egress,
"repository_egress + artifacts_egress + packages_egress + registry_egress as total_egress")
end
private
attr_reader :project, :from, :to, :user
end
end

View File

@ -3,8 +3,6 @@
module Mutations
module AwardEmojis
class Base < BaseMutation
include ::Mutations::FindsByGid
NOT_EMOJI_AWARDABLE = 'You cannot award emoji to this resource.'
authorize :award_emoji

View File

@ -29,12 +29,6 @@ module Mutations
errors: errors_on_object(board)
}
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -15,16 +15,12 @@ module Mutations
description: 'ID of the runner to delete.'
def resolve(id:, **runner_attrs)
runner = authorized_find!(id)
runner = authorized_find!(id: id)
::Ci::Runners::UnregisterRunnerService.new(runner, current_user).execute
{ errors: runner.errors.full_messages }
end
def find_object(id)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -27,7 +27,7 @@ module Mutations
description: 'Runner after mutation.'
def resolve(id:, **runner_attrs)
runner = authorized_find!(id)
runner = authorized_find!(id: id)
associated_projects_ids = runner_attrs.delete(:associated_projects)
@ -40,10 +40,6 @@ module Mutations
response
end
def find_object(id)
GitlabSchema.find_by_gid(id)
end
private
def associate_runner_projects(response, runner, associated_project_ids)

View File

@ -54,12 +54,6 @@ module Mutations
errors: Array.wrap(result.message)
}
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -21,12 +21,6 @@ module Mutations
{ errors: errors_on_object(token) }
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -24,12 +24,6 @@ module Mutations
errors: Array.wrap(result.message)
}
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Mutations
module FindsByGid
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end

View File

@ -4,12 +4,6 @@ module Mutations
module ContainerRepositories
class DestroyBase < Mutations::BaseMutation
include ::Mutations::PackageEventable
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -28,12 +28,6 @@ module Mutations
errors: errors_on_object(design)
}
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -53,10 +53,6 @@ module Mutations
end
end
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
def resolve!(discussion)
::Discussions::ResolveService.new(
discussion.project,

View File

@ -35,10 +35,6 @@ module Mutations
{ errors: Array.wrap(result[:message]) }
end
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
private
def certificate_based_clusters_enabled?

View File

@ -83,10 +83,6 @@ module Mutations
super(**args)
end
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
def annotation_create_params(args)
annotation_source = AnnotationSource.new(object: annotation_source(args))

View File

@ -13,12 +13,6 @@ module Mutations
Types::Notes::NoteType,
null: true,
description: 'Note after mutation.'
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -47,10 +47,6 @@ module Mutations
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
def create_note_params(noteable, args)
{
noteable: noteable,

View File

@ -23,12 +23,6 @@ module Mutations
errors: errors
}
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -21,12 +21,6 @@ module Mutations
{ errors: package_file.errors.full_messages }
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -19,7 +19,7 @@ module Mutations
description: 'Deleted release asset link.'
def resolve(id:)
link = authorized_find!(id)
link = authorized_find!(id: id)
result = ::Releases::Links::DestroyService
.new(link.release, current_user)
@ -31,10 +31,6 @@ module Mutations
{ link: nil, errors: result.message }
end
end
def find_object(id)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -44,7 +44,7 @@ module Mutations
end
def resolve(id:, **link_attrs)
link = authorized_find!(id)
link = authorized_find!(id: id)
result = ::Releases::Links::UpdateService
.new(link.release, current_user, link_attrs)
@ -56,10 +56,6 @@ module Mutations
{ link: nil, errors: result.message }
end
end
def find_object(id)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -10,12 +10,6 @@ module Mutations
Types::GlobalIDType[::Terraform::State],
required: true,
description: 'Global ID of the Terraform state.'
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -1,13 +0,0 @@
# frozen_string_literal: true
module Mutations
module Todos
class Base < ::Mutations::BaseMutation
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -2,7 +2,7 @@
module Mutations
module Todos
class Create < ::Mutations::Todos::Base
class Create < ::Mutations::BaseMutation
graphql_name 'TodoCreate'
authorize :create_todo
@ -17,7 +17,7 @@ module Mutations
description: 'To-do item created.'
def resolve(target_id:)
target = authorized_find!(target_id)
target = authorized_find!(id: target_id)
todo = TodoService.new.mark_todo(target, current_user)&.first
errors = errors_on_object(todo) if todo
@ -27,12 +27,6 @@ module Mutations
errors: errors
}
end
private
def find_object(id)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -2,7 +2,7 @@
module Mutations
module Todos
class MarkAllDone < ::Mutations::Todos::Base
class MarkAllDone < ::Mutations::BaseMutation
graphql_name 'TodosMarkAllDone'
authorize :update_user

View File

@ -2,7 +2,7 @@
module Mutations
module Todos
class MarkDone < ::Mutations::Todos::Base
class MarkDone < ::Mutations::BaseMutation
graphql_name 'TodoMarkDone'
authorize :update_todo

View File

@ -2,7 +2,7 @@
module Mutations
module Todos
class Restore < ::Mutations::Todos::Base
class Restore < ::Mutations::BaseMutation
graphql_name 'TodoRestore'
authorize :update_todo

View File

@ -2,7 +2,7 @@
module Mutations
module Todos
class RestoreMany < ::Mutations::Todos::Base
class RestoreMany < ::Mutations::BaseMutation
graphql_name 'TodoRestoreMany'
MAX_UPDATE_AMOUNT = 50

View File

@ -46,12 +46,6 @@ module Mutations
response
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -29,12 +29,6 @@ module Mutations
errors: result.errors
}
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -53,11 +53,6 @@ module Mutations
raise_resource_not_available_error!
end
end
# method used by `authorized_find!(id: id)`
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -42,10 +42,6 @@ module Mutations
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
def interpret_quick_actions!(work_item, current_user, widget_params, attributes = {})
return unless work_item.work_item_type.widgets.include?(::WorkItems::Widgets::Description)

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
module Resolvers
module DataTransfer
module DataTransferArguments
extend ActiveSupport::Concern
included do
argument :from, Types::DateType,
description:
'Retain egress data for one year. Data for the current month will increase dynamically as egress occurs.',
required: false
argument :to, Types::DateType,
description: 'End date for the data.',
required: false
end
end
end
end

View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
module Resolvers
module DataTransfer
class GroupDataTransferResolver < BaseResolver
include DataTransferArguments
include Gitlab::Graphql::Authorize::AuthorizeResource
authorizes_object!
authorize :read_usage_quotas
type Types::DataTransfer::GroupDataTransferType, null: false
alias_method :group, :object
def resolve(**args)
return { egress_nodes: [] } unless Feature.enabled?(:data_transfer_monitoring, group)
results = if Feature.enabled?(:data_transfer_monitoring_mock_data, group)
::DataTransfer::MockedTransferFinder.new.execute
else
::DataTransfer::GroupDataTransferFinder.new(
group: group,
from: args[:from],
to: args[:to],
user: current_user
).execute.map(&:attributes)
end
{ egress_nodes: results.to_a }
end
end
end
end

View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
module Resolvers
module DataTransfer
class ProjectDataTransferResolver < BaseResolver
include DataTransferArguments
include Gitlab::Graphql::Authorize::AuthorizeResource
authorizes_object!
authorize :read_usage_quotas
type Types::DataTransfer::ProjectDataTransferType, null: false
alias_method :project, :object
def resolve(**args)
return { egress_nodes: [] } unless Feature.enabled?(:data_transfer_monitoring, project.group)
results = if Feature.enabled?(:data_transfer_monitoring_mock_data, project.group)
::DataTransfer::MockedTransferFinder.new.execute
else
::DataTransfer::ProjectDataTransferFinder.new(
project: project,
from: args[:from],
to: args[:to],
user: current_user
).execute
end
{ egress_nodes: results }
end
end
end
end

View File

@ -1,59 +0,0 @@
# frozen_string_literal: true
module Resolvers
class DataTransferResolver < BaseResolver
argument :from, Types::DateType,
description: 'Retain egress data for 1 year. Current month will increase dynamically as egress occurs.',
required: false
argument :to, Types::DateType,
description: 'End date for the data.',
required: false
type ::Types::DataTransfer::BaseType, null: false
def self.source
raise NotImplementedError
end
def self.project
Class.new(self) do
type Types::DataTransfer::ProjectDataTransferType, null: false
def self.source
"Project"
end
end
end
def self.group
Class.new(self) do
type Types::DataTransfer::GroupDataTransferType, null: false
def self.source
"Group"
end
end
end
def resolve(**_args)
return unless Feature.enabled?(:data_transfer_monitoring)
# TODO: This is mock data as this feature is in development
# Follow this epic for recent progress: https://gitlab.com/groups/gitlab-org/-/epics/9330
start_date = Date.new(2023, 0o1, 0o1)
date_for_index = ->(i) { (start_date + i.months).strftime('%Y-%m-%d') }
nodes = 0.upto(11).map do |i|
{
date: date_for_index.call(i),
repository_egress: rand(70000..550000),
artifacts_egress: rand(70000..550000),
packages_egress: rand(70000..550000),
registry_egress: rand(70000..550000)
}
end
{ egress_nodes: nodes }
end
end
end

View File

@ -16,10 +16,6 @@ module Resolvers
def resolve(id:)
authorized_find!(id: id)
end
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -26,10 +26,6 @@ module Resolvers
synthetic_notes.find { |note| note.discussion_id == sha }
end
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end
end

View File

@ -13,11 +13,5 @@ module Resolvers
def resolve(id:)
authorized_find!(id: id)
end
private
def find_object(id:)
GitlabSchema.find_by_gid(id)
end
end
end

View File

@ -7,7 +7,7 @@ module Types
field :egress_nodes, type: Types::DataTransfer::EgressNodeType.connection_type,
description: 'Data nodes.',
null: true # disallow null once data_transfer_monitoring feature flag is rolled-out!
null: true # disallow null once data_transfer_monitoring feature flag is rolled-out! https://gitlab.com/gitlab-org/gitlab/-/issues/397693
end
end
end

View File

@ -26,12 +26,8 @@ module Types
null: false
field :registry_egress, GraphQL::Types::BigInt,
description: 'Registery egress for that project in that period of time.',
description: 'Registry egress for that project in that period of time.',
null: false
def total_egress
object.values.select { |x| x.is_a?(Integer) }.sum
end
end
end
end

View File

@ -8,12 +8,14 @@ module Types
field :total_egress, GraphQL::Types::BigInt,
description: 'Total egress for that project in that period of time.',
null: true # disallow null once data_transfer_monitoring feature flag is rolled-out!
null: true, # disallow null once data_transfer_monitoring feature flag is rolled-out! https://gitlab.com/gitlab-org/gitlab/-/issues/397693
extras: [:parent]
def total_egress(**_)
return unless Feature.enabled?(:data_transfer_monitoring)
def total_egress(parent:)
return unless Feature.enabled?(:data_transfer_monitoring, parent.group)
return 40_000_000 if Feature.enabled?(:data_transfer_monitoring_mock_data, parent.group)
40_000_000
object[:egress_nodes].sum('repository_egress + artifacts_egress + packages_egress + registry_egress')
end
end
end

View File

@ -241,7 +241,7 @@ module Types
field :data_transfer, Types::DataTransfer::GroupDataTransferType,
null: true,
resolver: Resolvers::DataTransferResolver.group,
resolver: Resolvers::DataTransfer::GroupDataTransferResolver,
description: 'Data transfer data point for a specific period. This is mocked data under a development feature flag.'
def label(title:)

View File

@ -567,8 +567,8 @@ module Types
description: "Find runners visible to the current user."
field :data_transfer, Types::DataTransfer::ProjectDataTransferType,
null: true, # disallow null once data_transfer_monitoring feature flag is rolled-out!
resolver: Resolvers::DataTransferResolver.project,
null: true, # disallow null once data_transfer_monitoring feature flag is rolled-out! https://gitlab.com/gitlab-org/gitlab/-/issues/391682
resolver: Resolvers::DataTransfer::ProjectDataTransferResolver,
description: 'Data transfer data point for a specific period. This is mocked data under a development feature flag.'
field :visible_forks, Types::ProjectType.connection_type,

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
module AbuseReportsHelper
def valid_image_mimetypes
Gitlab::FileTypeDetection::SAFE_IMAGE_EXT
.map { |extension| "image/#{extension}" }
.to_sentence(last_word_connector: ' or ')
end
end

View File

@ -5,6 +5,7 @@ module Admin
def batched_migration_status_badge_variant(migration)
variants = {
active: :info,
finalizing: :info,
paused: :warning,
failed: :danger,
finished: :success

View File

@ -3,8 +3,11 @@
class AbuseReport < ApplicationRecord
include CacheMarkdownField
include Sortable
include Gitlab::FileTypeDetection
include WithUploads
MAX_CHAR_LIMIT_URL = 512
MAX_FILE_SIZE = 1.megabyte
cache_markdown_field :message, pipeline: :single_line
@ -42,6 +45,10 @@ class AbuseReport < ApplicationRecord
before_validation :filter_empty_strings_from_links_to_spam
validate :links_to_spam_contains_valid_urls
mount_uploader :screenshot, AttachmentUploader
validates :screenshot, file_size: { maximum: MAX_FILE_SIZE }
validate :validate_screenshot_is_image
scope :by_user_id, ->(id) { where(user_id: id) }
scope :by_reporter_id, ->(id) { where(reporter_id: id) }
scope :by_category, ->(category) { where(category: category) }
@ -84,6 +91,20 @@ class AbuseReport < ApplicationRecord
AbuseReportMailer.notify(id).deliver_later
end
def screenshot_path
return unless screenshot
return screenshot.url unless screenshot.upload
asset_host = ActionController::Base.asset_host || Gitlab.config.gitlab.base_url
local_path = Gitlab::Routing.url_helpers.abuse_report_upload_path(
filename: screenshot.filename,
id: screenshot.upload.model_id,
model: 'abuse_report',
mounted_as: 'screenshot')
Gitlab::Utils.append_path(asset_host, local_path)
end
private
def filter_empty_strings_from_links_to_spam
@ -113,4 +134,24 @@ class AbuseReport < ApplicationRecord
rescue ::Gitlab::UrlBlocker::BlockedUrlError
errors.add(:links_to_spam, _('only supports valid HTTP(S) URLs'))
end
def filename
screenshot&.filename
end
def valid_image_extensions
Gitlab::FileTypeDetection::SAFE_IMAGE_EXT
end
def validate_screenshot_is_image
return if screenshot.blank?
return if image?
errors.add(
:screenshot,
format(
_('must match one of the following file types: %{extension_list}'),
extension_list: valid_image_extensions.to_sentence(last_word_connector: ' or '))
)
end
end

View File

@ -37,7 +37,7 @@ class PagesDeployment < ApplicationRecord
end
def store_after_commit?
Feature.enabled?(:pages_deploy_upload_file_outside_transaction)
Feature.enabled?(:pages_deploy_upload_file_outside_transaction, project)
end
strong_memoize_attr :store_after_commit?

View File

@ -13,6 +13,14 @@ module Projects
belongs_to :namespace
scope :current_month, -> { where(date: beginning_of_month) }
scope :with_project_between_dates, ->(project, from, to) {
where(project: project, date: from..to)
}
scope :with_namespace_between_dates, ->(namespace, from, to) {
where(namespace: namespace, date: from..to)
.group(:date, :namespace_id)
.order(date: :desc)
}
counter_attribute :repository_egress, returns_current: true
counter_attribute :artifacts_egress, returns_current: true

View File

@ -26,6 +26,17 @@
= f.label :reported_from
= f.text_field :reported_from_url, class: "form-control", readonly: true
#js-links-to-spam{ data: { links: Array(@abuse_report.links_to_spam) } }
.form-group.row
.col-lg-8
= f.label :screenshot do
%span
= s_('ReportAbuse|Screenshot')
.gl-font-weight-normal
= s_('ReportAbuse|Screenshot of abuse')
%div
= render 'shared/file_picker_button', f: f, field: :screenshot, help_text: _("Screenshot must be less than 1 MB."), mime_types: valid_image_mimetypes
.form-group.row
.col-lg-8
= f.label :reason

View File

@ -17,6 +17,9 @@
= gl_tab_link_to admin_background_migrations_path({ tab: nil, database: params[:database] }), item_active: @current_tab == 'queued' do
= _('Queued')
= gl_tab_counter_badge limited_counter_with_delimiter(@relations_by_tab['queued'])
= gl_tab_link_to admin_background_migrations_path({ tab: 'finalizing', database: params[:database] }), item_active: @current_tab == 'finalizing' do
= _('Finalizing')
= gl_tab_counter_badge limited_counter_with_delimiter(@relations_by_tab['finalizing'])
= gl_tab_link_to admin_background_migrations_path({ tab: 'failed', database: params[:database] }), item_active: @current_tab == 'failed' do
= _('Failed')
= gl_tab_counter_badge limited_counter_with_delimiter(@relations_by_tab['failed'])

View File

@ -1,9 +1,10 @@
- classes = local_assigns.fetch(:classes, '')
- mime_types = local_assigns.fetch(:mime_types, '')
%span.js-filepicker
= render Pajamas::ButtonComponent.new(button_options: { class: "js-filepicker-button #{classes}" }) do
= _("Choose file…")
%span.file_name.js-filepicker-filename= _("No file chosen.")
= f.file_field field, class: "js-filepicker-input hidden"
%span.file_name.gl-ml-3.js-filepicker-filename= _("No file chosen.")
= f.file_field field, class: "js-filepicker-input hidden", accept: mime_types
- if help_text.present?
.form-text.text-muted= help_text

View File

@ -1,4 +1,4 @@
- docs_link_url = help_page_path('user/project/integrations/webhooks', anchor: 'troubleshoot-webhooks')
- docs_link_url = help_page_path('user/project/integrations/webhooks', anchor: 'troubleshooting')
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
- link_end = '</a>'.html_safe

View File

@ -8,6 +8,6 @@
= c.body do
= s_('Webhooks|A webhook in this project was automatically disabled after being retried multiple times.')
= succeed '.' do
= link_to _('Learn more'), help_page_path('user/project/integrations/webhooks', anchor: 'troubleshoot-webhooks'), target: '_blank', rel: 'noopener noreferrer'
= link_to _('Learn more'), help_page_path('user/project/integrations/webhooks', anchor: 'troubleshooting'), target: '_blank', rel: 'noopener noreferrer'
= c.actions do
= link_to s_('Webhooks|Go to webhooks'), project_hooks_path(@project, anchor: 'webhooks-index'), class: 'btn gl-alert-action btn-confirm gl-button'

View File

@ -1,7 +1,7 @@
---
name: codeowners_default_owners
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113594
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/394811
name: data_transfer_monitoring_mock_data
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113392
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/397693
milestone: '15.11'
type: development
group: group::source code

View File

@ -43,6 +43,7 @@ options:
- g_analytics_ci_cd_lead_time
- g_analytics_ci_cd_time_to_restore_service
- g_analytics_ci_cd_change_failure_rate
- g_metrics_comparison_page
distribution:
- ce
- ee

View File

@ -36,6 +36,7 @@ options:
- p_analytics_ci_cd_pipelines
- p_analytics_ci_cd_deployment_frequency
- p_analytics_ci_cd_lead_time
- g_metrics_comparison_page
distribution:
- ce
- ee

View File

@ -37,6 +37,12 @@ scope path: :uploads do
to: "uploads#show",
constraints: { model: /alert_management_metric_image/, mounted_as: /file/, filename: %r{[^/]+} },
as: 'alert_metric_image_upload'
# Abuse Reports Images
get "-/system/:model/:mounted_as/:id/:filename",
to: "uploads#show",
constraints: { model: /abuse_report/, mounted_as: /screenshot/, filename: %r{[^/]+} },
as: 'abuse_report_upload'
end
# Redirect old note attachments path to new uploads path.

View File

@ -7,6 +7,6 @@
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/387299 # (required) Link to the deprecation issue in GitLab
body: | # (required) Do not modify this line, instead modify the lines below.
Cookie authentication in the GitLab for Jira Cloud app is now deprecated in favor of OAuth authentication.
You must [set up OAuth authentication](https://docs.gitlab.com/ee/integration/jira/connect-app.html#set-up-oauth-authentication)
to continue to use the GitLab for Jira Cloud app. Without OAuth, you will not be able to manage linked namespaces.
On self-managed, you must [set up OAuth authentication](https://docs.gitlab.com/ee/integration/jira/connect-app.html#set-up-oauth-authentication-for-self-managed-instances)
to continue to use the GitLab for Jira Cloud app. Without OAuth, you can't manage linked namespaces.
tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
class AddScreenshotToAbuseReports < Gitlab::Database::Migration[2.1]
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in 20230327074932_add_text_limit_to_abuse_reports_screenshot
def change
add_column :abuse_reports, :screenshot, :text
end
# rubocop:enable Migration/AddLimitToTextColumns
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddProjectAccessTokenLimitToPlanLimits < Gitlab::Database::Migration[2.1]
def change
add_column(:plan_limits, :project_access_token_limit, :integer, default: 0, null: false)
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class InsertProjectAccessTokenLimit < Gitlab::Database::Migration[2.1]
restrict_gitlab_migration gitlab_schema: :gitlab_main
def up
create_or_update_plan_limit('project_access_token_limit', 'premium_trial', 1)
create_or_update_plan_limit('project_access_token_limit', 'ultimate_trial', 1)
end
def down
create_or_update_plan_limit('project_access_token_limit', 'premium_trial', 0)
create_or_update_plan_limit('project_access_token_limit', 'ultimate_trial', 0)
end
end

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
class RerunRemoveInvalidDeployAccessLevel < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
# clean up any rows with invalid access_level entries
def up
update_column_in_batches(:protected_environment_deploy_access_levels, :access_level, nil) do |table, query|
query.where(
table.grouping(table[:user_id].not_eq(nil).or(table[:group_id].not_eq(nil)))
.and(table[:access_level].not_eq(nil)))
end
update_column_in_batches(:protected_environment_deploy_access_levels, :group_id, nil) do |table, query|
query.where(table[:user_id].not_eq(nil).and(table[:group_id].not_eq(nil)))
end
end
def down
# no-op
# we are setting access_level to NULL if group_id or user_id are present
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
class AddTextLimitToAbuseReportsScreenshot < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
def up
add_text_limit :abuse_reports, :screenshot, 255
end
def down
remove_text_limit :abuse_reports, :screenshot
end
end

View File

@ -3,20 +3,11 @@
class RemoveInvalidDeployAccessLevel < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
# clean up any rows with invalid access_level entries
def up
update_column_in_batches(:protected_environment_deploy_access_levels, :access_level, nil) do |table, query|
query.where(
table.grouping(table[:user_id].not_eq(nil).or(table[:group_id].not_eq(nil)))
.and(table[:access_level].not_eq(nil)))
end
# no-op, moved to 20230322151605_rerun_remove_invalid_deploy_access_level.rb
end
def down
# no-op
# we are setting access_level to NULL if group_id or user_id are present
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class EnsureCommitUserMentionsNoteIdBigintBackfillIsFinishedForGitlabDotCom < Gitlab::Database::Migration[2.1]
include Gitlab::Database::MigrationHelpers::ConvertToBigint
restrict_gitlab_migration gitlab_schema: :gitlab_main
disable_ddl_transaction!
def up
return unless should_run?
ensure_batched_background_migration_is_finished(
job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
table_name: 'commit_user_mentions',
column_name: 'id',
job_arguments: [['note_id'], ['note_id_convert_to_bigint']]
)
end
def down
# no-op
end
private
def should_run?
com_or_dev_or_test_but_not_jh?
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class RemoveMemberRoleDownloadCode < Gitlab::Database::Migration[2.1]
def change
remove_column :member_roles, :download_code, :boolean, default: false
end
end

View File

@ -0,0 +1,68 @@
# frozen_string_literal: true
class SwapCommitUserMentionsNoteIdToBigintForGitlabDotCom < Gitlab::Database::Migration[2.1]
include Gitlab::Database::MigrationHelpers::ConvertToBigint
disable_ddl_transaction!
TABLE_NAME = 'commit_user_mentions'
def up
return unless should_run?
swap
end
def down
return unless should_run?
swap
end
def swap
# This will replace the existing commit_user_mentions_on_commit_id_and_note_id_unique_index
add_concurrent_index TABLE_NAME, [:commit_id, :note_id_convert_to_bigint], unique: true,
name: 'commit_user_mentions_on_commit_id_and_note_id_convert_to_bigint'
# This will replace the existing index_commit_user_mentions_on_note_id
add_concurrent_index TABLE_NAME, :note_id_convert_to_bigint, unique: true,
name: 'index_commit_user_mentions_on_note_id_convert_to_bigint'
# This will replace the existing fk_rails_a6760813e0
add_concurrent_foreign_key TABLE_NAME, :notes, column: :note_id_convert_to_bigint,
name: 'fk_commit_user_mentions_note_id_convert_to_bigint',
on_delete: :cascade
with_lock_retries(raise_on_exhaustion: true) do
execute "LOCK TABLE notes, #{TABLE_NAME} IN ACCESS EXCLUSIVE MODE"
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id TO note_id_tmp"
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id_convert_to_bigint TO note_id"
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id_tmp TO note_id_convert_to_bigint"
function_name = Gitlab::Database::UnidirectionalCopyTrigger
.on_table(TABLE_NAME, connection: connection)
.name(:note_id, :note_id_convert_to_bigint)
execute "ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL"
# Swap defaults
change_column_default TABLE_NAME, :note_id, nil
change_column_default TABLE_NAME, :note_id_convert_to_bigint, 0
execute 'DROP INDEX IF EXISTS commit_user_mentions_on_commit_id_and_note_id_unique_index'
rename_index TABLE_NAME, 'commit_user_mentions_on_commit_id_and_note_id_convert_to_bigint',
'commit_user_mentions_on_commit_id_and_note_id_unique_index'
execute 'DROP INDEX IF EXISTS index_commit_user_mentions_on_note_id'
rename_index TABLE_NAME, 'index_commit_user_mentions_on_note_id_convert_to_bigint',
'index_commit_user_mentions_on_note_id'
execute "ALTER TABLE #{TABLE_NAME} DROP CONSTRAINT IF EXISTS fk_rails_a6760813e0"
rename_constraint(TABLE_NAME, 'fk_commit_user_mentions_note_id_convert_to_bigint', 'fk_rails_a6760813e0')
end
end
def should_run?
com_or_dev_or_test_but_not_jh?
end
end

View File

@ -0,0 +1 @@
86ffe1f3b8048cf01b96f66683fa68f889051c8633c6b803ffdb03aa0a8d2864

View File

@ -0,0 +1 @@
aedea3dd398210eb2d98a3ecefe3b02b518bce53d63d75160796eb0414574087

View File

@ -0,0 +1 @@
198cf0597e4a513c6c47b9cd576765d40f564838d5c54e33216fd7a5d25220ae

View File

@ -0,0 +1 @@
82c5c661c3fad14a0466e5669b59dca92084b8c77500d8ae3b97b34029277c94

View File

@ -0,0 +1 @@
efbe3f66fecfb275f8b4276cedc2210a141f4c63cc10242daafb445b352a4b70

View File

@ -0,0 +1 @@
7e3a9281e624341301d937d2422f0ff2d71367bfb42bf45ddcde7216e84ecb93

View File

@ -0,0 +1 @@
5300b4b70078fe3dadbdf42e7884dee84794c0de5b32c26b6ec46622b2a433c4

View File

@ -0,0 +1 @@
48f6ba4288122f400a0a2ef53a679cf6b4e9dc3052ec64e959066f6e30b3cd3a

View File

@ -10745,7 +10745,9 @@ CREATE TABLE abuse_reports (
links_to_spam text[] DEFAULT '{}'::text[] NOT NULL,
status smallint DEFAULT 1 NOT NULL,
resolved_at timestamp with time zone,
screenshot text,
CONSTRAINT abuse_reports_links_to_spam_length_check CHECK ((cardinality(links_to_spam) <= 20)),
CONSTRAINT check_4b0a5120e0 CHECK ((char_length(screenshot) <= 255)),
CONSTRAINT check_ab1260fa6c CHECK ((char_length(reported_from_url) <= 512))
);
@ -14462,12 +14464,12 @@ ALTER SEQUENCE clusters_kubernetes_namespaces_id_seq OWNED BY clusters_kubernete
CREATE TABLE commit_user_mentions (
id bigint NOT NULL,
note_id integer NOT NULL,
note_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
mentioned_users_ids integer[],
mentioned_projects_ids integer[],
mentioned_groups_ids integer[],
commit_id character varying NOT NULL,
note_id_convert_to_bigint bigint DEFAULT 0 NOT NULL
note_id bigint NOT NULL
);
CREATE SEQUENCE commit_user_mentions_id_seq
@ -17824,7 +17826,6 @@ CREATE TABLE member_roles (
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
base_access_level integer NOT NULL,
download_code boolean DEFAULT false,
read_code boolean DEFAULT false
);
@ -19987,7 +19988,8 @@ CREATE TABLE plan_limits (
enforcement_limit integer DEFAULT 0 NOT NULL,
notification_limit integer DEFAULT 0 NOT NULL,
dashboard_limit_enabled_at timestamp with time zone,
web_hook_calls integer DEFAULT 0 NOT NULL
web_hook_calls integer DEFAULT 0 NOT NULL,
project_access_token_limit integer DEFAULT 0 NOT NULL
);
CREATE SEQUENCE plan_limits_id_seq

View File

@ -27,7 +27,43 @@ alternatives to server hooks include:
[Geo](geo/index.md) doesn't replicate server hooks to secondary nodes.
## Create server hooks for a repository
## Set server hooks for a repository
::Tabs
:::TabTitle GitLab 15.11 and later
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/4629) in GitLab 15.11, `hooks set` command replaces direct file system access.
Prerequisites:
- The [storage name and relative path](repository_storage_types.md#from-project-name-to-hashed-path) for the repository.
To set server hooks for a repository:
1. Create tarball containing custom hooks:
1. Write the code to make the server hook function as expected. Git server hooks can be in any programming language.
Ensure the [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) at the top reflects the language type. For
example, if the script is in Ruby the shebang is probably `#!/usr/bin/env ruby`.
- To create a single server hook, create a file with a name that matches the hook type. For example, for a
`pre-receive` server hook, the filename should be `pre-receive` with no extension.
- To create many server hooks, create a directory for the hooks that matches the hook type. For example, for a
`pre-receive` server hook, the directory name should be `pre-receive.d`. Put the files for the hook in that
directory.
1. Ensure the server hook files are executable and do not match the backup file pattern (`*~`). The server hooks be
in a `custom_hooks` directory that is at the root of the tarball.
1. Create the custom hooks archive with the tar command. For example, `tar -cf custom_hooks.tar custom_hooks`.
1. Run the `hooks set` command with required options to set the Git hooks for the repository. For example,
`cat hooks.tar | gitaly hooks set --storage <storage> --repository <relative path> --config <config path>`.
- A path to a valid Gitaly configuration for the node is required to connect to the node and provided to the `--config` flag.
- Custom hooks tarball must be passed via `stdin`. For example, `cat hooks.tar | gitaly hooks set --storage <storage> --repository <relative path> --config <config path>`.
If you implemented the server hook code correctly, it should execute when the Git hook is next triggered.
:::TabTitle GitLab 15.10 and earlier
To create server hooks for a repository:
@ -55,6 +91,8 @@ To create server hooks for a repository:
If the server hook code is properly implemented, it should execute when the Git hook is next triggered.
::EndTabs
### Gitaly Cluster
If you use [Gitaly Cluster](gitaly/index.md), the scripts must be copied to every Gitaly node that has a replica of the repository. Every Gitaly node
@ -112,6 +150,16 @@ To create a global server hook for all repositories:
If the server hook code is properly implemented, it should execute when the Git hook is next triggered. Hooks are executed in alphabetical order by filename in the hook type
subdirectories.
## Remove server hooks for a repository using Gitaly CLI
> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/4629) in GitLab 15.11, `hooks set` command replaces direct file system access.
To remove hooks using the Gitaly CLI, pass an empty tarball to `hook set` to indicate that the repository should contain no hooks. For example:
```shell
cat empty_hooks.tar | gitaly hooks set --storage <storage> --repository <relative path> --config <config path>`.
```
## Chained server hooks
GitLab can execute server hooks in a chain. GitLab searches for and executes server hooks in the following order:

View File

@ -13355,7 +13355,7 @@ Returns [`[DoraMetric!]`](#dorametric).
| <a id="egressnodeartifactsegress"></a>`artifactsEgress` | [`BigInt!`](#bigint) | Artifacts egress for that project in that period of time. |
| <a id="egressnodedate"></a>`date` | [`String!`](#string) | First day of the node range. There is one node per month. |
| <a id="egressnodepackagesegress"></a>`packagesEgress` | [`BigInt!`](#bigint) | Packages egress for that project in that period of time. |
| <a id="egressnoderegistryegress"></a>`registryEgress` | [`BigInt!`](#bigint) | Registery egress for that project in that period of time. |
| <a id="egressnoderegistryegress"></a>`registryEgress` | [`BigInt!`](#bigint) | Registry egress for that project in that period of time. |
| <a id="egressnoderepositoryegress"></a>`repositoryEgress` | [`BigInt!`](#bigint) | Repository egress for that project in that period of time. |
| <a id="egressnodetotalegress"></a>`totalEgress` | [`BigInt!`](#bigint) | Total egress for that project in that period of time. |
@ -14574,7 +14574,7 @@ Returns [`GroupDataTransfer`](#groupdatatransfer).
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="groupdatatransferfrom"></a>`from` | [`Date`](#date) | Retain egress data for 1 year. Current month will increase dynamically as egress occurs. |
| <a id="groupdatatransferfrom"></a>`from` | [`Date`](#date) | Retain egress data for one year. Data for the current month will increase dynamically as egress occurs. |
| <a id="groupdatatransferto"></a>`to` | [`Date`](#date) | End date for the data. |
##### `Group.descendantGroups`
@ -18604,7 +18604,7 @@ Returns [`ProjectDataTransfer`](#projectdatatransfer).
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectdatatransferfrom"></a>`from` | [`Date`](#date) | Retain egress data for 1 year. Current month will increase dynamically as egress occurs. |
| <a id="projectdatatransferfrom"></a>`from` | [`Date`](#date) | Retain egress data for one year. Data for the current month will increase dynamically as egress occurs. |
| <a id="projectdatatransferto"></a>`to` | [`Date`](#date) | End date for the data. |
##### `Project.deployment`

View File

@ -39,31 +39,38 @@ several releases. Due to the limitations of partitioning and the related
migrations, you should understand how partitioning fits your use case
before attempting to leverage this feature.
## Determining when to use partitioning
## Determine when to use partitioning
While partitioning can be very useful when properly applied, it's
imperative to identify if the data and workload of a table naturally fit a
partitioning scheme. There are a few details you have to understand
to decide if partitioning is a good fit for your particular
problem.
partitioning scheme. Understand a few details to decide if partitioning
is a good fit for your particular problem:
First, a table is partitioned on a partition key, which is a column or
set of columns which determine how the data is split across the
partitions. The partition key is used by the database when reading or
writing data, to decide which partitions must be accessed. The
partition key should be a column that would be included in a `WHERE`
clause on almost all queries accessing that table.
- **Table partitioning**. A table is partitioned on a partition key, which is a
column or set of columns which determine how the data is split across the
partitions. The partition key is used by the database when reading or
writing data, to decide which partitions must be accessed. The
partition key should be a column that would be included in a `WHERE`
clause on almost all queries accessing that table.
Second, it's necessary to understand the strategy the database uses
to split the data across the partitions. The scheme supported by the
GitLab migration helpers is date-range partitioning, where each partition
in the table contains data for a single month. In this case, the partitioning
key must be a timestamp or date column. In order for this type of
- **How the data is split**. What strategy does the database use
to split the data across the partitions? The available choices are `range`,
`hash`, and `list`.
## Determine the appropriate partitioning strategy
The available partitioning strategy choices are `range`, `hash`, and `list`.
### Range partitioning
The scheme best supported by the GitLab migration helpers is date-range partitioning,
where each partition in the table contains data for a single month. In this case,
the partitioning key must be a timestamp or date column. For this type of
partitioning to work well, most queries must access data in a
certain date range.
For a more concrete example, the `audit_events` table can be used, which
was the first table to be partitioned in the application database
For a more concrete example, consider using the `audit_events` table.
It was the first table to be partitioned in the application database
(scheduled for deployment with the GitLab 13.5 release). This
table tracks audit entries of security events that happen in the
application. In almost all cases, users want to see audit activity that
@ -149,6 +156,31 @@ substantial. Partitioning should only be leveraged if the access patterns
of the data support the partitioning strategy, otherwise performance
suffers.
### Hash Partitioning
Hash partitioning splits a logical table into a series of partitioned
tables. Each partition corresponds to the ID range that matches
a hash and remainder. For example, if partitioning `BY HASH(id)`, rows
with `hash(id) % 64 == 1` would end up in the partition
`WITH (MODULUS 64, REMAINDER 1)`.
When hash partitioning, you must include a `WHERE hashed_column = ?` condition in
every performance-sensitive query issued by the application. If this is not possible,
hash partitioning may not be the correct fit for your use case.
Hash partitioning has one main advantage: it is the only type of partitioning that
can enforce uniqueness on a single numeric `id` column. (While also possible with
range partitioning, it's rarely the correct choice).
Hash partitioning has downsides:
- The number of partitions must be known up-front.
- It's difficult to move new data to an extra partition if current partitions become too large.
- Range queries, such as `WHERE id BETWEEN ? and ?`, are unsupported.
- Lookups by other keys, such as `WHERE other_id = ?`, are unsupported.
For this reason, it's often best to choose a large number of hash partitions to accommodate future table growth.
## Partitioning a table (Range)
Unfortunately, tables can only be partitioned at their creation, making
@ -264,6 +296,18 @@ for use by the application. This section will be updated when the
migration helper is ready, for now development can be followed in the
[Tracking Issue](https://gitlab.com/gitlab-org/gitlab/-/issues/241267).
## Partitioning a table (Hash)
Hash partitioning divides data into partitions based on a hash of their ID.
It works well only if most queries against the table include a clause like `WHERE id = ?`,
so that PostgreSQL can decide which partition to look in based on the ID or ids being requested.
Another key downside is that hash partitioning does not allow adding additional partitions after table creation.
The correct number of partitions must be chosen up-front.
Hash partitioning is the only type of partitioning (aside from some complex uses of list partitioning) that can guarantee
uniqueness of an ID across multiple partitions at the database level.
## Partitioning a table (List)
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96815) in GitLab 15.4.

View File

@ -190,26 +190,21 @@ This issue can occur when the request exceeds the
[webhook timeout](../user/project/integrations/webhooks.md#webhook-fails-or-multiple-webhook-requests-are-triggered),
which is set to 10 seconds by default.
Check the [service hook logs](../user/project/integrations/index.md#troubleshooting-integrations)
for request failures or check the `/var/log/gitlab/gitlab-rails/production.log`
file for messages like:
For this issue, check:
```plaintext
WebHook Error => Net::ReadTimeout
```
- [Integration webhook logs](../user/project/integrations/index.md#troubleshooting)
for request failures.
- `/var/log/gitlab/gitlab-rails/production.log` for messages like:
or
```plaintext
WebHook Error => Net::ReadTimeout
```
```plaintext
WebHook Error => execution expired
```
or
Or check for duplicate messages in `/var/log/gitlab/gitlab-rail`, like:
```plaintext
2019-10-25_04:22:41.25630 2019-10-25T04:22:41.256Z 1584 TID-ovowh4tek WebHookWorker JID-941fb7f40b69dff3d833c99b INFO: start
2019-10-25_04:22:41.25630 2019-10-25T04:22:41.256Z 1584 TID-ovowh4tek WebHookWorker JID-941fb7f40b69dff3d833c99b INFO: start
```
```plaintext
WebHook Error => execution expired
```
On self-managed GitLab instances, you can fix this issue by [increasing the webhook timeout value](../administration/instance_limits.md#webhook-timeout).

View File

@ -6,9 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab for Jira Cloud app **(FREE)**
You can integrate GitLab and Jira Cloud using the
[GitLab for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud)
app in the Atlassian Marketplace.
With the [GitLab for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud) app,
you can integrate GitLab and Jira Cloud.
Only Jira users with administrator access can install or configure
the GitLab for Jira Cloud app.
@ -18,7 +17,7 @@ the GitLab for Jira Cloud app.
If you use GitLab.com and Jira Cloud, you can install the GitLab for Jira Cloud app.
If you do not use both of these environments, use the [Jira DVCS Connector](dvcs/index.md) or
[install the GitLab for Jira Cloud app manually](#install-the-gitlab-for-jira-cloud-app-manually).
We recommend the GitLab for Jira Cloud app, because data is
You should use the GitLab for Jira Cloud app because data is
synchronized in real time. The DVCS connector updates data only once per hour.
To configure the GitLab for Jira Cloud app, you must have
@ -61,9 +60,9 @@ After a namespace is added:
- All future commits, branches, and merge requests of all projects under that namespace
are synced to Jira.
- From GitLab 13.8, past merge request data is synced to Jira.
- In GitLab 13.8 and later, past merge request data is synced to Jira.
Support for syncing past branch and commit data is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/263240).
For more information about syncing past branch and commit data, see [issue 263240](https://gitlab.com/gitlab-org/gitlab/-/issues/263240).
## Update the GitLab for Jira Cloud app
@ -73,15 +72,15 @@ for details.
If the app requires additional permissions, [the update must first be manually approved in Jira](https://developer.atlassian.com/platform/marketplace/upgrading-and-versioning-cloud-apps/#changes-that-require-manual-customer-approval).
## Set up OAuth authentication
## Set up OAuth authentication for self-managed instances **(FREE SELF)**
The GitLab for Jira Cloud app is [switching to OAuth authentication](https://gitlab.com/gitlab-org/gitlab/-/issues/387299).
To enable OAuth authentication, you must create an OAuth application on the GitLab instance.
Enabling OAuth authentication is:
You must enable OAuth authentication to:
- Required to [connect the GitLab for Jira Cloud app for self-managed instances](#connect-the-gitlab-for-jira-cloud-app-for-self-managed-instances).
- Recommended to [install the GitLab for Jira Cloud app manually](#install-the-gitlab-for-jira-cloud-app-manually).
- [Connect the GitLab for Jira Cloud app for self-managed instances](#connect-the-gitlab-for-jira-cloud-app-for-self-managed-instances).
- [Install the GitLab for Jira Cloud app manually](#install-the-gitlab-for-jira-cloud-app-manually).
To create an OAuth application:
@ -110,6 +109,7 @@ Prerequisites:
- GitLab.com must serve as a proxy for the instance.
- The instance must be publicly available.
- The instance must be on version 15.7 or later.
- You must set up [OAuth authentication](#set-up-oauth-authentication-for-self-managed-instances).
You can link self-managed instances after installing the GitLab for Jira Cloud app from the marketplace.
Jira apps can only link to one URL per marketplace listing. The official listing links to GitLab.com.
@ -123,7 +123,7 @@ It's not possible to create branches from Jira for self-managed instances. For m
To set up your self-managed instance for the GitLab for Jira Cloud app in GitLab 15.7 and later:
1. [Set up OAuth authentication](#set-up-oauth-authentication).
1. [Set up OAuth authentication](#set-up-oauth-authentication-for-self-managed-instances).
1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Settings > General** (`/admin/application_settings/general`).
1. Expand the **GitLab for Jira App** section.
@ -147,7 +147,7 @@ you can install the app manually.
Prerequisites:
- The instance must be publicly available.
- You must set up [OAuth authentication](#set-up-oauth-authentication).
- You must set up [OAuth authentication](#set-up-oauth-authentication-for-self-managed-instances).
### Set up your Jira app
@ -202,9 +202,9 @@ For full instructions, review the Atlassian [guide to creating a marketplace lis
To create a Marketplace listing:
1. Register as a Marketplace vendor.
1. List your application using the application descriptor URL.
1. List your application with the application descriptor URL.
- Your manifest file is located at: `https://your.domain/your-path/-/jira_connect/app_descriptor.json`
- We recommend you list your application as `private`, because public
- You should list your application as `private` because public
applications can be viewed and installed by any user.
1. Generate test license tokens for your application.
@ -212,11 +212,11 @@ NOTE:
This method uses [automated updates](#update-the-gitlab-for-jira-cloud-app)
the same way as our GitLab.com Marketplace listing.
## Configure your GitLab instance to serve as a proxy for the GitLab for Jira Cloud app
## Configure your GitLab instance to serve as a proxy for the GitLab for Jira Cloud app **(FREE SELF)**
A GitLab instance can serve as a proxy for other GitLab instances using the GitLab for Jira Cloud app.
This can be useful if you are managing multiple GitLab instance but only want to [manually install](#install-the-gitlab-for-jira-cloud-app-manually)
the GitLab for Jira app once.
A GitLab instance can serve as a proxy for other GitLab instances through the GitLab for Jira Cloud app.
You might want to use a proxy if you're managing multiple GitLab instances but only want to
[manually install](#install-the-gitlab-for-jira-cloud-app-manually) the GitLab for Jira Cloud app once.
To configure your GitLab instance to serve as a proxy:
@ -225,9 +225,36 @@ To configure your GitLab instance to serve as a proxy:
1. Expand the **GitLab for Jira App** section.
1. Select **Enable public key storage**.
1. Select **Save changes**.
1. [Install the GitLab for Jira Cloud app manually](#install-the-gitlab-for-jira-cloud-app-manually)
1. [Install the GitLab for Jira Cloud app manually](#install-the-gitlab-for-jira-cloud-app-manually).
Other GitLab instances using the proxy must configure the **Jira Connect Proxy URL** setting and the [OAuth application](#set-up-oauth-authentication) **Redirect URI** to point to the proxy instance.
Other GitLab instances that use the proxy must configure the **Jira Connect Proxy URL** and the [OAuth application](#set-up-oauth-authentication-for-self-managed-instances) **Redirect URI** settings to point to the proxy instance.
## Security considerations
The GitLab for Jira Cloud app connects GitLab and Jira. Data must be shared between the two applications, and access must be granted in both directions.
### Access to GitLab through OAuth **(FREE SELF)**
GitLab does not share an access token with Jira. However, users must authenticate through OAuth to configure the app.
An access token is retrieved through a [PKCE](https://www.rfc-editor.org/rfc/rfc7636) OAuth flow and stored only on the client side.
The app frontend that initializes the OAuth flow is a JavaScript application that's loaded from GitLab through an iframe on Jira.
The OAuth application must have the `api` scope, which grants complete read and write access to the API.
This access includes all groups and projects, the container registry, and the package registry.
However, the GitLab for Jira Cloud app only uses this access to:
- Display namespaces to be linked.
- Link namespaces.
Access through OAuth is only needed for the time a user configures the GitLab for Jira Cloud app. For more information, see [Access token expiration](../oauth_provider.md#access-token-expiration).
### Access to Jira through access token
Jira shares an access token with GitLab to authenticate and authorize data pushes to Jira.
As part of the app installation process, Jira sends a handshake request to GitLab containing the access token.
The handshake is signed with an [asymmetric JWT](https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/),
and the access token is stored encrypted with `AES256-GCM` on GitLab.
## Troubleshooting
@ -243,7 +270,7 @@ You need to sign in or sign up before continuing.
The GitLab for Jira Cloud app uses an iframe to add namespaces on the
settings page. Some browsers block cross-site cookies, which can lead to this issue.
To resolve this issue, set up [OAuth authentication](#set-up-oauth-authentication) and enable the `jira_connect_oauth` [feature flag](../../administration/feature_flags.md).
To resolve this issue, set up [OAuth authentication](#set-up-oauth-authentication-for-self-managed-instances) and enable the `jira_connect_oauth` [feature flag](../../administration/feature_flags.md).
### Manual installation fails
@ -285,29 +312,3 @@ To resolve this issue on GitLab self-managed, follow one of the solutions below,
- Contact the [Jira Software Cloud support](https://support.atlassian.com/jira-software-cloud/) and ask to trigger a new installed lifecycle event for the GitLab for Jira Cloud app in your namespace.
- In all GitLab versions:
- Re-install the GitLab for Jira Cloud app. This might remove all already synced development panel data.
## Security considerations
The GitLab for Jira Cloud app connects GitLab and Jira, as data must be shared between the two applications and access must be granted in both directions.
## Access to GitLab through OAuth
GitLab does not share an access token with Jira. However, users must authenticate via OAuth to configure the app.
An access token is retrieved via [PKCE](https://www.rfc-editor.org/rfc/rfc7636) OAuth flow, and stored only on the client side.
The app-frontend that initializes the OAuth flow is a JavaScript application, which is loaded from GitLab through an iframe on Jira.
The OAuth application requires the `api` scope that grants complete read/write access to the API, including to all groups and projects, the container registry, and the package registry.
However, the GitLab for Jira Cloud app only uses this access to:
- Display namespaces to be linked.
- Link namespaces.
Access through OAuth is only needed for the time a user configures the GitLab for Jira Cloud app. For more information, see [Access token expiration](../oauth_provider.md#access-token-expiration).
## Access to Jira through access token
Jira shares an access token with GitLab to authenticate and authorize data pushes to Jira.
As part of the app installation process, Jira sends a handshake request to GitLab containing the access token.
The handshake is signed with an [asymmetric JWT](https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/)
and the access token is stored encrypted with `AES256-GCM` on GitLab.

View File

@ -976,8 +976,8 @@ This is a [breaking change](https://docs.gitlab.com/ee/development/deprecation_g
Review the details carefully before upgrading.
Cookie authentication in the GitLab for Jira Cloud app is now deprecated in favor of OAuth authentication.
You must [set up OAuth authentication](https://docs.gitlab.com/ee/integration/jira/connect-app.html#set-up-oauth-authentication)
to continue to use the GitLab for Jira Cloud app. Without OAuth, you will not be able to manage linked namespaces.
On self-managed, you must [set up OAuth authentication](https://docs.gitlab.com/ee/integration/jira/connect-app.html#set-up-oauth-authentication-for-self-managed-instances)
to continue to use the GitLab for Jira Cloud app. Without OAuth, you can't manage linked namespaces.
</div>

View File

@ -359,7 +359,7 @@ The following package managers use lockfiles that GitLab analyzers are capable o
| Go | Not applicable | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/go-modules/gosum/default/go.sum) <sup><strong><a href="#notes-regarding-parsing-lockfiles-1">1</a></strong></sup> |
| NuGet | v1 | [4.9](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/csharp-nuget-dotnetcore/default/src/web.api/packages.lock.json#L2) |
| npm | v1, v2, v3<sup><b><a href="#notes-regarding-parsing-lockfiles-2">2</a></b></sup> | [6.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-npm/default/package-lock.json#L4), [7.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-npm/lockfileVersion2/package-lock.json#L4), [9.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/scanner/parser/npm/fixtures/lockfile-v3/simple/package-lock.json#L4) |
| yarn | v1 | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-yarn/default/yarn.lock#L2) |
| yarn | v1, v2<sup><b><a href="#notes-regarding-parsing-lockfiles-3">3</a></b></sup>, v3<sup><b><a href="#notes-regarding-parsing-lockfiles-3">3</a></b></sup> | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-yarn/default/yarn.lock#L2), [2.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-yarn-v2/default/yarn.lock), [3.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/js-yarn-v3/default/yarn.lock) |
| Poetry | v1 | [1.x](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/master/qa/fixtures/python-poetry/default/poetry.lock) |
<!-- markdownlint-disable MD044 -->
@ -377,6 +377,26 @@ The following package managers use lockfiles that GitLab analyzers are capable o
Support for <code>lockfileVersion = 3</code> was <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/365176">introduced</a> in GitLab 15.7.
</p>
</li>
<li>
<a id="notes-regarding-parsing-lockfiles-3"></a>
<p>
Support for Yarn <code>v2</code> and <code>v3</code> was <a href="https://gitlab.com/gitlab-org/gitlab/-/issues/263358">introduced in GitLab 15.11</a>. However, this feature is also available to versions of GitLab 15.0 and later.
</p>
<p>
The following features are not supported for Yarn <code>v2</code> or <code>v3</code>:
</p>
<ul>
<li>
<a href="https://yarnpkg.com/features/workspaces">workspaces</a>
</li>
<li>
<a href="https://yarnpkg.com/cli/patch">yarn patch</a>
</li>
</ul>
<p>
Yarn files that contain a patch, a workspace, or both, are still processed, but these features are ignored.
</p>
</li>
</ol>
<!-- markdownlint-enable MD044 -->

View File

@ -220,18 +220,10 @@ The following image shows a **Groups** and **Documentation** section:
![MR widget - Sectional Code Owners](img/sectional_code_owners_v13.2.png)
#### Set default owner for a section **(PREMIUM SELF)**
#### Set default owner for a section
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/371711) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `codeowners_default_owners`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `codeowners_default_owners`.
The feature is not ready for production use.
WARNING:
To disable this feature flag after setting default owners per section, edit your
CODEOWNERS file to [list Code Owners per line](#set-up-code-owners).
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/371711) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `codeowners_default_owners`. Disabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115888) in GitLab 15.11. Feature flag `codeowners_default_owners` removed.
If multiple file paths inside a section share the same ownership, define a default
Code Owner for the section. All paths in that section inherit this default, unless

Some files were not shown because too many files have changed in this diff Show More