Commit 5bfb8d1f authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent aaf59610
...@@ -204,8 +204,25 @@ gitlab:setup: ...@@ -204,8 +204,25 @@ gitlab:setup:
rspec:coverage: rspec:coverage:
extends: extends:
- .rails-job-base - .rails-job-base
- .rails:rules:ee-and-foss - .rails:rules:ee-only
stage: post-test stage: post-test
# We cannot use needs since it would mean needing 84 jobs (since most are parallelized)
# so we use `dependencies` here.
dependencies:
- setup-test-env
- rspec migration pg9
- rspec unit pg9
- rspec integration pg9
- rspec system pg9
- rspec-ee migration pg9
- rspec-ee unit pg9
- rspec-ee integration pg9
- rspec-ee system pg9
- rspec-ee unit pg9 geo
- rspec-ee integration pg9 geo
- rspec-ee system pg9 geo
- memory-static
- memory-on-boot
variables: variables:
SETUP_DB: "false" SETUP_DB: "false"
cache: cache:
......
...@@ -291,6 +291,8 @@ ...@@ -291,6 +291,8 @@
############### ###############
.pages:rules: .pages:rules:
rules: rules:
- <<: *if-not-ee
when: never
- <<: *if-dot-com-gitlab-org-master - <<: *if-dot-com-gitlab-org-master
changes: *code-backstage-qa-patterns changes: *code-backstage-qa-patterns
when: on_success when: on_success
......
...@@ -21,7 +21,7 @@ Set the title to: `Description of the original issue` ...@@ -21,7 +21,7 @@ Set the title to: `Description of the original issue`
- [ ] Create a merge request targeting `master` on `gitlab.com/gitlab-org/security` and use the [Security Release merge request template]. - [ ] Create a merge request targeting `master` on `gitlab.com/gitlab-org/security` and use the [Security Release merge request template].
- [ ] Follow the same [code review process]: Assign to a reviewer, then to a maintainer. - [ ] Follow the same [code review process]: Assign to a reviewer, then to a maintainer.
After your merge request has being approved according to our [approval guidelines], you're ready to prepare the backports After your merge request has been approved according to our [approval guidelines], you're ready to prepare the backports
## Backports ## Backports
......
...@@ -87,7 +87,7 @@ gem 'grape-entity', '~> 0.7.1' ...@@ -87,7 +87,7 @@ gem 'grape-entity', '~> 0.7.1'
gem 'rack-cors', '~> 1.0.6', require: 'rack/cors' gem 'rack-cors', '~> 1.0.6', require: 'rack/cors'
# GraphQL API # GraphQL API
gem 'graphql', '~> 1.9.19' gem 'graphql', '~> 1.10.5'
# NOTE: graphiql-rails v1.5+ doesn't work: https://gitlab.com/gitlab-org/gitlab/issues/31771 # NOTE: graphiql-rails v1.5+ doesn't work: https://gitlab.com/gitlab-org/gitlab/issues/31771
# TODO: remove app/views/graphiql/rails/editors/show.html.erb when https://github.com/rmosolgo/graphiql-rails/pull/71 is released: # TODO: remove app/views/graphiql/rails/editors/show.html.erb when https://github.com/rmosolgo/graphiql-rails/pull/71 is released:
# https://gitlab.com/gitlab-org/gitlab/issues/31747 # https://gitlab.com/gitlab-org/gitlab/issues/31747
......
...@@ -456,7 +456,7 @@ GEM ...@@ -456,7 +456,7 @@ GEM
graphiql-rails (1.4.10) graphiql-rails (1.4.10)
railties railties
sprockets-rails sprockets-rails
graphql (1.9.19) graphql (1.10.5)
graphql-docs (1.6.0) graphql-docs (1.6.0)
commonmarker (~> 0.16) commonmarker (~> 0.16)
escape_utils (~> 1.2) escape_utils (~> 1.2)
...@@ -1252,7 +1252,7 @@ DEPENDENCIES ...@@ -1252,7 +1252,7 @@ DEPENDENCIES
grape-path-helpers (~> 1.2) grape-path-helpers (~> 1.2)
grape_logging (~> 1.7) grape_logging (~> 1.7)
graphiql-rails (~> 1.4.10) graphiql-rails (~> 1.4.10)
graphql (~> 1.9.19) graphql (~> 1.10.5)
graphql-docs (~> 1.6.0) graphql-docs (~> 1.6.0)
grpc (~> 1.24.0) grpc (~> 1.24.0)
gssapi gssapi
......
...@@ -13,11 +13,18 @@ class AuditEvent < ApplicationRecord ...@@ -13,11 +13,18 @@ class AuditEvent < ApplicationRecord
scope :by_entity_type, -> (entity_type) { where(entity_type: entity_type) } scope :by_entity_type, -> (entity_type) { where(entity_type: entity_type) }
scope :by_entity_id, -> (entity_id) { where(entity_id: entity_id) } scope :by_entity_id, -> (entity_id) { where(entity_id: entity_id) }
scope :order_by_id_desc, -> { order(id: :desc) }
scope :order_by_id_asc, -> { order(id: :asc) }
after_initialize :initialize_details after_initialize :initialize_details
def self.order_by(method)
case method.to_s
when 'created_asc'
order(id: :asc)
else
order(id: :desc)
end
end
def initialize_details def initialize_details
self.details = {} if details.nil? self.details = {} if details.nil?
end end
......
---
title: Index issues on sent_notifications table
merge_request: 27034
author:
type: performance
---
title: Move feature flag list into process cache
merge_request: 27511
author:
type: performance
...@@ -14,14 +14,18 @@ class AddStatusToDeployments < ActiveRecord::Migration[4.2] ...@@ -14,14 +14,18 @@ class AddStatusToDeployments < ActiveRecord::Migration[4.2]
# Ideally, `status` column should not have default value because it should be leveraged by state machine (i.e. application level). # Ideally, `status` column should not have default value because it should be leveraged by state machine (i.e. application level).
# However, we have to use the default value for avoiding `NOT NULL` violation during the transition period. # However, we have to use the default value for avoiding `NOT NULL` violation during the transition period.
# The default value should be removed in the future release. # The default value should be removed in the future release.
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:deployments, # rubocop:disable Migration/AddColumnWithDefault add_column_with_default(:deployments,
:status, :status,
:integer, :integer,
limit: 2, limit: 2,
default: DEPLOYMENT_STATUS_SUCCESS, default: DEPLOYMENT_STATUS_SUCCESS,
allow_null: false) allow_null: false)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:deployments, :status) remove_column(:deployments, :status)
......
...@@ -7,10 +7,12 @@ class AddMergeTrainEnabledToCiCdSettings < ActiveRecord::Migration[5.1] ...@@ -7,10 +7,12 @@ class AddMergeTrainEnabledToCiCdSettings < ActiveRecord::Migration[5.1]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable # rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default :project_ci_cd_settings, :merge_trains_enabled, :boolean, default: false, allow_null: false add_column_with_default :project_ci_cd_settings, :merge_trains_enabled, :boolean, default: false, allow_null: false
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable # rubocop:enable Migration/UpdateLargeTable
def down def down
......
...@@ -7,9 +7,13 @@ class AddVariableTypeToCiPipelineVariables < ActiveRecord::Migration[5.0] ...@@ -7,9 +7,13 @@ class AddVariableTypeToCiPipelineVariables < ActiveRecord::Migration[5.0]
DOWNTIME = false DOWNTIME = false
ENV_VAR_VARIABLE_TYPE = 1 ENV_VAR_VARIABLE_TYPE = 1
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:ci_pipeline_variables, :variable_type, :smallint, default: ENV_VAR_VARIABLE_TYPE) # rubocop:disable Migration/AddColumnWithDefault add_column_with_default(:ci_pipeline_variables, :variable_type, :smallint, default: ENV_VAR_VARIABLE_TYPE)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:ci_pipeline_variables, :variable_type) remove_column(:ci_pipeline_variables, :variable_type)
......
...@@ -7,9 +7,13 @@ class AddDeploymentEventsToServices < ActiveRecord::Migration[5.0] ...@@ -7,9 +7,13 @@ class AddDeploymentEventsToServices < ActiveRecord::Migration[5.0]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:services, :deployment_events, :boolean, default: false, allow_null: false) add_column_with_default(:services, :deployment_events, :boolean, default: false, allow_null: false)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:services, :deployment_events) remove_column(:services, :deployment_events)
......
...@@ -7,9 +7,13 @@ class AddCommentActionsToServices < ActiveRecord::Migration[5.2] ...@@ -7,9 +7,13 @@ class AddCommentActionsToServices < ActiveRecord::Migration[5.2]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:services, :comment_on_event_enabled, :boolean, default: true) add_column_with_default(:services, :comment_on_event_enabled, :boolean, default: true)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:services, :comment_on_event_enabled) remove_column(:services, :comment_on_event_enabled)
......
...@@ -7,9 +7,13 @@ class AddInstanceToServices < ActiveRecord::Migration[6.0] ...@@ -7,9 +7,13 @@ class AddInstanceToServices < ActiveRecord::Migration[6.0]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:services, :instance, :boolean, default: false) add_column_with_default(:services, :instance, :boolean, default: false)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:services, :instance) remove_column(:services, :instance)
......
...@@ -7,6 +7,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0] ...@@ -7,6 +7,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/UpdateLargeTable
def up def up
return if column_exists? :services, :template return if column_exists? :services, :template
...@@ -16,6 +17,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0] ...@@ -16,6 +17,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0]
# of `template`, we would look for entries with `project_id IS NULL`. # of `template`, we would look for entries with `project_id IS NULL`.
add_column_with_default :services, :template, :boolean, default: false, allow_null: true add_column_with_default :services, :template, :boolean, default: false, allow_null: true
end end
# rubocop:enable Migration/UpdateLargeTable
def down def down
# NOP since the column is expected to exist # NOP since the column is expected to exist
......
# frozen_string_literal: true
class AddIndexOnNoteableTypeAndNoteableIdToSentNotifications < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_sent_notifications_on_noteable_type_noteable_id'
disable_ddl_transaction!
def up
add_concurrent_index :sent_notifications,
[:noteable_id],
name: INDEX_NAME,
where: "noteable_type = 'Issue'"
end
def down
remove_concurrent_index_by_name :sent_notifications, INDEX_NAME
end
end
...@@ -3919,6 +3919,7 @@ ActiveRecord::Schema.define(version: 2020_03_13_123934) do ...@@ -3919,6 +3919,7 @@ ActiveRecord::Schema.define(version: 2020_03_13_123934) do
t.string "note_type" t.string "note_type"
t.text "position" t.text "position"
t.string "in_reply_to_discussion_id" t.string "in_reply_to_discussion_id"
t.index ["noteable_id"], name: "index_sent_notifications_on_noteable_type_noteable_id", where: "((noteable_type)::text = 'Issue'::text)"
t.index ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true t.index ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true
end end
......
...@@ -51,11 +51,11 @@ future GitLab releases.** ...@@ -51,11 +51,11 @@ future GitLab releases.**
| `CI_ENVIRONMENT_NAME` | 8.15 | all | The name of the environment for this job. Only present if [`environment:name`](../yaml/README.md#environmentname) is set. | | `CI_ENVIRONMENT_NAME` | 8.15 | all | The name of the environment for this job. Only present if [`environment:name`](../yaml/README.md#environmentname) is set. |
| `CI_ENVIRONMENT_SLUG` | 8.15 | all | A simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, etc. Only present if [`environment:name`](../yaml/README.md#environmentname) is set. | | `CI_ENVIRONMENT_SLUG` | 8.15 | all | A simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, etc. Only present if [`environment:name`](../yaml/README.md#environmentname) is set. |
| `CI_ENVIRONMENT_URL` | 9.3 | all | The URL of the environment for this job. Only present if [`environment:url`](../yaml/README.md#environmenturl) is set. | | `CI_ENVIRONMENT_URL` | 9.3 | all | The URL of the environment for this job. Only present if [`environment:url`](../yaml/README.md#environmenturl) is set. |
| `CI_EXTERNAL_PULL_REQUEST_IID` | 12.3 | all | Pull Request ID from GitHub if the [pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` is used and the pull request is open. | | `CI_EXTERNAL_PULL_REQUEST_IID` | 12.3 | all | Pull Request ID from GitHub if the [pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
| `CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_NAME` | 12.3 | all | The source branch name of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` is used and the pull request is open. | | `CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_NAME` | 12.3 | all | The source branch name of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
| `CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_SHA` | 12.3 | all | The HEAD SHA of the source branch of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` is used and the pull request is open. | | `CI_EXTERNAL_PULL_REQUEST_SOURCE_BRANCH_SHA` | 12.3 | all | The HEAD SHA of the source branch of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
| `CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME` | 12.3 | all | The target branch name of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` is used and the pull request is open. | | `CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME` | 12.3 | all | The target branch name of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
| `CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_SHA` | 12.3 | all | The HEAD SHA of the target branch of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` is used and the pull request is open. | | `CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_SHA` | 12.3 | all | The HEAD SHA of the target branch of the pull request if [the pipelines are for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). Available only if `only: [external_pull_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the pull request is open. |
| `CI_JOB_ID` | 9.0 | all | The unique id of the current job that GitLab CI uses internally | | `CI_JOB_ID` | 9.0 | all | The unique id of the current job that GitLab CI uses internally |
| `CI_JOB_IMAGE` | 12.9 | 12.9 | The name of the image running the CI job | | `CI_JOB_IMAGE` | 12.9 | 12.9 | The name of the image running the CI job |
| `CI_JOB_MANUAL` | 8.12 | all | The flag to indicate that job was manually started | | `CI_JOB_MANUAL` | 8.12 | all | The flag to indicate that job was manually started |
...@@ -63,25 +63,25 @@ future GitLab releases.** ...@@ -63,25 +63,25 @@ future GitLab releases.**
| `CI_JOB_STAGE` | 9.0 | 0.5 | The name of the stage as defined in `.gitlab-ci.yml` | | `CI_JOB_STAGE` | 9.0 | 0.5 | The name of the stage as defined in `.gitlab-ci.yml` |
| `CI_JOB_TOKEN` | 9.0 | 1.2 | Token used for authenticating with the [GitLab Container Registry][registry] and downloading [dependent repositories][dependent-repositories] | | `CI_JOB_TOKEN` | 9.0 | 1.2 | Token used for authenticating with the [GitLab Container Registry][registry] and downloading [dependent repositories][dependent-repositories] |
| `CI_JOB_URL` | 11.1 | 0.5 | Job details URL | | `CI_JOB_URL` | 11.1 | 0.5 | Job details URL |
| `CI_MERGE_REQUEST_ASSIGNEES` | 11.9 | all | Comma-separated list of username(s) of assignee(s) for the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_ASSIGNEES` | 11.9 | all | Comma-separated list of username(s) of assignee(s) for the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_CHANGED_PAGE_PATHS` | 12.9 | all | Comma-separated list of paths of changed pages in a deployed [Review App](../review_apps/index.md) for a [Merge Request](../merge_request_pipelines/index.md). A [Route Map](../review_apps/index.md#route-maps) must be configured. | | `CI_MERGE_REQUEST_CHANGED_PAGE_PATHS` | 12.9 | all | Comma-separated list of paths of changed pages in a deployed [Review App](../review_apps/index.md) for a [Merge Request](../merge_request_pipelines/index.md). A [Route Map](../review_apps/index.md#route-maps) must be configured. |
| `CI_MERGE_REQUEST_CHANGED_PAGE_URLS` | 12.9 | all | Comma-separated list of URLs of changed pages in a deployed [Review App](../review_apps/index.md) for a [Merge Request](../merge_request_pipelines/index.md). A [Route Map](../review_apps/index.md#route-maps) must be configured. | | `CI_MERGE_REQUEST_CHANGED_PAGE_URLS` | 12.9 | all | Comma-separated list of URLs of changed pages in a deployed [Review App](../review_apps/index.md) for a [Merge Request](../merge_request_pipelines/index.md). A [Route Map](../review_apps/index.md#route-maps) must be configured. |
| `CI_MERGE_REQUEST_ID` | 11.6 | all | The ID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_ID` | 11.6 | all | The ID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_IID` | 11.6 | all | The IID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_IID` | 11.6 | all | The IID of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_LABELS` | 11.9 | all | Comma-separated label names of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_LABELS` | 11.9 | all | Comma-separated label names of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_MILESTONE` | 11.9 | all | The milestone title of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_MILESTONE` | 11.9 | all | The milestone title of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_PROJECT_ID` | 11.6 | all | The ID of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_PROJECT_ID` | 11.6 | all | The ID of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_PROJECT_PATH` | 11.6 | all | The path of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) (e.g. `namespace/awesome-project`). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_PROJECT_PATH` | 11.6 | all | The path of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) (e.g. `namespace/awesome-project`). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_PROJECT_URL` | 11.6 | all | The URL of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) (e.g. `http://192.168.10.15:3000/namespace/awesome-project`). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_PROJECT_URL` | 11.6 | all | The URL of the project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md) (e.g. `http://192.168.10.15:3000/namespace/awesome-project`). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_REF_PATH` | 11.6 | all | The ref path of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). (e.g. `refs/merge-requests/1/head`). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_REF_PATH` | 11.6 | all | The ref path of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). (e.g. `refs/merge-requests/1/head`). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_SOURCE_BRANCH_NAME` | 11.6 | all | The source branch name of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_SOURCE_BRANCH_NAME` | 11.6 | all | The source branch name of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_SOURCE_BRANCH_SHA` | 11.9 | all | The HEAD SHA of the source branch of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used, the merge request is created, and the pipeline is a [merged result pipeline](../merge_request_pipelines/pipelines_for_merged_results/index.md). **(PREMIUM)** | | `CI_MERGE_REQUEST_SOURCE_BRANCH_SHA` | 11.9 | all | The HEAD SHA of the source branch of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used, the merge request is created, and the pipeline is a [merged result pipeline](../merge_request_pipelines/pipelines_for_merged_results/index.md). **(PREMIUM)** |
| `CI_MERGE_REQUEST_SOURCE_PROJECT_ID` | 11.6 | all | The ID of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_SOURCE_PROJECT_ID` | 11.6 | all | The ID of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_SOURCE_PROJECT_PATH` | 11.6 | all | The path of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_SOURCE_PROJECT_PATH` | 11.6 | all | The path of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_SOURCE_PROJECT_URL` | 11.6 | all | The URL of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_SOURCE_PROJECT_URL` | 11.6 | all | The URL of the source project of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_TARGET_BRANCH_NAME` | 11.6 | all | The target branch name of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_TARGET_BRANCH_NAME` | 11.6 | all | The target branch name of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_TARGET_BRANCH_SHA` | 11.9 | all | The HEAD SHA of the target branch of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used, the merge request is created, and the pipeline is a [merged result pipeline](../merge_request_pipelines/pipelines_for_merged_results/index.md). **(PREMIUM)** | | `CI_MERGE_REQUEST_TARGET_BRANCH_SHA` | 11.9 | all | The HEAD SHA of the target branch of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used, the merge request is created, and the pipeline is a [merged result pipeline](../merge_request_pipelines/pipelines_for_merged_results/index.md). **(PREMIUM)** |
| `CI_MERGE_REQUEST_TITLE` | 11.9 | all | The title of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` is used and the merge request is created. | | `CI_MERGE_REQUEST_TITLE` | 11.9 | all | The title of the merge request if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Available only if `only: [merge_requests]` or [`rules`](../yaml/README.md#rules) syntax is used and the merge request is created. |
| `CI_MERGE_REQUEST_EVENT_TYPE` | 12.3 | all | The event type of the merge request, if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Can be `detached`, `merged_result` or `merge_train`. | | `CI_MERGE_REQUEST_EVENT_TYPE` | 12.3 | all | The event type of the merge request, if [the pipelines are for merge requests](../merge_request_pipelines/index.md). Can be `detached`, `merged_result` or `merge_train`. |
| `CI_NODE_INDEX` | 11.5 | all | Index of the job in the job set. If the job is not parallelized, this variable is not set. | | `CI_NODE_INDEX` | 11.5 | all | Index of the job in the job set. If the job is not parallelized, this variable is not set. |
| `CI_NODE_TOTAL` | 11.5 | all | Total number of instances of this job running in parallel. If the job is not parallelized, this variable is set to `1`. | | `CI_NODE_TOTAL` | 11.5 | all | Total number of instances of this job running in parallel. If the job is not parallelized, this variable is set to `1`. |
......
...@@ -11,6 +11,12 @@ to access them as we do in Rails views), local variables are fine. ...@@ -11,6 +11,12 @@ to access them as we do in Rails views), local variables are fine.
Always use an [Entity] to present the endpoint's payload. Always use an [Entity] to present the endpoint's payload.
## Documentation
API endpoints must come with [documentation](documentation/styleguide.md#api), unless it is internal or behind a feature flag.
The docs should be in the same merge request, or, if strictly necessary,
in a follow-up with the same milestone as the original merge request.
## Methods and parameters description ## Methods and parameters description
Every method must be described using the [Grape DSL](https://github.com/ruby-grape/grape#describing-methods) Every method must be described using the [Grape DSL](https://github.com/ruby-grape/grape#describing-methods)
......
...@@ -7,9 +7,11 @@ type: reference, howto ...@@ -7,9 +7,11 @@ type: reference, howto
GitLab can check your application for security vulnerabilities that may lead to unauthorized access, GitLab can check your application for security vulnerabilities that may lead to unauthorized access,
data leaks, denial of services, and more. GitLab reports vulnerabilities in the merge request so you data leaks, denial of services, and more. GitLab reports vulnerabilities in the merge request so you
can fix them before merging. The [Security Dashboard](security_dashboard/index.md) provides a can fix them before merging. The [Security Dashboard](security_dashboard/index.md) provides a
high-level view of vulnerabilities detected in your projects, pipeline, and groups. With the high-level view of vulnerabilities detected in your projects, pipeline, and groups. The [Threat Monitoring](threat_monitoring/index.md)
information provided, you can immediately begin risk analysis and remediation. page provides runtime security metrics for application environments. With the information provided,
you can immediately begin risk analysis and remediation.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview of application security with GitLab, see For an overview of application security with GitLab, see
[Security Deep Dive](https://www.youtube.com/watch?v=k4vEJnGYy84). [Security Deep Dive](https://www.youtube.com/watch?v=k4vEJnGYy84).
......
...@@ -13,7 +13,7 @@ connected to the internet, in what is sometimes known as an offline, ...@@ -13,7 +13,7 @@ connected to the internet, in what is sometimes known as an offline,
limited connectivity, Local Area Network (LAN), Intranet, or "air-gap" limited connectivity, Local Area Network (LAN), Intranet, or "air-gap"
environment. environment.
In this situation, the GitLab instance can be one, or more, servers and services running in a network that can talk to one another, but have zero, or perhaps very restricted access to the internet. Assume anything within the GitLab instance and supporting infrastrusture (private maven repository for example) can be accessed via local network connection. Assume any files from the internet must come in via physical media (USB drive, hard drive). In this situation, the GitLab instance can be one, or more, servers and services running in a network that can talk to one another, but have zero, or perhaps very restricted access to the internet. Assume anything within the GitLab instance and supporting infrastructure (private Maven repository for example) can be accessed via local network connection. Assume any files from the internet must come in via physical media (USB drive, hard drive).
GitLab scanners generally will connect to the internet to download the GitLab scanners generally will connect to the internet to download the
latest sets of signatures, rules, and patches. A few extra steps are necessary latest sets of signatures, rules, and patches. A few extra steps are necessary
......
---
type: reference, howto
---
# Threat Monitoring **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14707) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
The **Threat Monitoring** page provides metrics for the GitLab
application runtime security features. You can access these metrics by
navigating to your project's **Security & Compliance > Threat Monitoring** page.
GitLab supports statistics for the following security features:
- [Web Application Firewall](../../clusters/applications.md#web-application-firewall-modsecurity)
## Web Application Firewall
The Web Application Firewall section provides metrics for the NGINX
Ingress controller and ModSecurity firewall. This section has the
following prerequisites:
- Project has to have at least one [environment](../../../ci/environments.md).
- [Web Application Firewall](../../clusters/applications.md#web-application-firewall-modsecurity) has to be enabled.
- [Elastic Stack](../../clusters/applications.md#web-application-firewall-modsecurity) has to be installed.
If you are using custom Helm values for the Elastic Stack you have to
configure Filebeat similarly to the [vendored values](https://gitlab.com/gitlab-org/gitlab/-/blob/f610a080b1ccc106270f588a50cb3c07c08bdd5a/vendor/elastic_stack/values.yaml).
The **Web Application Firewall** section displays the following information
about your Ingress traffic:
- The total amount of requests to your application
- The proportion of traffic that is considered anomalous according to
the configured rules
- The request breakdown graph for the selected time interval
If a significant percentage of traffic is anomalous, you should
investigate it for potential threats by
[examining the application logs](../../clusters/applications.md#web-application-firewall-modsecurity).
...@@ -45,10 +45,10 @@ in October 2018. ...@@ -45,10 +45,10 @@ in October 2018.
You may have older issues, merge requests, or Markdown documents in your You may have older issues, merge requests, or Markdown documents in your
repository that were written using some of the nuances of GitLab's RedCarpet version repository that were written using some of the nuances of GitLab's RedCarpet version
of Markdown. Since CommonMark uses a slightly stricter syntax, these documents of Markdown. Since CommonMark uses slightly stricter syntax, these documents
may now display a little differently since we've transitioned to CommonMark. might now appear a little differently since we have transitioned to CommonMark.
It is usually quite easy to fix. For example, numbered lists with nested lists may It's usually quite easy to fix. For example, numbered lists with nested lists may
render incorrectly: render incorrectly:
```markdown ```markdown
...@@ -119,7 +119,7 @@ changing how standard Markdown is used: ...@@ -119,7 +119,7 @@ changing how standard Markdown is used:
> If this is not rendered correctly, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#colors). > If this is not rendered correctly, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#colors).
It is possible to have color written in HEX, RGB or HSL format rendered with a color It's possible to have color written in HEX, RGB, or HSL format rendered with a color
indicator. indicator.
Supported formats (named colors are not supported): Supported formats (named colors are not supported):
...@@ -154,14 +154,14 @@ Color written inside backticks will be followed by a color "chip": ...@@ -154,14 +154,14 @@ Color written inside backticks will be followed by a color "chip":
### Diagrams and flowcharts ### Diagrams and flowcharts
It is possible to generate diagrams and flowcharts from text in GitLab using [Mermaid](https://mermaidjs.github.io/) or [PlantUML](http://plantuml.com). It's possible to generate diagrams and flowcharts from text in GitLab using [Mermaid](https://mermaidjs.github.io/) or [PlantUML](http://plantuml.com).
#### Mermaid #### Mermaid
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15107) in > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15107) in
GitLab 10.3. GitLab 10.3.
Visit the [official page](https://mermaidjs.github.io/) for more details. If you are new to using Mermaid or need help identifying issues in your Mermaid code, the [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/) is a helpful tool for creating and resolving issues within Mermaid diagrams. Visit the [official page](https://mermaidjs.github.io/) for more details. If you're new to using Mermaid or need help identifying issues in your Mermaid code, the [Mermaid Live Editor](https://mermaid-js.github.io/mermaid-live-editor/) is a helpful tool for creating and resolving issues within Mermaid diagrams.
In order to generate a diagram or flowchart, you should write your text inside the `mermaid` block: In order to generate a diagram or flowchart, you should write your text inside the `mermaid` block:
...@@ -236,7 +236,7 @@ Sometimes you want to :monkey: around a bit and add some :star2: to your :speech ...@@ -236,7 +236,7 @@ Sometimes you want to :monkey: around a bit and add some :star2: to your :speech
You can use it to point out a :bug: or warn about :speak_no_evil: patches. And if someone improves your really :snail: code, send them some :birthday:. People will :heart: you for that. You can use it to point out a :bug: or warn about :speak_no_evil: patches. And if someone improves your really :snail: code, send them some :birthday:. People will :heart: you for that.
If you are new to this, don't be :fearful:. You can easily join the emoji :family:. All you need to do is to look up one of the supported codes. If you're new to this, don't be :fearful:. You can easily join the emoji :family:. All you need to do is to look up one of the supported codes.
Consult the [Emoji Cheat Sheet](https://www.emojicopy.com) for a list of all supported emoji codes. :thumbsup: Consult the [Emoji Cheat Sheet](https://www.emojicopy.com) for a list of all supported emoji codes. :thumbsup:
``` ```
...@@ -247,7 +247,7 @@ Sometimes you want to <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/ma ...@@ -247,7 +247,7 @@ Sometimes you want to <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/ma
You can use it to point out a <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/bug.png" width="20px" height="20px" style="display:inline;margin:0"> or warn about <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/speak_no_evil.png" width="20px" height="20px" style="display:inline;margin:0"> patches. And if someone improves your really <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/snail.png" width="20px" height="20px" style="display:inline;margin:0"> code, send them some <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/birthday.png" width="20px" height="20px" style="display:inline;margin:0">. People will <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/heart.png" width="20px" height="20px" style="display:inline;margin:0"> you for that. You can use it to point out a <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/bug.png" width="20px" height="20px" style="display:inline;margin:0"> or warn about <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/speak_no_evil.png" width="20px" height="20px" style="display:inline;margin:0"> patches. And if someone improves your really <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/snail.png" width="20px" height="20px" style="display:inline;margin:0"> code, send them some <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/birthday.png" width="20px" height="20px" style="display:inline;margin:0">. People will <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/heart.png" width="20px" height="20px" style="display:inline;margin:0"> you for that.
If you are new to this, don't be <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/fearful.png" width="20px" height="20px" style="display:inline;margin:0">. You can easily join the emoji <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/family.png" width="20px" height="20px" style="display:inline;margin:0">. All you need to do is to look up one of the supported codes. If you're new to this, don't be <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/fearful.png" width="20px" height="20px" style="display:inline;margin:0">. You can easily join the emoji <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/family.png" width="20px" height="20px" style="display:inline;margin:0">. All you need to do is to look up one of the supported codes.
Consult the [Emoji Cheat Sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) for a list of all supported emoji codes. <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/thumbsup.png" width="20px" height="20px" style="display:inline;margin:0"> Consult the [Emoji Cheat Sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) for a list of all supported emoji codes. <img src="https://gitlab.com/gitlab-org/gitlab-foss/raw/master/app/assets/images/emoji/thumbsup.png" width="20px" height="20px" style="display:inline;margin:0">
...@@ -345,7 +345,7 @@ The wrapping tags can be either curly braces or square brackets: ...@@ -345,7 +345,7 @@ The wrapping tags can be either curly braces or square brackets:
--- ---
However the wrapping tags cannot be mixed: However, the wrapping tags can't be mixed:
```markdown ```markdown
- {+ addition +] - {+ addition +]
...@@ -354,11 +354,24 @@ However the wrapping tags cannot be mixed: ...@@ -354,11 +354,24 @@ However the wrapping tags cannot be mixed:
- [- deletion -} - [- deletion -}
``` ```
If your diff includes words in `` `code` `` font, make sure to escape each bactick `` ` `` with a
backslash `\`, otherwise the diff highlight won't render correctly:
```markdown
- {+ Just regular text +}
- {+ Text with `backticks` inside +}
- {+ Text with escaped \`backticks\` inside +}
```
- {+ Just regular text +}
- {+ Text with `backticks` inside +}
- {+ Text with escaped \`backticks\` inside +}
### Math ### Math
> If this is not rendered correctly, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#math). > If this is not rendered correctly, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#math).
It is possible to have math written with LaTeX syntax rendered using [KaTeX](https://github.com/KaTeX/KaTeX). It's possible to have math written with LaTeX syntax rendered using [KaTeX](https://github.com/KaTeX/KaTeX).
Math written between dollar signs `$` will be rendered inline with the text. Math written Math written between dollar signs `$` will be rendered inline with the text. Math written
inside a [code block](#code-spans-and-blocks) with the language declared as `math`, will be rendered inside a [code block](#code-spans-and-blocks) with the language declared as `math`, will be rendered
...@@ -462,22 +475,35 @@ unordered or ordered lists: ...@@ -462,22 +475,35 @@ unordered or ordered lists:
1. [ ] Sub-task 1 1. [ ] Sub-task 1
1. [x] Sub-task 2 1. [x] Sub-task 2
### Table of Contents ### Table of contents
A table of contents can be added to a Markdown file, issue or merge request You can add a table of contents to a Markdown file, wiki page, or issue/merge request
description, or a wiki page, by adding the tag `[[_TOC_]]` on its own line. description, by adding the tag `[[_TOC_]]` on its own line.
It will be replaced with an unordered list that links to the various It will appear as an unordered list that links to the various headers.
headers.
```markdown ```markdown
This is an intro sentence to my Wiki page.
[[_TOC_]] [[_TOC_]]
## My first heading
First section content.
## My second heading
Second section content.
``` ```
![Preview of an auto-generated TOC in a Wiki](img/markdown_toc_preview_v12_9.png)
---
### Wiki-specific Markdown ### Wiki-specific Markdown
The following examples show how links inside wikis behave. The following examples show how links inside wikis behave.
#### Wiki - Direct page link #### Wiki - direct page link
A link which just includes the slug for a page will point to that page, A link which just includes the slug for a page will point to that page,
_at the base level of the wiki_. _at the base level of the wiki_.
...@@ -488,7 +514,7 @@ This snippet would link to a `documentation` page at the root of your wiki: ...@@ -488,7 +514,7 @@ This snippet would link to a `documentation` page at the root of your wiki:
[Link to Documentation](documentation) [Link to Documentation](documentation)
``` ```
#### Wiki - Direct file link #### Wiki - direct file link
Links with a file extension point to that file, _relative to the current page_. Links with a file extension point to that file, _relative to the current page_.
...@@ -499,10 +525,10 @@ it would link to `<your_wiki>/documentation/file.md`: ...@@ -499,10 +525,10 @@ it would link to `<your_wiki>/documentation/file.md`:
[Link to File](file.md) [Link to File](file.md)
``` ```
#### Wiki - Hierarchical link #### Wiki - hierarchical link
A link can be constructed relative to the current wiki page using `./<page>`, A link can be constructed relative to the current wiki page using `./<page>`,
`../<page>`, etc. `../<page>`, and so on.
If this snippet was placed on a page at `<your_wiki>/documentation/main`, If this snippet was placed on a page at `<your_wiki>/documentation/main`,
it would link to `<your_wiki>/documentation/related`: it would link to `<your_wiki>/documentation/related`:
...@@ -532,7 +558,7 @@ it would link to `<your_wiki>/documentation/main.md`: ...@@ -532,7 +558,7 @@ it would link to `<your_wiki>/documentation/main.md`:
[Link to Related Page](../main.md) [Link to Related Page](../main.md)
``` ```
#### Wiki - Root link #### Wiki - root link
A link starting with a `/` is relative to the wiki root. A link starting with a `/` is relative to the wiki root.
...@@ -560,7 +586,7 @@ If a functionality is extended, the new option will be listed as a sub-section. ...@@ -560,7 +586,7 @@ If a functionality is extended, the new option will be listed as a sub-section.
### Blockquotes ### Blockquotes
Blockquotes are an easy way to highlight information, such as a side-note. It is generated Blockquotes are an easy way to highlight information, such as a side-note. It's generated
by starting the lines of the blockquote with `>`: by starting the lines of the blockquote with `>`:
```markdown ```markdown
...@@ -667,8 +693,8 @@ Tildes are OK too. ...@@ -667,8 +693,8 @@ Tildes are OK too.
GitLab uses the [Rouge Ruby library](http://rouge.jneen.net/) for more colorful syntax GitLab uses the [Rouge Ruby library](http://rouge.jneen.net/) for more colorful syntax
highlighting in code blocks. For a list of supported languages visit the highlighting in code blocks. For a list of supported languages visit the
[Rouge project wiki](https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers). [Rouge project wiki](https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers).
Syntax highlighting is only supported in code blocks, it is not possible to highlight Syntax highlighting is only supported in code blocks, so it's not possible to highlight
code when it is inline. code when it's inline.
Blocks of code are fenced by lines with three back-ticks (```` ``` ````) or three tildes (`~~~`), and have Blocks of code are fenced by lines with three back-ticks (```` ``` ````) or three tildes (`~~~`), and have
the language identified at the end of the first fence: the language identified at the end of the first fence:
...@@ -756,7 +782,7 @@ NOTE: **Note:** Strikethrough is not part of the core Markdown standard, but is ...@@ -756,7 +782,7 @@ NOTE: **Note:** Strikethrough is not part of the core Markdown standard, but is
> If this is not rendered correctly, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#multiple-underscores-in-words). > If this is not rendered correctly, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#multiple-underscores-in-words).
It is not usually useful to italicize just _part_ of a word, especially when you're It's not usually useful to italicize just _part_ of a word, especially when you're
dealing with code and names that often appear with multiple underscores. As a result, dealing with code and names that often appear with multiple underscores. As a result,
GFM extends the standard Markdown standard by ignoring multiple underlines in words, GFM extends the standard Markdown standard by ignoring multiple underlines in words,
to allow better rendering of Markdown documents discussing code: to allow better rendering of Markdown documents discussing code:
...@@ -793,7 +819,8 @@ do*this*and*do*that*and*another thing ...@@ -793,7 +819,8 @@ do*this*and*do*that*and*another thing
Footnotes add a link to a note that will be rendered at the end of a Markdown file. Footnotes add a link to a note that will be rendered at the end of a Markdown file.
To make a footnote, you need both a reference tag and a separate line (anywhere in the file) with the note content. To make a footnote, you need both a reference tag and a separate line (anywhere in the file) with
the note content.
Regardless of the tag names, the relative order of the reference tags determines the rendered numbering. Regardless of the tag names, the relative order of the reference tags determines the rendered numbering.
...@@ -804,20 +831,23 @@ A footnote reference tag looks like this:[^1] ...@@ -804,20 +831,23 @@ A footnote reference tag looks like this:[^1]
Reference tags can use letters and other characters.[^footnote-note] Reference tags can use letters and other characters.[^footnote-note]
[^footnote-note]: Avoid using lowercase `w` or an underscore (`_`) Avoid using lowercase `w` or an underscore (`_`) in footnote tag names until
in your footnote tag name until an [this bug](https://gitlab.com/gitlab-org/gitlab/issues/24423) is resolved. [^this-name-has-w] [^this-name-has_]
[upstream bug](https://gitlab.com/gitlab-org/gitlab/issues/24423) is resolved.
```
A footnote reference tag looks like this:[^1] [^this-name-has-w]: This won't be rendered, because the name contains "w".
[^1]: This is the contents of a footnote. [^this-name-has_]: This won be rendered, because the name contains an underscore.
```
Reference tags can use letters and other characters.[^footnote-note] Reference tags can use letters and other characters.[^footnote-note]
[^footnote-note]: Avoid using lowercase `w` or an underscore (`_`) Avoid using lowercase `w` or an underscore (`_`) in footnote tag names until
in your footnote tag name until an [this bug](https://gitlab.com/gitlab-org/gitlab/issues/24423) is resolved. [^this-name-has-w] [^this-name-has_]
[upstream bug](https://gitlab.com/gitlab-org/gitlab/issues/24423) is resolved.
[^this-name-has-w]: This won't be rendered, because the name contains "w".
[^this-name-has_]: This won't be rendered, because the name contains an underscore.
### Headers ### Headers
...@@ -849,7 +879,7 @@ the header to use it somewhere else. ...@@ -849,7 +879,7 @@ the header to use it somewhere else.
The IDs are generated from the content of the header according to the following rules: The IDs are generated from the content of the header according to the following rules:
1. All text is converted to lowercase. 1. All text is converted to lowercase.
1. All non-word text (e.g., punctuation, HTML) is removed. 1. All non-word text (such as punctuation or HTML) is removed.
1. All spaces are converted to hyphens. 1. All spaces are converted to hyphens.
1. Two or more hyphens in a row are converted to one. 1. Two or more hyphens in a row are converted to one.
1. If a header with the same ID has already been generated, a unique 1. If a header with the same ID has already been generated, a unique
...@@ -875,8 +905,8 @@ Would generate the following link IDs: ...@@ -875,8 +905,8 @@ Would generate the following link IDs:
1. `this-header-has-spaces-in-it-2` 1. `this-header-has-spaces-in-it-2`
1. `this-header-has-3-5-in-it-and-parentheses` 1. `this-header-has-3-5-in-it-and-parentheses`
Note that the Emoji processing happens before the header IDs are generated, so the Note that the emoji processing happens before the header IDs are generated, so the
Emoji is converted to an image which is then removed from the ID. emoji is converted to an image which is then removed from the ID.
### Horizontal Rule ### Horizontal Rule
...@@ -966,7 +996,7 @@ Here's a sample audio clip: ...@@ -966,7 +996,7 @@ Here's a sample audio clip:
> To see the Markdown rendered within HTML in the second example, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#inline-html). > To see the Markdown rendered within HTML in the second example, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#inline-html).
You can also use raw HTML in your Markdown, and it'll usually work pretty well. You can also use raw HTML in your Markdown, and it will usually work pretty well.
See the documentation for HTML::Pipeline's [SanitizationFilter](https://www.rubydoc.info/gems/html-pipeline/1.11.0/HTML/Pipeline/SanitizationFilter#WHITELIST-constant) See the documentation for HTML::Pipeline's [SanitizationFilter](https://www.rubydoc.info/gems/html-pipeline/1.11.0/HTML/Pipeline/SanitizationFilter#WHITELIST-constant)
class for the list of allowed HTML tags and attributes. In addition to the default class for the list of allowed HTML tags and attributes. In addition to the default
...@@ -992,7 +1022,7 @@ class for the list of allowed HTML tags and attributes. In addition to the defau ...@@ -992,7 +1022,7 @@ class for the list of allowed HTML tags and attributes. In addition to the defau
--- ---
It is still possible to use Markdown inside HTML tags, but only if the lines containing Markdown It's still possible to use Markdown inside HTML tags, but only if the lines containing Markdown
are separated into their own lines: are separated into their own lines:
```html ```html
...@@ -1023,7 +1053,7 @@ are separated into their own lines: ...@@ -1023,7 +1053,7 @@ are separated into their own lines:
</dd> </dd>
</dl> </dl>
#### Details and Summary #### Details and summary
> To see the Markdown rendered within HTML in the second example, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#details-and-summary). > To see the Markdown rendered within HTML in the second example, [view it in GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md#details-and-summary).
...@@ -1034,7 +1064,7 @@ tags. This is especially useful for collapsing long logs so they take up less sc ...@@ -1034,7 +1064,7 @@ tags. This is especially useful for collapsing long logs so they take up less sc
```html ```html
<p> <p>
<details> <details>
<summary>Click me to collapse/fold.</summary> <summary>Click this to collapse/fold.</summary>
These details <em>will</em> remain <strong>hidden</strong> until expanded. These details <em>will</em> remain <strong>hidden</strong> until expanded.
...@@ -1046,7 +1076,7 @@ These details <em>will</em> remain <strong>hidden</strong> until expanded. ...@@ -1046,7 +1076,7 @@ These details <em>will</em> remain <strong>hidden</strong> until expanded.
<p> <p>
<details> <details>
<summary>Click me to collapse/fold.</summary> <summary>Click this to collapse/fold.</summary>
These details <em>will</em> remain <strong>hidden</strong> until expanded. These details <em>will</em> remain <strong>hidden</strong> until expanded.
...@@ -1062,7 +1092,7 @@ after the `</summary>` tag and before the `</details>` tag, as shown in the exam ...@@ -1062,7 +1092,7 @@ after the `</summary>` tag and before the `</details>` tag, as shown in the exam
````html ````html
<details> <details>
<summary>Click me to collapse/fold.</summary> <summary>Click this to collapse/fold.</summary>
These details _will_ remain **hidden** until expanded. These details _will_ remain **hidden** until expanded.
...@@ -1076,7 +1106,7 @@ PASTE LOGS HERE ...@@ -1076,7 +1106,7 @@ PASTE LOGS HERE
<!-- Note: The example below uses HTML to force correct rendering on docs.gitlab.com, Markdown will be fine in GitLab --> <!-- Note: The example below uses HTML to force correct rendering on docs.gitlab.com, Markdown will be fine in GitLab -->
<details> <details>
<summary>Click me to collapse/fold.</summary> <summary>Click this to collapse/fold.</summary>
These details <em>will</em> remain <b>hidden</b> until expanded. These details <em>will</em> remain <b>hidden</b> until expanded.
...@@ -1084,10 +1114,10 @@ These details <em>will</em> remain <b>hidden</b> until expanded. ...@@ -1084,10 +1114,10 @@ These details <em>will</em> remain <b>hidden</b> until expanded.
</details> </details>
### Line Breaks ### Line breaks
A line break will be inserted (a new paragraph will start) if the previous text is A line break will be inserted (a new paragraph will start) if the previous text is
ended with two newlines, i.e. you hit <kbd>Enter</kbd> twice in a row. If you only ended with two newlines, like when you hit <kbd>Enter</kbd> twice in a row. If you only
use one newline (hit <kbd>Enter</kbd> once), the next sentence will be part of the use one newline (hit <kbd>Enter</kbd> once), the next sentence will be part of the
same paragraph. This is useful if you want to keep long lines from wrapping, and keep same paragraph. This is useful if you want to keep long lines from wrapping, and keep
them easily editable: them easily editable:
...@@ -1116,8 +1146,8 @@ in the *same paragraph*. ...@@ -1116,8 +1146,8 @@ in the *same paragraph*.
GFM adheres to the Markdown specification in how [paragraphs and line breaks are handled](https://spec.commonmark.org/current/). GFM adheres to the Markdown specification in how [paragraphs and line breaks are handled](https://spec.commonmark.org/current/).
A paragraph is simply one or more consecutive lines of text, separated by one or A paragraph is one or more consecutive lines of text, separated by one or
more blank lines (i.e. two newlines at the end of the first paragraph), as [explained above](#line-breaks). more blank lines (two newlines at the end of the first paragraph), as [explained above](#line-breaks).
If you need more control over line-breaks or soft returns, you can add a single line-break If you need more control over line-breaks or soft returns, you can add a single line-break
by ending a line with a backslash, or two or more spaces. Two newlines in a row will create a new by ending a line with a backslash, or two or more spaces. Two newlines in a row will create a new
...@@ -1340,7 +1370,7 @@ Example: ...@@ -1340,7 +1370,7 @@ Example:
### Superscripts / Subscripts ### Superscripts / Subscripts
CommonMark and GFM currently do not support the superscript syntax ( `x^2` ) that Currently, CommonMark and GFM don't support the superscript syntax ( `x^2` ) that
Redcarpet does. You can use the standard HTML syntax for superscripts and subscripts: Redcarpet does. You can use the standard HTML syntax for superscripts and subscripts:
```html ```html
...@@ -1353,7 +1383,7 @@ while the equation for the theory of relativity is E = mc<sup>2</sup>. ...@@ -1353,7 +1383,7 @@ while the equation for the theory of relativity is E = mc<sup>2</sup>.
### Tables ### Tables
Tables aren't part of the core Markdown spec, but they are part of GFM. Tables are not part of the core Markdown spec, but they are part of GFM.
1. The first line contains the headers, separated by "pipes" (`|`). 1. The first line contains the headers, separated by "pipes" (`|`).
1. The second line separates the headers from the cells, and must contain three or more dashes. 1. The second line separates the headers from the cells, and must contain three or more dashes.
...@@ -1401,8 +1431,8 @@ to the sides of the "dash" lines in the second row. This will affect every cell ...@@ -1401,8 +1431,8 @@ to the sides of the "dash" lines in the second row. This will affect every cell
[Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27205) in GitLab 12.7. [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/27205) in GitLab 12.7.
If you're working in spreadsheet software (e.g. Microsoft Excel, Google If you're working in spreadsheet software (for example, Microsoft Excel, Google
Sheets, Apple Numbers), you can copy from a spreadsheet, and GitLab will Sheets, or Apple Numbers), you can copy from a spreadsheet, and GitLab will
paste it as a Markdown table. For example, suppose you have the paste it as a Markdown table. For example, suppose you have the
following spreadsheet: following spreadsheet:
......
...@@ -93,6 +93,11 @@ To edit a page, simply click on the **Edit** button. From there on, you can ...@@ -93,6 +93,11 @@ To edit a page, simply click on the **Edit** button. From there on, you can
change its content. When done, click **Save changes** for the changes to take change its content. When done, click **Save changes** for the changes to take
effect. effect.
### Adding a table of contents
To generate a table of contents from the headings in a Wiki page, use the `[[_TOC_]]` tag.
For an example, see [Table of contents](../../markdown.md#table-of-contents).
## Deleting a wiki page ## Deleting a wiki page
NOTE: **Note:** NOTE: **Note:**
......
...@@ -38,7 +38,7 @@ class Feature ...@@ -38,7 +38,7 @@ class Feature
begin begin
# We saw on GitLab.com, this database request was called 2300 # We saw on GitLab.com, this database request was called 2300
# times/s. Let's cache it for a minute to avoid that load. # times/s. Let's cache it for a minute to avoid that load.
Gitlab::ThreadMemoryCache.cache_backend.fetch('flipper:persisted_names', expires_in: 1.minute) do Gitlab::ProcessMemoryCache.cache_backend.fetch('flipper:persisted_names', expires_in: 1.minute) do
FlipperFeature.feature_names FlipperFeature.feature_names
end end
end end
......
...@@ -21,7 +21,7 @@ module Gitlab ...@@ -21,7 +21,7 @@ module Gitlab
process_commits do |commit| process_commits do |commit|
validate_once(commit) do validate_once(commit) do
commit.raw_deltas.each do |diff| commit.raw_deltas.each do |diff|
file_paths << (diff.new_path || diff.old_path) file_paths.concat([diff.new_path, diff.old_path].compact)
validate_diff(diff) validate_diff(diff)
end end
......
...@@ -8,11 +8,6 @@ module RuboCop ...@@ -8,11 +8,6 @@ module RuboCop
class AddColumn < RuboCop::Cop::Cop class AddColumn < RuboCop::Cop::Cop
include MigrationHelpers include MigrationHelpers
WHITELISTED_TABLES = %i[
application_settings
plan_limits
].freeze
MSG = '`add_column` with a default value requires downtime, ' \ MSG = '`add_column` with a default value requires downtime, ' \
'use `add_column_with_default` instead'.freeze 'use `add_column_with_default` instead'.freeze
......
...@@ -10,38 +10,6 @@ module RuboCop ...@@ -10,38 +10,6 @@ module RuboCop
class AddColumnWithDefault < RuboCop::Cop::Cop class AddColumnWithDefault < RuboCop::Cop::Cop
include MigrationHelpers include MigrationHelpers
# Tables >= 10 GB on GitLab.com as of 02/2020
BLACKLISTED_TABLES = %i[
audit_events
ci_build_trace_sections
ci_builds
ci_builds_metadata
ci_job_artifacts
ci_pipeline_variables
ci_pipelines
ci_stages
deployments
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_request_metrics
merge_requests
note_diff_files
notes
project_authorizations
projects
push_event_payloads
resource_label_events
sent_notifications
system_note_metadata
taggings
todos
users
web_hook_logs
].freeze
MSG = '`add_column_with_default` without `allow_null: true` may cause prolonged lock situations and downtime, ' \ MSG = '`add_column_with_default` without `allow_null: true` may cause prolonged lock situations and downtime, ' \
'see https://gitlab.com/gitlab-org/gitlab/issues/38060'.freeze 'see https://gitlab.com/gitlab-org/gitlab/issues/38060'.freeze
......
...@@ -23,10 +23,6 @@ module RuboCop ...@@ -23,10 +23,6 @@ module RuboCop
NULL_OFFENSE = 'Boolean columns on the `%s` table should disallow nulls.'.freeze NULL_OFFENSE = 'Boolean columns on the `%s` table should disallow nulls.'.freeze
DEFAULT_AND_NULL_OFFENSE = 'Boolean columns on the `%s` table should have a default and should disallow nulls. You may wish to use `add_column_with_default`.'.freeze DEFAULT_AND_NULL_OFFENSE = 'Boolean columns on the `%s` table should have a default and should disallow nulls. You may wish to use `add_column_with_default`.'.freeze
SMALL_TABLES = %i[
application_settings
].freeze
def_node_matcher :add_column?, <<~PATTERN def_node_matcher :add_column?, <<~PATTERN
(send nil? :add_column $...) (send nil? :add_column $...)
PATTERN PATTERN
...@@ -41,7 +37,7 @@ module RuboCop ...@@ -41,7 +37,7 @@ module RuboCop
table, _, type = matched.to_a.take(3).map(&:children).map(&:first) table, _, type = matched.to_a.take(3).map(&:children).map(&:first)
opts = matched[3] opts = matched[3]
return unless SMALL_TABLES.include?(table) && type == :boolean return unless WHITELISTED_TABLES.include?(table) && type == :boolean
no_default = no_default?(opts) no_default = no_default?(opts)
nulls_allowed = nulls_allowed?(opts) nulls_allowed = nulls_allowed?(opts)
......
...@@ -19,26 +19,6 @@ module RuboCop ...@@ -19,26 +19,6 @@ module RuboCop
'complete, and should be avoided unless absolutely ' \ 'complete, and should be avoided unless absolutely ' \
'necessary'.freeze 'necessary'.freeze
LARGE_TABLES = %i[
ci_build_trace_sections
ci_builds
ci_job_artifacts
ci_pipelines
ci_stages
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_requests
namespaces
notes
projects
project_ci_cd_settings
routes
users
].freeze
BATCH_UPDATE_METHODS = %w[ BATCH_UPDATE_METHODS = %w[
:add_column_with_default :add_column_with_default
:change_column_type_concurrently :change_column_type_concurrently
...@@ -59,7 +39,7 @@ module RuboCop ...@@ -59,7 +39,7 @@ module RuboCop
update_method = matches.first update_method = matches.first
table = matches.last.to_a.first table = matches.last.to_a.first
return unless LARGE_TABLES.include?(table) return unless BLACKLISTED_TABLES.include?(table)
add_offense(node, location: :expression, message: format(MSG, update_method, table)) add_offense(node, location: :expression, message: format(MSG, update_method, table))
end end
......
module RuboCop module RuboCop
# Module containing helper methods for writing migration cops. # Module containing helper methods for writing migration cops.
module MigrationHelpers module MigrationHelpers
WHITELISTED_TABLES = %i[
application_settings
plan_limits
].freeze
# Blacklisted table due to:
# - size in GB (>= 10 GB on GitLab.com as of 02/2020)
# - number of records
BLACKLISTED_TABLES = %i[
audit_events
ci_build_trace_sections
ci_builds
ci_builds_metadata
ci_job_artifacts
ci_pipeline_variables
ci_pipelines
ci_stages
deployments
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_request_metrics
merge_requests
namespaces
note_diff_files
notes
project_authorizations
projects
project_ci_cd_settings
push_event_payloads
resource_label_events
routes
sent_notifications
services
system_note_metadata
taggings
todos
users
web_hook_logs
].freeze
# Returns true if the given node originated from the db/migrate directory. # Returns true if the given node originated from the db/migrate directory.
def in_migration?(node) def in_migration?(node)
dirname(node).end_with?('db/migrate', 'db/geo/migrate') || in_post_deployment_migration?(node) dirname(node).end_with?('db/migrate', 'db/geo/migrate') || in_post_deployment_migration?(node)
......
...@@ -9,7 +9,7 @@ describe 'Gitlab::Graphql::Authorization' do ...@@ -9,7 +9,7 @@ describe 'Gitlab::Graphql::Authorization' do
let(:permission_single) { :foo } let(:permission_single) { :foo }
let(:permission_collection) { [:foo, :bar] } let(:permission_collection) { [:foo, :bar] }
let(:test_object) { double(name: 'My name') } let(:test_object) { double(name: 'My name') }
let(:query_string) { '{ item() { name } }' } let(:query_string) { '{ item { name } }' }
let(:result) { execute_query(query_type)['data'] } let(:result) { execute_query(query_type)['data'] }
subject { result['item'] } subject { result['item'] }
...@@ -177,7 +177,7 @@ describe 'Gitlab::Graphql::Authorization' do ...@@ -177,7 +177,7 @@ describe 'Gitlab::Graphql::Authorization' do
end end
describe 'type authorizations when applied to a relay connection' do describe 'type authorizations when applied to a relay connection' do
let(:query_string) { '{ item() { edges { node { name } } } }' } let(:query_string) { '{ item { edges { node { name } } } }' }
let(:second_test_object) { double(name: 'Second thing') } let(:second_test_object) { double(name: 'Second thing') }
let(:type) do let(:type) do
......
...@@ -9,7 +9,7 @@ describe 'Graphql Field feature flags' do ...@@ -9,7 +9,7 @@ describe 'Graphql Field feature flags' do
let(:feature_flag) { 'test_feature' } let(:feature_flag) { 'test_feature' }
let(:test_object) { double(name: 'My name') } let(:test_object) { double(name: 'My name') }
let(:query_string) { '{ item() { name } }' } let(:query_string) { '{ item { name } }' }
let(:result) { execute_query(query_type)['data'] } let(:result) { execute_query(query_type)['data'] }
subject { result } subject { result }
......
...@@ -27,11 +27,11 @@ describe GitlabSchema do ...@@ -27,11 +27,11 @@ describe GitlabSchema do
end end
it 'has the base mutation' do it 'has the base mutation' do
expect(described_class.mutation).to eq(::Types::MutationType.to_graphql) expect(described_class.mutation).to eq(::Types::MutationType)
end end
it 'has the base query' do it 'has the base query' do
expect(described_class.query).to eq(::Types::QueryType.to_graphql) expect(described_class.query).to eq(::Types::QueryType)
end end
it 'paginates active record relations using `Connections::Keyset::Connection`' do it 'paginates active record relations using `Connections::Keyset::Connection`' do
......
...@@ -5,7 +5,7 @@ require 'spec_helper' ...@@ -5,7 +5,7 @@ require 'spec_helper'
describe GitlabSchema.types['AwardEmoji'] do describe GitlabSchema.types['AwardEmoji'] do
it { expect(described_class.graphql_name).to eq('AwardEmoji') } it { expect(described_class.graphql_name).to eq('AwardEmoji') }
it { is_expected.to require_graphql_authorizations(:read_emoji) } it { expect(described_class).to require_graphql_authorizations(:read_emoji) }
it { expect(described_class).to have_graphql_fields(:description, :unicode_version, :emoji, :name, :unicode, :user) } it { expect(described_class).to have_graphql_fields(:description, :unicode_version, :emoji, :name, :unicode, :user) }
end end
...@@ -10,6 +10,6 @@ describe GitlabSchema.types['Board'] do ...@@ -10,6 +10,6 @@ describe GitlabSchema.types['Board'] do
it 'has specific fields' do it 'has specific fields' do
expected_fields = %w[id name] expected_fields = %w[id name]
is_expected.to include_graphql_fields(*expected_fields) expect(described_class).to include_graphql_fields(*expected_fields)
end end
end end
...@@ -5,7 +5,7 @@ require 'spec_helper' ...@@ -5,7 +5,7 @@ require 'spec_helper'
describe GitlabSchema.types['DiffRefs'] do describe GitlabSchema.types['DiffRefs'] do
it { expect(described_class.graphql_name).to eq('DiffRefs') } it { expect(described_class.graphql_name).to eq('DiffRefs') }
it { is_expected.to have_graphql_fields(:head_sha, :base_sha, :start_sha).only } it { expect(described_class).to have_graphql_fields(:head_sha, :base_sha, :start_sha).only }
it { expect(described_class.fields['headSha'].type).to be_non_null } it { expect(described_class.fields['headSha'].type).to be_non_null }
it { expect(described_class.fields['baseSha'].type).not_to be_non_null } it { expect(described_class.fields['baseSha'].type).not_to be_non_null }
......
...@@ -10,8 +10,8 @@ describe GitlabSchema.types['Environment'] do ...@@ -10,8 +10,8 @@ describe GitlabSchema.types['Environment'] do
name id name id
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
it { is_expected.to require_graphql_authorizations(:read_environment) } it { expect(described_class).to require_graphql_authorizations(:read_environment) }
end end
...@@ -37,6 +37,6 @@ describe GitlabSchema.types['SentryDetailedError'] do ...@@ -37,6 +37,6 @@ describe GitlabSchema.types['SentryDetailedError'] do
tags tags
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -15,7 +15,7 @@ describe GitlabSchema.types['SentryErrorCollection'] do ...@@ -15,7 +15,7 @@ describe GitlabSchema.types['SentryErrorCollection'] do
error_stack_trace error_stack_trace
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
describe 'errors field' do describe 'errors field' do
......
...@@ -14,6 +14,6 @@ describe GitlabSchema.types['SentryErrorStackTraceEntry'] do ...@@ -14,6 +14,6 @@ describe GitlabSchema.types['SentryErrorStackTraceEntry'] do
trace_context trace_context
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -14,6 +14,6 @@ describe GitlabSchema.types['SentryErrorStackTrace'] do ...@@ -14,6 +14,6 @@ describe GitlabSchema.types['SentryErrorStackTrace'] do
stack_trace_entries stack_trace_entries
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -26,6 +26,6 @@ describe GitlabSchema.types['SentryError'] do ...@@ -26,6 +26,6 @@ describe GitlabSchema.types['SentryError'] do
frequency frequency
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -18,5 +18,5 @@ describe GitlabSchema.types['GrafanaIntegration'] do ...@@ -18,5 +18,5 @@ describe GitlabSchema.types['GrafanaIntegration'] do
it { expect(described_class).to require_graphql_authorizations(:admin_operations) } it { expect(described_class).to require_graphql_authorizations(:admin_operations) }
it { is_expected.to have_graphql_fields(*expected_fields) } it { expect(described_class).to have_graphql_fields(*expected_fields) }
end end
...@@ -19,7 +19,7 @@ describe GitlabSchema.types['Group'] do ...@@ -19,7 +19,7 @@ describe GitlabSchema.types['Group'] do
mentions_disabled parent boards mentions_disabled parent boards
] ]
is_expected.to include_graphql_fields(*expected_fields) expect(described_class).to include_graphql_fields(*expected_fields)
end end
describe 'boards field' do describe 'boards field' do
......
...@@ -9,7 +9,7 @@ describe GitlabSchema.types['Issue'] do ...@@ -9,7 +9,7 @@ describe GitlabSchema.types['Issue'] do
it { expect(described_class).to require_graphql_authorizations(:read_issue) } it { expect(described_class).to require_graphql_authorizations(:read_issue) }
it { expect(described_class.interfaces).to include(Types::Notes::NoteableType.to_graphql) } it { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
it 'has specific fields' do it 'has specific fields' do
fields = %i[iid title description state reference author assignees participants labels milestone due_date fields = %i[iid title description state reference author assignees participants labels milestone due_date
......
...@@ -5,8 +5,8 @@ describe GitlabSchema.types['Label'] do ...@@ -5,8 +5,8 @@ describe GitlabSchema.types['Label'] do
it 'has the correct fields' do it 'has the correct fields' do
expected_fields = [:id, :description, :description_html, :title, :color, :text_color] expected_fields = [:id, :description, :description_html, :title, :color, :text_color]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
it { is_expected.to require_graphql_authorizations(:read_label) } it { expect(described_class).to require_graphql_authorizations(:read_label) }
end end
...@@ -7,7 +7,7 @@ describe GitlabSchema.types['MergeRequest'] do ...@@ -7,7 +7,7 @@ describe GitlabSchema.types['MergeRequest'] do
it { expect(described_class).to require_graphql_authorizations(:read_merge_request) } it { expect(described_class).to require_graphql_authorizations(:read_merge_request) }
it { expect(described_class.interfaces).to include(Types::Notes::NoteableType.to_graphql) } it { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
it 'has the expected fields' do it 'has the expected fields' do
expected_fields = %w[ expected_fields = %w[
...@@ -25,6 +25,6 @@ describe GitlabSchema.types['MergeRequest'] do ...@@ -25,6 +25,6 @@ describe GitlabSchema.types['MergeRequest'] do
total_time_spent reference total_time_spent reference
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -4,5 +4,5 @@ require 'spec_helper' ...@@ -4,5 +4,5 @@ require 'spec_helper'
describe GitlabSchema.types['Metadata'] do describe GitlabSchema.types['Metadata'] do
it { expect(described_class.graphql_name).to eq('Metadata') } it { expect(described_class.graphql_name).to eq('Metadata') }
it { is_expected.to require_graphql_authorizations(:read_instance_metadata) } it { expect(described_class).to require_graphql_authorizations(:read_instance_metadata) }
end end
...@@ -11,8 +11,8 @@ describe GitlabSchema.types['Namespace'] do ...@@ -11,8 +11,8 @@ describe GitlabSchema.types['Namespace'] do
lfs_enabled request_access_enabled projects root_storage_statistics lfs_enabled request_access_enabled projects root_storage_statistics
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
it { is_expected.to require_graphql_authorizations(:read_namespace) } it { expect(described_class).to require_graphql_authorizations(:read_namespace) }
end end
...@@ -7,6 +7,6 @@ describe GitlabSchema.types['DiffPosition'] do ...@@ -7,6 +7,6 @@ describe GitlabSchema.types['DiffPosition'] do
:new_path, :position_type, :old_line, :new_line, :x, :y, :new_path, :position_type, :old_line, :new_line, :x, :y,
:width, :height] :width, :height]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe GitlabSchema.types['Discussion'] do describe GitlabSchema.types['Discussion'] do
it { is_expected.to have_graphql_fields(:id, :created_at, :notes, :reply_id) } it { expect(described_class).to have_graphql_fields(:id, :created_at, :notes, :reply_id) }
it { is_expected.to require_graphql_authorizations(:read_note) } it { expect(described_class).to require_graphql_authorizations(:read_note) }
end end
...@@ -7,9 +7,9 @@ describe GitlabSchema.types['Note'] do ...@@ -7,9 +7,9 @@ describe GitlabSchema.types['Note'] do
:updated_at, :discussion, :resolvable, :position, :user_permissions, :updated_at, :discussion, :resolvable, :position, :user_permissions,
:resolved_by, :resolved_at, :system, :body_html] :resolved_by, :resolved_at, :system, :body_html]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
it { is_expected.to expose_permissions_using(Types::PermissionTypes::Note) } it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Note) }
it { is_expected.to require_graphql_authorizations(:read_note) } it { expect(described_class).to require_graphql_authorizations(:read_note) }
end end
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe Types::Notes::NoteableType do describe Types::Notes::NoteableType do
it { is_expected.to have_graphql_fields(:notes, :discussions) } it { expect(described_class).to have_graphql_fields(:notes, :discussions) }
describe ".resolve_type" do describe ".resolve_type" do
it 'knows the correct type for objects' do it 'knows the correct type for objects' do
......
...@@ -19,13 +19,13 @@ describe Types::PermissionTypes::BasePermissionType do ...@@ -19,13 +19,13 @@ describe Types::PermissionTypes::BasePermissionType do
describe '.permission_field' do describe '.permission_field' do
it 'adds a field for the required permission' do it 'adds a field for the required permission' do
is_expected.to have_graphql_field(:do_stuff) expect(test_type).to have_graphql_field(:do_stuff)
end end
end end
describe '.ability_field' do describe '.ability_field' do
it 'adds a field for the required permission' do it 'adds a field for the required permission' do
is_expected.to have_graphql_field(:read_issue) expect(test_type).to have_graphql_field(:read_issue)
end end
it 'does not add a resolver block if another resolving param is passed' do it 'does not add a resolver block if another resolving param is passed' do
...@@ -44,7 +44,7 @@ describe Types::PermissionTypes::BasePermissionType do ...@@ -44,7 +44,7 @@ describe Types::PermissionTypes::BasePermissionType do
describe '.abilities' do describe '.abilities' do
it 'adds a field for the passed permissions' do it 'adds a field for the passed permissions' do
is_expected.to have_graphql_field(:admin_issue) expect(test_type).to have_graphql_field(:admin_issue)
end end
end end
end end
...@@ -8,6 +8,6 @@ describe GitlabSchema.types['NotePermissions'] do ...@@ -8,6 +8,6 @@ describe GitlabSchema.types['NotePermissions'] do
:read_note, :create_note, :admin_note, :resolve_note, :award_emoji :read_note, :create_note, :admin_note, :resolve_note, :award_emoji
] ]
is_expected.to have_graphql_fields(expected_permissions) expect(described_class).to have_graphql_fields(expected_permissions)
end end
end end
...@@ -4,7 +4,7 @@ require 'spec_helper' ...@@ -4,7 +4,7 @@ require 'spec_helper'
describe GitlabSchema.types['ProjectStatistics'] do describe GitlabSchema.types['ProjectStatistics'] do
it "has all the required fields" do it "has all the required fields" do
is_expected.to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size, expect(described_class).to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
:build_artifacts_size, :packages_size, :commit_count, :build_artifacts_size, :packages_size, :commit_count,
:wiki_size) :wiki_size)
end end
......
...@@ -27,7 +27,7 @@ describe GitlabSchema.types['Project'] do ...@@ -27,7 +27,7 @@ describe GitlabSchema.types['Project'] do
boards boards
] ]
is_expected.to include_graphql_fields(*expected_fields) expect(described_class).to include_graphql_fields(*expected_fields)
end end
describe 'issue field' do describe 'issue field' do
......
...@@ -7,7 +7,7 @@ describe GitlabSchema.types['Repository'] do ...@@ -7,7 +7,7 @@ describe GitlabSchema.types['Repository'] do
it { expect(described_class).to require_graphql_authorizations(:download_code) } it { expect(described_class).to require_graphql_authorizations(:download_code) }
it { is_expected.to have_graphql_field(:root_ref) } it { expect(described_class).to have_graphql_field(:root_ref) }
it { is_expected.to have_graphql_field(:tree) } it { expect(described_class).to have_graphql_field(:tree) }
end end
...@@ -6,9 +6,9 @@ describe GitlabSchema.types['RootStorageStatistics'] do ...@@ -6,9 +6,9 @@ describe GitlabSchema.types['RootStorageStatistics'] do
it { expect(described_class.graphql_name).to eq('RootStorageStatistics') } it { expect(described_class.graphql_name).to eq('RootStorageStatistics') }
it 'has all the required fields' do it 'has all the required fields' do
is_expected.to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size, expect(described_class).to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
:build_artifacts_size, :packages_size, :wiki_size) :build_artifacts_size, :packages_size, :wiki_size)
end end
it { is_expected.to require_graphql_authorizations(:read_statistics) } it { expect(described_class).to require_graphql_authorizations(:read_statistics) }
end end
...@@ -10,7 +10,7 @@ describe GitlabSchema.types['Snippet'] do ...@@ -10,7 +10,7 @@ describe GitlabSchema.types['Snippet'] do
:web_url, :raw_url, :notes, :discussions, :web_url, :raw_url, :notes, :discussions,
:user_permissions, :description_html, :blob] :user_permissions, :description_html, :blob]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
describe 'authorizations' do describe 'authorizations' do
......
...@@ -8,6 +8,6 @@ describe GitlabSchema.types['SnippetBlob'] do ...@@ -8,6 +8,6 @@ describe GitlabSchema.types['SnippetBlob'] do
:raw_path, :size, :binary, :name, :path, :raw_path, :size, :binary, :name, :path,
:simple_viewer, :rich_viewer, :mode] :simple_viewer, :rich_viewer, :mode]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -7,6 +7,6 @@ describe GitlabSchema.types['SnippetBlobViewer'] do ...@@ -7,6 +7,6 @@ describe GitlabSchema.types['SnippetBlobViewer'] do
expected_fields = [:type, :load_async, :too_large, :collapsed, expected_fields = [:type, :load_async, :too_large, :collapsed,
:render_error, :file_type, :loading_partial_name] :render_error, :file_type, :loading_partial_name]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
end end
...@@ -6,7 +6,7 @@ describe GitlabSchema.types['Todo'] do ...@@ -6,7 +6,7 @@ describe GitlabSchema.types['Todo'] do
it 'has the correct fields' do it 'has the correct fields' do
expected_fields = [:id, :project, :group, :author, :action, :target_type, :body, :state, :created_at] expected_fields = [:id, :project, :group, :author, :action, :target_type, :body, :state, :created_at]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
it { expect(described_class).to require_graphql_authorizations(:read_todo) } it { expect(described_class).to require_graphql_authorizations(:read_todo) }
......
...@@ -12,7 +12,7 @@ describe GitlabSchema.types['User'] do ...@@ -12,7 +12,7 @@ describe GitlabSchema.types['User'] do
user_permissions snippets name username avatarUrl webUrl todos user_permissions snippets name username avatarUrl webUrl todos
] ]
is_expected.to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
describe 'snippets field' do describe 'snippets field' do
......
...@@ -42,7 +42,7 @@ describe Feature do ...@@ -42,7 +42,7 @@ describe Feature do
.once .once
.and_call_original .and_call_original
expect(Gitlab::ThreadMemoryCache.cache_backend) expect(Gitlab::ProcessMemoryCache.cache_backend)
.to receive(:fetch) .to receive(:fetch)
.once .once
.with('flipper:persisted_names', expires_in: 1.minute) .with('flipper:persisted_names', expires_in: 1.minute)
......
...@@ -17,7 +17,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do ...@@ -17,7 +17,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
allow(cop).to receive(:in_migration?).and_return(true) allow(cop).to receive(:in_migration?).and_return(true)
end end
described_class::SMALL_TABLES.each do |table| described_class::WHITELISTED_TABLES.each do |table|
context "for the #{table} table" do context "for the #{table} table" do
sources_and_offense = [ sources_and_offense = [
["add_column :#{table}, :column, :boolean, default: true", 'should disallow nulls'], ["add_column :#{table}, :column, :boolean, default: true", 'should disallow nulls'],
...@@ -62,14 +62,14 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do ...@@ -62,14 +62,14 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
end end
end end
it 'registers no offense for tables not listed in SMALL_TABLES' do it 'registers no offense for tables not listed in WHITELISTED_TABLES' do
inspect_source("add_column :large_table, :column, :boolean") inspect_source("add_column :large_table, :column, :boolean")
expect(cop.offenses).to be_empty expect(cop.offenses).to be_empty
end end
it 'registers no offense for non-boolean columns' do it 'registers no offense for non-boolean columns' do
table = described_class::SMALL_TABLES.sample table = described_class::WHITELISTED_TABLES.sample
inspect_source("add_column :#{table}, :column, :string") inspect_source("add_column :#{table}, :column, :string")
expect(cop.offenses).to be_empty expect(cop.offenses).to be_empty
...@@ -78,7 +78,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do ...@@ -78,7 +78,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
context 'outside of migration' do context 'outside of migration' do
it 'registers no offense' do it 'registers no offense' do
table = described_class::SMALL_TABLES.sample table = described_class::WHITELISTED_TABLES.sample
inspect_source("add_column :#{table}, :column, :boolean") inspect_source("add_column :#{table}, :column, :boolean")
expect(cop.offenses).to be_empty expect(cop.offenses).to be_empty
......
...@@ -18,7 +18,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do ...@@ -18,7 +18,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end end
shared_examples 'large tables' do |update_method| shared_examples 'large tables' do |update_method|
described_class::LARGE_TABLES.each do |table| described_class::BLACKLISTED_TABLES.each do |table|
it "registers an offense for the #{table} table" do it "registers an offense for the #{table} table" do
inspect_source("#{update_method} :#{table}, :column, default: true") inspect_source("#{update_method} :#{table}, :column, default: true")
...@@ -53,7 +53,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do ...@@ -53,7 +53,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end end
it 'registers no offense for non-blacklisted methods' do it 'registers no offense for non-blacklisted methods' do
table = described_class::LARGE_TABLES.sample table = described_class::BLACKLISTED_TABLES.sample
inspect_source("some_other_method :#{table}, :column, default: true") inspect_source("some_other_method :#{table}, :column, default: true")
...@@ -62,7 +62,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do ...@@ -62,7 +62,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end end
context 'outside of migration' do context 'outside of migration' do
let(:table) { described_class::LARGE_TABLES.sample } let(:table) { described_class::BLACKLISTED_TABLES.sample }
it 'registers no offense for add_column_with_default' do it 'registers no offense for add_column_with_default' do
inspect_source("add_column_with_default :#{table}, :column, default: true") inspect_source("add_column_with_default :#{table}, :column, default: true")
......
...@@ -71,10 +71,10 @@ module GraphqlHelpers ...@@ -71,10 +71,10 @@ module GraphqlHelpers
mutation_name = GraphqlHelpers.fieldnamerize(name) mutation_name = GraphqlHelpers.fieldnamerize(name)
input_variable_name = "$#{input_variable_name_for_mutation(name)}" input_variable_name = "$#{input_variable_name_for_mutation(name)}"
mutation_field = GitlabSchema.mutation.fields[mutation_name] mutation_field = GitlabSchema.mutation.fields[mutation_name]
fields ||= all_graphql_fields_for(mutation_field.type) fields ||= all_graphql_fields_for(mutation_field.type.to_graphql)
query = <<~MUTATION query = <<~MUTATION
mutation(#{input_variable_name}: #{mutation_field.arguments['input'].type}) { mutation(#{input_variable_name}: #{mutation_field.arguments['input'].type.to_graphql}) {
#{mutation_name}(input: #{input_variable_name}) { #{mutation_name}(input: #{input_variable_name}) {
#{fields} #{fields}
} }
...@@ -118,15 +118,22 @@ module GraphqlHelpers ...@@ -118,15 +118,22 @@ module GraphqlHelpers
GraphqlHelpers.fieldnamerize(input_type) GraphqlHelpers.fieldnamerize(input_type)
end end
def query_graphql_field(name, attributes = {}, fields = nil) def field_with_params(name, attributes = {})
field_params = if attributes.present? namerized = GraphqlHelpers.fieldnamerize(name.to_s)
return "#{namerized}" if attributes.blank?
field_params = if attributes.is_a?(Hash)
"(#{attributes_to_graphql(attributes)})" "(#{attributes_to_graphql(attributes)})"
else else
'' "(#{attributes})"
end end
"#{namerized}#{field_params}"
end
def query_graphql_field(name, attributes = {}, fields = nil)
<<~QUERY <<~QUERY
#{GraphqlHelpers.fieldnamerize(name.to_s)}#{field_params} #{field_with_params(name, attributes)}
#{wrap_fields(fields || all_graphql_fields_for(name.to_s.classify))} #{wrap_fields(fields || all_graphql_fields_for(name.to_s.classify))}
QUERY QUERY
end end
...@@ -300,7 +307,7 @@ module GraphqlHelpers ...@@ -300,7 +307,7 @@ module GraphqlHelpers
end end
def field_type(field) def field_type(field)
field_type = field.type field_type = field.type.respond_to?(:to_graphql) ? field.type.to_graphql : field.type
# The type could be nested. For example `[GraphQL::STRING_TYPE]`: # The type could be nested. For example `[GraphQL::STRING_TYPE]`:
# - List # - List
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
RSpec::Matchers.define :require_graphql_authorizations do |*expected| RSpec::Matchers.define :require_graphql_authorizations do |*expected|
match do |field| match do |field|
expect(field.metadata[:authorize]).to eq(*expected) expect(field.to_graphql.metadata[:authorize]).to eq(*expected)
end end
end end
...@@ -87,13 +87,13 @@ end ...@@ -87,13 +87,13 @@ end
RSpec::Matchers.define :have_graphql_type do |expected| RSpec::Matchers.define :have_graphql_type do |expected|
match do |field| match do |field|
expect(field.type).to eq(expected.to_graphql) expect(field.type).to eq(expected)
end end
end end
RSpec::Matchers.define :have_non_null_graphql_type do |expected| RSpec::Matchers.define :have_non_null_graphql_type do |expected|
match do |field| match do |field|
expect(field.type).to eq(!expected.to_graphql) expect(field.type.to_graphql).to eq(!expected.to_graphql)
end end
end end
...@@ -101,16 +101,16 @@ RSpec::Matchers.define :have_graphql_resolver do |expected| ...@@ -101,16 +101,16 @@ RSpec::Matchers.define :have_graphql_resolver do |expected|
match do |field| match do |field|
case expected case expected
when Method when Method
expect(field.metadata[:type_class].resolve_proc).to eq(expected) expect(field.to_graphql.metadata[:type_class].resolve_proc).to eq(expected)
else else
expect(field.metadata[:type_class].resolver).to eq(expected) expect(field.to_graphql.metadata[:type_class].resolver).to eq(expected)
end end
end end
end end
RSpec::Matchers.define :have_graphql_extension do |expected| RSpec::Matchers.define :have_graphql_extension do |expected|
match do |field| match do |field|
expect(field.metadata[:type_class].extensions).to include(expected) expect(field.to_graphql.metadata[:type_class].extensions).to include(expected)
end end
end end
......
...@@ -15,7 +15,7 @@ RSpec.shared_context 'group and project boards query context' do ...@@ -15,7 +15,7 @@ RSpec.shared_context 'group and project boards query context' do
board_parent_type, board_parent_type,
{ 'fullPath' => board_parent.full_path }, { 'fullPath' => board_parent.full_path },
<<~BOARDS <<~BOARDS
boards(#{board_params}) { #{field_with_params('boards', board_params)} {
pageInfo { pageInfo {
startCursor startCursor
endCursor endCursor
...@@ -35,7 +35,7 @@ RSpec.shared_context 'group and project boards query context' do ...@@ -35,7 +35,7 @@ RSpec.shared_context 'group and project boards query context' do
board_parent_type, board_parent_type,
{ 'fullPath' => board_parent.full_path }, { 'fullPath' => board_parent.full_path },
<<~BOARD <<~BOARD
board(#{board_params}) { #{field_with_params('board', board_params)} {
#{all_graphql_fields_for('board'.classify)} #{all_graphql_fields_for('board'.classify)}
} }
BOARD BOARD
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment