Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-11-29 15:07:33 +00:00
parent fb28ad5316
commit 762918f04a
40 changed files with 518 additions and 113 deletions

View File

@ -3368,7 +3368,6 @@ RSpec/FeatureCategory:
- 'spec/lib/gitlab/etag_caching/router/rails_spec.rb'
- 'spec/lib/gitlab/etag_caching/router_spec.rb'
- 'spec/lib/gitlab/etag_caching/store_spec.rb'
- 'spec/lib/gitlab/event_store/event_spec.rb'
- 'spec/lib/gitlab/event_store/store_spec.rb'
- 'spec/lib/gitlab/exception_log_formatter_spec.rb'
- 'spec/lib/gitlab/exceptions_app_spec.rb'

View File

@ -9,7 +9,7 @@ module Onboarding
def after_sign_up_path
if onboarding_status.single_invite?
flash[:notice] = helpers.invite_accepted_notice(onboarding_status.last_invited_member)
onboarding_status.last_invited_member_source.activity_path
polymorphic_path(onboarding_status.last_invited_member_source)
else
# Invites will come here if there is more than 1.
path_for_signed_in_user
@ -17,13 +17,13 @@ module Onboarding
end
def path_for_signed_in_user
stored_location_for(:user) || last_member_activity_path
stored_location_for(:user) || last_member_source_path
end
def last_member_activity_path
def last_member_source_path
return dashboard_projects_path unless onboarding_status.last_invited_member_source.present?
onboarding_status.last_invited_member_source.activity_path
polymorphic_path(onboarding_status.last_invited_member_source)
end
end
end

View File

@ -125,14 +125,14 @@ class InvitesController < ApplicationController
name: member.source.full_name,
url: project_url(member.source),
title: _("project"),
path: member.source.activity_path
path: project_path(member.source)
}
when Group
{
name: member.source.name,
url: group_url(member.source),
title: _("group"),
path: member.source.activity_path
path: group_path(member.source)
}
end
end

View File

@ -100,7 +100,7 @@ class SessionsController < Devise::SessionsController
def after_pending_invitations_hook
member = resource.members.last
store_location_for(:user, member.source.activity_path) if member
store_location_for(:user, polymorphic_path(member.source)) if member
end
def captcha_enabled?

View File

@ -790,10 +790,6 @@ class Group < Namespace
end
strong_memoize_attr :has_project_with_service_desk_enabled?
def activity_path
Gitlab::Routing.url_helpers.activity_group_path(self)
end
# rubocop: disable CodeReuse/ServiceClass
def open_issues_count(current_user = nil)
Groups::OpenIssuesCountService.new(self, current_user).count

View File

@ -2992,10 +2992,6 @@ class Project < ApplicationRecord
Projects::GitGarbageCollectWorker
end
def activity_path
Gitlab::Routing.url_helpers.activity_project_path(self)
end
def ci_forward_deployment_enabled?
return false unless ci_cd_settings

View File

@ -27,16 +27,19 @@
- docs_link = link_to('', help_page_path('user/group/import/index', anchor: 'migrated-group-items'), target: '_blank', rel: 'noopener noreferrer')
= safe_format(s_('GroupsNew|Not all group items are migrated. %{docs_link_start}What items are migrated%{docs_link_end}?'), tag_pair(docs_link, :docs_link_start, :docs_link_end))
%p.gl-mt-3
= s_('GroupsNew|Provide credentials for the source instance to import from. You can provide this instance as a source to move groups in this instance.')
.form-group.gl-display-flex.gl-flex-direction-column
= f.label :bulk_import_gitlab_url, s_('GroupsNew|GitLab source instance URL'), for: 'import_gitlab_url'
%p.gl-mt-5.gl-mb-3
- url_link = link_to('', help_page_path('user/group/import/index', anchor: 'connect-the-source-gitlab-instance'), target: '_blank', rel: 'noopener noreferrer')
= safe_format(s_('GroupsNew|Provide credentials for the %{url_link_start}source instance%{url_link_end} to import from. You can provide this instance as a source to move groups within this instance.'), tag_pair(url_link, :url_link_start, :url_link_end))
.form-group.gl-form-group.gl-display-flex.gl-flex-direction-column
= f.label :bulk_import_gitlab_url, s_('GroupsNew|GitLab source instance base URL'), for: 'import_gitlab_url'
= f.text_field :bulk_import_gitlab_url, disabled: bulk_imports_disabled, placeholder: 'https://gitlab.example.com', class: 'gl-form-input col-xs-12 col-sm-8',
required: true,
title: s_('GroupsNew|Enter the URL for the source instance.'),
id: 'import_gitlab_url',
data: { testid: 'import-gitlab-url' }
.form-group.gl-display-flex.gl-flex-direction-column
%small.form-text.text-gl-muted
= s_('Import|Must only contain the base URL of the source GitLab instance.')
.form-group.gl-form-group.gl-display-flex.gl-flex-direction-column
= f.label :bulk_import_gitlab_access_token, s_('GroupsNew|Personal access token'), for: 'import_gitlab_token', class: 'col-form-label'
.gl-font-weight-normal
- pat_link = link_to('', help_page_path('user/profile/personal_access_tokens'), target: '_blank')

View File

@ -1,8 +0,0 @@
---
name: duo_chat_absolute_doc_links
introduced_by_url: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136240'
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/431338
milestone: '16.6'
type: development
group: group::ai framework
default_enabled: false

View File

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415755
milestone: '16.2'
type: development
group: group::source code
default_enabled: false
default_enabled: true

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddUniqueIdPartitionIdIndexToCiJobArtifact < Gitlab::Database::Migration[2.2]
milestone '16.7'
TABLE_NAME = :ci_job_artifacts
INDEX_NAME = :index_ci_job_artifacts_on_id_partition_id_unique
COLUMNS = %i[id partition_id]
def up
prepare_async_index(TABLE_NAME, COLUMNS, unique: true, name: INDEX_NAME)
end
def down
unprepare_async_index(TABLE_NAME, COLUMNS, name: INDEX_NAME)
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddUniqueJobIdFilteTypePartitionIdIndexToCiJobArtifact < Gitlab::Database::Migration[2.2]
milestone '16.7'
TABLE_NAME = :ci_job_artifacts
INDEX_NAME = :idx_ci_job_artifacts_on_job_id_file_type_and_partition_id_uniq
COLUMNS = %i[job_id file_type partition_id]
def up
prepare_async_index(TABLE_NAME, COLUMNS, unique: true, name: INDEX_NAME)
end
def down
unprepare_async_index(TABLE_NAME, COLUMNS, name: INDEX_NAME)
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddAsyncIndexesWithPartitionIdForCiPipelineVariables < Gitlab::Database::Migration[2.2]
milestone '16.7'
TABLE_NAME = :ci_pipeline_variables
PK_INDEX_NAME = :index_ci_pipeline_variables_on_id_partition_id_unique
UNIQUE_INDEX_NAME = :index_pipeline_variables_on_pipeline_id_key_partition_id_unique
def up
prepare_async_index TABLE_NAME, %i[id partition_id], name: PK_INDEX_NAME, unique: true
prepare_async_index TABLE_NAME, %i[pipeline_id key partition_id], name: UNIQUE_INDEX_NAME, unique: true
end
def down
unprepare_async_index TABLE_NAME, %i[id partition_id], name: PK_INDEX_NAME, unique: true
unprepare_async_index TABLE_NAME, %i[pipeline_id key partition_id], name: UNIQUE_INDEX_NAME, unique: true
end
end

View File

@ -0,0 +1 @@
9cfcd48c86956f9f1a0429ab4a2b9f772b7cd6f2e7ac325bb8b1acbbe6ba4ed6

View File

@ -0,0 +1 @@
856be6ee89a0e0c4042539ffff10aa410dbfb59bff43527482af5817a20e20cc

View File

@ -0,0 +1 @@
a076623d4d7c2f475f1c712802288ef8bdd0c830798dd27d7397da63065b6639

View File

@ -157,7 +157,7 @@ For the storage-specific form,
because it does not require a shared folder.
For configuring object storage in GitLab 13.1 and earlier, _or_ for storage types not
For storage types not supported by the consolidated form, refer to the following guides:
supported by the consolidated form, refer to the following guides:
| Object storage type | Supported by consolidated form? |
|---------------------|------------------------------------------|

View File

@ -72,6 +72,23 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="queryabusereportlabelssearchterm"></a>`searchTerm` | [`String`](#string) | Search term to find labels with. |
### `Query.addOnPurchase`
Retrieve the active add-on purchase. This query can be used in GitLab SaaS and self-managed environments.
WARNING:
**Introduced** in 16.7.
This feature is an Experiment. It can be changed or removed at any time.
Returns [`AddOnPurchase`](#addonpurchase).
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="queryaddonpurchaseaddontype"></a>`addOnType` | [`GitlabSubscriptionsAddOnType!`](#gitlabsubscriptionsaddontype) | Type of add-on for the add-on purchase. |
| <a id="queryaddonpurchasenamespaceid"></a>`namespaceId` | [`NamespaceID`](#namespaceid) | ID of namespace that the add-on was purchased for. |
### `Query.aiMessages`
Find GitLab Duo Chat messages.

View File

@ -36,11 +36,11 @@ GitLab SaaS provides a set of VM images for macOS.
You can execute your build in one of the following images, which you specify
in your `.gitlab-ci.yml` file. Each image runs a specific version of macOS and Xcode.
| VM image | Status |
|----------------------------|--------|
| `macos-12-xcode-14` | `GA` |
| `macos-13-xcode-14` | `GA` |
| `macos-14-xcode-15` | `Beta` |
| VM image | Status | |
|----------------------------|--------|--------------|
| `macos-12-xcode-14` | `GA` | |
| `macos-13-xcode-14` | `GA` | [Preinstalled Software](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/job-images/-/blob/main/toolchain/macos-13.yml) |
| `macos-14-xcode-15` | `Beta` | [Preinstalled Software](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/job-images/-/blob/main/toolchain/macos-14.yml) |
If no image is specified, the macOS runner uses `macos-13-xcode-14`.
@ -48,7 +48,7 @@ If no image is specified, the macOS runner uses `macos-13-xcode-14`.
macOS and Xcode follow a yearly release cadence, during which GitLab increments its versions synchronously. GitLab typically supports multiple versions of preinstalled tools. For more information, see the [full list of preinstalled software](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/job-images/-/tree/main/toolchain).
When Apple releases a new macOS version, GitLab releases a new `stable` image based on the OS in the next release,
When Apple releases a new macOS version, GitLab releases a new `stable` image based on the OS in the next release,
which is in Beta.
With the release of the first patch to macOS, the `stable` image becomes Generally Available (GA). As only two GA images are supported at a time, the prior OS version becomes deprecated and is deleted after three months in accordance with the [supported image lifecycle](../index.md#supported-image-lifecycle).

View File

@ -199,7 +199,7 @@ In addition to recording to the database, we also write these events to
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367847) in GitLab 15.4.
All new audit events must have a type definition stored in `config/audit_events/types/` that contains a single source of truth for every auditable event in GitLab.
All new audit events must have a type definition stored in `config/audit_events/types/` or `ee/config/audit_events/types/` that contains a single source of truth for every auditable event in GitLab.
### Add a new audit event type

View File

@ -182,6 +182,7 @@ security dashboard.
To add a new ability to a custom role:
- Generate YAML file by running `./ee/bin/custom-ability` generator
- Add a new column to `member_roles` table, for example in [this change in merge request 114734](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/114734/diffs#diff-content-5c53d6f1c29a272a87eecea3f62d017ab6635275).
- Add the ability to the `MemberRole` model, `ALL_CUSTOMIZABLE_PERMISSIONS` hash, for example in [this change in merge request 121534](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121534/diffs#ce5ec769500a53ce2b603467d9984fc2b33ca71d_8_8). There are following possible keys in the `ALL_CUSTOMIZABLE_PERMISSIONS` hash:
@ -200,6 +201,33 @@ Examples of merge requests adding new abilities to custom roles:
You should make sure a new custom roles ability is under a feature flag.
## Custom abilities definition
All new custom abilities must have a type definition stored in `ee/config/custom_abilities` that contains a single source of truth for every ability that is part of custom roles feature.
### Add a new custom ability definition
To add a new custom ability:
1. Create the YAML definition. You can either:
- Use the `ee/bin/custom-ability` CLI to create the YAML definition automatically.
- Perform manual steps to create a new file in `ee/config/custom_abilities/` with the filename matching the name of the ability name.
1. Add contents to the file that conform to the [schema](#schema) defined in `ee/config/custom_abilities/types/type_schema.json`.
### Schema
| Field | Required | Description |
| ----- | -------- |--------------|
| `name` | yes | Unique, lowercase and underscored name describing the custom ability. Must match the filename. |
| `description` | yes | Human-readable description of the custom ability. |
| `feature_category` | yes | Name of the feature category. For example, `vulnerability_management`. |
| `introduced_by_issue` | yes | Issue URL that proposed the addition of this custom ability. |
| `introduced_by_mr` | yes | MR URL that added this custom ability. |
| `milestone` | yes | Milestone in which this custom ability was added. |
| `group_ability` | yes | Indicate whether this ability is checked on group level. |
| `project_ability` | yes | Indicate whether this ability is checked on project level. |
| `skip_seat_consumption` | yes | Indicate wheter this ability should be skiped when counting licensed users. |
### Privilege escalation consideration
A base role typically has permissions that allow creation or management of artifacts corresponding to the base role when interacting with that artifact. For example, when a `Developer` creates an access token for a project, it is created with `Developer` access encoded into that credential. It is important to keep in mind that as new custom permissions are created, there might be a risk of elevated privileges when interacting with GitLab artifacts, and appropriate safeguards or base role checks should be added.

View File

@ -201,7 +201,7 @@ Create the group you want to import to and connect the source GitLab instance:
- A new subgroup. On existing group's page, either:
- Select **New subgroup**.
- On the left sidebar, at the top, select **Create new** (**{plus}**) and **New subgroup**. Then select the **import an existing group** link.
1. Enter the URL of a GitLab instance running GitLab 14.0 or later.
1. Enter the base URL of a GitLab instance running GitLab 14.0 or later.
1. Enter the [personal access token](../../../user/profile/personal_access_tokens.md) for your source GitLab instance.
1. Select **Connect instance**.

View File

@ -81,7 +81,7 @@ module BulkImports
return true if response['scopes']&.include?('api')
raise ::BulkImports::Error.scope_validation_failure
raise ::BulkImports::Error.scope_or_url_validation_failure
end
def validate_instance_version!
@ -110,7 +110,7 @@ module BulkImports
rescue BulkImports::NetworkError => e
case e&.response&.code
when 401, 403
raise ::BulkImports::Error.scope_validation_failure
raise ::BulkImports::Error.scope_or_url_validation_failure
when 404
raise ::BulkImports::Error.invalid_url
else

View File

@ -3,35 +3,37 @@
module BulkImports
class Error < StandardError
def self.unsupported_gitlab_version
self.new("Unsupported GitLab version. Minimum supported version is #{BulkImport::MIN_MAJOR_VERSION}.")
self.new(format(s_("BulkImport|Unsupported GitLab version. Minimum supported version is '%{version}'."),
version: BulkImport::MIN_MAJOR_VERSION))
end
def self.scope_validation_failure
self.new("Personal access token does not have the required " \
"'api' scope or is no longer valid.")
def self.scope_or_url_validation_failure
self.new(s_("BulkImport|Check that the source instance base URL and the personal access " \
"token meet the necessary requirements."))
end
def self.invalid_url
self.new("Invalid source URL. Enter only the base URL of the source GitLab instance.")
self.new(s_("BulkImport|Invalid source URL. Enter only the base URL of the source GitLab instance."))
end
def self.destination_namespace_validation_failure(destination_namespace)
self.new("Import failed. Destination '#{destination_namespace}' is invalid, or you don't have permission.")
self.new(format(s_("BulkImport|Import failed. Destination '%{destination}' is invalid, " \
"or you don't have permission."), destination: destination_namespace))
end
def self.destination_slug_validation_failure
self.new("Import failed. Destination URL " \
"#{Gitlab::Regex.oci_repository_path_regex_message}")
self.new(format(s_("BulkImport|Import failed. Destination URL %{url}"),
url: Gitlab::Regex.oci_repository_path_regex_message))
end
def self.destination_full_path_validation_failure(full_path)
self.new("Import failed. '#{full_path}' already exists. Change the destination and try again.")
self.new(format(s_("BulkImport|Import failed. '%{path}' already exists. Change the destination and try again."),
path: full_path))
end
def self.setting_not_enabled
self.new("Group import disabled on source or destination instance. " \
"Ask an administrator to enable it on both instances and try again."
)
self.new(s_("BulkImport|Group import disabled on source or destination instance. " \
"Ask an administrator to enable it on both instances and try again."))
end
end
end

View File

@ -29,8 +29,13 @@ module Gitlab
class Event
attr_reader :data
class << self
attr_accessor :json_schema_valid
end
def initialize(data:)
validate_schema!(data)
validate_schema!
validate_data!(data)
@data = data
end
@ -40,7 +45,17 @@ module Gitlab
private
def validate_schema!(data)
def validate_schema!
if self.class.json_schema_valid.nil?
self.class.json_schema_valid = JSONSchemer.schema(self.class.json_schema).valid?(schema)
end
return if self.class.json_schema_valid == true
raise Gitlab::EventStore::InvalidEvent, "Schema for event #{self.class} is invalid"
end
def validate_data!(data)
unless data.is_a?(Hash)
raise Gitlab::EventStore::InvalidEvent, "Event data must be a Hash"
end
@ -49,6 +64,10 @@ module Gitlab
raise Gitlab::EventStore::InvalidEvent, "Data for event #{self.class} does not match the defined schema: #{schema}"
end
end
def self.json_schema
@json_schema ||= Gitlab::Json.parse(File.read(File.join(__dir__, 'json_schema_draft07.json')))
end
end
end
end

View File

@ -0,0 +1,250 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://json-schema.org/draft-07/schema#",
"title": "Core schema meta-schema",
"definitions": {
"schemaArray": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#"
}
},
"nonNegativeInteger": {
"type": "integer",
"minimum": 0
},
"nonNegativeIntegerDefault0": {
"allOf": [
{
"$ref": "#/definitions/nonNegativeInteger"
},
{
"default": 0
}
]
},
"simpleTypes": {
"enum": [
"array",
"boolean",
"integer",
"null",
"number",
"object",
"string"
]
},
"stringArray": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true,
"default": [
]
}
},
"type": [
"object",
"boolean"
],
"properties": {
"$id": {
"type": "string",
"format": "uri-reference"
},
"$schema": {
"type": "string",
"format": "uri"
},
"$ref": {
"type": "string",
"format": "uri-reference"
},
"$comment": {
"type": "string"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"default": true,
"readOnly": {
"type": "boolean",
"default": false
},
"writeOnly": {
"type": "boolean",
"default": false
},
"examples": {
"type": "array",
"items": true
},
"multipleOf": {
"type": "number",
"exclusiveMinimum": 0
},
"maximum": {
"type": "number"
},
"exclusiveMaximum": {
"type": "number"
},
"minimum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "number"
},
"maxLength": {
"$ref": "#/definitions/nonNegativeInteger"
},
"minLength": {
"$ref": "#/definitions/nonNegativeIntegerDefault0"
},
"pattern": {
"type": "string",
"format": "regex"
},
"additionalItems": {
"$ref": "#"
},
"items": {
"anyOf": [
{
"$ref": "#"
},
{
"$ref": "#/definitions/schemaArray"
}
],
"default": true
},
"maxItems": {
"$ref": "#/definitions/nonNegativeInteger"
},
"minItems": {
"$ref": "#/definitions/nonNegativeIntegerDefault0"
},
"uniqueItems": {
"type": "boolean",
"default": false
},
"contains": {
"$ref": "#"
},
"maxProperties": {
"$ref": "#/definitions/nonNegativeInteger"
},
"minProperties": {
"$ref": "#/definitions/nonNegativeIntegerDefault0"
},
"required": {
"$ref": "#/definitions/stringArray"
},
"additionalProperties": {
"$ref": "#"
},
"definitions": {
"type": "object",
"additionalProperties": {
"$ref": "#"
},
"default": {
}
},
"properties": {
"type": "object",
"additionalProperties": {
"$ref": "#"
},
"default": {
}
},
"patternProperties": {
"type": "object",
"additionalProperties": {
"$ref": "#"
},
"propertyNames": {
"format": "regex"
},
"default": {
}
},
"dependencies": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"$ref": "#"
},
{
"$ref": "#/definitions/stringArray"
}
]
}
},
"propertyNames": {
"$ref": "#"
},
"const": true,
"enum": {
"type": "array",
"items": true,
"minItems": 1,
"uniqueItems": true
},
"type": {
"anyOf": [
{
"$ref": "#/definitions/simpleTypes"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/simpleTypes"
},
"minItems": 1,
"uniqueItems": true
}
]
},
"format": {
"type": "string"
},
"contentMediaType": {
"type": "string"
},
"contentEncoding": {
"type": "string"
},
"if": {
"$ref": "#"
},
"then": {
"$ref": "#"
},
"else": {
"$ref": "#"
},
"allOf": {
"$ref": "#/definitions/schemaArray"
},
"anyOf": {
"$ref": "#/definitions/schemaArray"
},
"oneOf": {
"$ref": "#/definitions/schemaArray"
},
"not": {
"$ref": "#"
}
},
"default": true
}

View File

@ -9020,6 +9020,9 @@ msgstr ""
msgid "BulkImport|Be aware of %{linkStart}visibility rules%{linkEnd} when importing groups."
msgstr ""
msgid "BulkImport|Check that the source instance base URL and the personal access token meet the necessary requirements."
msgstr ""
msgid "BulkImport|Destination"
msgstr ""
@ -9035,9 +9038,21 @@ msgstr ""
msgid "BulkImport|GitLab Migration history"
msgstr ""
msgid "BulkImport|Group import disabled on source or destination instance. Ask an administrator to enable it on both instances and try again."
msgstr ""
msgid "BulkImport|History"
msgstr ""
msgid "BulkImport|Import failed. '%{path}' already exists. Change the destination and try again."
msgstr ""
msgid "BulkImport|Import failed. Destination '%{destination}' is invalid, or you don't have permission."
msgstr ""
msgid "BulkImport|Import failed. Destination URL %{url}"
msgstr ""
msgid "BulkImport|Import failed: Destination cannot be a subgroup of the source group. Change the destination and try again."
msgstr ""
@ -9059,6 +9074,9 @@ msgstr ""
msgid "BulkImport|Importing the group failed."
msgstr ""
msgid "BulkImport|Invalid source URL. Enter only the base URL of the source GitLab instance."
msgstr ""
msgid "BulkImport|Last imported to %{link}"
msgstr ""
@ -9116,6 +9134,9 @@ msgstr ""
msgid "BulkImport|Template / File-based import / GitLab Migration"
msgstr ""
msgid "BulkImport|Unsupported GitLab version. Minimum supported version is '%{version}'."
msgstr ""
msgid "BulkImport|Update of import statuses with realtime changes failed"
msgstr ""
@ -23555,7 +23576,7 @@ msgstr ""
msgid "GroupsNew|Enter the URL for the source instance."
msgstr ""
msgid "GroupsNew|GitLab source instance URL"
msgid "GroupsNew|GitLab source instance base URL"
msgstr ""
msgid "GroupsNew|Groups"
@ -23597,7 +23618,7 @@ msgstr ""
msgid "GroupsNew|Please fill in your personal access token."
msgstr ""
msgid "GroupsNew|Provide credentials for the source instance to import from. You can provide this instance as a source to move groups in this instance."
msgid "GroupsNew|Provide credentials for the %{url_link_start}source instance%{url_link_end} to import from. You can provide this instance as a source to move groups within this instance."
msgstr ""
msgid "GroupsNew|Remember to enable it also on the instance you are migrating from."
@ -24901,6 +24922,9 @@ msgstr ""
msgid "Import|Maximum size of decompressed archive."
msgstr ""
msgid "Import|Must only contain the base URL of the source GitLab instance."
msgstr ""
msgid "Import|No import details"
msgstr ""
@ -56317,6 +56341,9 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
msgid "Your push to this repository has been rejected because it would exceed the namespace storage limit of %{size_limit}. Reduce your namespace storage or purchase additional storage.To manage storage, or purchase additional storage, see %{manage_storage_url}. To learn more about restricted actions, see %{restricted_actions_url}"
msgstr ""
msgid "Your request for access could not be processed: %{error_message}"
msgstr ""

View File

@ -89,7 +89,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js, feature_categ
end
it 'renders fields and button disabled' do
expect(page).to have_field('GitLab source instance URL', disabled: true)
expect(page).to have_field('GitLab source instance base URL', disabled: true)
expect(page).to have_field('Personal access token', disabled: true)
expect(page).to have_button('Connect instance', disabled: true)
end

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_category: :acquisition do
let_it_be(:owner) { create(:user, name: 'John Doe') }
# private will ensure we really have access to the group when we land on the activity page
# private will ensure we really have access to the group when we land on the group page
let_it_be(:group) { create(:group, :private, name: 'Owned') }
let_it_be(:project) { create(:project, :repository, namespace: group) }
@ -60,12 +60,12 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
visit invite_path(group_invite.raw_invite_token, invite_type: Emails::Members::INITIAL_INVITE)
end
it 'sign in, grants access and redirects to group activity page' do
it 'sign in, grants access and redirects to group page' do
click_link 'Sign in'
gitlab_sign_in(user, remember: true, visit: false)
expect_to_be_on_group_activity_page(group)
expect_to_be_on_group_page(group)
end
end
@ -126,8 +126,8 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
end
end
def expect_to_be_on_group_activity_page(group)
expect(page).to have_current_path(activity_group_path(group))
def expect_to_be_on_group_page(group)
expect(page).to have_current_path(group_path(group))
end
end
end
@ -169,10 +169,10 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
end
context 'when the user signs up for an account with the invitation email address' do
it 'redirects to the most recent membership activity page with all invitations automatically accepted' do
it 'redirects to the most recent membership group page with all invitations automatically accepted' do
fill_in_sign_up_form(new_user)
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
expect(page).to have_current_path(group_path(group), ignore_query: true)
expect(page).to have_content('You have been granted Owner access to group Owned.')
end
end
@ -215,10 +215,10 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
end
context 'when the user signs up for an account with the invitation email address' do
it 'redirects to the most recent membership activity page with all invitations automatically accepted' do
it 'redirects to the most recent membership group page with all invitations automatically accepted' do
fill_in_sign_up_form(new_user)
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
expect(page).to have_current_path(group_path(group), ignore_query: true)
end
end
@ -271,7 +271,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
fill_in_sign_up_form(new_user, 'Register')
expect(page).to have_current_path(activity_group_path(group))
expect(page).to have_current_path(group_path(group))
expect(page).to have_content('You have been granted Owner access to group Owned.')
end
end
@ -295,16 +295,16 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
gitlab_sign_in(user)
end
it 'does not accept the pending invitation and does not redirect to the groups activity path' do
expect(page).not_to have_current_path(activity_group_path(group), ignore_query: true)
it 'does not accept the pending invitation and does not redirect to the group path' do
expect(page).not_to have_current_path(group_path(group), ignore_query: true)
expect(group.reload.users).not_to include(user)
end
context 'when the secondary email address is confirmed' do
let(:secondary_email) { create(:email, :confirmed, user: user) }
it 'accepts the pending invitation and redirects to the groups activity path' do
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
it 'accepts the pending invitation and redirects to the group path' do
expect(page).to have_current_path(group_path(group), ignore_query: true)
expect(group.reload.users).to include(user)
end
end

View File

@ -105,12 +105,12 @@ RSpec.describe 'OAuth Registration', :js, :allow_forgery_protection, feature_cat
mock_auth_hash(provider, uid, invite_email, additional_info: additional_info)
end
it 'redirects to the activity page with all the projects/groups invitations accepted' do
it 'redirects to the group page with all the projects/groups invitations accepted' do
visit invite_path(group_invite.raw_invite_token, extra_params)
click_link_or_button "oauth-login-#{provider}"
expect(page).to have_content('You have been granted Owner access to group Owned.')
expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
expect(page).to have_current_path(group_path(group), ignore_query: true)
end
end
end

View File

@ -250,9 +250,9 @@ RSpec.describe BulkImports::Clients::HTTP, feature_category: :importers do
stub_request(:get, 'http://gitlab.example/api/v4/metadata?private_token=token')
.to_return(status: 401, body: "", headers: { 'Content-Type' => 'application/json' })
expect { subject.instance_version }.to raise_exception(BulkImports::Error,
"Personal access token does not have the required 'api' scope or " \
"is no longer valid.")
expect { subject.instance_version }
.to raise_exception(BulkImports::Error,
"Check that the source instance base URL and the personal access token meet the necessary requirements.")
end
end
@ -262,9 +262,9 @@ RSpec.describe BulkImports::Clients::HTTP, feature_category: :importers do
stub_request(:get, 'http://gitlab.example/api/v4/metadata?private_token=token')
.to_return(status: 403, body: "", headers: { 'Content-Type' => 'application/json' })
expect { subject.instance_version }.to raise_exception(BulkImports::Error,
"Personal access token does not have the required 'api' scope or " \
"is no longer valid.")
expect { subject.instance_version }
.to raise_exception(BulkImports::Error,
"Check that the source instance base URL and the personal access token meet the necessary requirements.")
end
end

View File

@ -1,8 +1,10 @@
# frozen_string_literal: true
require 'spec_helper'
require 'fast_spec_helper'
require 'json_schemer'
require 'oj'
RSpec.describe Gitlab::EventStore::Event do
RSpec.describe Gitlab::EventStore::Event, feature_category: :shared do
let(:event_class) { stub_const('TestEvent', Class.new(described_class)) }
let(:event) { event_class.new(data: data) }
let(:data) { { project_id: 123, project_path: 'org/the-project' } }
@ -42,6 +44,14 @@ RSpec.describe Gitlab::EventStore::Event do
it 'initializes the event correctly' do
expect(event.data).to eq(data)
end
it 'validates schema' do
expect(event_class.json_schema_valid).to eq(nil)
event
expect(event_class.json_schema_valid).to eq(true)
end
end
context 'when some properties are missing' do
@ -59,6 +69,31 @@ RSpec.describe Gitlab::EventStore::Event do
expect { event }.to raise_error(Gitlab::EventStore::InvalidEvent, 'Event data must be a Hash')
end
end
context 'when schema is invalid' do
before do
event_class.class_eval do
def schema
{
'required' => ['project_id'],
'type' => 'object',
'properties' => {
'project_id' => { 'type' => 'int' },
'project_path' => { 'type' => 'string ' }
}
}
end
end
end
it 'raises an error' do
expect(event_class.json_schema_valid).to eq(nil)
expect { event }.to raise_error(Gitlab::EventStore::InvalidEvent, 'Schema for event TestEvent is invalid')
expect(event_class.json_schema_valid).to eq(false)
end
end
end
end
end

View File

@ -3014,14 +3014,6 @@ RSpec.describe Group, feature_category: :groups_and_projects do
end
end
describe '#activity_path' do
it 'returns the group activity_path' do
expected_path = "/groups/#{group.name}/-/activity"
expect(group.activity_path).to eq(expected_path)
end
end
context 'with export' do
let(:group) { create(:group, :with_export) }

View File

@ -7955,14 +7955,6 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
end
describe '#activity_path' do
it 'returns the project activity_path' do
expected_path = "/#{project.full_path}/activity"
expect(project.activity_path).to eq(expected_path)
end
end
end
describe '#default_branch_or_main' do

View File

@ -41,7 +41,7 @@ RSpec.describe 'Sessions', feature_category: :system_access do
post user_session_path(user: { login: user.username, password: user.password })
expect(response).to redirect_to(activity_group_path(member.source))
expect(response).to redirect_to(group_path(member.source))
end
end

View File

@ -123,7 +123,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
)
allow_next_instance_of(BulkImports::Clients::HTTP) do |client|
allow(client).to receive(:validate_import_scopes!).and_raise(BulkImports::Error.scope_validation_failure)
allow(client).to receive(:validate_import_scopes!)
.and_raise(BulkImports::Error.scope_or_url_validation_failure)
end
result = subject.execute
@ -132,8 +133,7 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
expect(result).to be_error
expect(result.message)
.to eq(
"Personal access token does not " \
"have the required 'api' scope or is no longer valid."
"Check that the source instance base URL and the personal access token meet the necessary requirements."
)
end
end
@ -546,7 +546,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
expect(result).to be_a(ServiceResponse)
expect(result).to be_error
expect(result.message)
.to eq("Import failed. Destination 'destination-namespace' is invalid, or you don't have permission.")
.to eq("Import failed. Destination 'destination-namespace' is invalid, " \
"or you don't have permission.")
end
end
@ -571,7 +572,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
expect(result).to be_a(ServiceResponse)
expect(result).to be_error
expect(result.message)
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, or you don't have permission.")
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, " \
"or you don't have permission.")
end
end
@ -596,7 +598,8 @@ RSpec.describe BulkImports::CreateService, feature_category: :importers do
expect(result).to be_a(ServiceResponse)
expect(result).to be_error
expect(result.message)
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, or you don't have permission.")
.to eq("Import failed. Destination '#{parent_group.path}' is invalid, " \
"or you don't have permission.")
end
end
end

View File

@ -42,7 +42,7 @@ RSpec.describe MergeRequests::CloseService, feature_category: :code_review_workf
.with(@merge_request, 'close')
end
it 'sends email to user2 about assign of new merge_request', :sidekiq_might_not_need_inline do
it 'sends email to user2 about assign of new merge_request', :sidekiq_inline do
email = ActionMailer::Base.deliveries.last
expect(email.to.first).to eq(user2.email)
expect(email.subject).to include(merge_request.title)

View File

@ -52,7 +52,7 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state, f
end.to change { project.open_merge_requests_count }.from(0).to(1)
end
it 'creates exactly 1 create MR event', :sidekiq_might_not_need_inline do
it 'creates exactly 1 create MR event', :sidekiq_inline do
attributes = {
action: :created,
target_id: merge_request.id,

View File

@ -44,7 +44,7 @@ RSpec.describe MergeRequests::ReopenService, feature_category: :code_review_work
expect(Integrations::GroupMentionWorker).not_to receive(:perform_async)
end
it 'sends email to user2 about reopen of merge_request', :sidekiq_might_not_need_inline do
it 'sends email to user2 about reopen of merge_request', :sidekiq_inline do
email = ActionMailer::Base.deliveries.last
expect(email.to.first).to eq(user2.email)
expect(email.subject).to include(merge_request.title)

View File

@ -6027,7 +6027,6 @@
- './spec/lib/gitlab/etag_caching/router/rails_spec.rb'
- './spec/lib/gitlab/etag_caching/router_spec.rb'
- './spec/lib/gitlab/etag_caching/store_spec.rb'
- './spec/lib/gitlab/event_store/event_spec.rb'
- './spec/lib/gitlab/event_store/store_spec.rb'
- './spec/lib/gitlab/exception_log_formatter_spec.rb'
- './spec/lib/gitlab/exceptions_app_spec.rb'

View File

@ -6,20 +6,20 @@ RSpec.shared_examples Onboarding::Redirectable do
context 'when the new user already has any accepted group membership' do
let!(:single_member) { create(:group_member, invite_email: email) }
it 'redirects to activity group path with a flash message' do
it 'redirects to the group path with a flash message' do
post_create
expect(response).to redirect_to activity_group_path(single_member.source)
expect(response).to redirect_to group_path(single_member.source)
expect(controller).to set_flash[:notice].to(/You have been granted/)
end
context 'when the new user already has more than 1 accepted group membership' do
let!(:last_member) { create(:group_member, invite_email: email) }
it 'redirects to the last member activity group path without a flash message' do
it 'redirects to the last member group path without a flash message' do
post_create
expect(response).to redirect_to activity_group_path(last_member.source)
expect(response).to redirect_to group_path(last_member.source)
expect(controller).not_to set_flash[:notice].to(/You have been granted/)
end
end