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.
- [ ] 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.
- [ ] 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.
- [ ] 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)).

View File

@ -483,9 +483,9 @@ BackgroundMigration/FeatureCategory:
Include:
- 'lib/gitlab/background_migration/*.rb'
BackgroundMigration/MissingDictionaryFile:
BackgroundMigration/DictionaryFile:
Enabled: true
EnforcedSince: 20230307160251
EnforcedSince: 20231018100907
Include:
- '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 || '',
endpointCoverage: dataset.endpointCoverage || '',
endpointCodequality: dataset.endpointCodequality || '',
// This is a workaround which will be solved in: https://gitlab.com/gitlab-org/gitlab/-/issues/428758
sastReportAvailable: Boolean(dataset.endpointSast),
sastReportAvailable: dataset.endpointSast,
helpPagePath: dataset.helpPagePath,
currentUser: JSON.parse(dataset.currentUserData) || {},
changesEmptyStateIllustration: dataset.changesEmptyStateIllustration,

View File

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

View File

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

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
class AcmeChallengesController < BaseActionController
# rubocop:disable Rails/ApplicationController
class AcmeChallengesController < ActionController::Base
def show
if acme_order
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])
end
end
# rubocop:enable Rails/ApplicationController

View File

@ -3,7 +3,7 @@
require 'gon'
require 'fogbugz'
class ApplicationController < BaseActionController
class ApplicationController < ActionController::Base
include Gitlab::GonHelper
include Gitlab::NoCacheHeaders
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
class ChaosController < BaseActionController
# rubocop:disable Rails/ApplicationController
class ChaosController < ActionController::Base
before_action :validate_chaos_secret, unless: :development_or_test?
def leakmem
@ -94,3 +95,4 @@ class ChaosController < BaseActionController
Rails.env.development? || Rails.env.test?
end
end
# rubocop:enable Rails/ApplicationController

View File

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

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
class MetricsController < BaseActionController
# rubocop:disable Rails/ApplicationController
class MetricsController < ActionController::Base
include RequiresAllowlistedMonitoringClient
protect_from_forgery with: :exception, prepend: true
@ -35,3 +36,4 @@ class MetricsController < BaseActionController
)
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
= _('Already have an account?')
- path_params = { redirect_to_referer: 'yes' }

View File

@ -1,77 +1,10 @@
- max_first_name_length = max_last_name_length = 127
- 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') }
= 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|
.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
= render 'devise/shared/signup_box_form',
button_text: button_text,
url: url,
show_omniauth_providers: omniauth_enabled? && button_based_providers_enabled?
.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:")
.gl-display-flex.gl-justify-content-between.gl-flex-wrap
- 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)
= provider_image_tag(provider)
%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
# rubocop: disable BackgroundMigration/MissingDictionaryFile
# rubocop: disable BackgroundMigration/DictionaryFile
class RescheduleMigrationForRemediation < Gitlab::Database::Migration[2.1]
MIGRATION = 'MigrateRemediationsForVulnerabilityFindings'
@ -29,4 +29,4 @@ class RescheduleMigrationForRemediation < Gitlab::Database::Migration[2.1]
delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, [])
end
end
# rubocop: enable BackgroundMigration/MissingDictionaryFile
# rubocop: enable BackgroundMigration/DictionaryFile

View File

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

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
# rubocop:disable BackgroundMigration/MissingDictionaryFile
# rubocop:disable BackgroundMigration/DictionaryFile
class RescheduleEvidencesHandlingUnicode < Gitlab::Database::Migration[2.1]
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, [])
end
end
# rubocop:enable BackgroundMigration/MissingDictionaryFile
# rubocop:enable BackgroundMigration/DictionaryFile

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
# rubocop: disable BackgroundMigration/MissingDictionaryFile
# rubocop: disable BackgroundMigration/DictionaryFile
class RescheduleMigrationForLinksFromMetadata < Gitlab::Database::Migration[2.1]
MIGRATION = 'MigrateLinksForVulnerabilityFindings'
@ -29,4 +29,4 @@ class RescheduleMigrationForLinksFromMetadata < Gitlab::Database::Migration[2.1]
delete_batched_background_migration(MIGRATION, :vulnerability_occurrences, :id, [])
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;
$$;
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
LANGUAGE plpgsql
AS $$
@ -353,15 +344,6 @@ BEGIN
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
LANGUAGE plpgsql
AS $$
@ -13788,7 +13770,6 @@ CREATE TABLE ci_namespace_monthly_usages (
namespace_id bigint NOT NULL,
date date 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,
amount_used numeric(18,4) DEFAULT 0.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,
project_id bigint NOT NULL,
date date NOT NULL,
shared_runners_duration_convert_to_bigint integer DEFAULT 0 NOT NULL,
created_at timestamp with time zone,
amount_used numeric(18,4) DEFAULT 0.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_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_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_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_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_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_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_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
metadata:
name: gitlab-agent-token
namespace: gitlab
type: Opaque
stringData:
token: "<your-token-here>"

View File

@ -94,37 +94,6 @@ module API
# rubocop: enable CodeReuse/ActiveRecord
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
updatable_optional_attributes = %w[target_url description coverage]
attributes_for_keys(updatable_optional_attributes)

View File

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

View File

@ -6,7 +6,8 @@
module Gitlab
module RequestForgeryProtection
class Controller < BaseActionController
# rubocop:disable Rails/ApplicationController
class Controller < ActionController::Base
protect_from_forgery with: :exception, prepend: true
def initialize
@ -39,5 +40,6 @@ module Gitlab
rescue ActionController::InvalidAuthenticityToken
false
end
# rubocop:enable Rails/ApplicationController
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"
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"
msgstr ""
msgid "InProductMarketing|Built-in security"
msgstr ""
msgid "InProductMarketing|Deliver software faster"
msgstr ""
msgid "InProductMarketing|Ensure compliance"
msgstr ""
@ -24760,12 +24769,18 @@ msgstr ""
msgid "InProductMarketing|If you no longer wish to receive marketing emails from us,"
msgstr ""
msgid "InProductMarketing|Improve collaboration and visibility"
msgstr ""
msgid "InProductMarketing|Invite unlimited colleagues"
msgstr ""
msgid "InProductMarketing|No credit card required"
msgstr ""
msgid "InProductMarketing|No credit card required."
msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
@ -33224,6 +33239,9 @@ msgstr ""
msgid "Options"
msgstr ""
msgid "Or create your own GitLab account:"
msgstr ""
msgid "Ordered list"
msgstr ""
@ -42651,6 +42669,9 @@ msgstr ""
msgid "SecurityOrchestration|Branch types don't match any existing branches."
msgstr ""
msgid "SecurityOrchestration|Cannot create an empty policy"
msgstr ""
msgid "SecurityOrchestration|Choose a project"
msgstr ""
@ -42726,6 +42747,9 @@ msgstr ""
msgid "SecurityOrchestration|Failed to load images."
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}"
msgstr ""
@ -42806,6 +42830,9 @@ msgid_plural "SecurityOrchestration|On runners with the tags:"
msgstr[0] ""
msgstr[1] ""
msgid "SecurityOrchestration|Only overriding settings will take effect"
msgstr ""
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
@ -42971,6 +42998,9 @@ msgstr ""
msgid "SecurityOrchestration|This is a project-level policy"
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"
msgstr ""
@ -44720,6 +44750,9 @@ msgstr ""
msgid "Sign up"
msgstr ""
msgid "Sign up for your free trial with:"
msgstr ""
msgid "Sign up was successful! Please confirm your email to sign in."
msgstr ""

View File

@ -5,7 +5,7 @@ ENV GITLAB_LICENSE_MODE=test \
# Clone GDK at specific sha and bootstrap packages
#
ARG GDK_SHA=65cf4576208b9f79c54c0042c44024c0008deafc
ARG GDK_SHA=d843a4d237bbb9c2f04d2cbddc89fd6dadeb86cf
RUN set -eux; \
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}; \

View File

@ -4,7 +4,7 @@ module QA
module Page
module Registration
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-last-name-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
attr_writer :user
attribute :id
attribute :token
attributes :id, :token
attribute :expires_at do
Time.now.utc.to_date + 2
end
# Only Admins can create PAT 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,
is_new_session: false,
user: user,
personal_access_token: self.token)
personal_access_token: token)
request_url = Runtime::API::Request.new(api_client,
"/personal_access_tokens?user_id=#{user.id}",
per_page: '100').url
@ -88,12 +91,7 @@ module QA
end
def cache_token
QA::Resource::PersonalAccessTokenCache.set_token_for_username(user.username, self.token) if @user && self.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
QA::Resource::PersonalAccessTokenCache.set_token_for_username(user.username, token) if @user && token
end
def fabricate!
@ -115,7 +113,7 @@ module QA
cache_token
self.token
token
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" }
} do
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
# Importer itself returns counts of objects it fetched and counts it imported
# We can use that for a lightweight comparison for very large projects
@ -103,10 +118,6 @@ module QA
]
end
let(:api_client) { Runtime::API::Client.as_admin }
let(:user) { create(:user, api_client: api_client) }
let(:github_client) do
Octokit::Client.new(
access_token: ENV['QA_LARGE_IMPORT_GH_TOKEN'] || Runtime::Env.github_access_token,

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
module RuboCop
class BatchedBackgroundMigrations
class BatchedBackgroundMigrationsDictionary
DICTIONARY_BASE_DIR = 'db/docs/batched_background_migrations'
attr_reader :queued_migration_version
@ -14,6 +14,7 @@ module RuboCop
next unless dictionary['queued_migration_version'].present?
data[dictionary['queued_migration_version'].to_s] = {
introduced_by_url: dictionary['introduced_by_url'],
finalize_after: dictionary['finalize_after'],
finalized_by: dictionary['finalized_by'].to_s
}
@ -26,7 +27,21 @@ module RuboCop
end
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

View File

@ -1,17 +1,23 @@
# frozen_string_literal: true
require_relative '../../migration_helpers'
require_relative '../../batched_background_migrations_dictionary'
module RuboCop
module Cop
module BackgroundMigration
# Checks the batched background migration has the corresponding dictionary file
class MissingDictionaryFile < RuboCop::Cop::Base
class DictionaryFile < RuboCop::Cop::Base
include MigrationHelpers
MSG = "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"
MSG = {
missing_key: "Mandatory key '%{key}' is missing from the dictionary. Please add with an appropriate value.",
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"
@ -35,9 +41,10 @@ module RuboCop
migration_name_node.value
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
private
@ -50,6 +57,18 @@ module RuboCop
File.join(rails_root, DICTIONARY_DIR, "#{migration_class_name.underscore}.yml")
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
@rails_root ||= File.expand_path('../../..', __dir__)
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative '../../migration_helpers'
require_relative '../../batched_background_migrations'
require_relative '../../batched_background_migrations_dictionary'
module RuboCop
module Cop
@ -43,7 +43,7 @@ module RuboCop
private
def fetch_finalized_by(queued_migration_version)
BatchedBackgroundMigrations.new(queued_migration_version).finalized_by
BatchedBackgroundMigrationsDictionary.new(queued_migration_version).finalized_by
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
describe 'GET /-/readiness' do
subject(:request) { get readiness_path, params: params, headers: headers }
it_behaves_like 'Base action controller'
subject { get '/-/readiness', params: params, headers: headers }
shared_context 'endpoint responding with readiness data' 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
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 CSP is disabled' do
before do

View File

@ -6,9 +6,7 @@ RSpec.describe RegistrationsController, type: :request, feature_category: :syste
describe 'POST #create' do
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 } }
it_behaves_like 'Base action controller'
subject(:create_user) { post user_registration_path, params: { user: user_attrs } }
context 'when email confirmation is required' do
before do
@ -17,7 +15,7 @@ RSpec.describe RegistrationsController, type: :request, feature_category: :syste
end
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]))
end

View File

@ -7,10 +7,6 @@ RSpec.describe 'Sessions', feature_category: :system_access do
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
it 'logout does not require a csrf token' do
login_as(user)

View File

@ -2,20 +2,24 @@
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(:migration_version) { 20230307160250 }
let(:finalized_by_version) { 20230307160255 }
let(:introduced_by_url) { 'https://test_url' }
let(:finalize_after) { '202312011212' }
let(:bbm_dictionary_data) do
{
migration_job_name: 'TestMigration',
feature_category: :database,
introduced_by_url: 'https://test_url',
introduced_by_url: introduced_by_url,
milestone: 16.5,
queued_migration_version: migration_version,
finalized_by: finalized_by_version
finalized_by: finalized_by_version,
finalize_after: finalize_after
}
end
@ -40,4 +44,24 @@ RSpec.describe RuboCop::BatchedBackgroundMigrations, feature_category: :database
expect(described_class.new('random').finalized_by).to be_nil
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

View File

@ -1,17 +1,36 @@
# frozen_string_literal: true
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
RuboCop::Config.new(
'BackgroundMigration/MissingDictionaryFile' => {
'EnforcedSince' => 20230307160251
'BackgroundMigration/DictionaryFile' => {
'EnforcedSince' => 20231018100907
}
)
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
before do
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
before do
allow(cop).to receive(:version).and_return(20230307160250)
allow(cop).to receive(:version).and_return(20230918100907)
end
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
before do
allow(cop).to receive(:version).and_return(20230307160252)
allow(cop).to receive(:version).and_return(20231118100907)
end
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
end
it 'does not throw offense with appropriate dictionary file' do
expect(File).to receive(:exist?).with(dictionary_file_path).and_return(true)
context 'with dictionary file' do
let(:introduced_by_url) { 'https://test_url' }
let(:finalize_after) { '20230507160251' }
expect_no_offenses(<<~RUBY)
class QueueMyMigration < Gitlab::Database::Migration[2.1]
MIGRATION = 'MyMigration'
before do
allow(File).to receive(:exist?).with(dictionary_file_path).and_return(true)
def up
queue_batched_background_migration(
MIGRATION,
:users,
:id
)
end
allow_next_instance_of(RuboCop::BatchedBackgroundMigrationsDictionary) do |dictionary|
allow(dictionary).to receive(:finalize_after).and_return(finalize_after)
allow(dictionary).to receive(:introduced_by_url).and_return(introduced_by_url)
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

View File

@ -99,7 +99,7 @@ RSpec.describe RuboCop::Cop::Migration::UnfinishedDependencies, feature_category
context 'with properly finalized dependent background migrations' 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)
end
end

View File

@ -6,9 +6,6 @@ abuse_reports:
alert_management_http_integrations:
index_http_integrations_on_project_and_endpoint:
- 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:
index_approval_project_rules_users_1:
- index_approval_project_rules_users_on_approval_project_rule_id
@ -111,9 +108,6 @@ members:
merge_request_assignees:
index_merge_request_assignees_on_merge_request_id_and_user_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:
index_merge_requests_on_author_id_and_created_at:
- 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