Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-01-20 21:07:30 +00:00
parent cc4e1c884c
commit 5d7e5a8902
43 changed files with 469 additions and 44 deletions

View File

@ -43,7 +43,7 @@ prepare-as-if-jh-branch:
- git commit -m 'Add JH files' # TODO: Mark which SHA we add
# Fetch for the history of the branch so it does not cause the following error:
# ! [remote rejected] ref -> ref (shallow update not allowed)
- git fetch --unshallow --filter=tree:0 origin "${CI_COMMIT_REF_NAME}"
- git fetch --unshallow --filter=tree:0 origin "${CI_COMMIT_SHA}"
- git push -f "${SANDBOX_REPOSITORY}" "${AS_IF_JH_BRANCH}"
start-as-if-jh:

View File

@ -61,6 +61,8 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
options[:merge_ref_head_diff]
]
expires_in(1.day) if cache_with_max_age?
return unless stale?(etag: [cache_context + diff_options_hash.fetch(:paths, []), diffs])
Gitlab::Metrics.measure(:diffs_unfold) do
@ -238,4 +240,10 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter
.track_mr_diffs_single_file_action(merge_request: @merge_request, user: current_user)
end
def cache_with_max_age?
@merge_request.diffs_batch_cache_with_max_age? &&
params[:ck].present? &&
render_merge_ref_head_diff?
end
end

View File

@ -414,6 +414,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
@update_current_user_path = expose_path(api_v4_user_preferences_path)
@endpoint_metadata_url = endpoint_metadata_url(@project, @merge_request)
@endpoint_diff_batch_url = endpoint_diff_batch_url(@project, @merge_request)
@diffs_batch_cache_key = @merge_request.merge_head_diff&.id if merge_request.diffs_batch_cache_with_max_age?
set_pipeline_variables
@ -571,6 +572,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def endpoint_diff_batch_url(project, merge_request)
per_page = current_user&.view_diffs_file_by_file ? '1' : '5'
params = request.query_parameters.merge(view: 'inline', diff_head: true, w: show_whitespace, page: '0', per_page: per_page)
params[:ck] = merge_request.merge_head_diff&.id if merge_request.diffs_batch_cache_with_max_age?
diffs_batch_project_json_merge_request_path(project, merge_request, 'json', params)
end

View File

@ -9,6 +9,10 @@ class Projects::ReleasesController < Projects::ApplicationController
before_action :authorize_create_release!, only: :new
before_action :validate_suffix_path, :fetch_latest_tag, only: :latest_permalink
prepend_before_action(only: [:downloads]) do
authenticate_sessionless_user!(:download) if Feature.enabled?(:allow_release_as_web_access_format)
end
feature_category :release_orchestration
urgency :low

View File

@ -2019,6 +2019,10 @@ class MergeRequest < ApplicationRecord
Feature.enabled?(:hide_merge_requests_from_banned_users) && author&.banned?
end
def diffs_batch_cache_with_max_age?
Feature.enabled?(:diffs_batch_cache_with_max_age, project)
end
private
attr_accessor :skip_fetch_ref

View File

@ -3,7 +3,7 @@
class PlanLimits < ApplicationRecord
include IgnorableColumns
ignore_column :ci_max_artifact_size_running_container_scanning, remove_with: '14.3', remove_after: '2021-08-22'
ignore_column :web_hook_calls, remove_with: '15.10', remove_after: '2022-02-22'
ignore_column :web_hook_calls_high, remove_with: '15.10', remove_after: '2022-02-22'
LimitUndefinedError = Class.new(StandardError)

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
# Tracks egress of various services per project
# This class ensures that we keep 1 record per project per month.
module Projects
class DataTransfer < ApplicationRecord
self.table_name = 'project_data_transfers'
belongs_to :project
belongs_to :namespace
scope :current_month, -> { where(date: beginning_of_month) }
def self.beginning_of_month(time = Time.current)
time.utc.beginning_of_month
end
end
end

View File

@ -15,17 +15,20 @@
= stylesheet_link_tag 'notify'
= yield :head
%body
= html_header_message
.content
= yield
.footer{ style: "margin-top: 10px;" }
%p
&mdash;
%br
= link_to "Unsubscribe", @unsubscribe_url
%p
&mdash;
%br
= link_to "Unsubscribe", @unsubscribe_url
-# EE-specific start
- if Gitlab::CurrentSettings.email_additional_text.present?
%br
%br
= Gitlab::Utils.nlbr(Gitlab::CurrentSettings.email_additional_text)
-# EE-specific end
-# EE-specific start
- if Gitlab::CurrentSettings.email_additional_text.present?
%br
%br
= Gitlab::Utils.nlbr(Gitlab::CurrentSettings.email_additional_text)
-# EE-specific end
= html_footer_message

View File

@ -0,0 +1,7 @@
<%= text_header_message %>
<%= yield -%>
<%= @unsubscribe_url %>
<%# EE-specific start %><%= render_if_exists 'layouts/mailer/additional_text' %><%# EE-specific end %>
<%= text_footer_message -%>

View File

@ -3,4 +3,3 @@
<%= _("Author: %{author_name}") % { author_name: sanitize_name(@note.author_name) } %>
<%= @note.note %>
<%# EE-specific start %><%= render_if_exists 'layouts/mailer/additional_text'%><%# EE-specific end %>

View File

@ -1,6 +1,3 @@
<%= _("Thank you for your support request! We are tracking your request as ticket #%{issue_iid}, and will respond as soon as we can.") % { issue_iid: @issue.iid } %>
<%= _("To unsubscribe from this issue, please paste the following link into your browser:") %>
<%= @unsubscribe_url %>
<%# EE-specific start %><%= render_if_exists 'layouts/mailer/additional_text' %><%# EE-specific end %>

View File

@ -19,7 +19,7 @@
- if mr_action == 'diffs'
- add_page_startup_api_call @endpoint_diff_batch_url
.merge-request{ data: { mr_action: mr_action, url: merge_request_path(@merge_request, format: :json), project_path: project_path(@merge_request.project), lock_version: @merge_request.lock_version } }
.merge-request{ data: { mr_action: mr_action, url: merge_request_path(@merge_request, format: :json), project_path: project_path(@merge_request.project), lock_version: @merge_request.lock_version, diffs_batch_cache_key: @diffs_batch_cache_key } }
- if moved_mr_sidebar_enabled?
#js-merge-sticky-header{ data: { data: sticky_header_data.to_json } }
= render "projects/merge_requests/mr_title"

View File

@ -0,0 +1,8 @@
---
name: allow_release_as_web_access_format
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109217
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/388471
milestone: '15.8'
type: development
group: group::release
default_enabled: false

View File

@ -0,0 +1,8 @@
---
name: diffs_batch_cache_with_max_age
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109451
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/388778
milestone: '15.9'
type: development
group: group::code review
default_enabled: false

View File

@ -0,0 +1,10 @@
---
table_name: project_data_transfers
classes:
- Projects::DataTransfer
feature_categories:
- source_code_management
description: Data transfer metrics per project
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107970
milestone: '15.9'
gitlab_schema: gitlab_main

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
class CreateProjectDataTransfer < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
def up
with_lock_retries do
create_table :project_data_transfers do |t|
t.references :project, index: false, null: false
t.references :namespace, index: true, null: false
t.bigint :repository_egress, null: false, default: 0
t.bigint :artifacts_egress, null: false, default: 0
t.bigint :packages_egress, null: false, default: 0
t.bigint :registry_egress, null: false, default: 0
t.date :date, null: false
t.datetime_with_timezone :created_at, null: false
t.index [:project_id, :namespace_id, :date], unique: true,
name: 'index_project_data_transfers_on_project_and_namespace_and_date'
end
end
add_check_constraint :project_data_transfers,
"(date = date_trunc('month', date))", 'project_data_transfers_project_year_month_constraint'
end
def down
with_lock_retries do
drop_table :project_data_transfers
end
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class ReAddWebHookCallsColumn < Gitlab::Database::Migration[2.1]
enable_lock_retries!
def change
add_column :plan_limits, :web_hook_calls, :integer, default: 0, null: false, if_not_exists: true
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class DropSyncTriggersFromWebHookCallsPlanLimits < Gitlab::Database::Migration[2.1]
enable_lock_retries!
def up
drop_trigger('trigger_c0776354152a', 'plan_limits')
drop_trigger('trigger_d0c336b01d00', 'plan_limits')
drop_trigger('trigger_e19c4cf656dc', 'plan_limits')
end
def down
# noop
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class SyncPlanLimitsWebHookCallsColumns < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
def up
execute('UPDATE plan_limits SET web_hook_calls=web_hook_calls_high')
end
def down
# noop
end
end

View File

@ -4,7 +4,7 @@ class CleanupWebHookCallsColumnRename < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
def up
cleanup_concurrent_column_rename :plan_limits, :web_hook_calls, :web_hook_calls_high
# noop, related incident: https://gitlab.com/gitlab-com/gl-infra/production/-/issues/8264
end
def down

View File

@ -0,0 +1 @@
ee7f3ba064eaaf4a1bf92e5c0a2ed32e5d294ddd6f1fdd8e6eed54c8b83c2af5

View File

@ -0,0 +1 @@
036fd539aa235ccaba493bfa7294f28cf71cfd73a1e069de2977b9313fd0b655

View File

@ -0,0 +1 @@
61838f8cfb759c53aa8ccc47620cd4d6595a72293172c7e3ac77b2e79e422200

View File

@ -0,0 +1 @@
c0f53f169d2525ebd5e374c102fe73521d344df078c37384675995ac97fbed9a

View File

@ -19656,6 +19656,7 @@ CREATE TABLE plan_limits (
notification_limit integer DEFAULT 0 NOT NULL,
dashboard_limit_enabled_at timestamp with time zone,
web_hook_calls_high integer DEFAULT 0,
web_hook_calls integer DEFAULT 0 NOT NULL,
CONSTRAINT check_0fa68f370e CHECK ((web_hook_calls_high IS NOT NULL))
);
@ -20226,6 +20227,28 @@ CREATE SEQUENCE project_daily_statistics_id_seq
ALTER SEQUENCE project_daily_statistics_id_seq OWNED BY project_daily_statistics.id;
CREATE TABLE project_data_transfers (
id bigint NOT NULL,
project_id bigint NOT NULL,
namespace_id bigint NOT NULL,
repository_egress bigint DEFAULT 0 NOT NULL,
artifacts_egress bigint DEFAULT 0 NOT NULL,
packages_egress bigint DEFAULT 0 NOT NULL,
registry_egress bigint DEFAULT 0 NOT NULL,
date date NOT NULL,
created_at timestamp with time zone NOT NULL,
CONSTRAINT project_data_transfers_project_year_month_constraint CHECK ((date = date_trunc('month'::text, (date)::timestamp with time zone)))
);
CREATE SEQUENCE project_data_transfers_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE project_data_transfers_id_seq OWNED BY project_data_transfers.id;
CREATE TABLE project_deploy_tokens (
id integer NOT NULL,
project_id integer NOT NULL,
@ -24583,6 +24606,8 @@ ALTER TABLE ONLY project_custom_attributes ALTER COLUMN id SET DEFAULT nextval('
ALTER TABLE ONLY project_daily_statistics ALTER COLUMN id SET DEFAULT nextval('project_daily_statistics_id_seq'::regclass);
ALTER TABLE ONLY project_data_transfers ALTER COLUMN id SET DEFAULT nextval('project_data_transfers_id_seq'::regclass);
ALTER TABLE ONLY project_deploy_tokens ALTER COLUMN id SET DEFAULT nextval('project_deploy_tokens_id_seq'::regclass);
ALTER TABLE ONLY project_export_jobs ALTER COLUMN id SET DEFAULT nextval('project_export_jobs_id_seq'::regclass);
@ -26821,6 +26846,9 @@ ALTER TABLE ONLY project_custom_attributes
ALTER TABLE ONLY project_daily_statistics
ADD CONSTRAINT project_daily_statistics_pkey PRIMARY KEY (id);
ALTER TABLE ONLY project_data_transfers
ADD CONSTRAINT project_data_transfers_pkey PRIMARY KEY (id);
ALTER TABLE ONLY project_deploy_tokens
ADD CONSTRAINT project_deploy_tokens_pkey PRIMARY KEY (id);
@ -30717,6 +30745,10 @@ CREATE UNIQUE INDEX index_project_custom_attributes_on_project_id_and_key ON pro
CREATE UNIQUE INDEX index_project_daily_statistics_on_project_id_and_date ON project_daily_statistics USING btree (project_id, date DESC);
CREATE INDEX index_project_data_transfers_on_namespace_id ON project_data_transfers USING btree (namespace_id);
CREATE UNIQUE INDEX index_project_data_transfers_on_project_and_namespace_and_date ON project_data_transfers USING btree (project_id, namespace_id, date);
CREATE INDEX index_project_deploy_tokens_on_deploy_token_id ON project_deploy_tokens USING btree (deploy_token_id);
CREATE UNIQUE INDEX index_project_deploy_tokens_on_project_id_and_deploy_token_id ON project_deploy_tokens USING btree (project_id, deploy_token_id);

View File

@ -385,9 +385,9 @@ The Ruby gem which performs the check is hard coded with `pool.ntp.org` as its r
This issue occurs when the hostname `pool.ntp.org` resolves to a server which does not provide a time service.
There is [an issue open](https://gitlab.com/gitlab-org/gitlab/-/issues/381422) for this dependency on `pool.ntp.org`.
In this case, in GitLab 15.7 and newer, [specify a custom NTP server using environment variables](#health-check-rake-task).
To workaround this, do one of the following:
In GitLab 15.6 and older, use one of the following workarounds:
- Add entries in `/etc/hosts` for `pool.ntp.org` to direct the request to valid local time servers.
This fixes the long timeout and the timeout error.

View File

@ -147,7 +147,7 @@ To set this limit for a self-managed installation, run the following in the
# If limits don't exist for the default plan, you can create one with:
# Plan.default.create_limits!
Plan.default.actual_limits.update!(web_hook_calls_high: 10)
Plan.default.actual_limits.update!(web_hook_calls: 10)
```
Set the limit to `0` to disable it.
@ -1077,6 +1077,16 @@ If a branch is merged while open merge requests still point to it, GitLab can
retarget merge requests pointing to the now-merged branch. To learn more, read
[Update merge requests when target branch merges](../user/project/merge_requests/index.md#update-merge-requests-when-target-branch-merges).
## Maximum number of assignees and reviewers
> - Maximum assignees [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368936) in GitLab 15.6.
> - Maximum reviewers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366485) in GitLab 15.9.
Issues and merge requests enforce these maximums:
- Maximum assignees: 200
- Maximum reviewers: 200
## CDN-based limits on GitLab.com
In addition to application-based limits, GitLab.com is configured to use Cloudflare's standard DDoS protection and Spectrum to protect Git over SSH. Cloudflare terminates client TLS connections but is not application aware and cannot be used for limits tied to users or groups. Cloudflare page rules and rate limits are configured with Terraform. These configurations are [not public](https://about.gitlab.com/handbook/communication/#not-public) because they include security and abuse implementations that detect malicious activities and making them public would undermine those operations.

View File

@ -331,11 +331,15 @@ for `shared_buffers` is quite high, and we are
GitLab.com uses the default of 60 seconds for [Puma request timeouts](../../administration/operations/puma.md#change-the-worker-timeout).
## Merge request reviewer maximum
## Maximum number of reviewers and assignees
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91406) in GitLab 15.3.
> - Maximum assignees [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368936) in GitLab 15.6.
> - Maximum reviewers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366485) in GitLab 15.9.
A maximum of 100 reviewers can be assigned to a merge request.
Merge requests enforce these maximums:
- Maximum assignees: 200
- Maximum reviewers: 200
## GitLab.com-specific rate limits

View File

@ -31,7 +31,7 @@ module Gitlab
group_import: { threshold: -> { application_settings.group_import_limit }, interval: 1.minute },
group_testing_hook: { threshold: 5, interval: 1.minute },
profile_add_new_email: { threshold: 5, interval: 1.minute },
web_hook_calls_high: { interval: 1.minute },
web_hook_calls: { interval: 1.minute },
web_hook_calls_mid: { interval: 1.minute },
web_hook_calls_low: { interval: 1.minute },
users_get_by_id: { threshold: -> { application_settings.users_get_by_id_limit }, interval: 10.minutes },

View File

@ -121,6 +121,7 @@ module Gitlab
# It is also used by GraphQL/API requests.
# And to allow accessing /archive programatically as it was a big pain point
# for users https://gitlab.com/gitlab-org/gitlab/-/issues/28978.
# Used for release downloading as well
def find_user_from_web_access_token(request_format, scopes: [:api])
return unless access_token && valid_web_access_format?(request_format)
@ -301,6 +302,8 @@ module Gitlab
api_request?
when :archive
archive_request?
when :download
download_request?
end
end
@ -352,6 +355,10 @@ module Gitlab
current_request.path.include?('/-/archive/')
end
def download_request?
current_request.path.include?('/downloads/')
end
def blob_request?
current_request.path.include?('/raw/')
end

View File

@ -5,7 +5,7 @@ module Gitlab
class RateLimiter
include Gitlab::Utils::StrongMemoize
LIMIT_NAME = :web_hook_calls_high
LIMIT_NAME = :web_hook_calls
NO_LIMIT = 0
# SystemHooks (instance admin hooks) and ServiceHooks (integration hooks)
# are not rate-limited.

View File

@ -610,5 +610,39 @@ RSpec.describe Projects::MergeRequests::DiffsController do
go
end
end
context 'when ck param is present' do
let(:cache_key) { merge_request.merge_head_diff.id }
before do
create(:merge_request_diff, :merge_head, merge_request: merge_request)
end
it 'sets Cache-Control with max-age' do
go(ck: cache_key, diff_head: true)
expect(response.headers['Cache-Control']).to eq('max-age=86400, private')
end
context 'when diffs_batch_cache_with_max_age feature flag is disabled' do
before do
stub_feature_flags(diffs_batch_cache_with_max_age: false)
end
it 'does not set Cache-Control with max-age' do
go(ck: cache_key, diff_head: true)
expect(response.headers['Cache-Control']).not_to eq('max-age=86400, private')
end
end
context 'when not rendering merge head diff' do
it 'does not set Cache-Control with max-age' do
go(ck: cache_key, diff_head: false)
expect(response.headers['Cache-Control']).not_to eq('max-age=86400, private')
end
end
end
end
end

View File

@ -82,6 +82,61 @@ RSpec.describe Projects::MergeRequestsController, feature_category: :code_review
w: '0'))
end
context 'when merge_head diff is present' do
before do
create(:merge_request_diff, :merge_head, merge_request: merge_request)
end
it 'sets the endpoint_diff_batch_url with ck' do
go
expect(assigns["endpoint_diff_batch_url"]).to eq(
diffs_batch_project_json_merge_request_path(
project,
merge_request,
'json',
diff_head: true,
view: 'inline',
w: '0',
page: '0',
per_page: '5',
ck: merge_request.merge_head_diff.id))
end
it 'sets diffs_batch_cache_key' do
go
expect(assigns['diffs_batch_cache_key']).to eq(merge_request.merge_head_diff.id)
end
context 'when diffs_batch_cache_with_max_age feature flag is disabled' do
before do
stub_feature_flags(diffs_batch_cache_with_max_age: false)
end
it 'sets the endpoint_diff_batch_url without ck param' do
go
expect(assigns['endpoint_diff_batch_url']).to eq(
diffs_batch_project_json_merge_request_path(
project,
merge_request,
'json',
diff_head: true,
view: 'inline',
w: '0',
page: '0',
per_page: '5'))
end
it 'does not set diffs_batch_cache_key' do
go
expect(assigns['diffs_batch_cache_key']).to be_nil
end
end
end
context 'when diff files were cleaned' do
render_views

View File

@ -89,6 +89,7 @@ RSpec.describe 'Database schema', feature_category: :database do
oauth_applications: %w[owner_id],
product_analytics_events_experimental: %w[event_id txn_id user_id],
project_build_artifacts_size_refreshes: %w[last_job_artifact_id],
project_data_transfers: %w[project_id namespace_id],
project_error_tracking_settings: %w[sentry_project_id],
project_group_links: %w[group_id],
project_statistics: %w[namespace_id],

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
FactoryBot.define do
factory :project_data_transfer, class: 'Projects::DataTransfer' do
project factory: :project
namespace { project.root_namespace }
date { Time.current.utc.beginning_of_month }
end
end

View File

@ -470,7 +470,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
expect { find_user_from_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError)
end
context 'no feed, API or archive requests' do
context 'no feed, API, archive or download requests' do
it 'returns nil if the request is not RSS' do
expect(find_user_from_web_access_token(:rss)).to be_nil
end
@ -486,6 +486,10 @@ RSpec.describe Gitlab::Auth::AuthFinders do
it 'returns nil if the request is not ARCHIVE' do
expect(find_user_from_web_access_token(:archive)).to be_nil
end
it 'returns nil if the request is not DOWNLOAD' do
expect(find_user_from_web_access_token(:download)).to be_nil
end
end
it 'returns the user for RSS requests' do
@ -506,6 +510,12 @@ RSpec.describe Gitlab::Auth::AuthFinders do
expect(find_user_from_web_access_token(:archive)).to eq(user)
end
it 'returns the user for DOWNLOAD requests' do
set_header('SCRIPT_NAME', '/-/1.0.0/downloads/main.zip')
expect(find_user_from_web_access_token(:download)).to eq(user)
end
context 'for API requests' do
it 'returns the user' do
set_header('SCRIPT_NAME', '/api/endpoint')

View File

@ -32,7 +32,7 @@ RSpec.describe Gitlab::WebHooks::RateLimiter, :clean_gitlab_redis_rate_limiting
context 'when there is a plan limit' do
before_all do
create(:plan_limits, plan: plan, web_hook_calls_high: limit)
create(:plan_limits, plan: plan, web_hook_calls: limit)
end
where(:hook, :limitless_hook_type) do
@ -65,7 +65,7 @@ RSpec.describe Gitlab::WebHooks::RateLimiter, :clean_gitlab_redis_rate_limiting
describe 'rate limit scope' do
it 'rate limits all hooks from the same namespace', :freeze_time do
create(:plan_limits, plan: plan, web_hook_calls_high: limit)
create(:plan_limits, plan: plan, web_hook_calls: limit)
project_hook_in_different_namespace = create(:project_hook)
project_hook_in_same_namespace = create(:project_hook,
project: create(:project, namespace: project_hook.project.namespace)
@ -92,7 +92,7 @@ RSpec.describe Gitlab::WebHooks::RateLimiter, :clean_gitlab_redis_rate_limiting
context 'when there is a plan limit' do
before_all do
create(:plan_limits, plan: plan, web_hook_calls_high: limit)
create(:plan_limits, plan: plan, web_hook_calls: limit)
end
context 'when hook is not rate-limited' do

View File

@ -1409,6 +1409,8 @@ RSpec.describe Notify do
subject { described_class.service_desk_thank_you_email(issue.id) }
it_behaves_like 'an unsubscribeable thread'
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
it 'has the correct recipient' do
is_expected.to deliver_to('service.desk@example.com')
@ -1450,6 +1452,8 @@ RSpec.describe Notify do
subject { described_class.service_desk_new_note_email(issue.id, first_note.id, 'service.desk@example.com') }
it_behaves_like 'an unsubscribeable thread'
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
it 'has the correct recipient' do
is_expected.to deliver_to('service.desk@example.com')

View File

@ -5535,4 +5535,24 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
end
end
end
describe '#diffs_batch_cache_with_max_age?' do
let(:merge_request) { build_stubbed(:merge_request) }
subject(:diffs_batch_cache_with_max_age?) { merge_request.diffs_batch_cache_with_max_age? }
it 'returns true' do
expect(diffs_batch_cache_with_max_age?).to be_truthy
end
context 'when diffs_batch_cache_with_max_age is disabled' do
before do
stub_feature_flags(diffs_batch_cache_with_max_age: false)
end
it 'returns false' do
expect(diffs_batch_cache_with_max_age?).to be_falsey
end
end
end
end

View File

@ -213,7 +213,7 @@ RSpec.describe PlanLimits do
ci_active_jobs
storage_size_limit
daily_invites
web_hook_calls_high
web_hook_calls
web_hook_calls_mid
web_hook_calls_low
ci_daily_pipeline_schedule_triggers

View File

@ -0,0 +1,62 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::DataTransfer, feature_category: :source_code_management do
let_it_be(:project) { create(:project) }
it { expect(subject).to be_valid }
describe 'associations' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:namespace) }
end
describe 'scopes' do
describe '.current_month' do
subject { described_class.current_month }
it 'returns data transfer for the current month' do
travel_to(Time.utc(2022, 5, 2)) do
_past_month = create(:project_data_transfer, project: project, date: '2022-04-01')
current_month = create(:project_data_transfer, project: project, date: '2022-05-01')
is_expected.to match_array([current_month])
end
end
end
end
describe '.beginning_of_month' do
subject { described_class.beginning_of_month(time) }
let(:time) { Time.utc(2022, 5, 2) }
it { is_expected.to eq(Time.utc(2022, 5, 1)) }
end
describe 'unique index' do
before do
create(:project_data_transfer, project: project, date: '2022-05-01')
end
it 'raises unique index violation' do
expect { create(:project_data_transfer, project: project, namespace: project.root_namespace, date: '2022-05-01') }
.to raise_error(ActiveRecord::RecordNotUnique)
end
context 'when project was moved from one namespace to another' do
it 'creates a new record' do
expect { create(:project_data_transfer, project: project, namespace: create(:namespace), date: '2022-05-01') }
.to change { described_class.count }.by(1)
end
end
context 'when a different project is created' do
it 'creates a new record' do
expect { create(:project_data_transfer, project: build(:project), date: '2022-05-01') }
.to change { described_class.count }.by(1)
end
end
end
end

View File

@ -8,17 +8,20 @@ RSpec.describe 'Projects::ReleasesController', feature_category: :release_orches
before do
project.add_developer(user)
login_as(user)
end
# Added as a request spec because of https://gitlab.com/gitlab-org/gitlab/-/issues/232386
describe 'GET #downloads' do
context 'filepath redirection' do
let_it_be(:release) { create(:release, project: project, tag: 'v11.9.0-rc2' ) }
let!(:link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: filepath, url: 'https://aws.example.com/s3/project/bin/hello-darwin-amd64') }
let_it_be(:url) { "#{project_releases_path(project)}/#{release.tag}/downloads/bin/darwin-amd64" }
let_it_be(:release) { create(:release, project: project, tag: 'v11.9.0-rc2' ) }
let!(:link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: filepath, url: 'https://aws.example.com/s3/project/bin/hello-darwin-amd64') }
let_it_be(:url) { "#{project_releases_path(project)}/#{release.tag}/downloads/bin/darwin-amd64" }
let(:subject) { get url }
let(:subject) { get url }
context 'filepath redirection' do
before do
login_as(user)
end
context 'valid filepath' do
let(:filepath) { '/bin/darwin-amd64' }
@ -47,14 +50,45 @@ RSpec.describe 'Projects::ReleasesController', feature_category: :release_orches
end
end
context 'invalid filepath' do
let(:invalid_filepath) { 'bin/darwin-amd64' }
context 'sessionless download authentication' do
let(:personal_access_token) { create(:personal_access_token, user: user) }
let(:filepath) { '/bin/darwin-amd64' }
let(:subject) { create(:release_link, name: 'linux-amd64 binaries', filepath: invalid_filepath, url: 'https://aws.example.com/s3/project/bin/hello-darwin-amd64') }
subject { get url, params: { private_token: personal_access_token.token } }
it 'cannot create an invalid filepath' do
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
context 'when allow_release_as_web_access_format FF is disabled' do
before do
stub_feature_flags(allow_release_as_web_access_format: false)
end
it 'will not allow sessionless authentication' do
expect_next_instance_of(::Projects::ReleasesController) do |controller|
expect(controller).not_to receive(:authenticate_sessionless_user!)
end
subject
end
end
context 'when allow_release_as_web_access_format FF is enabled' do
it 'will allow sessionless users to download the file' do
subject
expect(controller.current_user).to eq(user)
expect(response).to have_gitlab_http_status(:redirect)
expect(response).to redirect_to(link.url)
end
end
end
end
context 'invalid filepath' do
let(:invalid_filepath) { 'bin/darwin-amd64' }
let(:subject) { create(:release_link, name: 'linux-amd64 binaries', filepath: invalid_filepath, url: 'https://aws.example.com/s3/project/bin/hello-darwin-amd64') }
it 'cannot create an invalid filepath' do
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
end
end
end

View File

@ -606,7 +606,7 @@ RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state
def expect_to_rate_limit(hook, threshold:, throttled: false)
expect(Gitlab::ApplicationRateLimiter).to receive(:throttled?)
.with(:web_hook_calls_high, scope: [hook.parent.root_namespace], threshold: threshold)
.with(:web_hook_calls, scope: [hook.parent.root_namespace], threshold: threshold)
.and_return(throttled)
end
@ -621,7 +621,7 @@ RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state
context 'when rate limiting is configured' do
let_it_be(:threshold) { 3 }
let_it_be(:plan_limits) { create(:plan_limits, :default_plan, web_hook_calls_high: threshold) }
let_it_be(:plan_limits) { create(:plan_limits, :default_plan, web_hook_calls: threshold) }
it 'queues a worker and tracks the call' do
expect_to_rate_limit(project_hook, threshold: threshold)