Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-12-12 03:16:05 +00:00
parent 101d32c3b8
commit fdc2b6184d
48 changed files with 613 additions and 415 deletions

View File

@ -949,7 +949,6 @@ Layout/ArgumentAlignment:
- 'ee/spec/lib/gitlab/data_builder/vulnerability_spec.rb'
- 'ee/spec/lib/gitlab/elastic/indexer_spec.rb'
- 'ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- 'ee/spec/lib/gitlab/geo_spec.rb'
- 'ee/spec/lib/gitlab/git_access_spec.rb'
- 'ee/spec/lib/gitlab/git_access_wiki_spec.rb'

View File

@ -1664,7 +1664,6 @@ Layout/LineLength:
- 'ee/spec/lib/gitlab/geo/log_cursor/lease_spec.rb'
- 'ee/spec/lib/gitlab/geo/oauth/login_state_spec.rb'
- 'ee/spec/lib/gitlab/geo/oauth/logout_token_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- 'ee/spec/lib/gitlab/geo_spec.rb'
- 'ee/spec/lib/gitlab/git_access_spec.rb'
- 'ee/spec/lib/gitlab/git_access_wiki_spec.rb'

View File

@ -368,7 +368,6 @@ RSpec/ContextWording:
- 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb'
- 'ee/spec/lib/gitlab/geo/log_helpers_spec.rb'
- 'ee/spec/lib/gitlab/geo/oauth/session_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- 'ee/spec/lib/gitlab/geo/replicator_spec.rb'
- 'ee/spec/lib/gitlab/geo/signed_data_spec.rb'
- 'ee/spec/lib/gitlab/git_access_spec.rb'

View File

@ -436,7 +436,6 @@ RSpec/NamedSubject:
- 'ee/spec/lib/gitlab/geo/log_cursor/events/hashed_storage_attachments_event_spec.rb'
- 'ee/spec/lib/gitlab/geo/oauth/session_spec.rb'
- 'ee/spec/lib/gitlab/geo/registry_batcher_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_retriever_spec.rb'
- 'ee/spec/lib/gitlab/geo/replicator_spec.rb'
- 'ee/spec/lib/gitlab/geo/signed_data_spec.rb'

View File

@ -15,7 +15,6 @@ RSpec/ScatteredLet:
- 'ee/spec/lib/gitlab/code_owners/loader_spec.rb'
- 'ee/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb'
- 'ee/spec/lib/gitlab/elastic/bulk_indexer_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- 'ee/spec/lib/gitlab/git_access_spec.rb'
- 'ee/spec/lib/gitlab/insights/reducers/count_per_label_reducer_spec.rb'
- 'ee/spec/lib/gitlab/insights/reducers/label_count_per_period_reducer_spec.rb'

View File

@ -623,7 +623,6 @@ Style/IfUnlessModifier:
- 'ee/spec/helpers/ee/users/callouts_helper_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/data_collector_spec.rb'
- 'ee/spec/lib/gitlab/elastic/search_results_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- 'ee/spec/models/concerns/elastic/note_spec.rb'
- 'ee/spec/models/geo_node_status_spec.rb'
- 'ee/spec/models/push_rule_spec.rb'

View File

@ -9,7 +9,6 @@ Style/NumericLiteralPrefix:
- 'ee/lib/ee/gitlab/background_migration/backfill_project_statistics_container_repository_size.rb'
- 'ee/lib/gitlab/geo/replication/blob_downloader.rb'
- 'ee/spec/lib/bulk_imports/groups/pipelines/iterations_pipeline_spec.rb'
- 'ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- 'ee/spec/models/analytics/devops_adoption/snapshot_spec.rb'
- 'ee/spec/models/ci/minutes/usage_spec.rb'
- 'ee/spec/models/ee/group_spec.rb'
@ -30,6 +29,7 @@ Style/NumericLiteralPrefix:
- 'spec/lib/gitlab/database/background_migration/batched_job_spec.rb'
- 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb'
- 'spec/lib/gitlab/git/diff_spec.rb'
- 'spec/lib/gitlab/git/diff_collection_spec.rb'
- 'spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb'
- 'spec/lib/gitlab/gitaly_client/conflict_files_stitcher_spec.rb'
- 'spec/lib/gitlab/gitaly_client/diff_spec.rb'

View File

@ -6,6 +6,7 @@ Style/OpenStructUse:
- 'ee/spec/helpers/ee/blob_helper_spec.rb'
- 'ee/spec/lib/gitlab/auth/group_saml/failure_handler_spec.rb'
- 'spec/helpers/profiles_helper_spec.rb'
- 'spec/lib/gitlab/git/diff_collection_spec.rb'
- 'spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb'
- 'spec/lib/gitlab/gitaly_client/diff_stitcher_spec.rb'
- 'spec/support/helpers/repo_helpers.rb'

View File

@ -36,7 +36,7 @@ export default {
<li
:id="noteAnchorId"
class="timeline-entry note system-note note-wrapper gl-p-0!"
data-qa-selector="alert_system_note_container"
data-testid="alert-system-note-container"
>
<div class="gl-display-inline-flex gl-align-items-center gl-relative">
<div

View File

@ -53,7 +53,7 @@ class DiffNote < Note
end
creation_params = diff_file.diff.to_hash
.except(:too_large)
.except(:too_large, :generated)
.merge(diff: diff_file.diff_hunk(diff_line))
create_note_diff_file(creation_params)

View File

@ -805,7 +805,10 @@ class MergeRequestDiff < ApplicationRecord
if compare.commits.empty?
new_attributes[:state] = :empty
else
diff_collection = compare.diffs(Commit.max_diff_options)
options = Commit.max_diff_options
options[:generated_files] = compare.generated_files if Feature.enabled?(:collapse_generated_diff_files, project)
diff_collection = compare.diffs(options)
new_attributes[:real_size] = diff_collection.real_size
if diff_collection.any?

View File

@ -15,4 +15,4 @@
= f.label :throttle_authenticated_git_lfs_period_in_seconds, _('Authenticated Git LFS rate limit period in seconds'), class: 'gl-font-weight-bold'
= f.number_field :throttle_authenticated_git_lfs_period_in_seconds, class: 'form-control gl-form-input'
= f.submit _('Save changes'), pajamas_button: true, data: { qa_selector: 'save_changes_button' }
= f.submit _('Save changes'), pajamas_button: true

View File

@ -34,4 +34,4 @@
= f.label :group_download_export_limit, _('Maximum group export download requests per minute'), class: 'label-bold'
= f.number_field :group_download_export_limit, class: 'form-control gl-form-input'
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
= f.submit _('Save changes'), pajamas_button: true

View File

@ -6,4 +6,4 @@
= f.label :issues_create_limit, _('Maximum number of requests per minute')
= f.number_field :issues_create_limit, class: 'form-control gl-form-input'
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
= f.submit _('Save changes'), pajamas_button: true

View File

@ -8,7 +8,6 @@
.form-group
= f.gitlab_ui_checkbox_component :"throttle_unauthenticated_#{setting_fragment}_enabled",
_('Enable unauthenticated API request rate limit'),
checkbox_options: { data: { qa_selector: "throttle_unauthenticated_#{setting_fragment}_checkbox" } },
label_options: { class: 'label-bold' }
.form-group
= f.label :"throttle_unauthenticated_#{setting_fragment}_requests_per_period", _('Maximum unauthenticated API requests per rate limit period per IP'), class: 'label-bold'
@ -21,7 +20,6 @@
.form-group
= f.gitlab_ui_checkbox_component :"throttle_authenticated_#{setting_fragment}_enabled",
_('Enable authenticated API request rate limit'),
checkbox_options: { data: { qa_selector: "throttle_authenticated_#{setting_fragment}_checkbox" } },
label_options: { class: 'label-bold' }
.form-group
= f.label :"throttle_authenticated_#{setting_fragment}_requests_per_period", _('Maximum authenticated API requests per rate limit period per user'), class: 'label-bold'
@ -30,4 +28,4 @@
= f.label :"throttle_authenticated_#{setting_fragment}_period_in_seconds", _('Authenticated API rate limit period in seconds'), class: 'label-bold'
= f.number_field :"throttle_authenticated_#{setting_fragment}_period_in_seconds", class: 'form-control gl-form-input'
= f.submit _('Save changes'), pajamas_button: true, data: { qa_selector: 'save_changes_button' }
= f.submit _('Save changes'), pajamas_button: true, data: { testid: 'save_changes_button' }

View File

@ -12,4 +12,4 @@
= _('List of users who are allowed to exceed the rate limit. Example: username1, username2')
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
= f.submit _('Save changes'), pajamas_button: true

View File

@ -6,4 +6,4 @@
= f.label :pipeline_limit_per_project_user_sha, _('Maximum number of requests per minute')
= f.number_field :pipeline_limit_per_project_user_sha, class: 'form-control gl-form-input'
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
= f.submit _('Save changes'), pajamas_button: true

View File

@ -18,4 +18,4 @@
.form-text.gl-text-gray-600
= _("Set to 0 to disable the limit.")
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
= f.submit _('Save changes'), pajamas_button: true

View File

@ -19,4 +19,4 @@
= _('List of users who are allowed to exceed the rate limit. Example: username1, username2')
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
= f.submit _('Save changes'), pajamas_button: true

View File

@ -11,4 +11,4 @@
.form-text.text-muted{ id: 'users-api-limit-users-allowlist-field-description' }
= _('List of users who are allowed to exceed the rate limit. Example: username1, username2')
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
= f.submit _('Save changes'), pajamas_button: true

View File

@ -4,6 +4,6 @@
= gitlab_ui_form_for [:admin, @deploy_key], html: { class: 'deploy-key-form' } do |f|
= render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key }
.gl-display-flex.gl-mt-6.gl-gap-3
= f.submit 'Create', data: { qa_selector: "add_deploy_key_button" }, pajamas_button: true
= f.submit 'Create', pajamas_button: true
= render Pajamas::ButtonComponent.new(href: admin_deploy_keys_path) do
= _('Cancel')

View File

@ -45,7 +45,7 @@
- else
.form-actions
= f.submit _('Save changes'), pajamas_button: true, data: { qa_selector: 'save_changes_button' }
= f.submit _('Save changes'), pajamas_button: true
= render Pajamas::ButtonComponent.new(href: admin_topics_path) do
= _('Cancel')

View File

@ -0,0 +1,8 @@
---
name: collapse_generated_diff_files
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/138013
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/432670
milestone: '16.7'
type: development
group: group::code review
default_enabled: false

View File

@ -7,4 +7,6 @@ feature_categories:
description: Contains periodical DevOps Adoption data points.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47388
milestone: '13.7'
gitlab_schema: gitlab_main
gitlab_schema: gitlab_main_cell
sharding_key:
namespace_id: namespaces

View File

@ -7,4 +7,6 @@ feature_categories:
description: Package identifier tags for supported package types. See https://docs.gitlab.com/ee/user/packages/npm_registry/#add-npm-distribution-tags for an example.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20636
milestone: '12.7'
gitlab_schema: gitlab_main
gitlab_schema: gitlab_main_cell
sharding_key:
project_id: projects

View File

@ -10,6 +10,6 @@ class AddTextLimitToCustomJiraRegexFields < Gitlab::Database::Migration[2.1]
def down
remove_text_limit :jira_tracker_data, :jira_issue_regex
remove_text_limit :jira_tracker_data, :jira_issue_regex
remove_text_limit :jira_tracker_data, :jira_issue_prefix
end
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class AddGeneratedToMergeRequestContextCommitDiffFiles < Gitlab::Database::Migration[2.2]
milestone '16.7'
enable_lock_retries!
def change
add_column :merge_request_context_commit_diff_files, :generated, :boolean
end
end

View File

@ -0,0 +1 @@
a12e860dae13871a03c348f9acd2c653e91e2da454d40a4ae0b98167065be696

View File

@ -18767,7 +18767,8 @@ CREATE TABLE merge_request_context_commit_diff_files (
old_path text NOT NULL,
diff text,
"binary" boolean,
merge_request_context_commit_id bigint NOT NULL
merge_request_context_commit_id bigint NOT NULL,
generated boolean
);
CREATE TABLE merge_request_context_commits (

View File

@ -343,7 +343,7 @@ More about introspection:
### Query complexity
The calculated [complexity score and limit](index.md#max-query-complexity) for a query can be revealed to clients by
The calculated [complexity score and limit](index.md#maximum-query-complexity) for a query can be revealed to clients by
querying for `queryComplexity`.
```graphql

View File

@ -6,8 +6,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GraphQL API **(FREE ALL)**
> Enabled and [made generally available](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30444) in GitLab 12.1. [Feature flag `graphql`](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30444) removed.
[GraphQL](https://graphql.org/) is a query language for APIs. You can use it to
request the exact data you need, and therefore limit the number of requests you need.
@ -15,38 +13,22 @@ GraphQL data is arranged in types, so your client can use
[client-side GraphQL libraries](https://graphql.org/code/#graphql-clients)
to consume the API and avoid manual parsing.
There are no fixed endpoints and no data model, so you can add
to the API without creating [breaking changes](../../development/deprecation_guidelines/index.md).
This enables us to have a [versionless API](https://graphql.org/learn/best-practices/#versioning).
The GraphQL API is [versionless](https://graphql.org/learn/best-practices/#versioning).
## Vision
We want the GraphQL API to be the **primary** means of interacting
programmatically with GitLab. To achieve this, it needs full coverage - anything
possible in the REST API should also be possible in the GraphQL API.
To help us meet this vision, the frontend should use GraphQL in preference to
the REST API for new features.
There are no plans to deprecate the REST API. To reduce the technical burden of
supporting two APIs in parallel, they should share implementations as much as
possible.
## Work with GraphQL
## Getting started
If you're new to the GitLab GraphQL API, see [Get started with GitLab GraphQL API](getting_started.md).
You can view the available resources in the [GraphQL API reference](reference/index.md).
The reference is automatically generated from the GitLab GraphQL schema and
written to a Markdown file.
The GitLab GraphQL API endpoint is located at `/api/graphql`.
### GraphiQL
### Interactive GraphQL explorer
Explore the GraphQL API using the interactive [GraphiQL explorer](https://gitlab.com/-/graphql-explorer),
or on your self-managed GitLab instance on
`https://<your-gitlab-site.com>/-/graphql-explorer`.
Explore the GraphQL API using the interactive GraphQL explorer, either:
- [On GitLab.com](https://gitlab.com/-/graphql-explorer).
- On your self-managed GitLab instance on `https://<your-gitlab-site.com>/-/graphql-explorer`.
For more information, see [GraphiQL](getting_started.md#graphiql).
@ -72,33 +54,44 @@ Global IDs are a convention used for caching and fetching in some client-side li
GitLab Global IDs are subject to change. If changed, the use of the old Global ID as an argument is deprecated and supported according to the [deprecation and breaking change](#breaking-changes) process.
You should not expect that a cached Global ID will be valid beyond the time of a GitLab GraphQL deprecation cycle.
## Available top-level queries
The top-level entry points for all queries are defined in the [`Query` type](reference/index.md#query-type) in the
GraphQL reference.
### Multiplex queries
GitLab supports batching queries into a single request. For more information, see
[Multiplex](https://graphql-ruby.org/queries/multiplex.html).
## Breaking changes
The GitLab GraphQL API is [versionless](https://graphql.org/learn/best-practices/#versioning) and changes to the API are primarily backward-compatible.
The GitLab GraphQL API is [versionless](https://graphql.org/learn/best-practices/#versioning) and changes to the API are
primarily backward-compatible.
However, GitLab sometimes changes the GraphQL API in a way that is not backward-compatible. These changes are considered breaking changes, and
can include removing or renaming fields, arguments, or other parts of the schema.
When creating a breaking change, GitLab follows a [deprecation and removal process](#deprecation-and-removal-process).
To avoid having a breaking change affect your integrations, you should
familiarize yourself with the [deprecation and removal process](#deprecation-and-removal-process) and
frequently [verify your API calls against the future breaking-change schema](#verify-against-the-future-breaking-change-schema).
To avoid having a breaking change affect your integrations, you should:
- Familiarize yourself with the [deprecation and removal process](#deprecation-and-removal-process).
- Frequently [verify your API calls against the future breaking-change schema](#verify-against-the-future-breaking-change-schema).
For more information, see [Deprecating GitLab features](../../development/deprecation_guidelines/index.md).
### Breaking change exemptions
Schema items
[marked as alpha](../../development/api_graphql_styleguide.md#mark-schema-items-as-alpha)
are exempt from the deprecation process, and can be removed or changed at any
Schema items labeled as Experiments in the [GraphQL API reference](reference/index.md)
are exempt from the deprecation process. These items can be removed or changed at any
time without notice.
Fields behind a feature flag and disabled by default do not follow the
deprecation and removal process, and can be removed at any time without notice.
deprecation and removal process. These fields can be removed at any time without notice.
WARNING:
GitLab makes all attempts to follow the [deprecation and removal process](#deprecation-and-removal-process).
On rare occasions, GitLab might make immediate breaking changes to the GraphQL
GitLab might make immediate breaking changes to the GraphQL
API to patch critical security or performance concerns if the deprecation
process would pose significant risk.
@ -111,8 +104,8 @@ This way, you can verify API calls ahead of a [breaking-change release](#depreca
before the items are actually removed from the schema.
To make these calls, add a
`remove_deprecated=true` query parameter to the GitLab GraphQL API endpoint (for example,
`https://gitlab.com/api/graphql?remove_deprecated=true` for GitLab SaaS GraphQL).
`remove_deprecated=true` query parameter to the GraphQL API endpoint. For example,
`https://gitlab.com/api/graphql?remove_deprecated=true` for GraphQL on GitLab.com.
### Deprecation and removal process
@ -134,10 +127,8 @@ Items are marked as deprecated in:
The deprecation message provides an alternative for the deprecated schema item,
if applicable.
NOTE:
If you use the GraphQL API, we recommend you remove the deprecated schema from your GraphQL
API calls as soon as possible to avoid experiencing breaking changes.
You should [verify your API calls against the schema without the deprecated schema items](#verify-against-the-future-breaking-change-schema).
To avoid experiencing breaking changes, you should remove the deprecated schema from your GraphQL API calls as soon as
possible. You should [verify your API calls against the schema without the deprecated schema items](#verify-against-the-future-breaking-change-schema).
#### Deprecation example
@ -145,7 +136,7 @@ The following fields are deprecated in different minor releases, but both
removed in GitLab 14.0:
| Field deprecated in | Reason |
| ------------------- | --- |
|:--------------------|:-------|
| 12.7 | GitLab traditionally has 12 minor releases per major release. To ensure the field is available for 6 more releases, it is removed in the 14.0 major release (and not 13.0). |
| 13.6 | The removal in 14.0 allows for 6 months of availability. |
@ -153,50 +144,21 @@ removed in GitLab 14.0:
View the [list of items removed](removed_items.md) in previous releases.
## Available queries
The GraphQL API includes the following queries at the root level:
Query | Description
--------------|------------
`project` | Project information and many of its associations, such as issues and merge requests.
`group` | Basic group information and epics.
`user` | Information about a particular user.
`namespace` | The namespace and the `projects` in it.
`currentUser` | Information about the authenticated user.
`users` | Information about a collection of users.
`metaData` | Metadata about GitLab and the GraphQL API.
`snippets` | Snippets visible to the authenticated user.
New associations and root level objects are regularly added.
See the [GraphQL API Reference](reference/index.md) for up-to-date information.
Root-level queries are defined in
[`app/graphql/types/query_type.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/types/query_type.rb).
### Multiplex queries
GitLab supports batching queries into a single request using
[`@apollo/client/link/batch-http`](https://www.apollographql.com/docs/react/api/link/apollo-link-batch-http/). More
information about multiplexed queries is also available for
[GraphQL Ruby](https://graphql-ruby.org/queries/multiplex.html), the
library GitLab uses on the backend.
## Limits
The following limits apply to the GitLab GraphQL API.
Limit | Default
---------------------|---------------------------------------------------------------------
Max page size | 100 records (nodes) per page. Applies to most connections in the API. Particular connections may have different max page size limits that are higher or lower.
[Max query complexity](#max-query-complexity) | `200` for unauthenticated requests and `250` for authenticated requests.
Request timeout | 30 seconds.
Max query size | 10,000 characters per query or mutation. If this limit is reached, use [variables](https://graphql.org/learn/queries/#variables) and [fragments](https://graphql.org/learn/queries/#fragments) to reduce the query or mutation size. Remove white spaces as last resort.
| Limit | Default |
|:------------------------------------------------------|:--------|
| Maximum page size | 100 records (nodes) per page. Applies to most connections in the API. Particular connections may have different max page size limits that are higher or lower. |
| [Maximum query complexity](#maximum-query-complexity) | 200 for unauthenticated requests and 250 for authenticated requests. |
| Request timeout | 30 seconds. |
| Maximum query size | 10,000 characters per query or mutation. If this limit is reached, use [variables](https://graphql.org/learn/queries/#variables) and [fragments](https://graphql.org/learn/queries/#fragments) to reduce the query or mutation size. Remove white spaces as last resort. |
### Max query complexity
### Maximum query complexity
The GitLab GraphQL API scores the _complexity_ of a query. Generally, larger
queries have a higher complexity score. This limit is designed to protect
queries have a higher complexity score. This limit is designed to protecting
the API from performing queries that could negatively impact its overall performance.
You can [query](getting_started.md#query-complexity) the complexity score of a query
@ -209,14 +171,8 @@ In general, each field in a query adds `1` to the complexity score, although
this can be higher or lower for particular fields. Sometimes, adding
certain arguments may also increase the complexity of a query.
NOTE:
The complexity limits may be revised in future, and additionally, the complexity
of a query may be altered.
## Resolve mutations detected as spam
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327360) in GitLab 13.11.
GraphQL mutations can be detected as spam. If a mutation is detected as spam and:
- A CAPTCHA service is not configured, a

File diff suppressed because it is too large Load Diff

View File

@ -277,7 +277,7 @@ To get job information from the GraphQL API:
1. Go to the pipeline details page.
1. Select the **Jobs** tab and find the ID of the stuck job.
1. Go to [GraphiQL explorer](../../api/graphql/index.md#graphiql).
1. Go to the [interactive GraphQL explorer](../../api/graphql/index.md#interactive-graphql-explorer).
1. Run the following query:
```graphql

View File

@ -720,7 +720,7 @@ To gain insight into the errors, you can execute a GraphQL query using the follo
1. Go to the pipeline details page.
1. Append `.json` to the URL.
1. Copy the `iid` of the pipeline.
1. Go to [GraphiQL explorer](../../api/graphql/index.md#graphiql).
1. Go to the [interactive GraphQL explorer](../../api/graphql/index.md#interactive-graphql-explorer).
1. Run the following query:
```graphql

View File

@ -8,6 +8,20 @@ info: Any user with at least the Maintainer role can merge updates to this conte
This document outlines the style guide for the GitLab [GraphQL API](../api/graphql/index.md).
## Vision
We want the GraphQL API to be the **primary** means of interacting
programmatically with GitLab. To achieve this, it needs full coverage - anything
possible in the REST API should also be possible in the GraphQL API.
To help us meet this vision, the frontend should use GraphQL in preference to
the REST API for new features.
The GraphQL API is [versionless](https://graphql.org/learn/best-practices/#versioning).
There are no plans to deprecate the REST API. To reduce the technical burden of
supporting two APIs in parallel, they should share implementations as much as
possible.
## How GitLab implements GraphQL
<!-- vale gitlab.Spelling = NO -->
@ -78,7 +92,7 @@ a connection.
### Max complexity
Complexity is explained [on our client-facing API page](../api/graphql/index.md#max-query-complexity).
Complexity is explained [on our client-facing API page](../api/graphql/index.md#maximum-query-complexity).
Fields default to adding `1` to a query's complexity score, but developers can
[specify a custom complexity](#field-complexity) when defining a field.
@ -477,7 +491,7 @@ field :tags,
### Field complexity
The GitLab GraphQL API uses a _complexity_ score to limit performing overly complex queries.
Complexity is described in [our client documentation](../api/graphql/index.md#max-query-complexity) on the topic.
Complexity is described in [our client documentation](../api/graphql/index.md#maximum-query-complexity) on the topic.
Complexity limits are defined in [`app/graphql/gitlab_schema.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/gitlab_schema.rb).
@ -864,8 +878,8 @@ mount_mutation Mutations::Ci::JobArtifact::BulkDestroy, alpha: { milestone: '15.
Alpha GraphQL items is a custom GitLab feature that leverages GraphQL deprecations. An Alpha item
appears as deprecated in the GraphQL schema. Like all deprecated schema items, you can test an
Alpha field in [GraphiQL](../api/graphql/index.md#graphiql). However, be aware that the GraphiQL
autocomplete editor doesn't suggest deprecated fields.
Alpha field in the [interactive GraphQL explorer](../api/graphql/index.md#interactive-graphql-explorer) (GraphiQL).
However, be aware that the GraphiQL autocomplete editor doesn't suggest deprecated fields.
The item shows as Alpha in our generated GraphQL documentation and its GraphQL schema description.

View File

@ -24,7 +24,7 @@ When it comes to CSS, we use a utils-based CSS approach. GitLab has its own CSS
We also use [SCSS](https://sass-lang.com) and plain JavaScript with
modern ECMAScript standards supported through [Babel](https://babeljs.io/) and ES module support through [webpack](https://webpack.js.org/).
When making API calls, we use [GraphQL](graphql.md) as [the first choice](../../api/graphql/index.md#vision). There are still instances where GitLab REST API is used such as when creating new simple HAML pages or in legacy part of the codebase, but we should always default to GraphQL when possible.
When making API calls, we use [GraphQL](graphql.md) as [the first choice](../api_graphql_styleguide.md#vision). There are still instances where GitLab REST API is used such as when creating new simple HAML pages or in legacy part of the codebase, but we should always default to GraphQL when possible.
We use [Apollo](https://www.apollographql.com/) as our global state manager and [GraphQL client](graphql.md).
[VueX](vuex.md) is still in use across the codebase, but it is no longer the recommended global state manager.

View File

@ -8,7 +8,7 @@ info: Any user with at least the Maintainer role can merge updates to this conte
## Why?
We have defined [GraphQL as our primary API](../../api/graphql/index.md#vision) for all user-facing features,
We have defined the [GraphQL API](../../api/graphql/index.md) as [the primary API](../api_graphql_styleguide.md#vision) for all user-facing features,
so we can safely assume that whenever GraphQL is present, so will the Apollo Client.
We [do not want to use Vuex with Apollo](graphql.md#using-with-vuex), so the VueX stores count
will naturally decline over time as we move from the REST API to GraphQL.

View File

@ -60,7 +60,7 @@ You cannot select this option for public projects.
You should delete an uploaded file when that file contains sensitive or confidential information. When you have deleted that file, users cannot access the file and the direct URL returns a 404 error.
Project Owners and Maintainers can use the [interactive GraphiQL explorer](../api/graphql/index.md#graphiql) to access a [GraphQL endpoint](../api/graphql/reference/index.md#mutationuploaddelete) and delete an uploaded file.
Project Owners and Maintainers can use the [interactive GraphQL explorer](../api/graphql/index.md#interactive-graphql-explorer) to access a [GraphQL endpoint](../api/graphql/reference/index.md#mutationuploaddelete) and delete an uploaded file.
For example:

View File

@ -10,7 +10,7 @@ module Gitlab
attr_accessor :old_path, :new_path, :a_mode, :b_mode, :diff
# Stats properties
attr_accessor :new_file, :renamed_file, :deleted_file
attr_accessor :new_file, :renamed_file, :deleted_file, :generated
alias_method :new_file?, :new_file
alias_method :deleted_file?, :deleted_file
@ -20,6 +20,7 @@ module Gitlab
attr_writer :too_large
alias_method :expanded?, :expanded
alias_method :generated?, :generated
# The default maximum content size to display a diff patch.
#
@ -31,7 +32,18 @@ module Gitlab
# persisting limits over that.
MAX_PATCH_BYTES_UPPER_BOUND = 500.kilobytes
SERIALIZE_KEYS = %i[diff new_path old_path a_mode b_mode new_file renamed_file deleted_file too_large].freeze
SERIALIZE_KEYS = %i[
diff
new_path
old_path
a_mode
b_mode
new_file
renamed_file
deleted_file
too_large
generated
].freeze
BINARY_NOTICE_PATTERN = %r{Binary files (.*) and (.*) differ}
@ -79,9 +91,12 @@ module Gitlab
# If false, patch raw data will not be included in the diff after
# `max_files`, `max_lines` or any of the limits in `limits` are
# exceeded
# :generated_files ::
# If the list of generated files is given, those files will be marked
# as generated.
def filter_diff_options(options, default_options = {})
allowed_options = [:ignore_whitespace_change, :max_files, :max_lines,
:limits, :expanded, :collect_all_paths]
:limits, :expanded, :collect_all_paths, :generated_files]
if default_options
actual_defaults = default_options.dup
@ -144,8 +159,9 @@ module Gitlab
text.start_with?(BINARY_NOTICE_PATTERN)
end
end
def initialize(raw_diff, expanded: true, replace_invalid_utf8_chars: true)
def initialize(raw_diff, expanded: true, replace_invalid_utf8_chars: true, generated: nil)
@expanded = expanded
@generated = generated
case raw_diff
when Hash

View File

@ -35,6 +35,7 @@ module Gitlab
def initialize(iterator, options = {})
@iterator = iterator
@generated_files = options.fetch(:generated_files, nil)
@limits = self.class.limits(options)
@enforce_limits = !!options.fetch(:limits, true)
@expanded = !!options.fetch(:expanded, true)
@ -164,7 +165,10 @@ module Gitlab
i = @array.length
@iterator.each do |raw|
diff = Gitlab::Git::Diff.new(raw, expanded: expand_diff?)
options = { expanded: expand_diff? }
options[:generated] = @generated_files.include?(raw.from_path) if @generated_files
diff = Gitlab::Git::Diff.new(raw, **options)
if raw.overflow_marker
@overflow = true

View File

@ -7,7 +7,7 @@ module QA
module Alerts
class Show < Page::Base
view 'app/assets/javascripts/vue_shared/alert_details/components/system_notes/system_note.vue' do
element :alert_system_note_container
element 'alert-system-note-container'
end
def go_to_activity_feed_tab
@ -15,7 +15,7 @@ module QA
end
def has_system_note?(text)
has_element?(:alert_system_note_container, text: text)
has_element?('alert-system-note-container', text: text)
end
end
end

View File

@ -12,6 +12,15 @@ RSpec.describe 'new tables missing sharding_key', feature_category: :cell do
]
end
# Specific tables can be temporarily exempt from this requirement. You must add an issue link in a comment next to
# the table name to remove this once a decision has been made.
let(:allowed_to_be_missing_not_null) do
[
'labels.project_id', # https://gitlab.com/gitlab-org/gitlab/-/issues/434356
'labels.group_id' # https://gitlab.com/gitlab-org/gitlab/-/issues/434356
]
end
let(:starting_from_milestone) { 16.6 }
let(:allowed_sharding_key_referenced_tables) { %w[projects namespaces organizations] }
@ -33,6 +42,26 @@ RSpec.describe 'new tables missing sharding_key', feature_category: :cell do
end
end
it 'ensures all sharding_key columns are not nullable or have a not null check constraint',
:aggregate_failures do
all_tables_to_sharding_key.each do |table_name, sharding_key|
sharding_key.each do |column_name, _|
not_nullable = not_nullable?(table_name, column_name)
has_null_check_constraint = has_null_check_constraint?(table_name, column_name)
if allowed_to_be_missing_not_null.include?("#{table_name}.#{column_name}")
expect(not_nullable || has_null_check_constraint).to eq(false),
"You must remove `#{table_name}.#{column_name}` from allowed_to_be_missing_not_null" \
"since it now has a valid constraint."
else
expect(not_nullable || has_null_check_constraint).to eq(true),
"Missing a not null constraint for `#{table_name}.#{column_name}` . " \
"All sharding keys must be not nullable or have a NOT NULL check constraint"
end
end
end
end
it 'only allows `allowed_to_be_missing_sharding_key` to include tables that are missing a sharding_key',
:aggregate_failures do
allowed_to_be_missing_sharding_key.each do |exempted_table|
@ -73,6 +102,42 @@ RSpec.describe 'new tables missing sharding_key', feature_category: :cell do
end
end
def not_nullable?(table_name, column_name)
sql = <<~SQL
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'public' AND
table_name = '#{table_name}' AND
column_name = '#{column_name}' AND
is_nullable = 'NO'
SQL
result = ApplicationRecord.connection.execute(sql)
result.count > 0
end
def has_null_check_constraint?(table_name, column_name)
# This is a heuristic query to look for all check constraints on the table and see if any of them contain a clause
# column IS NOT NULL. This is to match tables that will have multiple sharding keys where either of them can be not
# null. Such cases may look like:
# (project_id IS NOT NULL) OR (group_id IS NOT NULL)
# It's possible that this will sometimes incorrectly find a check constraint that isn't exactly as strict as we want
# but it should be pretty unlikely.
sql = <<~SQL
SELECT 1
FROM pg_constraint
INNER JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
WHERE pg_class.relname = '#{table_name}'
AND contype = 'c'
AND pg_get_constraintdef(pg_constraint.oid) ILIKE '%#{column_name} IS NOT NULL%'
SQL
result = ApplicationRecord.connection.execute(sql)
result.count > 0
end
def column_exists?(table_name, column_name)
sql = <<~SQL
SELECT 1

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::Git::DiffCollection do
RSpec.describe Gitlab::Git::DiffCollection, feature_category: :source_code_management do
before do
stub_const('MutatingConstantIterator', Class.new)
@ -531,6 +531,73 @@ RSpec.describe Gitlab::Git::DiffCollection do
end
describe '#each' do
context 'with Gitlab::GitalyClient::DiffStitcher' do
let(:collection) do
described_class.new(
iterator,
max_files: max_files,
max_lines: max_lines,
limits: limits,
expanded: expanded,
generated_files: generated_files
)
end
let(:iterator) { Gitlab::GitalyClient::DiffStitcher.new(diff_params) }
let(:diff_params) { [diff_1, diff_2] }
let(:diff_1) do
OpenStruct.new(
to_path: ".gitmodules",
from_path: ".gitmodules",
old_mode: 0100644,
new_mode: 0100644,
from_id: '357406f3075a57708d0163752905cc1576fceacc',
to_id: '8e5177d718c561d36efde08bad36b43687ee6bf0',
patch: 'a' * 10,
raw_patch_data: 'a' * 10,
end_of_patch: true
)
end
let(:diff_2) do
OpenStruct.new(
to_path: ".gitignore",
from_path: ".gitignore",
old_mode: 0100644,
new_mode: 0100644,
from_id: '357406f3075a57708d0163752905cc1576fceacc',
to_id: '8e5177d718c561d36efde08bad36b43687ee6bf0',
patch: 'a' * 20,
raw_patch_data: 'a' * 20,
end_of_patch: true
)
end
context 'with generated_files' do
let(:generated_files) { [diff_1.from_path] }
it 'sets generated files as generated' do
collection.each do |d|
if d.old_path == diff_1.from_path
expect(d.generated).to be true
else
expect(d.generated).to be false
end
end
end
end
context 'without generated_files' do
let(:generated_files) { nil }
it 'set generated as nil' do
collection.each do |d|
expect(d.generated).to be_nil
end
end
end
end
context 'when diff are too large' do
let(:collection) do
described_class.new([{ diff: 'a' * 204800 }])

View File

@ -50,7 +50,7 @@ EOT
let(:diff) { described_class.new(@raw_diff_hash) }
it 'initializes the diff' do
expect(diff.to_hash).to eq(@raw_diff_hash)
expect(diff.to_hash).to eq(@raw_diff_hash.merge(generated: nil))
end
it 'does not prune the diff' do
@ -87,7 +87,7 @@ EOT
let(:raw_patch) { @raw_diff_hash[:diff] }
it 'initializes the diff' do
expect(diff.to_hash).to eq(@raw_diff_hash)
expect(diff.to_hash).to eq(@raw_diff_hash.merge(generated: nil))
end
it 'does not prune the diff' do
@ -173,7 +173,7 @@ EOT
let(:diff) { described_class.new(commit_delta) }
it 'initializes the diff' do
expect(diff.to_hash).to eq(@raw_diff_hash.merge(diff: ''))
expect(diff.to_hash).to eq(@raw_diff_hash.merge(diff: '', generated: nil))
end
it 'is not too large' do

View File

@ -390,9 +390,10 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
shared_examples_for 'merge request diffs' do
let(:merge_request) { create(:merge_request) }
let!(:diff) { merge_request.merge_request_diff.reload }
context 'when it was not cleaned by the system' do
let!(:diff) { merge_request.merge_request_diff.reload }
it 'returns persisted diffs' do
expect(diff).to receive(:load_diffs).and_call_original
@ -401,6 +402,8 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
end
context 'when diff was cleaned by the system' do
let!(:diff) { merge_request.merge_request_diff.reload }
before do
diff.clean!
end
@ -906,6 +909,57 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
expect(diff_file.diff).to include(content)
end
end
context 'handling generated files' do
let(:project) { create(:project, :repository) }
let(:target_branch) { project.default_branch }
let(:source_branch) { 'test-generated-diff-file' }
let(:generated_file_name) { 'generated.txt' }
let(:regular_file_name) { 'regular.rb' }
let(:merge_request) do
create(
:merge_request,
target_project: project,
source_project: project,
source_branch: source_branch,
target_branch: target_branch
)
end
let(:diff_files) do
merge_request.merge_request_diff.merge_request_diff_files
end
before do
project.repository.update_file(
project.creator,
'.gitattributes',
'*.txt gitlab-generated',
message: 'Update',
branch_name: target_branch)
create_file_in_repo(project, target_branch, source_branch, generated_file_name, "generated text\n")
create_file_in_repo(project, source_branch, source_branch, regular_file_name, "something else\n")
end
context 'with collapse_generated_diff_files feature flag' do
it 'sets generated field correctly' do
expect(diff_files.find_by(new_path: generated_file_name)).to be_generated
expect(diff_files.find_by(new_path: regular_file_name)).not_to be_generated
end
end
context 'without collapse_generated_diff_files feature flag' do
before do
stub_feature_flags(collapse_generated_diff_files: false)
end
it 'sets generated field correctly' do
expect(diff_files.find_by(new_path: generated_file_name)).not_to be_generated
expect(diff_files.find_by(new_path: regular_file_name)).not_to be_generated
end
end
end
end
end
@ -986,6 +1040,7 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
include_examples 'merge request diffs'
it 'stores up-to-date diffs in the database' do
diff = merge_request.merge_request_diff.reload
expect(diff).not_to be_stored_externally
end
@ -1002,7 +1057,8 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
end
it 'stores diffs for old MR versions in external storage' do
old_diff = diff
old_diff = merge_request.merge_request_diff.reload
merge_request.create_merge_request_diff
old_diff.migrate_files_to_external_storage!

View File

@ -1338,7 +1338,6 @@
- './ee/spec/lib/gitlab/geo/oauth/logout_token_spec.rb'
- './ee/spec/lib/gitlab/geo/oauth/session_spec.rb'
- './ee/spec/lib/gitlab/geo/registry_batcher_spec.rb'
- './ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb'
- './ee/spec/lib/gitlab/geo/replication/blob_retriever_spec.rb'
- './ee/spec/lib/gitlab/geo/replicator_spec.rb'
- './ee/spec/lib/gitlab/geo/signed_data_spec.rb'

View File

@ -42,7 +42,7 @@ module Tooling
CONNECTION_NOTE = <<~MD
This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#connection-pagination-arguments):
`before: String`, `after: String`, `first: Int`, `last: Int`.
`before: String`, `after: String`, `first: Int`, and `last: Int`.
MD
# Helper with functions to be used by HAML templates

View File

@ -7,7 +7,7 @@
This documentation is self-generated based on GitLab current GraphQL schema.
The API can be explored interactively using the [GraphiQL IDE](../index.md#graphiql).
The API can be explored using the [interactive GraphQL explorer](../index.md#interactive-graphql-explorer).
Each table below documents a GraphQL type. Types match loosely to models, but not all
fields and methods on a model are available via GraphQL.