Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
abd8aecf4b
commit
ce16444418
|
|
@ -50,6 +50,8 @@ module Types
|
|||
null: true,
|
||||
description: 'How long the job was enqueued before starting.'
|
||||
|
||||
field :downstream_pipeline, Types::Ci::PipelineType, null: true,
|
||||
description: 'Downstream pipeline for a bridge.'
|
||||
field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, null: true,
|
||||
description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.'
|
||||
field :detailed_status, Types::Ci::DetailedStatusType, null: true,
|
||||
|
|
@ -89,6 +91,10 @@ module Types
|
|||
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, object.pipeline_id).find
|
||||
end
|
||||
|
||||
def downstream_pipeline
|
||||
object.downstream_pipeline if object.respond_to?(:downstream_pipeline)
|
||||
end
|
||||
|
||||
def tags
|
||||
object.tags.map(&:name) if object.is_a?(::Ci::Build)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ module Types
|
|||
description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to indicate that more items exist)."
|
||||
field :admin_url, GraphQL::Types::String, null: true,
|
||||
description: 'Admin URL of the runner. Only available for administrators.'
|
||||
field :executor_name, GraphQL::Types::String, null: true,
|
||||
description: 'Executor last advertised by the runner.',
|
||||
method: :executor_name,
|
||||
feature_flag: :graphql_ci_runner_executor
|
||||
|
||||
def job_count
|
||||
# We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
|
||||
|
|
|
|||
|
|
@ -441,6 +441,7 @@ module Ci
|
|||
private
|
||||
|
||||
EXECUTOR_NAME_TO_TYPES = {
|
||||
'unknown' => :unknown,
|
||||
'custom' => :custom,
|
||||
'shell' => :shell,
|
||||
'docker' => :docker,
|
||||
|
|
@ -454,6 +455,8 @@ module Ci
|
|||
'kubernetes' => :kubernetes
|
||||
}.freeze
|
||||
|
||||
EXECUTOR_TYPE_TO_NAMES = EXECUTOR_NAME_TO_TYPES.invert.freeze
|
||||
|
||||
def cleanup_runner_queue
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.del(runner_queue_key)
|
||||
|
|
|
|||
|
|
@ -11,5 +11,9 @@ module Ci
|
|||
|
||||
delegator_override :locked
|
||||
alias_method :locked, :locked?
|
||||
|
||||
def executor_name
|
||||
Ci::Runner::EXECUTOR_TYPE_TO_NAMES[executor_type&.to_sym]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: graphql_ci_runner_executor
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76534
|
||||
rollout_issue_url:
|
||||
milestone: '14.7'
|
||||
type: development
|
||||
group: group::runner
|
||||
default_enabled: false
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
data_category: optional
|
||||
key_path: usage_activity_by_stage_monthly.manage.bulk_imports.gitlab
|
||||
description: DEPRECATED - Count of projects imported using bulk imports
|
||||
description: REMOVED - Count of projects imported using bulk imports
|
||||
product_section: dev
|
||||
product_stage: manage
|
||||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ product_stage: manage
|
|||
product_group: group::import
|
||||
product_category: importers
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
|
||||
type: reference
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Merge request diffs storage **(FREE SELF)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52568) in GitLab 11.8.
|
||||
|
||||
Merge request diffs are size-limited copies of diffs associated with merge
|
||||
requests. When viewing a merge request, diffs are sourced from these copies
|
||||
wherever possible as a performance optimization.
|
||||
|
|
|
|||
|
|
@ -8813,6 +8813,7 @@ Represents the total number of issues and their weights for a particular day.
|
|||
| <a id="cijobcreatedat"></a>`createdAt` | [`Time!`](#time) | When the job was created. |
|
||||
| <a id="cijobcreatedbytag"></a>`createdByTag` | [`Boolean!`](#boolean) | Whether the job was created by a tag. |
|
||||
| <a id="cijobdetailedstatus"></a>`detailedStatus` | [`DetailedStatus`](#detailedstatus) | Detailed status of the job. |
|
||||
| <a id="cijobdownstreampipeline"></a>`downstreamPipeline` | [`Pipeline`](#pipeline) | Downstream pipeline for a bridge. |
|
||||
| <a id="cijobduration"></a>`duration` | [`Int`](#int) | Duration of the job in seconds. |
|
||||
| <a id="cijobfinishedat"></a>`finishedAt` | [`Time`](#time) | When a job has finished running. |
|
||||
| <a id="cijobid"></a>`id` | [`JobID`](#jobid) | ID of the job. |
|
||||
|
|
@ -8887,6 +8888,7 @@ Represents the total number of issues and their weights for a particular day.
|
|||
| <a id="cirunneradminurl"></a>`adminUrl` | [`String`](#string) | Admin URL of the runner. Only available for administrators. |
|
||||
| <a id="cirunnercontactedat"></a>`contactedAt` | [`Time`](#time) | Last contact from the runner. |
|
||||
| <a id="cirunnerdescription"></a>`description` | [`String`](#string) | Description of the runner. |
|
||||
| <a id="cirunnerexecutorname"></a>`executorName` | [`String`](#string) | Executor last advertised by the runner. Available only when feature flag `graphql_ci_runner_executor` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
|
||||
| <a id="cirunnerid"></a>`id` | [`CiRunnerID!`](#cirunnerid) | ID of the runner. |
|
||||
| <a id="cirunneripaddress"></a>`ipAddress` | [`String`](#string) | IP address of the runner. |
|
||||
| <a id="cirunnerjobcount"></a>`jobCount` | [`Int`](#int) | Number of jobs processed by the runner (limited to 1000, plus one to indicate that more items exist). |
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
|
||||
type: reference, api
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Project snippets **(FREE)**
|
||||
|
|
@ -247,8 +246,6 @@ curl "https://gitlab.com/api/v4/projects/1/snippets/2/files/master/snippet%2Erb/
|
|||
|
||||
## Get user agent details
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29508) in GitLab 9.4.
|
||||
|
||||
Available only for users with the Administrator [role](../user/permissions.md).
|
||||
|
||||
```plaintext
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
|
||||
type: reference, api
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Snippets API **(FREE)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/6373) in GitLab 8.15.
|
||||
|
||||
Snippets API operates on [snippets](../user/snippets.md). Related APIs exist for
|
||||
[project snippets](project_snippets.md) and
|
||||
[moving snippets between storages](snippet_repository_storage_moves.md).
|
||||
|
|
@ -449,8 +446,6 @@ Example response:
|
|||
|
||||
## Get user agent details
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12655) in GitLab 9.4.
|
||||
|
||||
NOTE:
|
||||
Available only for administrators.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
|
||||
type: reference, api
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Project wikis API **(FREE)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13372) in GitLab 10.0.
|
||||
|
||||
The project [wikis](../user/project/wiki/index.md) API is available only in APIv4.
|
||||
An API for [group wikis](group_wikis.md) is also available.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
type: reference, dev
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
|
|
@ -91,8 +90,6 @@ Only some data is persisted in the database:
|
|||
|
||||
The web UI uploads attachments through the REST API, which stores the files as commits in the wiki repository.
|
||||
|
||||
Prior to GitLab 11.3 attachments were stored outside of the repository, [see this issue](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33475).
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Gollum installation instructions](https://github.com/gollum/gollum/wiki/Installation)
|
||||
|
|
|
|||
|
|
@ -22,10 +22,6 @@ NOTE:
|
|||
By default, all Git operations are first tried unauthenticated. Because of this, HTTP Git operations
|
||||
may trigger the rate limits configured for unauthenticated requests.
|
||||
|
||||
NOTE:
|
||||
The rate limits for API requests don't affect requests made by the frontend, as these are always
|
||||
counted as web traffic.
|
||||
|
||||
## Enable unauthenticated API request rate limit
|
||||
|
||||
To enable the unauthenticated request rate limit:
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ The certificate [fingerprint algorithm](../../../integration/saml.md#notes-on-co
|
|||
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/292811) in GitLab 13.8, with an updated timeout experience.
|
||||
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/211962) in GitLab 13.8 with allowing group owners to not go through SSO.
|
||||
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/9152) in GitLab 13.11 with enforcing open SSO session to use Git if this setting is switched on.
|
||||
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/339888) in GitLab 14.7 to not enforce SSO checks for Git activity originating from CI/CD jobs.
|
||||
|
||||
With this option enabled, users (except users with the Owner role) must access GitLab using your group GitLab single sign-on URL to access group resources. Users added manually as members can't access group resources.
|
||||
|
||||
|
|
@ -127,6 +128,7 @@ SSO has the following effects when enabled:
|
|||
even if the project is forked.
|
||||
- For Git activity over SSH and HTTPS, users must have at least one active session signed-in through SSO before they can push to or
|
||||
pull from a GitLab repository.
|
||||
- Git activity originating from CI/CD jobs do not have the SSO check enforced.
|
||||
- Credentials that are not tied to regular users (for example, access tokens and deploy keys) do not have the SSO check enforced.
|
||||
- Users must be signed-in through SSO before they can pull images using the [Dependency Proxy](../../packages/dependency_proxy/index.md).
|
||||
<!-- Add bullet for API activity when https://gitlab.com/gitlab-org/gitlab/-/issues/9152 is complete -->
|
||||
|
|
|
|||
|
|
@ -2,13 +2,10 @@
|
|||
stage: Create
|
||||
group: Code Review
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: reference, howto
|
||||
---
|
||||
|
||||
# Allow collaboration on merge requests across forks **(FREE)**
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17395) in GitLab 10.6.
|
||||
|
||||
When a user opens a merge request from a fork, they are given the option to allow
|
||||
upstream members to collaborate with them on the source branch. This allows
|
||||
the members of the upstream project to make small fixes or rebase branches
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
stage: Create
|
||||
group: Code Review
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: howto
|
||||
description: "How to create merge requests in GitLab."
|
||||
disqus_identifier: 'https://docs.gitlab.com/ee/gitlab-basics/add-merge-request.html'
|
||||
---
|
||||
|
|
@ -111,10 +110,6 @@ For more information, [see the forking workflow documentation](../repository/for
|
|||
|
||||
## By sending an email
|
||||
|
||||
> The format of the generated email address changed in GitLab 11.7.
|
||||
The earlier format is still supported so existing aliases
|
||||
or contacts still work.
|
||||
|
||||
You can create a merge request by sending an email message to GitLab.
|
||||
The merge request target branch is the project's default branch.
|
||||
|
||||
|
|
@ -142,8 +137,6 @@ A merge request is created.
|
|||
|
||||
### Add attachments when creating a merge request by email
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/22723) in GitLab 11.5.
|
||||
|
||||
You can add commits to a merge request by adding
|
||||
patches as attachments to the email. All attachments with a filename
|
||||
ending in `.patch` are considered patches and are processed
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
stage: Create
|
||||
group: Code Review
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: index, reference
|
||||
description: "Getting started with merge requests."
|
||||
---
|
||||
|
||||
|
|
@ -92,8 +91,7 @@ and the merge request is added to their
|
|||
|
||||
#### Multiple assignees **(PREMIUM)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2004) in GitLab 11.11.
|
||||
> - Moved to GitLab Premium in 13.9
|
||||
> Moved to GitLab Premium in 13.9
|
||||
|
||||
Multiple people often review merge requests at the same time.
|
||||
GitLab allows you to have multiple assignees for merge requests
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
stage: Create
|
||||
group: Code Review
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: reference, concepts
|
||||
---
|
||||
|
||||
# Revert changes **(FREE)**
|
||||
|
|
@ -12,11 +11,6 @@ by clicking the **Revert** button in merge requests and commit details.
|
|||
|
||||
## Revert a merge request
|
||||
|
||||
NOTE:
|
||||
The **Revert** button is available only for merge requests
|
||||
created in GitLab 8.5 and later. However, you can still revert a merge request
|
||||
by reverting the merge commit from the list of Commits page.
|
||||
|
||||
NOTE:
|
||||
The **Revert** button is shown only for projects that use the
|
||||
merge method "Merge Commit", which can be set under the project's
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@ changes appears as a system note.
|
|||
|
||||
## Find the merge request that introduced a change
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/2383) in GitLab 10.5.
|
||||
|
||||
When viewing the commit details page, GitLab links to the merge request (or
|
||||
merge requests, if it's in more than one) containing that commit.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
stage: Create
|
||||
group: Editor
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: howto
|
||||
---
|
||||
|
||||
# GitLab Web Editor **(FREE)**
|
||||
|
|
@ -118,8 +117,6 @@ There are multiple ways to create a branch from the GitLab web interface.
|
|||
|
||||
### Create a new branch from an issue
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/2808) in GitLab 8.6.
|
||||
|
||||
If your development workflow requires an issue for every merge
|
||||
request, you can create a branch directly from the issue to speed the process up.
|
||||
The new branch, and later its merge request, are marked as related to this issue.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
|
||||
type: reference, how-to
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Wiki **(FREE)**
|
||||
|
|
@ -87,11 +86,7 @@ Users with the [Developer role](../../permissions.md) can create new wiki pages:
|
|||
[special characters](#special-characters-in-page-titles) for subdirectories and formatting,
|
||||
and have [length restrictions](#length-restrictions-for-file-and-directory-names).
|
||||
1. Add content to your wiki page.
|
||||
1. Optional. Attach a file, and GitLab stores it according to your installed version of GitLab:
|
||||
- *Files added in [GitLab 11.3 and later](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/33475):*
|
||||
Files are stored in the wiki's Git repository.
|
||||
- *Files added GitLab 11.2 and earlier:* Files are stored in GitLab itself. To add
|
||||
the file to the wiki's Git repository, you must re-upload the file.
|
||||
1. Optional. Attach a file, and GitLab stores it in the wiki's Git repository.
|
||||
1. Add a **Commit message**. Git requires a commit message, so GitLab creates one
|
||||
if you don't enter one yourself.
|
||||
1. Select **Create page**.
|
||||
|
|
@ -227,9 +222,9 @@ You can see the changes made in a version of a wiki page, similar to versioned d
|
|||
|
||||
## Track wiki events
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14902) in **GitLab 12.10.**
|
||||
> - Git events were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216014) in **GitLab 13.0.**
|
||||
> - [Feature flag for Git events was removed](https://gitlab.com/gitlab-org/gitlab/-/issues/258665) in **GitLab 13.5**
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14902) in GitLab 12.10.
|
||||
> - Git events were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216014) in GitLab 13.0.
|
||||
> - [Feature flag for Git events was removed](https://gitlab.com/gitlab-org/gitlab/-/issues/258665) in GitLab 13.5.
|
||||
|
||||
GitLab tracks wiki creation, deletion, and update events. These events are displayed on these pages:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
|
||||
type: index, reference, howto
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Searching in GitLab **(FREE)**
|
||||
|
|
@ -102,8 +101,7 @@ You can filter the **Issues** list to individual instances by their ID. For exam
|
|||
|
||||
### Filtering merge requests by approvers **(PREMIUM)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9468) in GitLab 11.9.
|
||||
> - Moved to GitLab Premium in 13.9.
|
||||
> Moved to GitLab Premium in 13.9.
|
||||
|
||||
To filter merge requests by an individual approver, you can type (or select from
|
||||
the dropdown) **Approver** and select the user.
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
module Gitlab
|
||||
module RackAttack
|
||||
module Request
|
||||
include ::Gitlab::Utils::StrongMemoize
|
||||
|
||||
FILES_PATH_REGEX = %r{^/api/v\d+/projects/[^/]+/repository/files/.+}.freeze
|
||||
GROUP_PATH_REGEX = %r{^/api/v\d+/groups/[^/]+/?$}.freeze
|
||||
|
||||
|
|
@ -32,15 +30,15 @@ module Gitlab
|
|||
end
|
||||
|
||||
def api_internal_request?
|
||||
path.match?(%r{^/api/v\d+/internal/})
|
||||
path =~ %r{^/api/v\d+/internal/}
|
||||
end
|
||||
|
||||
def health_check_request?
|
||||
path.match?(%r{^/-/(health|liveness|readiness|metrics)})
|
||||
path =~ %r{^/-/(health|liveness|readiness|metrics)}
|
||||
end
|
||||
|
||||
def container_registry_event?
|
||||
path.match?(%r{^/api/v\d+/container_registry_event/})
|
||||
path =~ %r{^/api/v\d+/container_registry_event/}
|
||||
end
|
||||
|
||||
def product_analytics_collector_request?
|
||||
|
|
@ -60,7 +58,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def protected_path_regex
|
||||
path.match?(protected_paths_regex)
|
||||
path =~ protected_paths_regex
|
||||
end
|
||||
|
||||
def throttle?(throttle, authenticated:)
|
||||
|
|
@ -72,7 +70,6 @@ module Gitlab
|
|||
def throttle_unauthenticated_api?
|
||||
api_request? &&
|
||||
!should_be_skipped? &&
|
||||
!frontend_request? &&
|
||||
!throttle_unauthenticated_packages_api? &&
|
||||
!throttle_unauthenticated_files_api? &&
|
||||
!throttle_unauthenticated_deprecated_api? &&
|
||||
|
|
@ -81,7 +78,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def throttle_unauthenticated_web?
|
||||
(web_request? || frontend_request?) &&
|
||||
web_request? &&
|
||||
!should_be_skipped? &&
|
||||
# TODO: Column will be renamed in https://gitlab.com/gitlab-org/gitlab/-/issues/340031
|
||||
Gitlab::Throttle.settings.throttle_unauthenticated_enabled &&
|
||||
|
|
@ -90,7 +87,6 @@ module Gitlab
|
|||
|
||||
def throttle_authenticated_api?
|
||||
api_request? &&
|
||||
!frontend_request? &&
|
||||
!throttle_authenticated_packages_api? &&
|
||||
!throttle_authenticated_files_api? &&
|
||||
!throttle_authenticated_deprecated_api? &&
|
||||
|
|
@ -98,7 +94,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def throttle_authenticated_web?
|
||||
(web_request? || frontend_request?) &&
|
||||
web_request? &&
|
||||
!throttle_authenticated_git_lfs? &&
|
||||
Gitlab::Throttle.settings.throttle_authenticated_web_enabled
|
||||
end
|
||||
|
|
@ -182,24 +178,15 @@ module Gitlab
|
|||
end
|
||||
|
||||
def packages_api_path?
|
||||
path.match?(::Gitlab::Regex::Packages::API_PATH_REGEX)
|
||||
path =~ ::Gitlab::Regex::Packages::API_PATH_REGEX
|
||||
end
|
||||
|
||||
def git_lfs_path?
|
||||
path.match?(Gitlab::PathRegex.repository_git_lfs_route_regex)
|
||||
path =~ Gitlab::PathRegex.repository_git_lfs_route_regex
|
||||
end
|
||||
|
||||
def files_api_path?
|
||||
path.match?(FILES_PATH_REGEX)
|
||||
end
|
||||
|
||||
def frontend_request?
|
||||
strong_memoize(:frontend_request) do
|
||||
next false unless env.include?('HTTP_X_CSRF_TOKEN') && session.include?(:_csrf_token)
|
||||
|
||||
# CSRF tokens are not verified for GET/HEAD requests, so we pretend that we always have a POST request.
|
||||
Gitlab::RequestForgeryProtection.verified?(env.merge('REQUEST_METHOD' => 'POST'))
|
||||
end
|
||||
path =~ FILES_PATH_REGEX
|
||||
end
|
||||
|
||||
def deprecated_api_request?
|
||||
|
|
@ -208,7 +195,7 @@ module Gitlab
|
|||
with_projects = params['with_projects']
|
||||
with_projects = true if with_projects.blank?
|
||||
|
||||
path.match?(GROUP_PATH_REGEX) && Gitlab::Utils.to_boolean(with_projects)
|
||||
path =~ GROUP_PATH_REGEX && Gitlab::Utils.to_boolean(with_projects)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -553,33 +553,11 @@ module Gitlab
|
|||
user_auth_by_provider: distinct_count_user_auth_by_provider(time_period),
|
||||
unique_users_all_imports: unique_users_all_imports(time_period),
|
||||
bulk_imports: {
|
||||
gitlab: DEPRECATED_VALUE,
|
||||
gitlab_v1: count(::BulkImport.where(**time_period, source_type: :gitlab))
|
||||
},
|
||||
project_imports: project_imports(time_period),
|
||||
issue_imports: issue_imports(time_period),
|
||||
group_imports: group_imports(time_period),
|
||||
|
||||
# Deprecated data to be removed
|
||||
projects_imported: {
|
||||
total: DEPRECATED_VALUE,
|
||||
gitlab_project: DEPRECATED_VALUE,
|
||||
gitlab: DEPRECATED_VALUE,
|
||||
github: DEPRECATED_VALUE,
|
||||
bitbucket: DEPRECATED_VALUE,
|
||||
bitbucket_server: DEPRECATED_VALUE,
|
||||
gitea: DEPRECATED_VALUE,
|
||||
git: DEPRECATED_VALUE,
|
||||
manifest: DEPRECATED_VALUE
|
||||
},
|
||||
issues_imported: {
|
||||
jira: DEPRECATED_VALUE,
|
||||
fogbugz: DEPRECATED_VALUE,
|
||||
phabricator: DEPRECATED_VALUE,
|
||||
csv: DEPRECATED_VALUE
|
||||
},
|
||||
groups_imported: DEPRECATED_VALUE
|
||||
# End of deprecated keys
|
||||
group_imports: group_imports(time_period)
|
||||
}
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
|
|
|||
|
|
@ -3,11 +3,15 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ApplicationCable::Connection, :clean_gitlab_redis_sessions do
|
||||
include SessionHelpers
|
||||
let(:session_id) { Rack::Session::SessionId.new('6919a6f1bb119dd7396fadc38fd18d0d') }
|
||||
|
||||
context 'when session cookie is set' do
|
||||
before do
|
||||
stub_session(session_hash)
|
||||
Gitlab::Redis::Sessions.with do |redis|
|
||||
redis.set("session:gitlab:#{session_id.private_id}", Marshal.dump(session_hash))
|
||||
end
|
||||
|
||||
cookies[Gitlab::Application.config.session_options[:key]] = session_id.public_id
|
||||
end
|
||||
|
||||
context 'when user is logged in' do
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ RSpec.describe Types::Ci::JobType do
|
|||
created_by_tag
|
||||
detailedStatus
|
||||
duration
|
||||
downstreamPipeline
|
||||
finished_at
|
||||
id
|
||||
manual_job
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ RSpec.describe GitlabSchema.types['CiRunner'] do
|
|||
expected_fields = %w[
|
||||
id description contacted_at maximum_timeout access_level active status
|
||||
version short_sha revision locked run_untagged ip_address runner_type tag_list
|
||||
project_count job_count admin_url user_permissions
|
||||
project_count job_count admin_url user_permissions executor_name
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
|
|
|
|||
|
|
@ -5,19 +5,6 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::RackAttack::Request do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
let(:env) { {} }
|
||||
let(:session) { {} }
|
||||
let(:request) do
|
||||
::Rack::Attack::Request.new(
|
||||
env.reverse_merge(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'PATH_INFO' => path,
|
||||
'rack.input' => StringIO.new,
|
||||
'rack.session' => session
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
describe 'FILES_PATH_REGEX' do
|
||||
subject { described_class::FILES_PATH_REGEX }
|
||||
|
||||
|
|
@ -29,63 +16,11 @@ RSpec.describe Gitlab::RackAttack::Request do
|
|||
it { is_expected.not_to match('/api/v4/projects/some/nested/repo/repository/files/README') }
|
||||
end
|
||||
|
||||
describe '#api_request?' do
|
||||
subject { request.api_request? }
|
||||
|
||||
where(:path, :env, :expected) do
|
||||
'/' | {} | false
|
||||
'/groups' | {} | false
|
||||
|
||||
'/api' | {} | true
|
||||
'/api/v4/groups/1' | {} | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#web_request?' do
|
||||
subject { request.web_request? }
|
||||
|
||||
where(:path, :env, :expected) do
|
||||
'/' | {} | true
|
||||
'/groups' | {} | true
|
||||
|
||||
'/api' | {} | false
|
||||
'/api/v4/groups/1' | {} | false
|
||||
end
|
||||
|
||||
with_them do
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#frontend_request?', :allow_forgery_protection do
|
||||
subject { request.send(:frontend_request?) }
|
||||
|
||||
let(:path) { '/' }
|
||||
|
||||
# Define these as local variables so we can use them in the `where` block.
|
||||
valid_token = SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH)
|
||||
other_token = SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH)
|
||||
|
||||
where(:session, :env, :expected) do
|
||||
{} | {} | false # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
|
||||
{} | { 'HTTP_X_CSRF_TOKEN' => valid_token } | false
|
||||
{ _csrf_token: valid_token } | { 'HTTP_X_CSRF_TOKEN' => other_token } | false
|
||||
{ _csrf_token: valid_token } | { 'HTTP_X_CSRF_TOKEN' => valid_token } | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
it { is_expected.to eq(expected) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#deprecated_api_request?' do
|
||||
subject { request.send(:deprecated_api_request?) }
|
||||
let(:env) { { 'REQUEST_METHOD' => 'GET', 'rack.input' => StringIO.new, 'PATH_INFO' => path, 'QUERY_STRING' => query } }
|
||||
let(:request) { ::Rack::Attack::Request.new(env) }
|
||||
|
||||
let(:env) { { 'QUERY_STRING' => query } }
|
||||
subject { !!request.__send__(:deprecated_api_request?) }
|
||||
|
||||
where(:path, :query, :expected) do
|
||||
'/' | '' | false
|
||||
|
|
|
|||
|
|
@ -279,8 +279,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
expect(described_class.usage_activity_by_stage_manage({})).to include(
|
||||
{
|
||||
bulk_imports: {
|
||||
gitlab_v1: 2,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
gitlab_v1: 2
|
||||
},
|
||||
project_imports: {
|
||||
bitbucket: 2,
|
||||
|
|
@ -303,32 +302,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
group_imports: {
|
||||
group_import: 2,
|
||||
gitlab_migration: 2
|
||||
},
|
||||
projects_imported: {
|
||||
total: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab_project: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
github: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket_server: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitea: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
git: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
manifest: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
issues_imported: {
|
||||
jira: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
fogbugz: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
phabricator: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
csv: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
groups_imported: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
}
|
||||
}
|
||||
)
|
||||
expect(described_class.usage_activity_by_stage_manage(described_class.monthly_time_range_db_params)).to include(
|
||||
{
|
||||
bulk_imports: {
|
||||
gitlab_v1: 1,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
gitlab_v1: 1
|
||||
},
|
||||
project_imports: {
|
||||
bitbucket: 1,
|
||||
|
|
@ -351,25 +331,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
group_imports: {
|
||||
group_import: 1,
|
||||
gitlab_migration: 1
|
||||
},
|
||||
projects_imported: {
|
||||
total: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab_project: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitlab: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
github: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
bitbucket_server: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
gitea: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
git: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
manifest: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
issues_imported: {
|
||||
jira: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
fogbugz: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
phabricator: Gitlab::UsageData::DEPRECATED_VALUE,
|
||||
csv: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
},
|
||||
groups_imported: Gitlab::UsageData::DEPRECATED_VALUE
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ require 'mime/types'
|
|||
|
||||
RSpec.describe API::Commits do
|
||||
include ProjectForksHelper
|
||||
include SessionHelpers
|
||||
|
||||
let(:user) { create(:user) }
|
||||
let(:guest) { create(:user).tap { |u| project.add_guest(u) } }
|
||||
|
|
@ -379,7 +378,14 @@ RSpec.describe API::Commits do
|
|||
|
||||
context 'when using warden' do
|
||||
it 'increments usage counters', :clean_gitlab_redis_sessions do
|
||||
stub_session('warden.user.user.key' => [[user.id], user.encrypted_password[0, 29]])
|
||||
session_id = Rack::Session::SessionId.new('6919a6f1bb119dd7396fadc38fd18d0d')
|
||||
session_hash = { 'warden.user.user.key' => [[user.id], user.encrypted_password[0, 29]] }
|
||||
|
||||
Gitlab::Redis::Sessions.with do |redis|
|
||||
redis.set("session:gitlab:#{session_id.private_id}", Marshal.dump(session_hash))
|
||||
end
|
||||
|
||||
cookies[Gitlab::Application.config.session_options[:key]] = session_id.public_id
|
||||
|
||||
expect(::Gitlab::UsageDataCounters::WebIdeCounter).to receive(:increment_commits_count)
|
||||
expect(::Gitlab::UsageDataCounters::EditorUniqueCounter).to receive(:track_web_ide_edit_action)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ RSpec.describe 'Query.project.pipeline' do
|
|||
name
|
||||
jobs {
|
||||
nodes {
|
||||
downstreamPipeline {
|
||||
id
|
||||
path
|
||||
}
|
||||
name
|
||||
needs {
|
||||
nodes { #{all_graphql_fields_for('CiBuildNeed')} }
|
||||
|
|
@ -131,6 +135,8 @@ RSpec.describe 'Query.project.pipeline' do
|
|||
end
|
||||
|
||||
it 'does not generate N+1 queries', :request_store, :use_sql_query_cache do
|
||||
create(:ci_bridge, name: 'bridge-1', pipeline: pipeline, downstream_pipeline: create(:ci_pipeline))
|
||||
|
||||
post_graphql(query, current_user: user)
|
||||
|
||||
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
|
||||
|
|
@ -139,6 +145,8 @@ RSpec.describe 'Query.project.pipeline' do
|
|||
|
||||
create(:ci_build, name: 'test-a', pipeline: pipeline)
|
||||
create(:ci_build, name: 'test-b', pipeline: pipeline)
|
||||
create(:ci_bridge, name: 'bridge-2', pipeline: pipeline, downstream_pipeline: create(:ci_pipeline))
|
||||
create(:ci_bridge, name: 'bridge-3', pipeline: pipeline, downstream_pipeline: create(:ci_pipeline))
|
||||
|
||||
expect do
|
||||
post_graphql(query, current_user: user)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
let_it_be(:active_instance_runner) do
|
||||
create(:ci_runner, :instance, description: 'Runner 1', contacted_at: 2.hours.ago,
|
||||
active: true, version: 'adfe156', revision: 'a', locked: true, ip_address: '127.0.0.1', maximum_timeout: 600,
|
||||
access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true)
|
||||
access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :custom)
|
||||
end
|
||||
|
||||
let_it_be(:inactive_instance_runner) do
|
||||
|
|
@ -22,7 +22,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
let_it_be(:active_group_runner) do
|
||||
create(:ci_runner, :group, groups: [group], description: 'Group runner 1', contacted_at: 2.hours.ago,
|
||||
active: true, version: 'adfe156', revision: 'a', locked: true, ip_address: '127.0.0.1', maximum_timeout: 600,
|
||||
access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true)
|
||||
access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :shell)
|
||||
end
|
||||
|
||||
def get_runner(id)
|
||||
|
|
@ -69,6 +69,7 @@ RSpec.describe 'Query.runner(id)' do
|
|||
'runUntagged' => runner.run_untagged,
|
||||
'ipAddress' => runner.ip_address,
|
||||
'runnerType' => runner.instance_type? ? 'INSTANCE_TYPE' : 'PROJECT_TYPE',
|
||||
'executorName' => runner.executor_type&.dasherize,
|
||||
'jobCount' => 0,
|
||||
'projectCount' => nil,
|
||||
'adminUrl' => "http://localhost/admin/runners/#{runner.id}",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_caching do
|
||||
include RackAttackSpecHelpers
|
||||
include SessionHelpers
|
||||
|
||||
let(:settings) { Gitlab::CurrentSettings.current_application_settings }
|
||||
|
||||
|
|
@ -64,22 +63,6 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
|
|||
end
|
||||
end
|
||||
|
||||
describe 'API requests from the frontend', :api, :clean_gitlab_redis_sessions do
|
||||
context 'when unauthenticated' do
|
||||
it_behaves_like 'rate-limited frontend API requests' do
|
||||
let(:throttle_setting_prefix) { 'throttle_unauthenticated' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it_behaves_like 'rate-limited frontend API requests' do
|
||||
let_it_be(:personal_access_token) { create(:personal_access_token) }
|
||||
|
||||
let(:throttle_setting_prefix) { 'throttle_authenticated' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'API requests authenticated with personal access token', :api do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:token) { create(:personal_access_token, user: user) }
|
||||
|
|
|
|||
|
|
@ -26,14 +26,14 @@ module RackAttackSpecHelpers
|
|||
{ 'AUTHORIZATION' => "Basic #{encoded_login}" }
|
||||
end
|
||||
|
||||
def expect_rejection(name = nil, &block)
|
||||
def expect_rejection(&block)
|
||||
yield
|
||||
|
||||
expect(response).to have_gitlab_http_status(:too_many_requests)
|
||||
|
||||
expect(response.headers.to_h).to include(
|
||||
'RateLimit-Limit' => a_string_matching(/^\d+$/),
|
||||
'RateLimit-Name' => name || a_string_matching(/^throttle_.*$/),
|
||||
'RateLimit-Name' => a_string_matching(/^throttle_.*$/),
|
||||
'RateLimit-Observed' => a_string_matching(/^\d+$/),
|
||||
'RateLimit-Remaining' => a_string_matching(/^\d+$/),
|
||||
'Retry-After' => a_string_matching(/^\d+$/)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module SessionHelpers
|
||||
# Stub a session in Redis, for use in request specs where we can't mock the session directly.
|
||||
# This also needs the :clean_gitlab_redis_sessions tag on the spec.
|
||||
def stub_session(session_hash)
|
||||
unless RSpec.current_example.metadata[:clean_gitlab_redis_sessions]
|
||||
raise 'Add :clean_gitlab_redis_sessions to your spec!'
|
||||
end
|
||||
|
||||
session_id = Rack::Session::SessionId.new(SecureRandom.hex)
|
||||
|
||||
Gitlab::Redis::Sessions.with do |redis|
|
||||
redis.set("session:gitlab:#{session_id.private_id}", Marshal.dump(session_hash))
|
||||
end
|
||||
|
||||
cookies[Gitlab::Application.config.session_options[:key]] = session_id.public_id
|
||||
end
|
||||
|
||||
def expect_single_session_with_authenticated_ttl
|
||||
expect_single_session_with_expiration(Settings.gitlab['session_expire_delay'] * 60)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ RSpec.shared_examples 'when the snippet is not found' do
|
|||
end
|
||||
|
||||
RSpec.shared_examples 'snippet edit usage data counters' do
|
||||
include SessionHelpers
|
||||
|
||||
context 'when user is sessionless' do
|
||||
it 'does not track usage data actions' do
|
||||
expect(::Gitlab::UsageDataCounters::EditorUniqueCounter).not_to receive(:track_snippet_editor_edit_action)
|
||||
|
|
@ -22,7 +20,14 @@ RSpec.shared_examples 'snippet edit usage data counters' do
|
|||
|
||||
context 'when user is not sessionless', :clean_gitlab_redis_sessions do
|
||||
before do
|
||||
stub_session('warden.user.user.key' => [[current_user.id], current_user.encrypted_password[0, 29]])
|
||||
session_id = Rack::Session::SessionId.new('6919a6f1bb119dd7396fadc38fd18d0d')
|
||||
session_hash = { 'warden.user.user.key' => [[current_user.id], current_user.encrypted_password[0, 29]] }
|
||||
|
||||
Gitlab::Redis::Sessions.with do |redis|
|
||||
redis.set("session:gitlab:#{session_id.private_id}", Marshal.dump(session_hash))
|
||||
end
|
||||
|
||||
cookies[Gitlab::Application.config.session_options[:key]] = session_id.public_id
|
||||
end
|
||||
|
||||
it 'tracks usage data actions', :clean_gitlab_redis_sessions do
|
||||
|
|
|
|||
|
|
@ -580,88 +580,3 @@ RSpec.shared_examples 'rate-limited unauthenticated requests' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Requires let variables:
|
||||
# * throttle_setting_prefix: "throttle_authenticated", "throttle_unauthenticated"
|
||||
RSpec.shared_examples 'rate-limited frontend API requests' do
|
||||
let(:requests_per_period) { 1 }
|
||||
let(:csrf_token) { SecureRandom.base64(ActionController::RequestForgeryProtection::AUTHENTICITY_TOKEN_LENGTH) }
|
||||
let(:csrf_session) { { _csrf_token: csrf_token } }
|
||||
let(:personal_access_token) { nil }
|
||||
|
||||
let(:api_path) { '/projects' }
|
||||
|
||||
# These don't actually exist, so a 404 is the expected response.
|
||||
let(:files_api_path) { '/projects/1/repository/files/ref/path' }
|
||||
let(:packages_api_path) { '/projects/1/packages/foo' }
|
||||
let(:deprecated_api_path) { '/groups/1?with_projects=true' }
|
||||
|
||||
def get_api(path: api_path, csrf: false)
|
||||
headers = csrf ? { 'X-CSRF-Token' => csrf_token } : nil
|
||||
get api(path, personal_access_token: personal_access_token), headers: headers
|
||||
end
|
||||
|
||||
def expect_not_found(&block)
|
||||
yield
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
|
||||
before do
|
||||
stub_application_setting(
|
||||
"#{throttle_setting_prefix}_enabled" => true,
|
||||
"#{throttle_setting_prefix}_requests_per_period" => requests_per_period,
|
||||
"#{throttle_setting_prefix}_api_enabled" => true,
|
||||
"#{throttle_setting_prefix}_api_requests_per_period" => requests_per_period,
|
||||
"#{throttle_setting_prefix}_web_enabled" => true,
|
||||
"#{throttle_setting_prefix}_web_requests_per_period" => requests_per_period,
|
||||
"#{throttle_setting_prefix}_files_api_enabled" => true,
|
||||
"#{throttle_setting_prefix}_packages_api_enabled" => true,
|
||||
"#{throttle_setting_prefix}_deprecated_api_enabled" => true
|
||||
)
|
||||
|
||||
stub_session(csrf_session)
|
||||
end
|
||||
|
||||
context 'with a CSRF token' do
|
||||
it 'uses the rate limit for web requests' do
|
||||
requests_per_period.times { get_api csrf: true }
|
||||
|
||||
expect_rejection("#{throttle_setting_prefix}_web") { get_api csrf: true }
|
||||
expect_rejection("#{throttle_setting_prefix}_web") { get_api csrf: true, path: files_api_path }
|
||||
expect_rejection("#{throttle_setting_prefix}_web") { get_api csrf: true, path: packages_api_path }
|
||||
expect_rejection("#{throttle_setting_prefix}_web") { get_api csrf: true, path: deprecated_api_path }
|
||||
|
||||
# API rate limit is not triggered yet
|
||||
expect_ok { get_api }
|
||||
expect_not_found { get_api path: files_api_path }
|
||||
expect_not_found { get_api path: packages_api_path }
|
||||
expect_not_found { get_api path: deprecated_api_path }
|
||||
end
|
||||
|
||||
context 'without a CSRF session' do
|
||||
let(:csrf_session) { nil }
|
||||
|
||||
it 'always uses the rate limit for API requests' do
|
||||
requests_per_period.times { get_api csrf: true }
|
||||
|
||||
expect_rejection("#{throttle_setting_prefix}_api") { get_api csrf: true }
|
||||
expect_rejection("#{throttle_setting_prefix}_api") { get_api }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without a CSRF token' do
|
||||
it 'uses the rate limit for API requests' do
|
||||
requests_per_period.times { get_api }
|
||||
|
||||
expect_rejection("#{throttle_setting_prefix}_api") { get_api }
|
||||
|
||||
# Web and custom API rate limits are not triggered yet
|
||||
expect_ok { get_api csrf: true }
|
||||
expect_not_found { get_api path: files_api_path }
|
||||
expect_not_found { get_api path: packages_api_path }
|
||||
expect_not_found { get_api path: deprecated_api_path }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue