Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
1d935c1c61
commit
c90ff9583a
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
# Cop supports --autocorrect.
|
||||
Lint/RedundantRequireStatement:
|
||||
Enabled: false
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
# Cop supports --autocorrect.
|
||||
Style/HashSyntax:
|
||||
Enabled: false
|
||||
|
|
@ -9,22 +9,27 @@
|
|||
"format": "uri"
|
||||
},
|
||||
"image": {
|
||||
"$ref": "#/definitions/image"
|
||||
"$ref": "#/definitions/image",
|
||||
"markdownDescription": "Defining `image` globally is deprecated. Use [`default`](https://docs.gitlab.com/ee/ci/yaml/#default) instead. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#globally-defined-image-services-cache-before_script-after_script)."
|
||||
},
|
||||
"services": {
|
||||
"$ref": "#/definitions/services"
|
||||
"$ref": "#/definitions/services",
|
||||
"markdownDescription": "Defining `services` globally is deprecated. Use [`default`](https://docs.gitlab.com/ee/ci/yaml/#default) instead. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#globally-defined-image-services-cache-before_script-after_script)."
|
||||
},
|
||||
"before_script": {
|
||||
"$ref": "#/definitions/before_script"
|
||||
"$ref": "#/definitions/before_script",
|
||||
"markdownDescription": "Defining `before_script` globally is deprecated. Use [`default`](https://docs.gitlab.com/ee/ci/yaml/#default) instead. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#globally-defined-image-services-cache-before_script-after_script)."
|
||||
},
|
||||
"after_script": {
|
||||
"$ref": "#/definitions/after_script"
|
||||
"$ref": "#/definitions/after_script",
|
||||
"markdownDescription": "Defining `after_script` globally is deprecated. Use [`default`](https://docs.gitlab.com/ee/ci/yaml/#default) instead. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#globally-defined-image-services-cache-before_script-after_script)."
|
||||
},
|
||||
"variables": {
|
||||
"$ref": "#/definitions/globalVariables"
|
||||
},
|
||||
"cache": {
|
||||
"$ref": "#/definitions/cache"
|
||||
"$ref": "#/definitions/cache",
|
||||
"markdownDescription": "Defining `cache` globally is deprecated. Use [`default`](https://docs.gitlab.com/ee/ci/yaml/#default) instead. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#globally-defined-image-services-cache-before_script-after_script)."
|
||||
},
|
||||
"!reference": {
|
||||
"$ref": "#/definitions/!reference"
|
||||
|
|
@ -744,39 +749,61 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"before_script": {
|
||||
"type": "array",
|
||||
"markdownDescription": "Defines scripts that should run *before* the job. Can be set globally or per job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#before_script).",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
"script": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
"minItems": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"optional_script": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"before_script": {
|
||||
"$ref": "#/definitions/optional_script",
|
||||
"markdownDescription": "Defines scripts that should run *before* the job. Can be set globally or per job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#before_script)."
|
||||
},
|
||||
"after_script": {
|
||||
"type": "array",
|
||||
"markdownDescription": "Defines scripts that should run *after* the job. Can be set globally or per job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#after_script).",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"$ref": "#/definitions/optional_script",
|
||||
"markdownDescription": "Defines scripts that should run *after* the job. Can be set globally or per job. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#after_script)."
|
||||
},
|
||||
"rules": {
|
||||
"type": [
|
||||
|
|
@ -1508,30 +1535,8 @@
|
|||
"$ref": "#/definitions/secrets"
|
||||
},
|
||||
"script": {
|
||||
"markdownDescription": "Shell scripts executed by the Runner. The only required property of jobs. Be careful with special characters (e.g. `:`, `{`, `}`, `&`) and use single or double quotes to avoid issues. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#script)",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
]
|
||||
"$ref": "#/definitions/script",
|
||||
"markdownDescription": "Shell scripts executed by the Runner. The only required property of jobs. Be careful with special characters (e.g. `:`, `{`, `}`, `&`) and use single or double quotes to avoid issues. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#script)"
|
||||
},
|
||||
"stage": {
|
||||
"description": "Define what stage the job will run in.",
|
||||
|
|
@ -2145,30 +2150,8 @@
|
|||
"markdownDescription": "Specifies lists of commands to execute on the runner at certain stages of job execution. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#hooks).",
|
||||
"properties": {
|
||||
"pre_get_sources_script": {
|
||||
"markdownDescription": "Specifies a list of commands to execute on the runner before updating the Git repository and any submodules. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#hookspre_get_sources_script).",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
]
|
||||
"$ref": "#/definitions/optional_script",
|
||||
"markdownDescription": "Specifies a list of commands to execute on the runner before updating the Git repository and any submodules. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#hookspre_get_sources_script)."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Types
|
|||
|
||||
authorize :read_custom_emoji
|
||||
|
||||
connection_type_class(Types::CountableConnectionType)
|
||||
connection_type_class Types::CountableConnectionType
|
||||
|
||||
expose_permissions Types::PermissionTypes::CustomEmoji
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ module Types
|
|||
class NoteType < BaseObject
|
||||
graphql_name 'Note'
|
||||
|
||||
connection_type_class Types::CountableConnectionType
|
||||
|
||||
authorize :read_note
|
||||
|
||||
expose_permissions Types::PermissionTypes::Note
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ module Types
|
|||
class UserType < ::Types::BaseObject
|
||||
graphql_name 'UserCore'
|
||||
description 'Core representation of a GitLab user.'
|
||||
|
||||
connection_type_class Types::CountableConnectionType
|
||||
|
||||
implements ::Types::UserInterface
|
||||
|
||||
authorize :read_user
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ class Namespace < ApplicationRecord
|
|||
validates :path,
|
||||
presence: true,
|
||||
length: { maximum: URL_MAX_LENGTH }
|
||||
validate :container_registry_namespace_path_validation
|
||||
|
||||
validates :path,
|
||||
format: { with: Gitlab::Regex.oci_repository_path_regex, message: Gitlab::Regex.oci_repository_path_regex_message },
|
||||
if: :path_changed?
|
||||
|
||||
validates :path, namespace_path: true, if: ->(n) { !n.project_namespace? }
|
||||
# Project path validator is used for project namespaces for now to assure
|
||||
|
|
@ -289,13 +292,6 @@ class Namespace < ApplicationRecord
|
|||
"#{self.class.reference_prefix}#{full_path}"
|
||||
end
|
||||
|
||||
def container_registry_namespace_path_validation
|
||||
return if Feature.disabled?(:restrict_special_characters_in_namespace_path, self)
|
||||
return if !path_changed? || path.match?(Gitlab::Regex.oci_repository_path_regex)
|
||||
|
||||
errors.add(:path, Gitlab::Regex.oci_repository_path_regex_message)
|
||||
end
|
||||
|
||||
def package_settings
|
||||
package_setting_relation || build_package_setting_relation
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: restrict_special_characters_in_namespace_path
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/111017
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/390954
|
||||
milestone: '15.9'
|
||||
type: development
|
||||
group: group::tenant scale
|
||||
default_enabled: true
|
||||
|
|
@ -236,6 +236,9 @@ class Gitlab::Seeder::CycleAnalytics # rubocop:disable Style/ClassAndModuleChild
|
|||
@developers << user
|
||||
end
|
||||
|
||||
project.group&.add_developer(admin)
|
||||
project.add_developer(admin)
|
||||
|
||||
AuthorizedProjectUpdate::ProjectRecalculateService.new(project).execute
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10593,6 +10593,7 @@ The connection type for [`MergeRequestAssignee`](#mergerequestassignee).
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestassigneeconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
|
||||
| <a id="mergerequestassigneeconnectionedges"></a>`edges` | [`[MergeRequestAssigneeEdge]`](#mergerequestassigneeedge) | A list of edges. |
|
||||
| <a id="mergerequestassigneeconnectionnodes"></a>`nodes` | [`[MergeRequestAssignee]`](#mergerequestassignee) | A list of nodes. |
|
||||
| <a id="mergerequestassigneeconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
|
@ -10710,6 +10711,7 @@ The connection type for [`MergeRequestParticipant`](#mergerequestparticipant).
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestparticipantconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
|
||||
| <a id="mergerequestparticipantconnectionedges"></a>`edges` | [`[MergeRequestParticipantEdge]`](#mergerequestparticipantedge) | A list of edges. |
|
||||
| <a id="mergerequestparticipantconnectionnodes"></a>`nodes` | [`[MergeRequestParticipant]`](#mergerequestparticipant) | A list of nodes. |
|
||||
| <a id="mergerequestparticipantconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
|
@ -10756,6 +10758,7 @@ The connection type for [`MergeRequestReviewer`](#mergerequestreviewer).
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestreviewerconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
|
||||
| <a id="mergerequestreviewerconnectionedges"></a>`edges` | [`[MergeRequestReviewerEdge]`](#mergerequestrevieweredge) | A list of edges. |
|
||||
| <a id="mergerequestreviewerconnectionnodes"></a>`nodes` | [`[MergeRequestReviewer]`](#mergerequestreviewer) | A list of nodes. |
|
||||
| <a id="mergerequestreviewerconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
|
@ -10894,6 +10897,7 @@ The connection type for [`Note`](#note).
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="noteconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
|
||||
| <a id="noteconnectionedges"></a>`edges` | [`[NoteEdge]`](#noteedge) | A list of edges. |
|
||||
| <a id="noteconnectionnodes"></a>`nodes` | [`[Note]`](#note) | A list of nodes. |
|
||||
| <a id="noteconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
|
@ -12450,6 +12454,7 @@ The connection type for [`UserCore`](#usercore).
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="usercoreconnectioncount"></a>`count` | [`Int!`](#int) | Total count of collection. |
|
||||
| <a id="usercoreconnectionedges"></a>`edges` | [`[UserCoreEdge]`](#usercoreedge) | A list of edges. |
|
||||
| <a id="usercoreconnectionnodes"></a>`nodes` | [`[UserCore]`](#usercore) | A list of nodes. |
|
||||
| <a id="usercoreconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
|
|
|||
|
|
@ -6,26 +6,14 @@ module API
|
|||
module BulkImports
|
||||
class DestinationSlugPath < Grape::Validations::Validators::Base
|
||||
def validate_param!(attr_name, params)
|
||||
if Feature.disabled?(:restrict_special_characters_in_namespace_path)
|
||||
return if params[attr_name] =~ Gitlab::Regex.group_path_regex
|
||||
return if params[attr_name] =~ Gitlab::Regex.oci_repository_path_regex
|
||||
|
||||
raise Grape::Exceptions::Validation.new(
|
||||
params: [@scope.full_name(attr_name)],
|
||||
message: "#{Gitlab::Regex.group_path_regex_message} " \
|
||||
"It can only contain alphanumeric characters, periods, underscores, and dashes. " \
|
||||
"For example, 'destination_namespace' not 'destination/namespace'"
|
||||
)
|
||||
else
|
||||
return if params[attr_name] =~ Gitlab::Regex.oci_repository_path_regex
|
||||
|
||||
raise Grape::Exceptions::Validation.new(
|
||||
params: [@scope.full_name(attr_name)],
|
||||
message: "#{Gitlab::Regex.oci_repository_path_regex_message} " \
|
||||
"It can only contain alphanumeric characters, periods, underscores, and dashes. " \
|
||||
"For example, 'destination_namespace' not 'destination/namespace'"
|
||||
)
|
||||
|
||||
end
|
||||
raise Grape::Exceptions::Validation.new(
|
||||
params: [@scope.full_name(attr_name)],
|
||||
message: "#{Gitlab::Regex.oci_repository_path_regex_message} " \
|
||||
"It can only contain alphanumeric characters, periods, underscores, and dashes. " \
|
||||
"For example, 'destination_namespace' not 'destination/namespace'"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,21 +6,6 @@ module Gitlab
|
|||
extend MergeRequests
|
||||
extend Packages
|
||||
|
||||
def group_path_regex
|
||||
# This regexp validates the string conforms to rules for a group slug:
|
||||
# i.e does not start with a non-alphanumeric character except for periods or underscores,
|
||||
# contains only alphanumeric characters, periods, and underscores,
|
||||
# does not end with a period or forward slash, and has no leading or trailing forward slashes
|
||||
# eg 'destination-path' or 'destination_pth' not 'example/com/destination/full/path'
|
||||
@group_path_regex ||= %r{\A[.]?[^\W]([.]?[0-9a-z][-_]*)+\z}i
|
||||
end
|
||||
|
||||
def group_path_regex_message
|
||||
"cannot start with a non-alphanumeric character except for periods or underscores, " \
|
||||
"can contain only alphanumeric characters, periods, and underscores, " \
|
||||
"cannot end with a period or forward slash, and has no leading or trailing forward slashes." \
|
||||
end
|
||||
|
||||
def project_name_regex
|
||||
# The character range \p{Alnum} overlaps with \u{00A9}-\u{1f9ff}
|
||||
# hence the Ruby warning.
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import HooksYaml from './yaml_tests/positive_tests/hooks.yml';
|
|||
import SecretsYaml from './yaml_tests/positive_tests/secrets.yml';
|
||||
import ServicesYaml from './yaml_tests/positive_tests/services.yml';
|
||||
import NeedsParallelMatrixYaml from './yaml_tests/positive_tests/needs_parallel_matrix.yml';
|
||||
import ScriptYaml from './yaml_tests/positive_tests/script.yml';
|
||||
|
||||
// YAML NEGATIVE TEST
|
||||
import ArtifactsNegativeYaml from './yaml_tests/negative_tests/artifacts.yml';
|
||||
|
|
@ -60,6 +61,7 @@ import ServicesNegativeYaml from './yaml_tests/negative_tests/services.yml';
|
|||
import NeedsParallelMatrixNumericYaml from './yaml_tests/negative_tests/needs/parallel_matrix/numeric.yml';
|
||||
import NeedsParallelMatrixWrongParallelValueYaml from './yaml_tests/negative_tests/needs/parallel_matrix/wrong_parallel_value.yml';
|
||||
import NeedsParallelMatrixWrongMatrixValueYaml from './yaml_tests/negative_tests/needs/parallel_matrix/wrong_matrix_value.yml';
|
||||
import ScriptNegativeYaml from './yaml_tests/negative_tests/script.yml';
|
||||
|
||||
const ajv = new Ajv({
|
||||
strictTypes: false,
|
||||
|
|
@ -101,6 +103,7 @@ describe('positive tests', () => {
|
|||
ServicesYaml,
|
||||
SecretsYaml,
|
||||
NeedsParallelMatrixYaml,
|
||||
ScriptYaml,
|
||||
}),
|
||||
)('schema validates %s', (_, input) => {
|
||||
// We construct a new "JSON" from each main key that is inside a
|
||||
|
|
@ -144,6 +147,7 @@ describe('negative tests', () => {
|
|||
NeedsParallelMatrixNumericYaml,
|
||||
NeedsParallelMatrixWrongParallelValueYaml,
|
||||
NeedsParallelMatrixWrongMatrixValueYaml,
|
||||
ScriptNegativeYaml,
|
||||
}),
|
||||
)('schema validates %s', (_, input) => {
|
||||
// We construct a new "JSON" from each main key that is inside a
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
script: echo "invalid global script"
|
||||
|
||||
default:
|
||||
before_script: 0.1
|
||||
after_script: 1
|
||||
|
||||
invalid_script_type:
|
||||
script: true
|
||||
|
||||
empty_array_script:
|
||||
script: []
|
||||
|
||||
empty_string_script:
|
||||
script: ""
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
default:
|
||||
before_script:
|
||||
- echo "default before_script"
|
||||
after_script: |
|
||||
echo "default after_script"
|
||||
|
||||
valid_job_with_empty_string_script:
|
||||
before_script: ""
|
||||
after_script: ""
|
||||
script:
|
||||
- echo "overwrite default before_script and after_script"
|
||||
|
||||
valid_job_with_empty_array_script:
|
||||
before_script: []
|
||||
after_script: []
|
||||
script:
|
||||
- echo "overwrite default before_script and after_script"
|
||||
|
||||
valid_job_with_string_scripts:
|
||||
before_script: echo before_script
|
||||
script: echo script
|
||||
after_script: echo after_script
|
||||
|
||||
valid_job_with_multi_line_scripts:
|
||||
before_script: |
|
||||
echo multiline
|
||||
echo before_script
|
||||
script: |
|
||||
echo multiline
|
||||
echo script
|
||||
after_script: |
|
||||
echo multiline
|
||||
echo after_script
|
||||
|
||||
valid_job_with_array_scripts:
|
||||
before_script:
|
||||
- echo array
|
||||
- echo before_script
|
||||
script:
|
||||
- echo array
|
||||
- echo script
|
||||
after_script:
|
||||
- echo array
|
||||
- echo after_script
|
||||
|
||||
valid_job_with_nested_array_scripts:
|
||||
before_script:
|
||||
- [echo nested_array, echo before_script]
|
||||
script:
|
||||
- [echo nested_array, echo script]
|
||||
after_script:
|
||||
- [echo nested_array, echo after_script]
|
||||
|
|
@ -38,7 +38,7 @@ RSpec.describe Gitlab::Memory::Instrumentation, feature_category: :application_p
|
|||
|
||||
subject do
|
||||
described_class.with_memory_allocations do
|
||||
Array.new(1000).map { '0' * 100 }
|
||||
Array.new(1000).map { '0' * 1000 }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ RSpec.describe Gitlab::Memory::Instrumentation, feature_category: :application_p
|
|||
expect(result).to include(
|
||||
mem_objects: be > 1000,
|
||||
mem_mallocs: be > 1000,
|
||||
mem_bytes: be > 100_000, # 100 items * 100 bytes each
|
||||
mem_bytes: be > 1000_000, # 1000 items * 1000 bytes each
|
||||
mem_total_bytes: eq(result[:mem_bytes] + 40 * result[:mem_objects])
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -86,33 +86,6 @@ RSpec.describe Gitlab::Regex, feature_category: :tooling do
|
|||
it { is_expected.to match('<any-Charact3r$|any-Charact3r$>') }
|
||||
end
|
||||
|
||||
describe '.group_path_regex' do
|
||||
subject { described_class.group_path_regex }
|
||||
|
||||
it { is_expected.not_to match('?gitlab') }
|
||||
it { is_expected.not_to match("Users's something") }
|
||||
it { is_expected.not_to match('/source') }
|
||||
it { is_expected.not_to match('http:') }
|
||||
it { is_expected.not_to match('https:') }
|
||||
it { is_expected.not_to match('example.com/?stuff=true') }
|
||||
it { is_expected.not_to match('example.com:5000/?stuff=true') }
|
||||
it { is_expected.not_to match('http://gitlab.example/gitlab-org/manage/import/gitlab-migration-test') }
|
||||
it { is_expected.not_to match('_good_for_me!') }
|
||||
it { is_expected.not_to match('good_for+you') }
|
||||
it { is_expected.not_to match('source/') }
|
||||
it { is_expected.not_to match('.source/full./path') }
|
||||
|
||||
it { is_expected.not_to match('source/full') }
|
||||
it { is_expected.not_to match('source/full/path') }
|
||||
it { is_expected.not_to match('.source/.full/.path') }
|
||||
|
||||
it { is_expected.to match('source') }
|
||||
it { is_expected.to match('.source') }
|
||||
it { is_expected.to match('_source') }
|
||||
it { is_expected.to match('domain_namespace') }
|
||||
it { is_expected.to match('gitlab-migration-test') }
|
||||
end
|
||||
|
||||
describe '.environment_name_regex' do
|
||||
subject { described_class.environment_name_regex }
|
||||
|
||||
|
|
|
|||
|
|
@ -206,18 +206,6 @@ RSpec.describe Namespace, feature_category: :groups_and_projects do
|
|||
expect { parent.update!(name: 'Foo') }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when restrict_special_characters_in_namespace_path feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(restrict_special_characters_in_namespace_path: false)
|
||||
end
|
||||
|
||||
it 'allows special character at the start or end of project namespace path' do
|
||||
namespace = build(:namespace, type: project_sti_name, parent: parent, path: '_path_')
|
||||
|
||||
expect(namespace).to be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '1 char path length' do
|
||||
|
|
|
|||
|
|
@ -262,26 +262,7 @@ RSpec.describe API::BulkImports, feature_category: :importers do
|
|||
end
|
||||
|
||||
context 'when the destination_slug is invalid' do
|
||||
it 'returns invalid error when restricting special characters is disabled' do
|
||||
Feature.disable(:restrict_special_characters_in_namespace_path)
|
||||
|
||||
params[:entities][0][:destination_slug] = 'des?tin?atoi-slugg'
|
||||
|
||||
request
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['error']).to include("entities[0][destination_slug] cannot start with " \
|
||||
"a non-alphanumeric character except for periods or " \
|
||||
"underscores, can contain only alphanumeric characters, " \
|
||||
"periods, and underscores, cannot end with a period or " \
|
||||
"forward slash, and has no leading or trailing forward " \
|
||||
"slashes. It can only contain alphanumeric characters, " \
|
||||
"periods, underscores, and dashes. For example, " \
|
||||
"'destination_namespace' not 'destination/namespace'")
|
||||
end
|
||||
|
||||
it 'returns invalid error when restricting special characters is enabled' do
|
||||
Feature.enable(:restrict_special_characters_in_namespace_path)
|
||||
|
||||
it 'returns invalid error' do
|
||||
params[:entities][0][:destination_slug] = 'des?tin?atoi-slugg'
|
||||
|
||||
request
|
||||
|
|
|
|||
|
|
@ -246,13 +246,13 @@ RSpec.describe MergeRequests::CreateRefService, feature_category: :merge_trains
|
|||
expect_next_instance_of(described_class) do |instance|
|
||||
original = instance.method(:maybe_merge!)
|
||||
|
||||
expect(instance).to receive(:maybe_merge!) do |*args|
|
||||
expect(instance).to receive(:maybe_merge!) do |*args, **kwargs|
|
||||
# Corrupt target_ref before the merge, simulating a race with
|
||||
# another instance of the service for the same MR. source_sha is
|
||||
# just an arbitrary valid commit that differs from what was just
|
||||
# written.
|
||||
project.repository.write_ref(target_ref, source_sha)
|
||||
original.call(*args)
|
||||
original.call(*args, **kwargs)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue