Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
86e3fc6eed
commit
b6ffa18741
|
|
@ -61,6 +61,9 @@ default:
|
|||
workflow:
|
||||
name: '$PIPELINE_NAME'
|
||||
rules:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/514740
|
||||
- if: '$GITLAB_USER_LOGIN == "gitlab-crowdin-bot" && $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_APPROVED != "true"'
|
||||
when: never
|
||||
- if: '$CI_PIPELINE_SOURCE == "pipeline" && $GITALY_TEST'
|
||||
variables:
|
||||
<<: *default-ruby-variables
|
||||
|
|
|
|||
|
|
@ -708,8 +708,9 @@ class ApplicationSetting < ApplicationRecord
|
|||
validates :sign_in_restrictions, json_schema: { filename: 'application_setting_sign_in_restrictions' }
|
||||
|
||||
jsonb_accessor :search,
|
||||
global_search_issues_enabled: [:boolean, { default: true }],
|
||||
global_search_merge_requests_enabled: [:boolean, { default: true }],
|
||||
global_search_work_items_enabled: [:boolean, { default: true }],
|
||||
global_search_snippet_titles_enabled: [:boolean, { default: true }],
|
||||
global_search_users_enabled: [:boolean, { default: true }]
|
||||
|
||||
validates :search, json_schema: { filename: 'application_setting_search' }
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Packages
|
||||
module Nuget
|
||||
class CheckDuplicatesService < BaseService
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
ExtractionError = Class.new(StandardError)
|
||||
|
||||
def execute
|
||||
return ServiceResponse.success if package_settings_allow_duplicates?
|
||||
|
||||
ServiceResponse.error(
|
||||
message: 'A package with the same name and version already exists',
|
||||
reason: :conflict
|
||||
)
|
||||
rescue ExtractionError => e
|
||||
ServiceResponse.error(message: e.message, reason: :bad_request)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def package_settings_allow_duplicates?
|
||||
package_settings.nuget_duplicates_allowed? || package_settings.class.duplicates_allowed?(existing_package)
|
||||
end
|
||||
|
||||
def package_settings
|
||||
project.namespace.package_settings
|
||||
end
|
||||
strong_memoize_attr :package_settings
|
||||
|
||||
def existing_package
|
||||
::Packages::Nuget::PackageFinder
|
||||
.new(
|
||||
current_user,
|
||||
project,
|
||||
package_name: metadata[:package_name],
|
||||
package_version: metadata[:package_version]
|
||||
)
|
||||
.execute
|
||||
.first
|
||||
end
|
||||
strong_memoize_attr :existing_package
|
||||
|
||||
def metadata
|
||||
if params[:remote_url].present?
|
||||
::Packages::Nuget::ExtractMetadataContentService
|
||||
.new(nuspec_file_content)
|
||||
.execute
|
||||
.payload
|
||||
else # to cover the case when package file is on disk not in object storage
|
||||
Zip::InputStream.open(params[:file]) do |zip|
|
||||
::Packages::Nuget::MetadataExtractionService
|
||||
.new(zip)
|
||||
.execute
|
||||
.payload
|
||||
end
|
||||
end
|
||||
end
|
||||
strong_memoize_attr :metadata
|
||||
|
||||
def nuspec_file_content
|
||||
response = ::Packages::Nuget::ExtractRemoteMetadataFileService
|
||||
.new(params[:remote_url])
|
||||
.execute
|
||||
|
||||
raise ExtractionError, response.message if response.error?
|
||||
|
||||
response.payload
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -67,8 +67,6 @@ module Packages
|
|||
end
|
||||
|
||||
def duplicates_allowed?
|
||||
return true if Feature.disabled?(:create_nuget_packages_on_the_fly, @package_file.project)
|
||||
|
||||
::Namespace::PackageSetting.duplicates_allowed?(existing_package)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,18 @@
|
|||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"global_search_work_items_enabled": {
|
||||
"global_search_issues_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable global search for work items"
|
||||
"description": "Enable global search for issues"
|
||||
},
|
||||
"global_search_merge_requests_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable global search for merge requests"
|
||||
},
|
||||
"global_search_snippet_titles_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable global search for snippets"
|
||||
},
|
||||
"global_search_users_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable global search for users"
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: create_nuget_packages_on_the_fly
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/506035
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176359
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/509970
|
||||
milestone: '17.8'
|
||||
group: group::package registry
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: use_primary_and_secondary_stores_for_db_load_balancing
|
||||
feature_issue_url: https://gitlab.com/gitlab-com/gl-infra/data-access/durability/team/-/issues/39
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175822
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/509561
|
||||
milestone: '17.8'
|
||||
group: group::durability
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: use_primary_store_as_default_for_db_load_balancing
|
||||
feature_issue_url: https://gitlab.com/gitlab-com/gl-infra/data-access/durability/team/-/issues/39
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175822
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/509562
|
||||
milestone: '17.8'
|
||||
group: group::durability
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddVulnerabilityFindingsRemediationsProjectIdNotNullConstraint < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.9'
|
||||
|
||||
def up
|
||||
add_not_null_constraint :vulnerability_findings_remediations, :project_id, validate: false
|
||||
end
|
||||
|
||||
def down
|
||||
remove_not_null_constraint :vulnerability_findings_remediations, :project_id
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PrepareVulnerabilityFindingsRemediationsProjectIdNotNullValidation < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.9'
|
||||
|
||||
CONSTRAINT_NAME = :check_65e61a488a
|
||||
|
||||
def up
|
||||
prepare_async_check_constraint_validation :vulnerability_findings_remediations, name: CONSTRAINT_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
unprepare_async_check_constraint_validation :vulnerability_findings_remediations, name: CONSTRAINT_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
561891712cb74052e6d0d218ad7fb9cec592e60878ebfbf1c31389d1e7b70eb6
|
||||
|
|
@ -0,0 +1 @@
|
|||
49f94c7d150ad203295b6e08686d0a1463da2a93494f1323a5bae383840aba90
|
||||
|
|
@ -26418,6 +26418,9 @@ ALTER TABLE security_scans
|
|||
ALTER TABLE vulnerability_scanners
|
||||
ADD CONSTRAINT check_37608c9db5 CHECK ((char_length(vendor) <= 255)) NOT VALID;
|
||||
|
||||
ALTER TABLE vulnerability_findings_remediations
|
||||
ADD CONSTRAINT check_65e61a488a CHECK ((project_id IS NOT NULL)) NOT VALID;
|
||||
|
||||
ALTER TABLE wiki_repository_states
|
||||
ADD CONSTRAINT check_69aed91301 CHECK ((project_id IS NOT NULL)) NOT VALID;
|
||||
|
||||
|
|
|
|||
|
|
@ -448,8 +448,8 @@ In the UI:
|
|||
Your changes are automatically saved.
|
||||
|
||||
WARNING:
|
||||
If the .nuspec file isn't located in the root of the package, the package might
|
||||
not be recognized as a duplicate.
|
||||
If the .nuspec file isn't located in the root of the package or the beginning of the archive, the package might
|
||||
not be recognized as a duplicate right away. However, it will be rejected later, and an error will be shown in the UI.
|
||||
|
||||
## Install packages
|
||||
|
||||
|
|
|
|||
|
|
@ -451,3 +451,21 @@ See [the release permissions](#release-permissions) for more information.
|
|||
### Note about storage
|
||||
|
||||
This feature is built on top of Git tags, so virtually no extra data is needed besides to create the release itself. Additional assets and the release evidence that is automatically generated consume storage.
|
||||
|
||||
### GitLab CLI version requirement
|
||||
|
||||
The way of using the [`release` keyword](../../../ci/yaml/index.md#release) is planned to change.
|
||||
The `release-cli` tool is [being replaced](https://gitlab.com/groups/gitlab-org/-/epics/15437) by the [GitLab CLI tool](https://gitlab.com/gitlab-org/cli/).
|
||||
|
||||
You must use GitLab CLI tool `v1.52.0` or higher, or you could receive one of these error messages:
|
||||
|
||||
- `Error: glab command not found. Please install glab v1.52.0 or higher.`
|
||||
- `Error: Please use glab v1.52.0 or higher.`
|
||||
|
||||
There are two ways to have the GitLab CLI tool:
|
||||
|
||||
- If you use the `registry.gitlab.com/gitlab-org/release-cli:<version>` container image,
|
||||
you can start using either `registry.gitlab.com/gitlab-org/cli:v1.52.0` or
|
||||
`registry.gitlab.com/gitlab-org/release-cli:v0.21.0`, which contains `glab` `v1.52.0`.
|
||||
- If you manually installed the release-cli or GitLab CLI tool on your runners,
|
||||
make sure the GitLab CLI version is at least `v1.52.0`.
|
||||
|
|
|
|||
|
|
@ -80,31 +80,6 @@ module API
|
|||
PACKAGE_FILENAME
|
||||
end
|
||||
|
||||
def legacy_upload_nuget_package_file(symbol_package: false)
|
||||
project = project_or_group
|
||||
authorize_upload!(project)
|
||||
|
||||
bad_request!('File is too large') if project.actual_limits.exceeded?(:nuget_max_file_size,
|
||||
params[:package].size)
|
||||
|
||||
file_params = params.merge(
|
||||
file: params[:package],
|
||||
file_name: file_name(symbol_package)
|
||||
)
|
||||
|
||||
check_duplicate(file_params, symbol_package)
|
||||
|
||||
package = ::Packages::CreateTemporaryPackageService.new(
|
||||
project, current_user, declared_params.merge(build: current_authenticated_job)
|
||||
).execute(:nuget, name: temp_file_name(symbol_package))
|
||||
|
||||
package_file = ::Packages::CreatePackageFileService
|
||||
.new(package, file_params.merge(build: current_authenticated_job))
|
||||
.execute
|
||||
|
||||
::Packages::Nuget::ExtractionWorker.perform_async(package_file.id) # rubocop:disable CodeReuse/Worker -- not newly introduced
|
||||
end
|
||||
|
||||
def upload_nuget_package_file(symbol_package: false)
|
||||
authorize_upload!(project_or_group)
|
||||
|
||||
|
|
@ -118,28 +93,26 @@ module API
|
|||
build: current_authenticated_job
|
||||
)
|
||||
|
||||
if !symbol_package && nuspec_file_service.success?
|
||||
if !symbol_package && extracted_metadata.success?
|
||||
# Create or update package on the fly if nuspec file is extracted successfully,
|
||||
# otherwise fallback to the background job
|
||||
create_or_update_package(file_params)
|
||||
elsif symbol_package || nuspec_file_service.cause.nuspec_extraction_failed?
|
||||
elsif symbol_package || extracted_metadata.cause.nuspec_extraction_failed?
|
||||
create_temp_package_and_enqueue_worker(file_params, symbol_package)
|
||||
else
|
||||
render_api_error!(nuspec_file_service.message, nuspec_file_service.reason)
|
||||
render_api_error!(extracted_metadata.message, extracted_metadata.reason)
|
||||
end
|
||||
end
|
||||
|
||||
def create_or_update_package(file_params)
|
||||
response = Packages::Nuget::CreateOrUpdatePackageService
|
||||
.new(project_or_group, current_user, file_params.merge(nuspec_file_content: nuspec_file_service.payload))
|
||||
.new(project_or_group, current_user, file_params.merge(nuspec_file_content: extracted_metadata.payload))
|
||||
.execute
|
||||
|
||||
render_api_error!(response.message, response.reason) if response.error?
|
||||
end
|
||||
|
||||
def create_temp_package_and_enqueue_worker(file_params, symbol_package)
|
||||
check_duplicate(file_params, symbol_package)
|
||||
|
||||
package = ::Packages::CreateTemporaryPackageService.new(
|
||||
project_or_group, current_user, declared_params.merge(build: current_authenticated_job)
|
||||
).execute(:nuget, name: temp_file_name(symbol_package))
|
||||
|
|
@ -150,7 +123,7 @@ module API
|
|||
::Packages::Nuget::ExtractionWorker.perform_async(package_file.id) # rubocop:disable CodeReuse/Worker -- not newly introduced
|
||||
end
|
||||
|
||||
def nuspec_file_service
|
||||
def extracted_metadata
|
||||
if params['package.remote_url'].present?
|
||||
::Packages::Nuget::ExtractRemoteMetadataFileService.new(params['package.remote_url']).execute
|
||||
else # file on disk
|
||||
|
|
@ -161,22 +134,10 @@ module API
|
|||
rescue ::Packages::Nuget::ExtractMetadataFileService::ExtractionError => e
|
||||
ServiceResponse.error(message: e.message, reason: :bad_request)
|
||||
end
|
||||
strong_memoize_attr :nuspec_file_service
|
||||
|
||||
def check_duplicate(file_params, symbol_package)
|
||||
return if symbol_package || Feature.enabled?(:create_nuget_packages_on_the_fly, project_or_group)
|
||||
|
||||
service_params = file_params.merge(remote_url: params['package.remote_url'])
|
||||
response = ::Packages::Nuget::CheckDuplicatesService.new(project_or_group, current_user, service_params).execute
|
||||
render_api_error!(response.message, response.reason) if response.error?
|
||||
end
|
||||
strong_memoize_attr :extracted_metadata
|
||||
|
||||
def publish_package(symbol_package: false)
|
||||
if Feature.enabled?(:create_nuget_packages_on_the_fly, project_or_group)
|
||||
upload_nuget_package_file(symbol_package: symbol_package)
|
||||
else
|
||||
legacy_upload_nuget_package_file(symbol_package: symbol_package)
|
||||
end
|
||||
upload_nuget_package_file(symbol_package: symbol_package)
|
||||
|
||||
track_package_event(
|
||||
symbol_package ? 'push_symbol_package' : 'push_package',
|
||||
|
|
|
|||
|
|
@ -8,11 +8,15 @@ module Gitlab
|
|||
CREATE_SINGLE_FLAGS = %i[name description tag_name tag_message ref released_at].freeze
|
||||
CREATE_ARRAY_FLAGS = %i[milestones].freeze
|
||||
|
||||
RELEASE_CLI_REQUIRED_VERSION = '0.20.0'
|
||||
GLAB_REQUIRED_VERSION = '1.50.0'
|
||||
# If these versions or error messages are updated, the documentation should be updated as well.
|
||||
|
||||
RELEASE_CLI_REQUIRED_VERSION = '0.21.0'
|
||||
GLAB_REQUIRED_VERSION = '1.52.0'
|
||||
TROUBLE_SHOOTING_URL = Rails.application.routes.url_helpers.help_page_url('user/project/releases/index.md', anchor: 'gitlab-cli-version-requirement')
|
||||
|
||||
GLAB_COMMAND_CHECK_COMMAND = <<~BASH.freeze
|
||||
if ! command -v glab &> /dev/null; then
|
||||
echo "Error: glab command not found. Please use release-cli image #{RELEASE_CLI_REQUIRED_VERSION} or higher, or install glab #{GLAB_REQUIRED_VERSION} or higher."
|
||||
echo "Error: glab command not found. Please install glab #{GLAB_REQUIRED_VERSION} or higher. Troubleshooting: #{TROUBLE_SHOOTING_URL}"
|
||||
exit 1
|
||||
fi
|
||||
BASH
|
||||
|
|
@ -21,7 +25,7 @@ module Gitlab
|
|||
if [ "$(printf "%s\n%s" "#{GLAB_REQUIRED_VERSION}" "$(glab --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')" | sort -V | head -n1)" = "#{GLAB_REQUIRED_VERSION}" ]; then
|
||||
echo "Validating glab version. OK"
|
||||
else
|
||||
echo "Error: Please use release-cli image #{RELEASE_CLI_REQUIRED_VERSION} or higher, or install glab #{GLAB_REQUIRED_VERSION} or higher."
|
||||
echo "Error: Please use glab #{GLAB_REQUIRED_VERSION} or higher. Troubleshooting: #{TROUBLE_SHOOTING_URL}"
|
||||
exit 1
|
||||
fi
|
||||
BASH
|
||||
|
|
@ -29,7 +33,9 @@ module Gitlab
|
|||
GLAB_LOGIN_COMMAND = 'glab auth login --job-token $CI_JOB_TOKEN --hostname $CI_SERVER_FQDN --api-protocol $CI_SERVER_PROTOCOL'
|
||||
GLAB_MAIN_COMMAND = 'GITLAB_HOST=$CI_SERVER_URL glab -R $CI_PROJECT_PATH'
|
||||
GLAB_CREATE_COMMAND = "#{GLAB_MAIN_COMMAND} release create".freeze
|
||||
GLAB_PUBLISH_TO_CATALOG_FLAG = '--publish-to-catalog'
|
||||
GLAB_PUBLISH_TO_CATALOG_FLAG = '--publish-to-catalog' # enables publishing to the catalog after creating the release
|
||||
GLAB_NO_UPDATE_FLAG = '--no-update' # disables updating the release if it already exists
|
||||
GLAB_NO_CLOSE_MILESTONE_FLAG = '--no-close-milestone' # disables closing the milestone after creating the release
|
||||
|
||||
attr_reader :job, :config
|
||||
|
||||
|
|
@ -71,7 +77,7 @@ module Gitlab
|
|||
command.concat(" --ref \"#{config[:ref]}\"") if config[:ref].present?
|
||||
command.concat(" --tag-message \"#{config[:tag_message]}\"") if config[:tag_message].present?
|
||||
command.concat(" --released-at \"#{config[:released_at]}\"") if config[:released_at].present?
|
||||
command.concat(" #{GLAB_PUBLISH_TO_CATALOG_FLAG}")
|
||||
command.concat(" #{GLAB_PUBLISH_TO_CATALOG_FLAG} #{GLAB_NO_UPDATE_FLAG} #{GLAB_NO_CLOSE_MILESTONE_FLAG}")
|
||||
command.freeze
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ module Gitlab
|
|||
ALL_CLASSES = [
|
||||
Gitlab::Redis::BufferedCounter,
|
||||
Gitlab::Redis::Cache,
|
||||
Gitlab::Redis::ClusterDbLoadBalancing,
|
||||
Gitlab::Redis::ClusterSessions,
|
||||
Gitlab::Redis::DbLoadBalancing,
|
||||
Gitlab::Redis::FeatureFlag,
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Redis
|
||||
class ClusterDbLoadBalancing < ::Gitlab::Redis::Wrapper
|
||||
class << self
|
||||
# The data we store on DbLoadBalancing used to be stored on SharedState.
|
||||
def config_fallback
|
||||
SharedState
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,16 +2,12 @@
|
|||
|
||||
module Gitlab
|
||||
module Redis
|
||||
class DbLoadBalancing < ::Gitlab::Redis::MultiStoreWrapper
|
||||
class DbLoadBalancing < ::Gitlab::Redis::Wrapper
|
||||
class << self
|
||||
# The data we store on DbLoadBalancing used to be stored on SharedState.
|
||||
def config_fallback
|
||||
SharedState
|
||||
end
|
||||
|
||||
def multistore
|
||||
MultiStore.create_using_pool(ClusterDbLoadBalancing.pool, pool, store_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
import nodePath from 'node:path';
|
||||
import nodeFs from 'node:fs/promises';
|
||||
|
||||
describe('asset patching in @gitlab/web-ide', () => {
|
||||
const PATH_PUBLIC_VSCODE = nodePath.join(
|
||||
nodePath.dirname(require.resolve('@gitlab/web-ide')),
|
||||
'public/vscode',
|
||||
);
|
||||
const PATH_EXTENSION_HOST_HTML = nodePath.join(
|
||||
PATH_PUBLIC_VSCODE,
|
||||
'out/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html',
|
||||
);
|
||||
|
||||
it('prevents xss by patching parentOrigin in webIdeExtensionHost.html', async () => {
|
||||
const content = await nodeFs.readFile(PATH_EXTENSION_HOST_HTML, { encoding: 'utf-8' });
|
||||
|
||||
// https://gitlab.com/gitlab-org/security/gitlab-web-ide-vscode-fork/-/issues/1#note_1905417620
|
||||
expect(content).toContain('const parentOrigin = window.origin;');
|
||||
});
|
||||
|
||||
it('contains vscode/node_modules', async () => {
|
||||
// Yarn was doing weird stuff when trying to include a directory called `node_modules`
|
||||
// We think we've worked around this, but let's add a test just in case.
|
||||
// https://gitlab.com/gitlab-org/gitlab-web-ide/-/merge_requests/400
|
||||
const stat = await nodeFs.stat(`${PATH_PUBLIC_VSCODE}/node_modules`);
|
||||
|
||||
expect(stat.isDirectory()).toBe(true);
|
||||
});
|
||||
|
||||
it('doesnt have extraneous html files', async () => {
|
||||
const allChildren = await nodeFs.readdir(PATH_PUBLIC_VSCODE, {
|
||||
encoding: 'utf-8',
|
||||
recursive: true,
|
||||
});
|
||||
const htmlChildren = allChildren.filter((x) => x.endsWith('.html'));
|
||||
|
||||
/**
|
||||
* ## What in the world is this test doing!?
|
||||
*
|
||||
* This test was introduced when we were fixing a [security vulnerability][1] related to GitLab self-hosting
|
||||
* problematic `.html` files. These files could be exploited through an `iframe` on an `evil.com` and will
|
||||
* assume the user's cookie authentication. Boom!
|
||||
*
|
||||
* ## How do I know if an `.html` file is vulnerable?
|
||||
*
|
||||
* - The `.html` file used the `postMessage` API and allowed any `origin` which enabled any external site to
|
||||
* open it in an `iframe` and communicate to it.
|
||||
* - The `iframe` exposed some internal VSCode message bus that could allow arbitrary requests. So watch out for
|
||||
* `fetch`.
|
||||
*
|
||||
* [1]: https://gitlab.com/gitlab-org/security/gitlab-web-ide-vscode-fork/-/issues/1#note_1905417620
|
||||
*
|
||||
* ========== If expectation fails and you can't see the full comment... LOOK UP! ==============
|
||||
*/
|
||||
expect(htmlChildren).toEqual([
|
||||
// This is the only HTML file we expect and it's protected by the other test.
|
||||
'out/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html',
|
||||
// HTML files from "extensions" should be safe (since they only work in an extension host environment really).
|
||||
// We're going to list them out here though to err on the side of caution.
|
||||
'extensions/microsoft-authentication/media/index.html',
|
||||
'extensions/gitlab-vscode-extension/webviews/security_finding/index.html',
|
||||
'extensions/gitlab-vscode-extension/webviews/gitlab_duo_chat/index.html',
|
||||
'extensions/gitlab-vscode-extension/assets/language-server/webviews/duo-workflow/index.html',
|
||||
'extensions/gitlab-vscode-extension/assets/language-server/webviews/duo-chat/index.html',
|
||||
'extensions/gitlab-vscode-extension/assets/language-server/webviews/chat/index.html',
|
||||
'extensions/github-authentication/media/index.html',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
@ -51,13 +51,16 @@ RSpec.describe Gitlab::Ci::Build::Releaser, feature_category: :continuous_integr
|
|||
|
||||
it 'generates glab scripts' do
|
||||
expect(script).to eq([
|
||||
"if ! command -v glab &> /dev/null; then\n echo \"Error: glab command not found. Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n",
|
||||
"if [ \"$(printf \"%s\n%s\" \"1.50.0\" \"$(glab --version | grep -oE '[0-9]+.[0-9]+.[0-9]+')\" | sort -V | head -n1)\" = \"1.50.0\" ]; then\n echo \"Validating glab version. OK\"\nelse\n echo \"Error: Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n",
|
||||
"if ! command -v glab &> /dev/null; then\n " \
|
||||
"echo \"Error: glab command not found. Please install glab 1.52.0 or higher. Troubleshooting: http://localhost/help/user/project/releases/index.md#gitlab-cli-version-requirement\"\n exit 1\nfi\n",
|
||||
"if [ \"$(printf \"%s\n%s\" \"1.52.0\" \"$(glab --version | grep -oE '[0-9]+.[0-9]+.[0-9]+')\" | sort -V | head -n1)\" = \"1.52.0\" ]; " \
|
||||
"then\n echo \"Validating glab version. OK\"\nelse\n echo \"Error: Please use glab 1.52.0 or higher. Troubleshooting: http://localhost/help/user/project/releases/index.md#gitlab-cli-version-requirement\"\n exit 1\nfi\n",
|
||||
'glab auth login --job-token $CI_JOB_TOKEN --hostname $CI_SERVER_FQDN --api-protocol $CI_SERVER_PROTOCOL',
|
||||
'GITLAB_HOST=$CI_SERVER_URL glab -R $CI_PROJECT_PATH release create "release-$CI_COMMIT_SHA" ' \
|
||||
'--assets-links "[{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\",\"link_type\":\"other\",\"filepath\":\"/pretty/asset/1\"},{\"name\":\"asset2\",\"url\":\"https://example.com/assets/2\"}]" ' \
|
||||
'--milestone "m1,m2,m3" --name "Release $CI_COMMIT_SHA" --notes "Created using the release-cli $EXTRA_DESCRIPTION" ' \
|
||||
'--ref "$CI_COMMIT_SHA" --tag-message "Annotated tag message" --released-at "2020-07-15T08:00:00Z" --publish-to-catalog'
|
||||
'--ref "$CI_COMMIT_SHA" --tag-message "Annotated tag message" --released-at "2020-07-15T08:00:00Z" ' \
|
||||
'--publish-to-catalog --no-update --no-close-milestone'
|
||||
])
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -83,13 +83,15 @@ RSpec.describe Gitlab::Ci::Build::Step, feature_category: :continuous_integratio
|
|||
|
||||
it 'returns glab scripts' do
|
||||
expect(subject.script).to eq([
|
||||
"if ! command -v glab &> /dev/null; then\n echo \"Error: glab command not found. Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n",
|
||||
"if [ \"$(printf \"%s\n%s\" \"1.50.0\" \"$(glab --version | grep -oE '[0-9]+.[0-9]+.[0-9]+')\" | sort -V | head -n1)\" = \"1.50.0\" ]; then\n echo \"Validating glab version. OK\"\nelse\n echo \"Error: Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n",
|
||||
"if ! command -v glab &> /dev/null; then\n " \
|
||||
"echo \"Error: glab command not found. Please install glab 1.52.0 or higher. Troubleshooting: http://localhost/help/user/project/releases/index.md#gitlab-cli-version-requirement\"\n exit 1\nfi\n",
|
||||
"if [ \"$(printf \"%s\n%s\" \"1.52.0\" \"$(glab --version | grep -oE '[0-9]+.[0-9]+.[0-9]+')\" | sort -V | head -n1)\" = \"1.52.0\" ]; " \
|
||||
"then\n echo \"Validating glab version. OK\"\nelse\n echo \"Error: Please use glab 1.52.0 or higher. Troubleshooting: http://localhost/help/user/project/releases/index.md#gitlab-cli-version-requirement\"\n exit 1\nfi\n",
|
||||
'glab auth login --job-token $CI_JOB_TOKEN --hostname $CI_SERVER_FQDN --api-protocol $CI_SERVER_PROTOCOL',
|
||||
'GITLAB_HOST=$CI_SERVER_URL glab -R $CI_PROJECT_PATH release create "release-$CI_COMMIT_SHA" ' \
|
||||
'--assets-links "[{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\"}]" ' \
|
||||
'--name "Release $CI_COMMIT_SHA" --notes "Created using the release-cli $EXTRA_DESCRIPTION" ' \
|
||||
'--ref "$CI_COMMIT_SHA" --publish-to-catalog'
|
||||
'--ref "$CI_COMMIT_SHA" --publish-to-catalog --no-update --no-close-milestone'
|
||||
])
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Redis::ClusterDbLoadBalancing, feature_category: :scalability do
|
||||
include_examples "redis_new_instance_shared_examples", 'cluster_db_load_balancing', Gitlab::Redis::SharedState
|
||||
end
|
||||
|
|
@ -5,10 +5,4 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::Redis::DbLoadBalancing, feature_category: :scalability do
|
||||
include_examples "redis_new_instance_shared_examples", 'db_load_balancing', Gitlab::Redis::SharedState
|
||||
include_examples "redis_shared_examples"
|
||||
include_examples "multi_store_wrapper_shared_examples"
|
||||
|
||||
it 'migrates from self to ClusterDbLoadBalancing' do
|
||||
expect(described_class.multistore.secondary_pool).to eq(described_class.pool)
|
||||
expect(described_class.multistore.primary_pool).to eq(Gitlab::Redis::ClusterDbLoadBalancing.pool)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -53,8 +53,9 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
|
|||
it { expect(setting.resource_access_token_notify_inherited).to be(false) }
|
||||
it { expect(setting.lock_resource_access_token_notify_inherited).to be(false) }
|
||||
it { expect(setting.ropc_without_client_credentials).to be(true) }
|
||||
it { expect(setting.global_search_issues_enabled).to be(true) }
|
||||
it { expect(setting.global_search_merge_requests_enabled).to be(true) }
|
||||
it { expect(setting.global_search_work_items_enabled).to be(true) }
|
||||
it { expect(setting.global_search_snippet_titles_enabled).to be(true) }
|
||||
it { expect(setting.global_search_users_enabled).to be(true) }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,150 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Packages::Nuget::CheckDuplicatesService, feature_category: :package_registry do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:file_name) { 'package.nupkg' }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
file_name: file_name,
|
||||
file: fixture_file_upload('spec/fixtures/packages/nuget/package.nupkg')
|
||||
}
|
||||
end
|
||||
|
||||
let(:service) { described_class.new(project, user, params) }
|
||||
|
||||
describe '#execute' do
|
||||
subject(:execute) { service.execute }
|
||||
|
||||
shared_examples 'returning error' do |reason:, message:|
|
||||
it 'returns an error' do
|
||||
response = execute
|
||||
|
||||
expect(response.status).to eq(:error)
|
||||
expect(response.reason).to eq(reason)
|
||||
expect(response.message).to eq(message)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'returning success' do
|
||||
it 'returns success' do
|
||||
response = execute
|
||||
|
||||
expect(response.status).to eq(:success)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'handling duplicates disallowed when package exists' do
|
||||
it_behaves_like 'returning error', reason: :conflict,
|
||||
message: 'A package with the same name and version already exists'
|
||||
|
||||
context 'with nuget_duplicate_exception_regex' do
|
||||
before do
|
||||
package_settings.update_column(:nuget_duplicate_exception_regex, ".*#{existing_package.name.last(3)}.*")
|
||||
end
|
||||
|
||||
it_behaves_like 'returning success'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with existing package' do
|
||||
let_it_be(:existing_package) { create(:nuget_package, :with_metadatum, project: project, version: '1.7.15.0') }
|
||||
let_it_be(:metadata) do
|
||||
{
|
||||
package_name: existing_package.name,
|
||||
package_version: existing_package.version,
|
||||
authors: 'authors',
|
||||
description: 'description'
|
||||
}
|
||||
end
|
||||
|
||||
context 'when nuget duplicates are allowed' do
|
||||
before do
|
||||
allow_next_instance_of(Namespace::PackageSetting) do |instance|
|
||||
allow(instance).to receive(:nuget_duplicates_allowed?).and_return(true)
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'returning success'
|
||||
end
|
||||
|
||||
context 'when nuget duplicates are not allowed' do
|
||||
let!(:package_settings) do
|
||||
create(:namespace_package_setting, :group, namespace: project.namespace, nuget_duplicates_allowed: false)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(::Packages::Nuget::ExtractMetadataContentService).to receive(:new) do
|
||||
instance_double(
|
||||
::Packages::Nuget::ExtractMetadataContentService, execute: ServiceResponse.success(payload: metadata)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when package file is in object storage' do
|
||||
let(:params) { super().merge(remote_url: 'https://example.com') }
|
||||
|
||||
before do
|
||||
allow_next_instance_of(::Packages::Nuget::ExtractRemoteMetadataFileService) do |instance|
|
||||
allow(instance).to receive(:execute)
|
||||
.and_return(ServiceResponse.success(payload: Nokogiri::XML::Document.new))
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'handling duplicates disallowed when package exists'
|
||||
|
||||
context 'when ExtractRemoteMetadataFileService returns an error' do
|
||||
before do
|
||||
allow_next_instance_of(::Packages::Nuget::ExtractRemoteMetadataFileService) do |instance|
|
||||
allow(instance).to receive(:execute).and_return(ServiceResponse.error(message: 'nuspec file not found'))
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'returning error', reason: :bad_request, message: 'nuspec file not found'
|
||||
end
|
||||
|
||||
context 'when version is normalized' do
|
||||
let(:metadata) { super().merge(package_version: '1.7.15') }
|
||||
|
||||
it_behaves_like 'handling duplicates disallowed when package exists'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when package file is on disk' do
|
||||
it_behaves_like 'handling duplicates disallowed when package exists'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with non existing package' do
|
||||
let_it_be(:metadata) do
|
||||
{ package_name: 'foo', package_version: '1.0.0', authors: 'author', description: 'description' }
|
||||
end
|
||||
|
||||
before do
|
||||
allow_next_instance_of(::Packages::Nuget::MetadataExtractionService) do |instance|
|
||||
allow(instance).to receive(:execute).and_return(ServiceResponse.success(payload: metadata))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when nuget duplicates are allowed' do
|
||||
let_it_be(:package_settings) do
|
||||
create(:namespace_package_setting, :group, namespace: project.namespace, nuget_duplicates_allowed: true)
|
||||
end
|
||||
|
||||
it_behaves_like 'returning success'
|
||||
end
|
||||
|
||||
context 'when nuget duplicates are not allowed' do
|
||||
let_it_be(:package_settings) do
|
||||
create(:namespace_package_setting, :group, namespace: project.namespace, nuget_duplicates_allowed: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'returning success'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -132,16 +132,6 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
|
|||
end
|
||||
|
||||
it_behaves_like 'raising an', described_class::DuplicatePackageError, with_message: "A package 'DummyProject.DummyPackage' with version '1.0.0' already exists"
|
||||
|
||||
context 'when create_nuget_packages_on_the_fly feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(create_nuget_packages_on_the_fly: false)
|
||||
end
|
||||
|
||||
it 'does not raise an error' do
|
||||
expect { subject }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ RSpec.shared_examples 'process nuget upload' do |user_type, status, add_member =
|
|||
shared_context 'with nuspec extraction service stub' do
|
||||
before do
|
||||
Grape::Endpoint.before_each do |endpoint|
|
||||
allow(endpoint).to receive(:nuspec_file_service).and_return(service_result)
|
||||
allow(endpoint).to receive(:extracted_metadata).and_return(service_result)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -212,23 +212,6 @@ RSpec.shared_examples 'process nuget upload' do |user_type, status, add_member =
|
|||
package_file = target.packages.last.package_files.reload.last
|
||||
expect(package_file.file_name).to eq('dummyproject.withmetadata.1.2.3.nupkg')
|
||||
end
|
||||
|
||||
context 'when create_nuget_packages_on_the_fly feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(create_nuget_packages_on_the_fly: false)
|
||||
end
|
||||
|
||||
it 'calls the extraction worker' do
|
||||
expect(::Packages::Nuget::ExtractionWorker).to receive(:perform_async).once
|
||||
expect { subject }
|
||||
.to change { target.packages.count }.by(1)
|
||||
.and change { Packages::PackageFile.count }.by(1)
|
||||
expect(response).to have_gitlab_http_status(status)
|
||||
|
||||
package_file = target.packages.last.package_files.reload.last
|
||||
expect(package_file.file_name).to eq(file_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when nuspec extraction fails' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue