Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-01-19 00:09:27 +00:00
parent 75d101a1c2
commit dcd01617a7
60 changed files with 475 additions and 173 deletions

View File

@ -110,7 +110,6 @@ Layout/LineContinuationSpacing:
- 'ee/spec/services/phone_verification/telesign_client/send_verification_code_service_spec.rb'
- 'ee/spec/services/phone_verification/users/send_verification_code_service_spec.rb'
- 'ee/spec/services/security/security_orchestration_policies/ci_configuration_service_spec.rb'
- 'ee/spec/services/security/security_orchestration_policies/legacy_ci_configuration_service_spec.rb'
- 'ee/spec/views/compliance_management/compliance_framework/_project_settings.html.haml_spec.rb'
- 'ee/spec/workers/ee/issuable_export_csv_worker_spec.rb'
- 'lib/api/dependency_proxy.rb'

View File

@ -1,5 +1,4 @@
import { flatten } from 'lodash';
import { hideFlash } from '~/flash';
import dateFormat from '~/lib/dateformat';
import { slugify } from '~/lib/utils/text_utility';
import { urlQueryToFilter } from '~/vue_shared/components/filtered_search_bar/filtered_search_utils';
@ -74,10 +73,8 @@ export const getDataZoomOption = ({
};
export const removeFlash = (type = 'alert') => {
const flashEl = document.querySelector(`.flash-${type}`);
if (flashEl) {
hideFlash(flashEl);
}
// flash-warning don't have dismiss button.
document.querySelector(`.flash-${type} .js-close`)?.click();
};
/**

View File

@ -1,5 +1,5 @@
import $ from 'jquery';
import { createAlert, hideFlash } from './flash';
import { createAlert } from './flash';
import axios from './lib/utils/axios_utils';
import { parseBoolean } from './lib/utils/common_utils';
import { __ } from './locale';
@ -18,7 +18,7 @@ export default () => {
};
const hideConsentMessage = () =>
hideFlash(document.querySelector('.service-ping-consent-message'));
document.querySelector('.service-ping-consent-message .js-close')?.click();
axios
.put(url, data)

View File

@ -139,9 +139,11 @@ export default {
this.fetchingApprovals = false;
})
.catch(() =>
createAlert({
message: FETCH_ERROR,
}),
this.alerts.push(
createAlert({
message: FETCH_ERROR,
}),
),
);
},
methods: {
@ -154,9 +156,11 @@ export default {
this.updateApproval(
() => this.service.approveMergeRequest(),
() =>
createAlert({
message: APPROVE_ERROR,
}),
this.alerts.push(
createAlert({
message: APPROVE_ERROR,
}),
),
);
},
approveWithAuth(data) {
@ -167,9 +171,11 @@ export default {
this.hasApprovalAuthError = true;
return;
}
createAlert({
message: APPROVE_ERROR,
});
this.alerts.push(
createAlert({
message: APPROVE_ERROR,
}),
);
},
);
},
@ -177,9 +183,11 @@ export default {
this.updateApproval(
() => this.service.unapproveMergeRequest(),
() =>
createAlert({
message: UNAPPROVE_ERROR,
}),
this.alerts.push(
createAlert({
message: UNAPPROVE_ERROR,
}),
),
);
},
updateApproval(serviceFn, errFn) {

View File

@ -1,14 +1,15 @@
import { hideFlash } from '~/flash';
export default {
data() {
return {
alerts: [],
};
},
methods: {
clearError() {
this.$emit('clearError');
this.hasApprovalAuthError = false;
const flashEl = document.querySelector('.flash-alert');
if (flashEl) {
hideFlash(flashEl);
}
this.alerts.forEach((alert) => alert.dismiss());
this.alerts = [];
},
refreshApprovals() {
return this.service.fetchApprovals().then((data) => {

View File

@ -68,8 +68,10 @@ class Admin::ApplicationSettings::AppearancesController < Admin::ApplicationCont
def allowed_appearance_params
%i[
title
pwa_short_name
description
pwa_name
pwa_short_name
pwa_description
logo
logo_cache
header_logo

View File

@ -29,28 +29,6 @@ class Admin::RunnersController < Admin::ApplicationController
end
end
def destroy
Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
redirect_to admin_runners_path, status: :found
end
def resume
if Ci::Runners::UpdateRunnerService.new(@runner).execute(active: true).success?
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
end
end
def pause
if Ci::Runners::UpdateRunnerService.new(@runner).execute(active: false).success?
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
end
end
def tag_list
tags = Autocomplete::ActsAsTaggableOn::TagsFinder.new(params: params).execute

View File

@ -9,8 +9,6 @@ class Groups::RunnersController < Groups::ApplicationController
urgency :low
def index
finder = Ci::RunnersFinder.new(current_user: current_user, params: { group: @group })
@group_runners_limited_count = finder.execute.except(:limit, :offset).page.total_count_with_limit(:all, limit: 1000)
@group_runner_registration_token = @group.runners_token if can?(current_user, :register_group_runners, group)
Gitlab::Tracking.event(self.class.name, 'index', user: current_user, namespace: @group)

View File

@ -53,6 +53,7 @@ class Import::BulkImportsController < ApplicationController
end
def create
return render json: { success: false }, status: :too_many_requests if throttled_request?
return render json: { success: false }, status: :unprocessable_entity unless valid_create_params?
responses = create_params.map do |entry|
@ -204,4 +205,8 @@ class Import::BulkImportsController < ApplicationController
def current_user_bulk_imports
current_user.bulk_imports.gitlab
end
def throttled_request?
::Gitlab::ApplicationRateLimiter.throttled_request?(request, current_user, :bulk_import, scope: current_user)
end
end

View File

@ -4,14 +4,26 @@ module AppearancesHelper
include MarkupHelper
include Gitlab::Utils::StrongMemoize
def appearance_short_name
Appearance.current&.pwa_short_name.presence || _('GitLab')
end
def brand_title
current_appearance&.title.presence || default_brand_title
end
def appearance_pwa_name
current_appearance&.pwa_name.presence || _('GitLab')
end
def appearance_pwa_short_name
current_appearance&.pwa_short_name.presence || _('GitLab')
end
def appearance_pwa_description
current_appearance&.pwa_description.presence ||
_("The complete DevOps platform. " \
"One application with endless possibilities. " \
"Organizations rely on GitLabs source code management, " \
"CI/CD, security, and more to deliver software rapidly.")
end
def default_brand_title
# This resides in a separate method so that EE can easily redefine it.
_('GitLab Community Edition')

View File

@ -6,8 +6,10 @@ class Appearance < ApplicationRecord
include WithUploads
attribute :title, default: ''
attribute :pwa_short_name, default: ''
attribute :description, default: ''
attribute :pwa_name, default: ''
attribute :pwa_short_name, default: ''
attribute :pwa_description, default: ''
attribute :new_project_guidelines, default: ''
attribute :profile_image_guidelines, default: ''
attribute :header_message, default: ''
@ -22,6 +24,18 @@ class Appearance < ApplicationRecord
cache_markdown_field :header_message, pipeline: :broadcast_message
cache_markdown_field :footer_message, pipeline: :broadcast_message
validates :pwa_name,
length: { maximum: 255, message: N_("is too long (maximum is %{count} characters)") },
allow_blank: true
validates :pwa_short_name,
length: { maximum: 255, message: N_("is too long (maximum is %{count} characters)") },
allow_blank: true
validates :pwa_description,
length: { maximum: 2048, message: N_("is too long (maximum is %{count} characters)") },
allow_blank: true
validates :logo, file_size: { maximum: 1.megabyte }
validates :pwa_icon, file_size: { maximum: 1.megabyte }
validates :header_logo, file_size: { maximum: 1.megabyte }

View File

@ -1,3 +1,3 @@
- page_title s_('Runners|Runners')
#js-group-runners{ data: group_runners_data_attributes(@group).merge({ group_runners_limited_count: @group_runners_limited_count, registration_token: @group_runner_registration_token }) }
#js-group-runners{ data: group_runners_data_attributes(@group).merge({registration_token: @group_runner_registration_token }) }

View File

@ -1,7 +1,7 @@
{
"name": "<%= Appearance.current&.title.presence || _('GitLab') %>",
"short_name": "<%= appearance_short_name %>",
"description": "<%= Appearance.current&.description.presence || _("The complete DevOps platform. One application with endless possibilities. Organizations rely on GitLabs source code management, CI/CD, security, and more to deliver software rapidly.") %>",
"name": "<%= appearance_pwa_name %>",
"short_name": "<%= appearance_pwa_short_name %>",
"description": "<%= appearance_pwa_description %>",
"start_url": "<%= explore_projects_path %>",
"scope": "<%= root_path %>",
"display": "browser",

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class AddPwaAttributesToAppearances < Gitlab::Database::Migration[2.1]
# rubocop:disable Migration/AddLimitToTextColumns
def up
add_column :appearances, :pwa_name, :text
add_column :appearances, :pwa_description, :text
end
# rubocop:enable Migration/AddLimitToTextColumns
def down
remove_column :appearances, :pwa_name
remove_column :appearances, :pwa_description
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class AddTextLimitToPwaAttributes < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
def up
add_text_limit :appearances, :pwa_name, 255
add_text_limit :appearances, :pwa_description, 2048
end
def down
remove_text_limit :appearances, :pwa_name
remove_text_limit :appearances, :pwa_description
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
class RenameWebHookCallsToWebHookCallsHigh < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
def up
rename_column_concurrently :plan_limits, :web_hook_calls, :web_hook_calls_high
end
def down
undo_rename_column_concurrently :plan_limits, :web_hook_calls, :web_hook_calls_high
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
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
end
def down
undo_cleanup_concurrent_column_rename :plan_limits, :web_hook_calls, :web_hook_calls_high
end
end

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class AddTmpIndexToCiBuildNeed < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
INDEX_NAME = :tmp_index_ci_build_needs_on_partition_id_and_id
TABLE_NAME = :ci_build_needs
def up
return unless Gitlab.com?
prepare_async_index(TABLE_NAME, [:partition_id, :id], where: 'partition_id = 101', name: INDEX_NAME)
end
def down
return unless Gitlab.com?
unprepare_async_index_by_name(TABLE_NAME, INDEX_NAME)
end
end

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class AddTmpIndexToCiPipelineVariable < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
INDEX_NAME = :tmp_index_ci_pipeline_variables_on_partition_id_and_id
TABLE_NAME = :ci_pipeline_variables
def up
return unless Gitlab.com?
prepare_async_index(TABLE_NAME, [:partition_id, :id], where: 'partition_id = 101', name: INDEX_NAME)
end
def down
return unless Gitlab.com?
unprepare_async_index_by_name(TABLE_NAME, INDEX_NAME)
end
end

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class AddTmpIndexToCiBuildReportResults < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
INDEX_NAME = :tmp_index_ci_build_report_results_on_partition_id_and_id
TABLE_NAME = :ci_build_report_results
def up
return unless Gitlab.com?
prepare_async_index(TABLE_NAME, [:partition_id, :id], where: 'partition_id = 101', name: INDEX_NAME)
end
def down
return unless Gitlab.com?
unprepare_async_index_by_name(TABLE_NAME, INDEX_NAME)
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddTmpIndexToCiBuildsOnPartitionId < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
INDEX_NAME = :tmp_index_ci_builds_on_partition_id_and_id
def up
return unless Gitlab.com?
prepare_async_index :ci_builds, [:partition_id, :id], name: INDEX_NAME, where: 'partition_id = 101'
end
def down
return unless Gitlab.com?
unprepare_async_index :ci_builds, [:partition_id, :id], name: INDEX_NAME, where: 'partition_id = 101'
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddTmpIndexToCiPipelinesOnPartitionId < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
INDEX_NAME = :tmp_index_ci_pipelines_on_partition_id_and_id
def up
return unless Gitlab.com?
prepare_async_index :ci_pipelines, [:partition_id, :id], name: INDEX_NAME, where: 'partition_id = 101'
end
def down
return unless Gitlab.com?
unprepare_async_index :ci_pipelines, [:partition_id, :id], name: INDEX_NAME, where: 'partition_id = 101'
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddTmpIndexToCiStagesOnPartitionId < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
INDEX_NAME = :tmp_index_ci_stages_on_partition_id_and_id
def up
return unless Gitlab.com?
prepare_async_index :ci_stages, [:partition_id, :id], name: INDEX_NAME, where: 'partition_id = 101'
end
def down
return unless Gitlab.com?
unprepare_async_index :ci_stages, [:partition_id, :id], name: INDEX_NAME, where: 'partition_id = 101'
end
end

View File

@ -0,0 +1 @@
2935444c762f3fdc8bd04055fc6048be4b637d2136e71a84479135e44c50856b

View File

@ -0,0 +1 @@
0105a4d40b8ecb6e4c1bc543001f223bf9bbb25c03288dd394859d4926bb4801

View File

@ -0,0 +1 @@
a567168b41dc56069e485ef303aeb69b967e685d463ed44d99f54dc96cdf9bbd

View File

@ -0,0 +1 @@
052c36d0911e104f8bc42f3229170c234f3c61555f53712adbfee6ab385233b3

View File

@ -0,0 +1 @@
a2cb76b2138b3edc014c01c4b130fcd58bf81a10c68c897376f5bf8d69d5a660

View File

@ -0,0 +1 @@
97a52b54895ff5f5ea3c2dac6148c8d8110081bffe9064c50547b776ec56e78a

View File

@ -0,0 +1 @@
775eb98fc81524f667cfab4dfdcee9bd668143c7286011dd1f0d40f87fc06ab0

View File

@ -0,0 +1 @@
4d38db045a0d505ea8f62327de8cc58fc0896e7c194cf71ca28ba08113757696

View File

@ -0,0 +1 @@
28b959fe3c79a9d24e24d296112ee7ada71b9932e608cbf5fa2d01cac3db0247

View File

@ -0,0 +1 @@
0a34ab643f8ac5fdd0dd604f53244fe07a88ebf992fed7863bf38300817c9acb

View File

@ -11065,8 +11065,12 @@ CREATE TABLE appearances (
profile_image_guidelines_html text,
pwa_short_name text,
pwa_icon text,
pwa_name text,
pwa_description text,
CONSTRAINT appearances_profile_image_guidelines CHECK ((char_length(profile_image_guidelines) <= 4096)),
CONSTRAINT check_13b2165eca CHECK ((char_length(pwa_name) <= 255)),
CONSTRAINT check_5c3fd63577 CHECK ((char_length(pwa_short_name) <= 255)),
CONSTRAINT check_5e0e6f24ed CHECK ((char_length(pwa_description) <= 2048)),
CONSTRAINT check_5e5b7ac344 CHECK ((char_length(pwa_icon) <= 1024))
);
@ -19565,7 +19569,6 @@ CREATE TABLE plan_limits (
helm_max_file_size bigint DEFAULT 5242880 NOT NULL,
ci_registered_group_runners integer DEFAULT 1000 NOT NULL,
ci_registered_project_runners integer DEFAULT 1000 NOT NULL,
web_hook_calls integer DEFAULT 0 NOT NULL,
ci_daily_pipeline_schedule_triggers integer DEFAULT 0 NOT NULL,
ci_max_artifact_size_running_container_scanning integer DEFAULT 0 NOT NULL,
ci_max_artifact_size_cluster_image_scanning integer DEFAULT 0 NOT NULL,
@ -19589,7 +19592,9 @@ CREATE TABLE plan_limits (
pipeline_hierarchy_size integer DEFAULT 1000 NOT NULL,
enforcement_limit integer DEFAULT 0 NOT NULL,
notification_limit integer DEFAULT 0 NOT NULL,
dashboard_limit_enabled_at timestamp with time zone
dashboard_limit_enabled_at timestamp with time zone,
web_hook_calls_high integer DEFAULT 0,
CONSTRAINT check_0fa68f370e CHECK ((web_hook_calls_high IS NOT NULL))
);
CREATE SEQUENCE plan_limits_id_seq

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: 10)
Plan.default.actual_limits.update!(web_hook_calls_high: 10)
```
Set the limit to `0` to disable it.

View File

@ -29,8 +29,10 @@ Example response:
```json
{
"title": "GitLab Test Instance",
"pwa_short_name": "GitLab",
"description": "gitlab-test.example.com",
"pwa_name": "GitLab PWA",
"pwa_short_name": "GitLab",
"pwa_description": "GitLab as PWA",
"pwa_icon": "/uploads/-/system/appearance/pwa_icon/1/pwa_logo.png",
"logo": "/uploads/-/system/appearance/logo/1/logo.png",
"header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",
@ -56,8 +58,10 @@ PUT /application/appearance
| Attribute | Type | Required | Description |
| --------------------------------- | ------- | -------- | ----------- |
| `title` | string | no | Instance title on the sign in / sign up page
| `pwa_short_name` | string | no | Optional, short name for Progressive Web App
| `description` | string | no | Markdown text shown on the sign in / sign up page
| `pwa_name` | string | no | Full name of the Progressive Web App. Used for the attribute `name` in `manifest.json`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375708) in GitLab 15.8.
| `pwa_short_name` | string | no | Short name for Progressive Web App. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375708) in GitLab 15.8.
| `pwa_description` | string | no | An explanation of what the Progressive Web App does. Used for the attribute `description` in `manifest.json`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375708) in GitLab 15.8.
| `pwa_icon` | mixed | no | Icon used for Progressive Web App. See [Change logo](#change-logo). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375708) in GitLab 15.8.
| `logo` | mixed | no | Instance image used on the sign in / sign up page. See [Change logo](#change-logo)
| `header_logo` | mixed | no | Instance image used for the main navigation bar
@ -79,8 +83,10 @@ Example response:
```json
{
"title": "GitLab Test Instance",
"pwa_short_name": "GitLab",
"description": "gitlab-test.example.com",
"pwa_name": "GitLab PWA",
"pwa_short_name": "GitLab",
"pwa_description": "GitLab as PWA",
"pwa_icon": "/uploads/-/system/appearance/pwa_icon/1/pwa_logo.png",
"logo": "/uploads/-/system/appearance/logo/1/logo.png",
"header_logo": "/uploads/-/system/appearance/header_logo/1/header.png",

View File

@ -78,7 +78,7 @@ sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::Ba
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/329511) in GitLab 13.12.
> - Enabled on GitLab.com.
> - Recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-batched-background-migrations).
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-background-migrations).
There can be [risks when disabling released features](../administration/feature_flags.md#risks-when-disabling-released-features).
Refer to this feature's version history for more details.
@ -203,17 +203,21 @@ Feature.disable(:optimize_batched_migrations)
## Troubleshooting
### Enable or disable batched background migrations
### Enable or disable background migrations
In extremely limited circumstances, a GitLab administrator can disable the
`execute_batched_migrations_on_schedule` [feature flag](../administration/feature_flags.md).
This flag is enabled by default, and should be disabled only as a last resort
In extremely limited circumstances, a GitLab administrator can disable either or
both of these [feature flags](../administration/feature_flags.md):
- `execute_background_migrations`
- `execute_batched_migrations_on_schedule`
These flags are enabled by default. Disable them only as a last resort
to limit database operations in special circumstances, like database host maintenance.
WARNING:
Do not disable this flag unless you fully understand the ramifications. If you disable
the `execute_batched_migrations_on_schedule` feature flag, GitLab upgrades may fail
and data loss may occur.
Do not disable either of these flags unless you fully understand the ramifications. If you disable
the `execute_background_migrations` or `execute_batched_migrations_on_schedule` feature flag,
GitLab upgrades might fail and data loss might occur.
### Database migrations failing because of batched background migration not finished

View File

@ -21,12 +21,18 @@ To use the Security Dashboards, you must:
## When Security Dashboards are updated
The Security Dashboards show results of the most recent security scan on the
The Security Dashboards show results of scans from the most recent completed pipeline on the
[default branch](../../project/repository/branches/default.md).
Security scans run only when the default branch updates, so
information on the Security Dashboard might not reflect newly-discovered vulnerabilities.
Dashboards are updated with the result of completed pipelines run on the default branch; they do not include vulnerabilities discovered in pipelines from other un-merged branches.
To run a daily security scan,
If you use manual jobs, for example gate deployments, in the default branch's pipeline,
the results of any scans are only updated when the job has been successfully run.
If manual jobs are skipped regularly, you should to define the job as optional,
using the [`allow_failure`](../../../ci/jobs/job_control.md#types-of-manual-jobs) attribute.
To ensure regular security scans (even on infrequently developed projects),
you should use [scan execution policies](../../../user/application_security/policies/scan-execution-policies.md).
Alternatively, you can
[configure a scheduled pipeline](../../../ci/pipelines/schedules.md).
## Reduce false negatives in dependency scans

View File

@ -37,8 +37,8 @@ PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module
| Attribute | Type | Required | Description |
| -------------------| --------------- | ---------| -------------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../../../api/rest/index.md#namespaced-path-encoding). |
| `module-name` | string | yes | The package name. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z), digits (0-9), and hyphens (`-`).
| `module-system` | string | yes | The package system. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z), digits (0-9), and hyphens (`-`). More information can be found in the [Terraform Module Registry Protocol documentation](https://www.terraform.io/internals/module-registry-protocol).
| `module-name` | string | yes | The package name. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z) and digits (0-9). The package name can't exceed 64 characters.
| `module-system` | string | yes | The package system. **Supported syntax**: One to 64 ASCII characters, including lowercase letters (a-z) and digits (0-9). The package system can't exceed 64 characters. More information can be found in the [Terraform Module Registry Protocol documentation](https://www.terraform.io/internals/module-registry-protocol).
| `module-version` | string | yes | The package version. It must be valid according to the [Semantic Versioning Specification](https://semver.org/).
Provide the file content in the request body.

View File

@ -243,7 +243,7 @@ like in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87727/diffs?diff_i
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available per project or for your entire instance, ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `moved_mr_sidebar`.
On GitLab.com, this feature is not available.
On GitLab.com, this feature is enabled in the following projects: `gitlab-org/gitlab`, `gitlab-com/www-gitlab-com`, and `gitlab-org/customers-gitlab-com`.
When this feature flag is enabled, you can find the following actions in
**Merge request actions** (**{ellipsis_v}**) on the top right:

View File

@ -26,8 +26,10 @@ module API
end
params do
optional :title, type: String, desc: 'Instance title on the sign in / sign up page'
optional :pwa_short_name, type: String, desc: 'Optional, short name for Progressive Web App'
optional :description, type: String, desc: 'Markdown text shown on the sign in / sign up page'
optional :pwa_name, type: String, desc: 'Name of the Progressive Web App'
optional :pwa_short_name, type: String, desc: 'Optional, short name for Progressive Web App'
optional :pwa_description, type: String, desc: 'An explanation of what the Progressive Web App does'
# TODO: remove rubocop disable - https://gitlab.com/gitlab-org/gitlab/issues/14960
optional :logo, type: File, desc: 'Instance image used on the sign in / sign up page' # rubocop:disable Scalability/FileUploads
optional :pwa_icon, type: File, desc: 'Icon used for Progressive Web App' # rubocop:disable Scalability/FileUploads

View File

@ -91,6 +91,8 @@ module API
end
end
post do
check_rate_limit!(:bulk_import, scope: current_user)
params[:entities].each do |entity|
if entity[:destination_name]
entity[:destination_slug] ||= entity[:destination_name]

View File

@ -4,8 +4,10 @@ module API
module Entities
class Appearance < Grape::Entity
expose :title
expose :pwa_short_name
expose :description
expose :pwa_name
expose :pwa_short_name
expose :pwa_description
expose :logo do |appearance, options|
appearance.logo.url

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: { interval: 1.minute },
web_hook_calls_high: { 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 },
@ -55,7 +55,8 @@ module Gitlab
phone_verification_verify_code: { threshold: 10, interval: 10.minutes },
namespace_exists: { threshold: 20, interval: 1.minute },
fetch_google_ip_list: { threshold: 10, interval: 1.minute },
jobs_index: { threshold: 600, interval: 1.minute }
jobs_index: { threshold: 600, interval: 1.minute },
bulk_import: { threshold: 6, interval: 1.minute }
}.freeze
end

View File

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

View File

@ -111,7 +111,7 @@
"codesandbox-api": "0.0.23",
"compression-webpack-plugin": "^5.0.2",
"copy-webpack-plugin": "^6.4.1",
"core-js": "^3.27.1",
"core-js": "^3.27.2",
"cron-validator": "^1.1.1",
"cronstrue": "^1.122.0",
"cropper": "^2.3.0",

View File

@ -11,8 +11,10 @@ RSpec.describe Admin::ApplicationSettings::AppearancesController do
let(:create_params) do
{
title: 'Foo',
pwa_short_name: 'F',
description: 'Bar',
pwa_name: 'GitLab PWA',
pwa_short_name: 'F',
pwa_description: 'This is GitLab as PWA',
header_message: header_message,
footer_message: footer_message
}
@ -26,6 +28,11 @@ RSpec.describe Admin::ApplicationSettings::AppearancesController do
post :create, params: { appearance: create_params }
expect(Appearance.current).to have_attributes(
title: 'Foo',
description: 'Bar',
pwa_name: 'GitLab PWA',
pwa_short_name: 'F',
pwa_description: 'This is GitLab as PWA',
header_message: header_message,
footer_message: footer_message,
email_header_and_footer_enabled: false,
@ -41,6 +48,11 @@ RSpec.describe Admin::ApplicationSettings::AppearancesController do
post :create, params: { appearance: create_params }
expect(Appearance.current).to have_attributes(
title: 'Foo',
description: 'Bar',
pwa_name: 'GitLab PWA',
pwa_short_name: 'F',
pwa_description: 'This is GitLab as PWA',
header_message: header_message,
footer_message: footer_message,
email_header_and_footer_enabled: true

View File

@ -105,49 +105,6 @@ RSpec.describe Admin::RunnersController, feature_category: :runner_fleet do
end
end
describe '#destroy' do
it 'destroys the runner' do
expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
delete :destroy, params: { id: runner.id }
expect(response).to have_gitlab_http_status(:found)
expect(Ci::Runner.find_by(id: runner.id)).to be_nil
end
end
describe '#resume' do
it 'marks the runner as active and ticks the queue' do
runner.update!(active: false)
expect do
post :resume, params: { id: runner.id }
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(:found)
expect(runner.active).to eq(true)
end
end
describe '#pause' do
it 'marks the runner as inactive and ticks the queue' do
runner.update!(active: true)
expect do
post :pause, params: { id: runner.id }
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(:found)
expect(runner.active).to eq(false)
end
end
describe 'GET #runner_setup_scripts' do
it 'renders the setup scripts' do
get :runner_setup_scripts, params: { os: 'linux', arch: 'amd64' }

View File

@ -30,7 +30,6 @@ RSpec.describe Groups::RunnersController, feature_category: :runner_fleet do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
expect(assigns(:group_runners_limited_count)).to be(2)
end
it 'tracks the event' do

View File

@ -9,14 +9,12 @@ RSpec.describe Import::BulkImportsController, feature_category: :importers do
stub_application_setting(bulk_import_enabled: true)
sign_in(user)
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(false)
end
context 'when user is signed in' do
context 'when bulk_import feature flag is enabled' do
before do
stub_feature_flags(bulk_import: true)
end
describe 'POST configure' do
before do
allow_next_instance_of(BulkImports::Clients::HTTP) do |instance|
@ -400,6 +398,18 @@ RSpec.describe Import::BulkImportsController, feature_category: :importers do
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
context 'when request exceeds rate limits' do
it 'prevents user from starting a new migration' do
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
post :create, params: { bulk_import: {} }
request
expect(response).to have_gitlab_http_status(:too_many_requests)
end
end
end
end

View File

@ -13,7 +13,12 @@ import {
} from '~/vue_merge_request_widget/components/approvals/messages';
import eventHub from '~/vue_merge_request_widget/event_hub';
jest.mock('~/flash');
const mockAlertDismiss = jest.fn();
jest.mock('~/flash', () => ({
createAlert: jest.fn().mockImplementation(() => ({
dismiss: mockAlertDismiss,
})),
}));
const RULE_NAME = 'first_rule';
const TEST_HELP_PATH = 'help/path';
@ -267,9 +272,16 @@ describe('MRWidget approvals', () => {
return nextTick();
});
it('flashes error message', () => {
it('shows an alert with error message', () => {
expect(createAlert).toHaveBeenCalledWith({ message: APPROVE_ERROR });
});
it('clears the previous alert', () => {
expect(mockAlertDismiss).toHaveBeenCalledTimes(0);
findAction().vm.$emit('click');
expect(mockAlertDismiss).toHaveBeenCalledTimes(1);
});
});
});
});

View File

@ -10,17 +10,45 @@ RSpec.describe AppearancesHelper do
allow(helper).to receive(:current_user).and_return(user)
end
describe '#appearance_short_name' do
describe '#appearance_pwa_name' do
it 'returns the default value' do
create(:appearance)
expect(helper.appearance_short_name).to match('GitLab')
expect(helper.appearance_pwa_name).to match('GitLab')
end
it 'returns the customized value' do
create(:appearance, pwa_name: 'GitLab as PWA')
expect(helper.appearance_pwa_name).to match('GitLab as PWA')
end
end
describe '#appearance_pwa_short_name' do
it 'returns the default value' do
create(:appearance)
expect(helper.appearance_pwa_short_name).to match('GitLab')
end
it 'returns the customized value' do
create(:appearance, pwa_short_name: 'Short')
expect(helper.appearance_short_name).to match('Short')
expect(helper.appearance_pwa_short_name).to match('Short')
end
end
describe '#appearance_pwa_description' do
it 'returns the default value' do
create(:appearance)
expect(helper.appearance_pwa_description).to include('The complete DevOps platform.')
end
it 'returns the customized value' do
create(:appearance, pwa_description: 'This is a description')
expect(helper.appearance_pwa_description).to match('This is a description')
end
end

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: limit)
create(:plan_limits, plan: plan, web_hook_calls_high: 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: limit)
create(:plan_limits, plan: plan, web_hook_calls_high: 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: limit)
create(:plan_limits, plan: plan, web_hook_calls_high: limit)
end
context 'when hook is not rate-limited' do

View File

@ -3,6 +3,7 @@
require 'spec_helper'
RSpec.describe Appearance do
using RSpec::Parameterized::TableSyntax
subject { build(:appearance) }
it { include(CacheableAttributes) }
@ -14,8 +15,10 @@ RSpec.describe Appearance do
subject(:appearance) { described_class.new }
it { expect(appearance.title).to eq('') }
it { expect(appearance.pwa_short_name).to eq('') }
it { expect(appearance.description).to eq('') }
it { expect(appearance.pwa_name).to eq('') }
it { expect(appearance.pwa_short_name).to eq('') }
it { expect(appearance.pwa_description).to eq('') }
it { expect(appearance.new_project_guidelines).to eq('') }
it { expect(appearance.profile_image_guidelines).to eq('') }
it { expect(appearance.header_message).to eq('') }
@ -96,6 +99,41 @@ RSpec.describe Appearance do
it { is_expected.not_to allow_value('000').for(:message_font_color) }
end
shared_examples 'validation allows' do
it { is_expected.to allow_value(value).for(attribute) }
end
shared_examples 'validation permits with message' do
it { is_expected.not_to allow_value(value).for(attribute).with_message(message) }
end
context 'valid pwa attributes' do
where(:attribute, :value) do
:pwa_name | nil
:pwa_name | "G" * 255
:pwa_short_name | nil
:pwa_short_name | "S" * 255
:pwa_description | nil
:pwa_description | "T" * 2048
end
with_them do
it_behaves_like 'validation allows'
end
end
context 'invalid pwa attributes' do
where(:attribute, :value, :message) do
:pwa_name | "G" * 256 | 'is too long (maximum is 255 characters)'
:pwa_short_name | "S" * 256 | 'is too long (maximum is 255 characters)'
:pwa_description | "T" * 2049 | 'is too long (maximum is 2048 characters)'
end
with_them do
it_behaves_like 'validation permits with message'
end
end
describe 'email_header_and_footer_enabled' do
context 'default email_header_and_footer_enabled flag value' do
it 'returns email_header_and_footer_enabled as true' do

View File

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

View File

@ -34,7 +34,9 @@ RSpec.describe API::Appearance, 'Appearance', feature_category: :navigation do
expect(json_response['new_project_guidelines']).to eq('')
expect(json_response['profile_image_guidelines']).to eq('')
expect(json_response['title']).to eq('')
expect(json_response['pwa_name']).to eq('')
expect(json_response['pwa_short_name']).to eq('')
expect(json_response['pwa_description']).to eq('')
end
end
end
@ -53,8 +55,10 @@ RSpec.describe API::Appearance, 'Appearance', feature_category: :navigation do
it "allows updating the settings" do
put api("/application/appearance", admin), params: {
title: "GitLab Test Instance",
pwa_short_name: "GitLab PWA",
description: "gitlab-test.example.com",
pwa_name: "GitLab PWA Test",
pwa_short_name: "GitLab PWA",
pwa_description: "This is GitLab as PWA",
new_project_guidelines: "Please read the FAQs for help.",
profile_image_guidelines: "Custom profile image guidelines"
}
@ -74,7 +78,9 @@ RSpec.describe API::Appearance, 'Appearance', feature_category: :navigation do
expect(json_response['new_project_guidelines']).to eq('Please read the FAQs for help.')
expect(json_response['profile_image_guidelines']).to eq('Custom profile image guidelines')
expect(json_response['title']).to eq('GitLab Test Instance')
expect(json_response['pwa_name']).to eq('GitLab PWA Test')
expect(json_response['pwa_short_name']).to eq('GitLab PWA')
expect(json_response['pwa_description']).to eq('This is GitLab as PWA')
end
end

View File

@ -13,6 +13,8 @@ RSpec.describe API::BulkImports, feature_category: :importers do
before do
stub_application_setting(bulk_import_enabled: true)
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(false)
end
shared_examples 'disabled feature' do
@ -73,6 +75,24 @@ RSpec.describe API::BulkImports, feature_category: :importers do
end
describe 'POST /bulk_imports' do
let(:request) { post api('/bulk_imports', user), params: params }
let(:destination_param) { { destination_slug: 'destination_slug' } }
let(:params) do
{
configuration: {
url: 'http://gitlab.example',
access_token: 'access_token'
},
entities: [
{
source_type: 'group_entity',
source_full_path: 'full_path',
destination_namespace: 'destination_namespace'
}.merge(destination_param)
]
}
end
before do
allow_next_instance_of(BulkImports::Clients::HTTP) do |instance|
allow(instance)
@ -86,23 +106,6 @@ RSpec.describe API::BulkImports, feature_category: :importers do
end
shared_examples 'starting a new migration' do
let(:request) { post api('/bulk_imports', user), params: params }
let(:params) do
{
configuration: {
url: 'http://gitlab.example',
access_token: 'access_token'
},
entities: [
{
source_type: 'group_entity',
source_full_path: 'full_path',
destination_namespace: 'destination_namespace'
}.merge(destination_param)
]
}
end
it 'starts a new migration' do
request
@ -278,6 +281,17 @@ RSpec.describe API::BulkImports, feature_category: :importers do
end
include_examples 'disabled feature'
context 'when request exceeds rate limits' do
it 'prevents user from starting a new migration' do
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
request
expect(response).to have_gitlab_http_status(:too_many_requests)
expect(json_response['message']['error']).to eq('This endpoint has been requested too many times. Try again later.')
end
end
end
describe 'GET /bulk_imports/entities' do

View File

@ -7,14 +7,15 @@ RSpec.describe PwaController, feature_category: :navigation do
it 'responds with json' do
get manifest_path(format: :json)
expect(response.body).to include('The complete DevOps platform.')
expect(Gitlab::Json.parse(response.body)).to include({ 'name' => 'GitLab' })
expect(Gitlab::Json.parse(response.body)).to include({ 'short_name' => 'GitLab' })
expect(response.body).to include('The complete DevOps platform.')
expect(response).to have_gitlab_http_status(:success)
end
context 'with customized appearance' do
let_it_be(:appearance) do
create(:appearance, title: 'Long name', pwa_short_name: 'Short name', description: 'This is a test')
create(:appearance, pwa_name: 'PWA name', pwa_short_name: 'Short name', pwa_description: 'This is a test')
end
it 'uses custom values', :aggregate_failures do
@ -22,7 +23,7 @@ RSpec.describe PwaController, feature_category: :navigation do
expect(Gitlab::Json.parse(response.body)).to include({
'description' => 'This is a test',
'name' => 'Long name',
'name' => 'PWA name',
'short_name' => 'Short name'
})
expect(response).to have_gitlab_http_status(:success)

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, scope: [hook.parent.root_namespace], threshold: threshold)
.with(:web_hook_calls_high, 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: threshold) }
let_it_be(:plan_limits) { create(:plan_limits, :default_plan, web_hook_calls_high: threshold) }
it 'queues a worker and tracks the call' do
expect_to_rate_limit(project_hook, threshold: threshold)

View File

@ -3999,10 +3999,10 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
core-js@^3.27.1, core-js@^3.6.5:
version "3.27.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.27.1.tgz#23cc909b315a6bb4e418bf40a52758af2103ba46"
integrity sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==
core-js@^3.27.2, core-js@^3.6.5:
version "3.27.2"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.27.2.tgz#85b35453a424abdcacb97474797815f4d62ebbf7"
integrity sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w==
core-util-is@~1.0.0:
version "1.0.3"