Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-10-26 21:10:31 +00:00
parent ea413f31cf
commit 277496b843
55 changed files with 387 additions and 337 deletions

View File

@ -63,7 +63,7 @@ and cross-posted (with the command results) to the responsible team's Slack chan
Cross link the issue here if it does. Cross link the issue here if it does.
- [ ] Ensure that you or a representative in development can be available for at least 2 hours after feature flag updates in production. - [ ] Ensure that you or a representative in development can be available for at least 2 hours after feature flag updates in production.
If a different developer will be covering, or an exception is needed, please inform the oncall SRE by using the `@sre-oncall` Slack alias. If a different developer will be covering, or an exception is needed, please inform the oncall SRE by using the `@sre-oncall` Slack alias.
- [ ] Ensure that [documentation has been updated](https://docs.gitlab.com/ee/development/documentation/feature_flags.html). - [ ] Ensure that documentation exists for the feature, and the [version history text](https://docs.gitlab.com/ee/development/documentation/feature_flags.html#add-version-history-text) has been updated.
- [ ] Leave a comment on [the feature issue][main-issue] announcing estimated time when this feature flag will be enabled on GitLab.com. - [ ] Leave a comment on [the feature issue][main-issue] announcing estimated time when this feature flag will be enabled on GitLab.com.
- [ ] Ensure that any breaking changes have been announced following the [release post process](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-removals-and-breaking-changes) to ensure GitLab customers are aware. - [ ] Ensure that any breaking changes have been announced following the [release post process](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-removals-and-breaking-changes) to ensure GitLab customers are aware.
- [ ] Notify the [`#support_gitlab-com` Slack channel](https://gitlab.slack.com/archives/C4XFU81LG) and your team channel ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#communicate-the-change)). - [ ] Notify the [`#support_gitlab-com` Slack channel](https://gitlab.slack.com/archives/C4XFU81LG) and your team channel ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#communicate-the-change)).

View File

@ -483,9 +483,9 @@ BackgroundMigration/FeatureCategory:
Include: Include:
- 'lib/gitlab/background_migration/*.rb' - 'lib/gitlab/background_migration/*.rb'
BackgroundMigration/MissingDictionaryFile: BackgroundMigration/DictionaryFile:
Enabled: true Enabled: true
EnforcedSince: 20230307160251 EnforcedSince: 20231018100907
Include: Include:
- 'db/post_migrate/*.rb' - 'db/post_migrate/*.rb'

View File

@ -0,0 +1,4 @@
---
# Grace period will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/428931
BackgroundMigration/DictionaryFile:
Details: grace period

View File

@ -36,8 +36,7 @@ export default function initDiffsApp(store = notesStore) {
iid: dataset.iid || '', iid: dataset.iid || '',
endpointCoverage: dataset.endpointCoverage || '', endpointCoverage: dataset.endpointCoverage || '',
endpointCodequality: dataset.endpointCodequality || '', endpointCodequality: dataset.endpointCodequality || '',
// This is a workaround which will be solved in: https://gitlab.com/gitlab-org/gitlab/-/issues/428758 sastReportAvailable: dataset.endpointSast,
sastReportAvailable: Boolean(dataset.endpointSast),
helpPagePath: dataset.helpPagePath, helpPagePath: dataset.helpPagePath,
currentUser: JSON.parse(dataset.currentUserData) || {}, currentUser: JSON.parse(dataset.currentUserData) || {},
changesEmptyStateIllustration: dataset.changesEmptyStateIllustration, changesEmptyStateIllustration: dataset.changesEmptyStateIllustration,

View File

@ -657,7 +657,6 @@ $discord: #5865f2;
$linkedin: #2867b2; $linkedin: #2867b2;
$mastodon: #6364ff; $mastodon: #6364ff;
$skype: #0078d7; $skype: #0078d7;
$twitter: #1d9bf0;
/* /*
* Award emoji * Award emoji

View File

@ -235,7 +235,7 @@
} }
.twitter-icon { .twitter-icon {
color: $twitter; color: var(--gl-text-color, $gl-text-color);
} }
.discord-icon { .discord-icon {

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class AcmeChallengesController < BaseActionController # rubocop:disable Rails/ApplicationController
class AcmeChallengesController < ActionController::Base
def show def show
if acme_order if acme_order
render plain: acme_order.challenge_file_content, content_type: 'text/plain' render plain: acme_order.challenge_file_content, content_type: 'text/plain'
@ -15,3 +16,4 @@ class AcmeChallengesController < BaseActionController
@acme_order ||= PagesDomainAcmeOrder.find_by_domain_and_token(params[:domain], params[:token]) @acme_order ||= PagesDomainAcmeOrder.find_by_domain_and_token(params[:domain], params[:token])
end end
end end
# rubocop:enable Rails/ApplicationController

View File

@ -3,7 +3,7 @@
require 'gon' require 'gon'
require 'fogbugz' require 'fogbugz'
class ApplicationController < BaseActionController class ApplicationController < ActionController::Base
include Gitlab::GonHelper include Gitlab::GonHelper
include Gitlab::NoCacheHeaders include Gitlab::NoCacheHeaders
include GitlabRoutingHelper include GitlabRoutingHelper

View File

@ -1,31 +0,0 @@
# frozen_string_literal: true
# GitLab lightweight base action controller
#
# This class should be limited to content that
# is desired/required for *all* controllers in
# GitLab.
#
# Most controllers inherit from `ApplicationController`.
# Some controllers don't want or need all of that
# logic and instead inherit from `ActionController::Base`.
# This makes it difficult to set security headers and
# handle other critical logic across *all* controllers.
#
# Between this controller and `ApplicationController`
# no controller should ever inherit directly from
# `ActionController::Base`
#
# rubocop:disable Rails/ApplicationController
# rubocop:disable Gitlab/NamespacedClass
class BaseActionController < ActionController::Base
before_action :security_headers
private
def security_headers
headers['Cross-Origin-Opener-Policy'] = 'same-origin' if ::Feature.enabled?(:coop_header)
end
end
# rubocop:enable Gitlab/NamespacedClass
# rubocop:enable Rails/ApplicationController

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class ChaosController < BaseActionController # rubocop:disable Rails/ApplicationController
class ChaosController < ActionController::Base
before_action :validate_chaos_secret, unless: :development_or_test? before_action :validate_chaos_secret, unless: :development_or_test?
def leakmem def leakmem
@ -94,3 +95,4 @@ class ChaosController < BaseActionController
Rails.env.development? || Rails.env.test? Rails.env.development? || Rails.env.test?
end end
end end
# rubocop:enable Rails/ApplicationController

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class HealthController < BaseActionController # rubocop:disable Rails/ApplicationController
class HealthController < ActionController::Base
protect_from_forgery with: :exception, prepend: true protect_from_forgery with: :exception, prepend: true
include RequiresAllowlistedMonitoringClient include RequiresAllowlistedMonitoringClient
@ -39,3 +40,4 @@ class HealthController < BaseActionController
render json: result.json, status: result.http_status render json: result.json, status: result.http_status
end end
end end
# rubocop:enable Rails/ApplicationController

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class MetricsController < BaseActionController # rubocop:disable Rails/ApplicationController
class MetricsController < ActionController::Base
include RequiresAllowlistedMonitoringClient include RequiresAllowlistedMonitoringClient
protect_from_forgery with: :exception, prepend: true protect_from_forgery with: :exception, prepend: true
@ -35,3 +36,4 @@ class MetricsController < BaseActionController
) )
end end
end end
# rubocop:enable Rails/ApplicationController

View File

@ -1,4 +1,4 @@
%p.text-center %p{ class: local_assigns.fetch(:wrapper_class, 'gl-text-center') }
%span.light %span.light
= _('Already have an account?') = _('Already have an account?')
- path_params = { redirect_to_referer: 'yes' } - path_params = { redirect_to_referer: 'yes' }

View File

@ -1,77 +1,10 @@
- max_first_name_length = max_last_name_length = 127
- borderless ||= false - borderless ||= false
- form_resource_name = "new_#{resource_name}"
.gl-mb-3.gl-p-4{ class: (borderless ? '' : 'gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-base') } .gl-mb-3.gl-p-4{ class: (borderless ? '' : 'gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-base') }
= yield :omniauth_providers_top if show_omniauth_providers = yield :omniauth_providers_top if show_omniauth_providers
= gitlab_ui_form_for(resource, as: form_resource_name, url: url, html: { class: 'gl-show-field-errors js-arkose-labs-form', aria: { live: 'assertive' }}, data: { testid: 'signup-form' }) do |f| = render 'devise/shared/signup_box_form',
.devise-errors button_text: button_text,
= render 'devise/shared/error_messages', resource: resource url: url,
- if Gitlab::CurrentSettings.invisible_captcha_enabled show_omniauth_providers: omniauth_enabled? && button_based_providers_enabled?
= invisible_captcha nonce: true, autocomplete: SecureRandom.alphanumeric(12)
.name.form-row
.col.form-group
= f.label :first_name, _('First name'), for: 'new_user_first_name'
= f.text_field :first_name,
class: 'form-control gl-form-input top js-block-emoji js-validate-length',
data: { max_length: max_first_name_length,
max_length_message: s_('SignUp|First name is too long (maximum is %{max_length} characters).') % { max_length: max_first_name_length },
testid: 'new-user-first-name-field' },
required: true,
title: _('This field is required.')
.col.form-group
= f.label :last_name, _('Last name'), for: 'new_user_last_name'
= f.text_field :last_name,
class: 'form-control gl-form-input top js-block-emoji js-validate-length',
data: { max_length: max_last_name_length,
max_length_message: s_('SignUp|Last name is too long (maximum is %{max_length} characters).') % { max_length: max_last_name_length },
testid: 'new-user-last-name-field' },
required: true,
title: _('This field is required.')
.username.form-group
= f.label :username, _('Username')
= f.text_field :username,
class: 'form-control gl-form-input middle js-block-emoji js-validate-length js-validate-username',
data: signup_username_data_attributes,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
required: true,
title: _('Please create a username with only alphanumeric characters.')
%p.validation-error.gl-text-red-500.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is already taken.')
%p.validation-success.gl-text-green-600.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is available.')
%p.validation-pending.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Checking username availability...')
.form-group
= f.label :email, _('Email')
= f.email_field :email,
class: 'form-control gl-form-input middle js-validate-email',
data: { testid: 'new-user-email-field' },
required: true,
title: _('Please provide a valid email address.')
%p.validation-hint.gl-field-hint.text-secondary= _('We recommend a work email address.')
%p.validation-warning.gl-field-error-ignore.text-secondary.hide= _('This email address does not look right, are you sure you typed it correctly?')
-# This is used for providing entry to Jihu on email verification
= render_if_exists 'devise/shared/signup_email_additional_info'
.form-group.gl-mb-5
= f.label :password, _('Password')
%input.form-control.gl-form-input.js-password{ data: { id: "#{form_resource_name}_password",
title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length },
minimum_password_length: @minimum_password_length,
testid: 'new-user-password-field',
autocomplete: 'new-password',
name: "#{form_resource_name}[password]" } }
%p.gl-field-hint-valid.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
= render_if_exists 'shared/password_requirements_list'
= render_if_exists 'devise/shared/phone_verification', form: f
.form-group
- if arkose_labs_enabled?
= render_if_exists 'devise/registrations/arkose_labs'
- elsif show_recaptcha_sign_up?
= recaptcha_tags nonce: content_security_policy_nonce
= render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true, button_options: { data: { testid: 'new-user-register-button' }}) do
= button_text
= render 'devise/shared/terms_of_service_notice', button_text: button_text
= yield :omniauth_providers_bottom if show_omniauth_providers

View File

@ -0,0 +1,73 @@
- max_first_name_length = max_last_name_length = 127
- form_resource_name = "new_#{resource_name}"
= gitlab_ui_form_for(resource, as: form_resource_name, url: url, html: { class: 'gl-show-field-errors js-arkose-labs-form', aria: { live: 'assertive' }}, data: { testid: 'signup-form' }) do |f|
.devise-errors
= render 'devise/shared/error_messages', resource: resource
- if Gitlab::CurrentSettings.invisible_captcha_enabled
= invisible_captcha nonce: true, autocomplete: SecureRandom.alphanumeric(12)
.name.form-row
.col.form-group
= f.label :first_name, _('First name'), for: 'new_user_first_name'
= f.text_field :first_name,
class: 'form-control gl-form-input top js-block-emoji js-validate-length',
data: { max_length: max_first_name_length,
max_length_message: s_('SignUp|First name is too long (maximum is %{max_length} characters).') % { max_length: max_first_name_length },
testid: 'new-user-first-name-field' },
required: true,
title: _('This field is required.')
.col.form-group
= f.label :last_name, _('Last name'), for: 'new_user_last_name'
= f.text_field :last_name,
class: 'form-control gl-form-input top js-block-emoji js-validate-length',
data: { max_length: max_last_name_length,
max_length_message: s_('SignUp|Last name is too long (maximum is %{max_length} characters).') % { max_length: max_last_name_length },
testid: 'new-user-last-name-field' },
required: true,
title: _('This field is required.')
.username.form-group
= f.label :username, _('Username')
= f.text_field :username,
class: 'form-control gl-form-input middle js-block-emoji js-validate-length js-validate-username',
data: signup_username_data_attributes,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
required: true,
title: _('Please create a username with only alphanumeric characters.')
%p.validation-error.gl-text-red-500.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is already taken.')
%p.validation-success.gl-text-green-600.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Username is available.')
%p.validation-pending.gl-field-error-ignore.gl-mt-2.field-validation.hide= _('Checking username availability...')
.form-group
= f.label :email, _('Email')
= f.email_field :email,
class: 'form-control gl-form-input middle js-validate-email',
data: { testid: 'new-user-email-field' },
required: true,
title: _('Please provide a valid email address.')
%p.validation-hint.gl-field-hint.text-secondary= _('We recommend a work email address.')
%p.validation-warning.gl-field-error-ignore.text-secondary.hide= _('This email address does not look right, are you sure you typed it correctly?')
-# This is used for providing entry to Jihu on email verification
= render_if_exists 'devise/shared/signup_email_additional_info'
.form-group.gl-mb-5
= f.label :password, _('Password')
%input.form-control.gl-form-input.js-password{ data: { id: "#{form_resource_name}_password",
title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length },
minimum_password_length: @minimum_password_length,
testid: 'new-user-password-field',
autocomplete: 'new-password',
name: "#{form_resource_name}[password]" } }
%p.gl-field-hint-valid.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
= render_if_exists 'shared/password_requirements_list'
= render_if_exists 'devise/shared/phone_verification', form: f
.form-group
- if arkose_labs_enabled?
= render_if_exists 'devise/registrations/arkose_labs'
- elsif show_recaptcha_sign_up?
= recaptcha_tags nonce: content_security_policy_nonce
= render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, block: true, button_options: { data: { testid: 'new-user-register-button' }}) do
= button_text
= render 'devise/shared/terms_of_service_notice', button_text: button_text
= yield :omniauth_providers_bottom if show_omniauth_providers

View File

@ -14,7 +14,10 @@
= _("Create an account using:") = _("Create an account using:")
.gl-display-flex.gl-justify-content-between.gl-flex-wrap .gl-display-flex.gl-justify-content-between.gl-flex-wrap
- providers.each do |provider| - providers.each do |provider|
= button_to omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)), class: "btn gl-button btn-default gl-w-full gl-mb-4 js-oauth-login #{qa_selector_for_provider(provider)}", data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label }, id: "oauth-login-#{provider}" do = button_to omniauth_authorize_path(:user, provider, register_omniauth_params(local_assigns)),
class: "btn gl-button btn-default gl-w-full gl-mb-4 js-oauth-login #{qa_selector_for_provider(provider)}",
data: { provider: provider, track_action: "#{provider}_sso", track_label: tracking_label },
id: "oauth-login-#{provider}" do
- if provider_has_icon?(provider) - if provider_has_icon?(provider)
= provider_image_tag(provider) = provider_image_tag(provider)
%span.gl-button-text %span.gl-button-text

View File

@ -1,8 +0,0 @@
---
name: coop_header
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131571
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/425701
milestone: '16.5'
type: development
group: group::authentication
default_enabled: false

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# rubocop: disable BackgroundMigration/MissingDictionaryFile # rubocop: disable BackgroundMigration/DictionaryFile
class RescheduleMigrationForRemediation < Gitlab::Database::Migration[2.1] class RescheduleMigrationForRemediation < Gitlab::Database::Migration[2.1]
MIGRATION = 'MigrateRemediationsForVulnerabilityFindings' MIGRATION = 'MigrateRemediationsForVulnerabilityFindings'
@ -29,4 +29,4 @@ class RescheduleMigrationForRemediation < Gitlab::Database::Migration[2.1]
delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, []) delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, [])
end end
end end
# rubocop: enable BackgroundMigration/MissingDictionaryFile # rubocop: enable BackgroundMigration/DictionaryFile

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# rubocop:disable BackgroundMigration/MissingDictionaryFile # rubocop:disable BackgroundMigration/DictionaryFile
class RequeueBackfillProjectWikiRepositories < Gitlab::Database::Migration[2.1] class RequeueBackfillProjectWikiRepositories < Gitlab::Database::Migration[2.1]
MIGRATION = "BackfillProjectWikiRepositories" MIGRATION = "BackfillProjectWikiRepositories"
DELAY_INTERVAL = 2.minutes DELAY_INTERVAL = 2.minutes
@ -26,4 +26,4 @@ class RequeueBackfillProjectWikiRepositories < Gitlab::Database::Migration[2.1]
delete_batched_background_migration(MIGRATION, :projects, :id, []) delete_batched_background_migration(MIGRATION, :projects, :id, [])
end end
end end
# rubocop:enable BackgroundMigration/MissingDictionaryFile # rubocop:enable BackgroundMigration/DictionaryFile

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# rubocop:disable BackgroundMigration/MissingDictionaryFile # rubocop:disable BackgroundMigration/DictionaryFile
class RescheduleEvidencesHandlingUnicode < Gitlab::Database::Migration[2.1] class RescheduleEvidencesHandlingUnicode < Gitlab::Database::Migration[2.1]
restrict_gitlab_migration gitlab_schema: :gitlab_main restrict_gitlab_migration gitlab_schema: :gitlab_main
@ -29,4 +29,4 @@ class RescheduleEvidencesHandlingUnicode < Gitlab::Database::Migration[2.1]
delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, []) delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, [])
end end
end end
# rubocop:enable BackgroundMigration/MissingDictionaryFile # rubocop:enable BackgroundMigration/DictionaryFile

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
# rubocop: disable BackgroundMigration/MissingDictionaryFile # rubocop: disable BackgroundMigration/DictionaryFile
class RescheduleMigrationForLinksFromMetadata < Gitlab::Database::Migration[2.1] class RescheduleMigrationForLinksFromMetadata < Gitlab::Database::Migration[2.1]
MIGRATION = 'MigrateLinksForVulnerabilityFindings' MIGRATION = 'MigrateLinksForVulnerabilityFindings'
@ -29,4 +29,4 @@ class RescheduleMigrationForLinksFromMetadata < Gitlab::Database::Migration[2.1]
delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, []) delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, [])
end end
end end
# rubocop: enable BackgroundMigration/MissingDictionaryFile # rubocop: enable BackgroundMigration/DictionaryFile

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class CleanupBigintConversionForCiProjectMonthlyUsagesSharedRunnersDuration < Gitlab::Database::Migration[2.1]
enable_lock_retries!
TABLE = :ci_project_monthly_usages
COLUMNS = [:shared_runners_duration]
def up
cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS)
end
def down
restore_conversion_of_integer_to_bigint(TABLE, COLUMNS)
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class CleanupBigintConversionForCiNamespaceMonthlyUsagesSharedRunnersDuration < Gitlab::Database::Migration[2.1]
enable_lock_retries!
TABLE = :ci_namespace_monthly_usages
COLUMNS = [:shared_runners_duration]
def up
cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS)
end
def down
restore_conversion_of_integer_to_bigint(TABLE, COLUMNS)
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class RemoveRedundantGroupStagesIndex < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '16.6'
INDEX_NAME = 'index_analytics_ca_group_stages_on_group_id'
def up
remove_concurrent_index_by_name(:analytics_cycle_analytics_group_stages, INDEX_NAME)
end
def down
add_concurrent_index(:analytics_cycle_analytics_group_stages, :group_id, name: INDEX_NAME)
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class RemoveRedundantMrMetricsIndexOnTargetProjectId < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '16.6'
INDEX_NAME = 'index_merge_request_metrics_on_target_project_id'
def up
remove_concurrent_index_by_name(:merge_request_metrics, INDEX_NAME)
end
def down
add_concurrent_index(:merge_request_metrics, :target_project_id, name: INDEX_NAME)
end
end

View File

@ -0,0 +1 @@
1bd136e7d4fb7c34030cea6c915a2eeae619ea5ae1a701cb4d5d4bb069df7113

View File

@ -0,0 +1 @@
bf03b09c6247d2f5c3543f4046b48763dfc7e6fb2cdaedc52d8cfc8777f70e71

View File

@ -0,0 +1 @@
add7ce4f9fb56221512227d5aa3697245d537cd5c975978b7dc6dab992890e4e

View File

@ -0,0 +1 @@
08275dacbe6b1bd44cc67834fc77d6615e43ebd1b9a85edc9e7237cbecc57315

View File

@ -335,15 +335,6 @@ BEGIN
END; END;
$$; $$;
CREATE FUNCTION trigger_bbb95b2d6929() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW."shared_runners_duration_convert_to_bigint" := NEW."shared_runners_duration";
RETURN NEW;
END;
$$;
CREATE FUNCTION trigger_bfad0e2b9c86() RETURNS trigger CREATE FUNCTION trigger_bfad0e2b9c86() RETURNS trigger
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
@ -353,15 +344,6 @@ BEGIN
END; END;
$$; $$;
CREATE FUNCTION trigger_c0353bbb6145() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW."shared_runners_duration_convert_to_bigint" := NEW."shared_runners_duration";
RETURN NEW;
END;
$$;
CREATE FUNCTION unset_has_issues_on_vulnerability_reads() RETURNS trigger CREATE FUNCTION unset_has_issues_on_vulnerability_reads() RETURNS trigger
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
@ -13788,7 +13770,6 @@ CREATE TABLE ci_namespace_monthly_usages (
namespace_id bigint NOT NULL, namespace_id bigint NOT NULL,
date date NOT NULL, date date NOT NULL,
notification_level smallint DEFAULT 100 NOT NULL, notification_level smallint DEFAULT 100 NOT NULL,
shared_runners_duration_convert_to_bigint integer DEFAULT 0 NOT NULL,
created_at timestamp with time zone, created_at timestamp with time zone,
amount_used numeric(18,4) DEFAULT 0.0 NOT NULL, amount_used numeric(18,4) DEFAULT 0.0 NOT NULL,
shared_runners_duration bigint DEFAULT 0 NOT NULL, shared_runners_duration bigint DEFAULT 0 NOT NULL,
@ -14074,7 +14055,6 @@ CREATE TABLE ci_project_monthly_usages (
id bigint NOT NULL, id bigint NOT NULL,
project_id bigint NOT NULL, project_id bigint NOT NULL,
date date NOT NULL, date date NOT NULL,
shared_runners_duration_convert_to_bigint integer DEFAULT 0 NOT NULL,
created_at timestamp with time zone, created_at timestamp with time zone,
amount_used numeric(18,4) DEFAULT 0.0 NOT NULL, amount_used numeric(18,4) DEFAULT 0.0 NOT NULL,
shared_runners_duration bigint DEFAULT 0 NOT NULL, shared_runners_duration bigint DEFAULT 0 NOT NULL,
@ -31413,8 +31393,6 @@ CREATE INDEX index_allowed_email_domains_on_group_id ON allowed_email_domains US
CREATE INDEX index_analytics_ca_group_stages_on_end_event_label_id ON analytics_cycle_analytics_group_stages USING btree (end_event_label_id); CREATE INDEX index_analytics_ca_group_stages_on_end_event_label_id ON analytics_cycle_analytics_group_stages USING btree (end_event_label_id);
CREATE INDEX index_analytics_ca_group_stages_on_group_id ON analytics_cycle_analytics_group_stages USING btree (group_id);
CREATE INDEX index_analytics_ca_group_stages_on_relative_position ON analytics_cycle_analytics_group_stages USING btree (relative_position); CREATE INDEX index_analytics_ca_group_stages_on_relative_position ON analytics_cycle_analytics_group_stages USING btree (relative_position);
CREATE INDEX index_analytics_ca_group_stages_on_start_event_label_id ON analytics_cycle_analytics_group_stages USING btree (start_event_label_id); CREATE INDEX index_analytics_ca_group_stages_on_start_event_label_id ON analytics_cycle_analytics_group_stages USING btree (start_event_label_id);
@ -33129,8 +33107,6 @@ CREATE INDEX index_merge_request_metrics_on_merged_by_id ON merge_request_metric
CREATE INDEX index_merge_request_metrics_on_pipeline_id ON merge_request_metrics USING btree (pipeline_id); CREATE INDEX index_merge_request_metrics_on_pipeline_id ON merge_request_metrics USING btree (pipeline_id);
CREATE INDEX index_merge_request_metrics_on_target_project_id ON merge_request_metrics USING btree (target_project_id);
CREATE INDEX index_merge_request_review_llm_summaries_on_mr_diff_id ON merge_request_review_llm_summaries USING btree (merge_request_diff_id); CREATE INDEX index_merge_request_review_llm_summaries_on_mr_diff_id ON merge_request_review_llm_summaries USING btree (merge_request_diff_id);
CREATE INDEX index_merge_request_review_llm_summaries_on_review_id ON merge_request_review_llm_summaries USING btree (review_id); CREATE INDEX index_merge_request_review_llm_summaries_on_review_id ON merge_request_review_llm_summaries USING btree (review_id);
@ -36779,12 +36755,8 @@ CREATE TRIGGER trigger_7f3d66a7d7f5 BEFORE INSERT OR UPDATE ON ci_pipeline_varia
CREATE TRIGGER trigger_b2d852e1e2cb BEFORE INSERT OR UPDATE ON ci_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_b2d852e1e2cb(); CREATE TRIGGER trigger_b2d852e1e2cb BEFORE INSERT OR UPDATE ON ci_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_b2d852e1e2cb();
CREATE TRIGGER trigger_bbb95b2d6929 BEFORE INSERT OR UPDATE ON ci_project_monthly_usages FOR EACH ROW EXECUTE FUNCTION trigger_bbb95b2d6929();
CREATE TRIGGER trigger_bfad0e2b9c86 BEFORE INSERT OR UPDATE ON ci_pipeline_messages FOR EACH ROW EXECUTE FUNCTION trigger_bfad0e2b9c86(); CREATE TRIGGER trigger_bfad0e2b9c86 BEFORE INSERT OR UPDATE ON ci_pipeline_messages FOR EACH ROW EXECUTE FUNCTION trigger_bfad0e2b9c86();
CREATE TRIGGER trigger_c0353bbb6145 BEFORE INSERT OR UPDATE ON ci_namespace_monthly_usages FOR EACH ROW EXECUTE FUNCTION trigger_c0353bbb6145();
CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace(); CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace();
CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker(); CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();

View File

@ -121,6 +121,7 @@ To install `agentk`:
kind: Secret kind: Secret
metadata: metadata:
name: gitlab-agent-token name: gitlab-agent-token
namespace: gitlab
type: Opaque type: Opaque
stringData: stringData:
token: "<your-token-here>" token: "<your-token-here>"

View File

@ -94,37 +94,6 @@ module API
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
helpers do helpers do
def commit
strong_memoize(:commit) do
user_project.commit(params[:sha])
end
end
def all_matching_pipelines
pipelines = user_project.ci_pipelines.newest_first(sha: commit.sha)
pipelines = pipelines.for_ref(params[:ref]) if params[:ref]
pipelines = pipelines.id_in(params[:pipeline_id]) if params[:pipeline_id]
pipelines
end
def apply_job_state!(job)
case params[:state]
when 'pending'
job.enqueue!
when 'running'
job.enqueue
job.run!
when 'success'
job.success!
when 'failed'
job.drop!(:api_failure)
when 'canceled'
job.cancel!
else
render_api_error!('invalid state', 400)
end
end
def optional_commit_status_params def optional_commit_status_params
updatable_optional_attributes = %w[target_url description coverage] updatable_optional_attributes = %w[target_url description coverage]
attributes_for_keys(updatable_optional_attributes) attributes_for_keys(updatable_optional_attributes)

View File

@ -3,7 +3,8 @@
# This is a base controller for doorkeeper. # This is a base controller for doorkeeper.
# It adds the `can?` helper used in the views. # It adds the `can?` helper used in the views.
module Gitlab module Gitlab
class BaseDoorkeeperController < BaseActionController # rubocop:disable Rails/ApplicationController
class BaseDoorkeeperController < ActionController::Base
include Gitlab::Allowable include Gitlab::Allowable
include EnforcesTwoFactorAuthentication include EnforcesTwoFactorAuthentication
include SessionsHelper include SessionsHelper
@ -12,4 +13,5 @@ module Gitlab
helper_method :can? helper_method :can?
end end
# rubocop:enable Rails/ApplicationController
end end

View File

@ -6,7 +6,8 @@
module Gitlab module Gitlab
module RequestForgeryProtection module RequestForgeryProtection
class Controller < BaseActionController # rubocop:disable Rails/ApplicationController
class Controller < ActionController::Base
protect_from_forgery with: :exception, prepend: true protect_from_forgery with: :exception, prepend: true
def initialize def initialize
@ -39,5 +40,6 @@ module Gitlab
rescue ActionController::InvalidAuthenticityToken rescue ActionController::InvalidAuthenticityToken
false false
end end
# rubocop:enable Rails/ApplicationController
end end
end end

View File

@ -24739,12 +24739,21 @@ msgstr ""
msgid "InProductMarketing|%{strong_start}GitLab Inc.%{strong_end} 268 Bush Street, #350, San Francisco, CA 94104, USA" msgid "InProductMarketing|%{strong_start}GitLab Inc.%{strong_end} 268 Bush Street, #350, San Francisco, CA 94104, USA"
msgstr "" msgstr ""
msgid "InProductMarketing|%{upper_start}Start your 30-day free trial of%{upper_end} %{lower_start}GitLab Ultimate%{lower_end}"
msgstr ""
msgid "InProductMarketing|Accelerate your digital transform"
msgstr ""
msgid "InProductMarketing|Blog" msgid "InProductMarketing|Blog"
msgstr "" msgstr ""
msgid "InProductMarketing|Built-in security" msgid "InProductMarketing|Built-in security"
msgstr "" msgstr ""
msgid "InProductMarketing|Deliver software faster"
msgstr ""
msgid "InProductMarketing|Ensure compliance" msgid "InProductMarketing|Ensure compliance"
msgstr "" msgstr ""
@ -24760,12 +24769,18 @@ msgstr ""
msgid "InProductMarketing|If you no longer wish to receive marketing emails from us," msgid "InProductMarketing|If you no longer wish to receive marketing emails from us,"
msgstr "" msgstr ""
msgid "InProductMarketing|Improve collaboration and visibility"
msgstr ""
msgid "InProductMarketing|Invite unlimited colleagues" msgid "InProductMarketing|Invite unlimited colleagues"
msgstr "" msgstr ""
msgid "InProductMarketing|No credit card required" msgid "InProductMarketing|No credit card required"
msgstr "" msgstr ""
msgid "InProductMarketing|No credit card required."
msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial" msgid "InProductMarketing|Start a Self-Managed trial"
msgstr "" msgstr ""
@ -33224,6 +33239,9 @@ msgstr ""
msgid "Options" msgid "Options"
msgstr "" msgstr ""
msgid "Or create your own GitLab account:"
msgstr ""
msgid "Ordered list" msgid "Ordered list"
msgstr "" msgstr ""
@ -42651,6 +42669,9 @@ msgstr ""
msgid "SecurityOrchestration|Branch types don't match any existing branches." msgid "SecurityOrchestration|Branch types don't match any existing branches."
msgstr "" msgstr ""
msgid "SecurityOrchestration|Cannot create an empty policy"
msgstr ""
msgid "SecurityOrchestration|Choose a project" msgid "SecurityOrchestration|Choose a project"
msgstr "" msgstr ""
@ -42726,6 +42747,9 @@ msgstr ""
msgid "SecurityOrchestration|Failed to load images." msgid "SecurityOrchestration|Failed to load images."
msgstr "" msgstr ""
msgid "SecurityOrchestration|For any MR that matches this policy's rules, only the override project approval settings apply. No additional approvals are required."
msgstr ""
msgid "SecurityOrchestration|For any merge request on %{branches}%{commitType}%{branchExceptionsString}" msgid "SecurityOrchestration|For any merge request on %{branches}%{commitType}%{branchExceptionsString}"
msgstr "" msgstr ""
@ -42806,6 +42830,9 @@ msgid_plural "SecurityOrchestration|On runners with the tags:"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "SecurityOrchestration|Only overriding settings will take effect"
msgstr ""
msgid "SecurityOrchestration|Only owners can update Security Policy Project" msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr "" msgstr ""
@ -42971,6 +42998,9 @@ msgstr ""
msgid "SecurityOrchestration|This is a project-level policy" msgid "SecurityOrchestration|This is a project-level policy"
msgstr "" msgstr ""
msgid "SecurityOrchestration|This policy doesn't contain any actions or override project approval settings. You cannot create an empty policy."
msgstr ""
msgid "SecurityOrchestration|This policy is inherited" msgid "SecurityOrchestration|This policy is inherited"
msgstr "" msgstr ""
@ -44720,6 +44750,9 @@ msgstr ""
msgid "Sign up" msgid "Sign up"
msgstr "" msgstr ""
msgid "Sign up for your free trial with:"
msgstr ""
msgid "Sign up was successful! Please confirm your email to sign in." msgid "Sign up was successful! Please confirm your email to sign in."
msgstr "" msgstr ""

View File

@ -5,7 +5,7 @@ ENV GITLAB_LICENSE_MODE=test \
# Clone GDK at specific sha and bootstrap packages # Clone GDK at specific sha and bootstrap packages
# #
ARG GDK_SHA=65cf4576208b9f79c54c0042c44024c0008deafc ARG GDK_SHA=d843a4d237bbb9c2f04d2cbddc89fd6dadeb86cf
RUN set -eux; \ RUN set -eux; \
git clone --depth 1 https://gitlab.com/gitlab-org/gitlab-development-kit.git && cd gitlab-development-kit; \ git clone --depth 1 https://gitlab.com/gitlab-org/gitlab-development-kit.git && cd gitlab-development-kit; \
git fetch --depth 1 origin ${GDK_SHA} && git -c advice.detachedHead=false checkout ${GDK_SHA}; \ git fetch --depth 1 origin ${GDK_SHA} && git -c advice.detachedHead=false checkout ${GDK_SHA}; \

View File

@ -4,7 +4,7 @@ module QA
module Page module Page
module Registration module Registration
class SignUp < Page::Base class SignUp < Page::Base
view 'app/views/devise/shared/_signup_box.html.haml' do view 'app/views/devise/shared/_signup_box_form.html.haml' do
element 'new-user-first-name-field' element 'new-user-first-name-field'
element 'new-user-last-name-field' element 'new-user-last-name-field'
element 'new-user-email-field' element 'new-user-email-field'

View File

@ -11,8 +11,11 @@ module QA
# This *could* be different than the api_client.user or the api_user provided by the QA::Resource::ApiFabricator # This *could* be different than the api_client.user or the api_user provided by the QA::Resource::ApiFabricator
attr_writer :user attr_writer :user
attribute :id attributes :id, :token
attribute :token
attribute :expires_at do
Time.now.utc.to_date + 2
end
# Only Admins can create PAT via the API. # Only Admins can create PAT via the API.
# If Runtime::Env.admin_personal_access_token is provided, fabricate via the API, # If Runtime::Env.admin_personal_access_token is provided, fabricate via the API,
@ -49,7 +52,7 @@ module QA
api_client = Runtime::API::Client.new(:gitlab, api_client = Runtime::API::Client.new(:gitlab,
is_new_session: false, is_new_session: false,
user: user, user: user,
personal_access_token: self.token) personal_access_token: token)
request_url = Runtime::API::Request.new(api_client, request_url = Runtime::API::Request.new(api_client,
"/personal_access_tokens?user_id=#{user.id}", "/personal_access_tokens?user_id=#{user.id}",
per_page: '100').url per_page: '100').url
@ -88,12 +91,7 @@ module QA
end end
def cache_token def cache_token
QA::Resource::PersonalAccessTokenCache.set_token_for_username(user.username, self.token) if @user && self.token QA::Resource::PersonalAccessTokenCache.set_token_for_username(user.username, token) if @user && token
end
# Expire in 2 days just in case the token is created just before midnight
def expires_at
@expires_at || Time.now.utc.to_date + 2
end end
def fabricate! def fabricate!
@ -115,7 +113,7 @@ module QA
cache_token cache_token
self.token token
end end
end end
end end

View File

@ -18,6 +18,21 @@ module QA
tags: { import_type: ENV["QA_IMPORT_TYPE"], import_repo: ENV["QA_LARGE_IMPORT_REPO"] || "rspec/rspec-core" } tags: { import_type: ENV["QA_IMPORT_TYPE"], import_repo: ENV["QA_LARGE_IMPORT_REPO"] || "rspec/rspec-core" }
} do } do
describe 'Project import', product_group: :import_and_integrate do # rubocop:disable RSpec/MultipleMemoizedHelpers describe 'Project import', product_group: :import_and_integrate do # rubocop:disable RSpec/MultipleMemoizedHelpers
let!(:api_client) { Runtime::API::Client.as_admin }
let!(:user) { create(:user, api_client: api_client) }
let!(:user_api_client) do
Runtime::API::Client.new(
user: user,
is_new_session: false,
personal_access_token: Resource::PersonalAccessToken.fabricate_via_api! do |pat|
pat.user = user
# importing very large project can take multiple days
# token must not expire while we still poll for import result
pat.expires_at = (Time.now.to_date + 5)
end.token
)
end
# Full object comparison is a fairly heavy operation # Full object comparison is a fairly heavy operation
# Importer itself returns counts of objects it fetched and counts it imported # Importer itself returns counts of objects it fetched and counts it imported
# We can use that for a lightweight comparison for very large projects # We can use that for a lightweight comparison for very large projects
@ -103,10 +118,6 @@ module QA
] ]
end end
let(:api_client) { Runtime::API::Client.as_admin }
let(:user) { create(:user, api_client: api_client) }
let(:github_client) do let(:github_client) do
Octokit::Client.new( Octokit::Client.new(
access_token: ENV['QA_LARGE_IMPORT_GH_TOKEN'] || Runtime::Env.github_access_token, access_token: ENV['QA_LARGE_IMPORT_GH_TOKEN'] || Runtime::Env.github_access_token,

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module RuboCop module RuboCop
class BatchedBackgroundMigrations class BatchedBackgroundMigrationsDictionary
DICTIONARY_BASE_DIR = 'db/docs/batched_background_migrations' DICTIONARY_BASE_DIR = 'db/docs/batched_background_migrations'
attr_reader :queued_migration_version attr_reader :queued_migration_version
@ -14,6 +14,7 @@ module RuboCop
next unless dictionary['queued_migration_version'].present? next unless dictionary['queued_migration_version'].present?
data[dictionary['queued_migration_version'].to_s] = { data[dictionary['queued_migration_version'].to_s] = {
introduced_by_url: dictionary['introduced_by_url'],
finalize_after: dictionary['finalize_after'], finalize_after: dictionary['finalize_after'],
finalized_by: dictionary['finalized_by'].to_s finalized_by: dictionary['finalized_by'].to_s
} }
@ -26,7 +27,21 @@ module RuboCop
end end
def finalized_by def finalized_by
self.class.dictionary_data.dig(queued_migration_version.to_s, :finalized_by) dictionary_data&.dig(:finalized_by)
end
def finalize_after
dictionary_data&.dig(:finalize_after)
end
def introduced_by_url
dictionary_data&.dig(:introduced_by_url)
end
private
def dictionary_data
@dictionary_data ||= self.class.dictionary_data[queued_migration_version.to_s]
end end
end end
end end

View File

@ -1,17 +1,23 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative '../../migration_helpers' require_relative '../../migration_helpers'
require_relative '../../batched_background_migrations_dictionary'
module RuboCop module RuboCop
module Cop module Cop
module BackgroundMigration module BackgroundMigration
# Checks the batched background migration has the corresponding dictionary file # Checks the batched background migration has the corresponding dictionary file
class MissingDictionaryFile < RuboCop::Cop::Base class DictionaryFile < RuboCop::Cop::Base
include MigrationHelpers include MigrationHelpers
MSG = "Missing %{file_name}. " \ MSG = {
"Use the generator 'batched_background_migration' to create dictionary files automatically. " \ missing_key: "Mandatory key '%{key}' is missing from the dictionary. Please add with an appropriate value.",
"For more details refer: https://docs.gitlab.com/ee/development/database/batched_background_migrations.html#generator" missing_dictionary: <<-MESSAGE.delete("\n").squeeze(' ').strip
Missing %{file_name}.
Use the generator 'batched_background_migration' to create dictionary files automatically.
For more details refer: https://docs.gitlab.com/ee/development/database/batched_background_migrations.html#generator
MESSAGE
}.freeze
DICTIONARY_DIR = "db/docs/batched_background_migrations" DICTIONARY_DIR = "db/docs/batched_background_migrations"
@ -35,9 +41,10 @@ module RuboCop
migration_name_node.value migration_name_node.value
end end
return if dictionary_file?(migration_name) error_code, msg_params = validate_dictionary_file(migration_name, node)
return unless error_code.present?
add_offense(node, message: format(MSG, file_name: dictionary_file_path(migration_name))) add_offense(node, message: format(MSG[error_code], msg_params))
end end
private private
@ -50,6 +57,18 @@ module RuboCop
File.join(rails_root, DICTIONARY_DIR, "#{migration_class_name.underscore}.yml") File.join(rails_root, DICTIONARY_DIR, "#{migration_class_name.underscore}.yml")
end end
def validate_dictionary_file(migration_name, node)
unless dictionary_file?(migration_name)
return [:missing_dictionary, { file_name: dictionary_file_path(migration_name) }]
end
bbm_dictionary = RuboCop::BatchedBackgroundMigrationsDictionary.new(version(node))
return [:missing_key, { key: :finalize_after }] unless bbm_dictionary.finalize_after.present?
return [:missing_key, { key: :introduced_by_url }] unless bbm_dictionary.introduced_by_url.present?
end
def rails_root def rails_root
@rails_root ||= File.expand_path('../../..', __dir__) @rails_root ||= File.expand_path('../../..', __dir__)
end end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative '../../migration_helpers' require_relative '../../migration_helpers'
require_relative '../../batched_background_migrations' require_relative '../../batched_background_migrations_dictionary'
module RuboCop module RuboCop
module Cop module Cop
@ -43,7 +43,7 @@ module RuboCop
private private
def fetch_finalized_by(queued_migration_version) def fetch_finalized_by(queued_migration_version)
BatchedBackgroundMigrations.new(queued_migration_version).finalized_by BatchedBackgroundMigrationsDictionary.new(queued_migration_version).finalized_by
end end
end end
end end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe AcmeChallengesController, type: :request, feature_category: :pages do
it_behaves_like 'Base action controller' do
subject(:request) { get acme_challenge_path }
end
end

View File

@ -1,15 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ApplicationController, type: :request, feature_category: :shared do
let_it_be(:user) { create(:user) }
before do
sign_in(user)
end
it_behaves_like 'Base action controller' do
subject(:request) { get root_path }
end
end

View File

@ -1,14 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ChaosController, type: :request, feature_category: :tooling do
it_behaves_like 'Base action controller' do
before do
# Stub leak_mem so we don't actually leak memory for the base action controller tests.
allow(Gitlab::Chaos).to receive(:leak_mem).with(100, 30.seconds)
end
subject(:request) { get leakmem_chaos_path }
end
end

View File

@ -73,9 +73,7 @@ RSpec.describe HealthController, feature_category: :database do
end end
describe 'GET /-/readiness' do describe 'GET /-/readiness' do
subject(:request) { get readiness_path, params: params, headers: headers } subject { get '/-/readiness', params: params, headers: headers }
it_behaves_like 'Base action controller'
shared_context 'endpoint responding with readiness data' do shared_context 'endpoint responding with readiness data' do
context 'when requesting instance-checks' do context 'when requesting instance-checks' do

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe MetricsController, type: :request, feature_category: :metrics do
it_behaves_like 'Base action controller' do
subject(:request) { get metrics_path }
end
end

View File

@ -20,10 +20,6 @@ RSpec.describe Oauth::AuthorizationsController, feature_category: :system_access
end end
describe 'GET #new' do describe 'GET #new' do
it_behaves_like 'Base action controller' do
subject(:request) { get oauth_authorization_path }
end
context 'when application redirect URI has a custom scheme' do context 'when application redirect URI has a custom scheme' do
context 'when CSP is disabled' do context 'when CSP is disabled' do
before do before do

View File

@ -6,9 +6,7 @@ RSpec.describe RegistrationsController, type: :request, feature_category: :syste
describe 'POST #create' do describe 'POST #create' do
let_it_be(:user_attrs) { build_stubbed(:user).slice(:first_name, :last_name, :username, :email, :password) } let_it_be(:user_attrs) { build_stubbed(:user).slice(:first_name, :last_name, :username, :email, :password) }
subject(:request) { post user_registration_path, params: { user: user_attrs } } subject(:create_user) { post user_registration_path, params: { user: user_attrs } }
it_behaves_like 'Base action controller'
context 'when email confirmation is required' do context 'when email confirmation is required' do
before do before do
@ -17,7 +15,7 @@ RSpec.describe RegistrationsController, type: :request, feature_category: :syste
end end
it 'redirects to the `users_almost_there_path`', unless: Gitlab.ee? do it 'redirects to the `users_almost_there_path`', unless: Gitlab.ee? do
request create_user
expect(response).to redirect_to(users_almost_there_path(email: user_attrs[:email])) expect(response).to redirect_to(users_almost_there_path(email: user_attrs[:email]))
end end

View File

@ -7,10 +7,6 @@ RSpec.describe 'Sessions', feature_category: :system_access do
let(:user) { create(:user) } let(:user) { create(:user) }
it_behaves_like 'Base action controller' do
subject(:request) { get new_user_session_path }
end
context 'for authentication', :allow_forgery_protection do context 'for authentication', :allow_forgery_protection do
it 'logout does not require a csrf token' do it 'logout does not require a csrf token' do
login_as(user) login_as(user)

View File

@ -2,20 +2,24 @@
require 'rubocop_spec_helper' require 'rubocop_spec_helper'
require_relative '../../rubocop/batched_background_migrations' require_relative '../../rubocop/batched_background_migrations_dictionary'
RSpec.describe RuboCop::BatchedBackgroundMigrations, feature_category: :database do RSpec.describe RuboCop::BatchedBackgroundMigrationsDictionary, feature_category: :database do
let(:bbm_dictionary_file_name) { "#{described_class::DICTIONARY_BASE_DIR}/test_migration.yml" } let(:bbm_dictionary_file_name) { "#{described_class::DICTIONARY_BASE_DIR}/test_migration.yml" }
let(:migration_version) { 20230307160250 } let(:migration_version) { 20230307160250 }
let(:finalized_by_version) { 20230307160255 } let(:finalized_by_version) { 20230307160255 }
let(:introduced_by_url) { 'https://test_url' }
let(:finalize_after) { '202312011212' }
let(:bbm_dictionary_data) do let(:bbm_dictionary_data) do
{ {
migration_job_name: 'TestMigration', migration_job_name: 'TestMigration',
feature_category: :database, feature_category: :database,
introduced_by_url: 'https://test_url', introduced_by_url: introduced_by_url,
milestone: 16.5, milestone: 16.5,
queued_migration_version: migration_version, queued_migration_version: migration_version,
finalized_by: finalized_by_version finalized_by: finalized_by_version,
finalize_after: finalize_after
} }
end end
@ -40,4 +44,24 @@ RSpec.describe RuboCop::BatchedBackgroundMigrations, feature_category: :database
expect(described_class.new('random').finalized_by).to be_nil expect(described_class.new('random').finalized_by).to be_nil
end end
end end
describe '#introduced_by_url' do
it 'returns the introduced_by_url of the bbm with given version' do
expect(batched_background_migration.introduced_by_url).to eq(introduced_by_url)
end
it 'returns nothing for non-existing bbm dictionary' do
expect(described_class.new('random').introduced_by_url).to be_nil
end
end
describe '#finalize_after' do
it 'returns the finalize_after timestamp of the bbm with given version' do
expect(batched_background_migration.finalize_after).to eq(finalize_after)
end
it 'returns nothing for non-existing bbm dictionary' do
expect(described_class.new('random').finalize_after).to be_nil
end
end
end end

View File

@ -1,17 +1,36 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'rubocop_spec_helper' require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/background_migration/missing_dictionary_file' require_relative '../../../../rubocop/cop/background_migration/dictionary_file'
RSpec.describe RuboCop::Cop::BackgroundMigration::MissingDictionaryFile, feature_category: :database do RSpec.describe RuboCop::Cop::BackgroundMigration::DictionaryFile, feature_category: :database do
let(:config) do let(:config) do
RuboCop::Config.new( RuboCop::Config.new(
'BackgroundMigration/MissingDictionaryFile' => { 'BackgroundMigration/DictionaryFile' => {
'EnforcedSince' => 20230307160251 'EnforcedSince' => 20231018100907
} }
) )
end end
shared_examples 'migration with missing dictionary keys offense' do |missing_key|
it 'registers an offense' do
expect_offense(<<~RUBY)
class QueueMyMigration < Gitlab::Database::Migration[2.1]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{format(described_class::MSG[:missing_key], key: missing_key)}
MIGRATION = 'MyMigration'
def up
queue_batched_background_migration(
MIGRATION,
:users,
:id
)
end
end
RUBY
end
end
context 'for non post migrations' do context 'for non post migrations' do
before do before do
allow(cop).to receive(:in_post_deployment_migration?).and_return(false) allow(cop).to receive(:in_post_deployment_migration?).and_return(false)
@ -57,7 +76,7 @@ RSpec.describe RuboCop::Cop::BackgroundMigration::MissingDictionaryFile, feature
context 'for migrations before enforced time' do context 'for migrations before enforced time' do
before do before do
allow(cop).to receive(:version).and_return(20230307160250) allow(cop).to receive(:version).and_return(20230918100907)
end end
it 'does not throw any offenses' do it 'does not throw any offenses' do
@ -79,7 +98,7 @@ RSpec.describe RuboCop::Cop::BackgroundMigration::MissingDictionaryFile, feature
context 'for migrations after enforced time' do context 'for migrations after enforced time' do
before do before do
allow(cop).to receive(:version).and_return(20230307160252) allow(cop).to receive(:version).and_return(20231118100907)
end end
it 'throws offense on not having the appropriate dictionary file with migration name as a constant' do it 'throws offense on not having the appropriate dictionary file with migration name as a constant' do
@ -114,22 +133,48 @@ RSpec.describe RuboCop::Cop::BackgroundMigration::MissingDictionaryFile, feature
RUBY RUBY
end end
it 'does not throw offense with appropriate dictionary file' do context 'with dictionary file' do
expect(File).to receive(:exist?).with(dictionary_file_path).and_return(true) let(:introduced_by_url) { 'https://test_url' }
let(:finalize_after) { '20230507160251' }
expect_no_offenses(<<~RUBY) before do
class QueueMyMigration < Gitlab::Database::Migration[2.1] allow(File).to receive(:exist?).with(dictionary_file_path).and_return(true)
MIGRATION = 'MyMigration'
def up allow_next_instance_of(RuboCop::BatchedBackgroundMigrationsDictionary) do |dictionary|
queue_batched_background_migration( allow(dictionary).to receive(:finalize_after).and_return(finalize_after)
MIGRATION, allow(dictionary).to receive(:introduced_by_url).and_return(introduced_by_url)
:users,
:id
)
end
end end
RUBY end
context 'without introduced_by_url' do
it_behaves_like 'migration with missing dictionary keys offense', :introduced_by_url do
let(:introduced_by_url) { nil }
end
end
context 'without finalize_after' do
it_behaves_like 'migration with missing dictionary keys offense', :finalize_after do
let(:finalize_after) { nil }
end
end
context 'with required dictionary keys' do
it 'does not throw offense with appropriate dictionary file' do
expect_no_offenses(<<~RUBY)
class QueueMyMigration < Gitlab::Database::Migration[2.1]
MIGRATION = 'MyMigration'
def up
queue_batched_background_migration(
MIGRATION,
:users,
:id
)
end
end
RUBY
end
end
end end
end end
end end

View File

@ -99,7 +99,7 @@ RSpec.describe RuboCop::Cop::Migration::UnfinishedDependencies, feature_category
context 'with properly finalized dependent background migrations' do context 'with properly finalized dependent background migrations' do
before do before do
allow_next_instance_of(RuboCop::BatchedBackgroundMigrations) do |bbms| allow_next_instance_of(RuboCop::BatchedBackgroundMigrationsDictionary) do |bbms|
allow(bbms).to receive(:finalized_by).and_return(version - 5) allow(bbms).to receive(:finalized_by).and_return(version - 5)
end end
end end

View File

@ -6,9 +6,6 @@ abuse_reports:
alert_management_http_integrations: alert_management_http_integrations:
index_http_integrations_on_project_and_endpoint: index_http_integrations_on_project_and_endpoint:
- index_alert_management_http_integrations_on_project_id - index_alert_management_http_integrations_on_project_id
analytics_cycle_analytics_group_stages:
index_group_stages_on_group_id_group_value_stream_id_and_name:
- index_analytics_ca_group_stages_on_group_id
approval_project_rules_users: approval_project_rules_users:
index_approval_project_rules_users_1: index_approval_project_rules_users_1:
- index_approval_project_rules_users_on_approval_project_rule_id - index_approval_project_rules_users_on_approval_project_rule_id
@ -111,9 +108,6 @@ members:
merge_request_assignees: merge_request_assignees:
index_merge_request_assignees_on_merge_request_id_and_user_id: index_merge_request_assignees_on_merge_request_id_and_user_id:
- index_merge_request_assignees_on_merge_request_id - index_merge_request_assignees_on_merge_request_id
merge_request_metrics:
index_mr_metrics_on_target_project_id_merged_at_nulls_last:
- index_merge_request_metrics_on_target_project_id
merge_requests: merge_requests:
index_merge_requests_on_author_id_and_created_at: index_merge_requests_on_author_id_and_created_at:
- index_merge_requests_on_author_id - index_merge_requests_on_author_id

View File

@ -1,26 +0,0 @@
# frozen_string_literal: true
# Requires `request` subject to be defined
#
# subject(:request) { get root_path }
RSpec.shared_examples 'Base action controller' do
describe 'security headers' do
describe 'Cross-Origin-Opener-Policy' do
it 'sets the header' do
request
expect(response.headers['Cross-Origin-Opener-Policy']).to eq('same-origin')
end
context 'when coop_header feature flag is disabled' do
it 'does not set the header' do
stub_feature_flags(coop_header: false)
request
expect(response.headers['Cross-Origin-Opener-Policy']).to be_nil
end
end
end
end
end