summaryrefslogtreecommitdiff
path: root/app/graphql/types
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-17 11:59:07 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-17 11:59:07 +0000
commit8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch)
tree544930fb309b30317ae9797a9683768705d664c4 /app/graphql/types
parent4b1de649d0168371549608993deac953eb692019 (diff)
downloadgitlab-ce-8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca.tar.gz
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'app/graphql/types')
-rw-r--r--app/graphql/types/alert_management/domain_filter_enum.rb13
-rw-r--r--app/graphql/types/alert_management/prometheus_integration_type.rb2
-rw-r--r--app/graphql/types/award_emojis/award_emoji_type.rb9
-rw-r--r--app/graphql/types/base_field.rb7
-rw-r--r--app/graphql/types/base_interface.rb2
-rw-r--r--app/graphql/types/board_list_type.rb7
-rw-r--r--app/graphql/types/board_type.rb6
-rw-r--r--app/graphql/types/ci/analytics_type.rb33
-rw-r--r--app/graphql/types/ci/ci_cd_setting_type.rb20
-rw-r--r--app/graphql/types/ci/config/config_type.rb21
-rw-r--r--app/graphql/types/ci/config/group_type.rb19
-rw-r--r--app/graphql/types/ci/config/job_type.rb21
-rw-r--r--app/graphql/types/ci/config/need_type.rb15
-rw-r--r--app/graphql/types/ci/config/stage_type.rb17
-rw-r--r--app/graphql/types/ci/config/status_enum.rb15
-rw-r--r--app/graphql/types/ci/detailed_status_type.rb30
-rw-r--r--app/graphql/types/ci/group_type.rb7
-rw-r--r--app/graphql/types/ci/job_artifact_file_type_enum.rb13
-rw-r--r--app/graphql/types/ci/job_artifact_type.rb24
-rw-r--r--app/graphql/types/ci/job_type.rb30
-rw-r--r--app/graphql/types/ci/pipeline_type.rb24
-rw-r--r--app/graphql/types/ci/stage_type.rb7
-rw-r--r--app/graphql/types/commit_type.rb11
-rw-r--r--app/graphql/types/concerns/gitlab_style_deprecations.rb4
-rw-r--r--app/graphql/types/container_repository_type.rb5
-rw-r--r--app/graphql/types/design_management/design_collection_type.rb2
-rw-r--r--app/graphql/types/error_tracking/sentry_error_collection_type.rb21
-rw-r--r--app/graphql/types/group_invitation_type.rb7
-rw-r--r--app/graphql/types/group_member_relation_enum.rb12
-rw-r--r--app/graphql/types/group_member_type.rb7
-rw-r--r--app/graphql/types/group_type.rb25
-rw-r--r--app/graphql/types/issue_type.rb26
-rw-r--r--app/graphql/types/jira_import_type.rb3
-rw-r--r--app/graphql/types/jira_users_mapping_input_type.rb2
-rw-r--r--app/graphql/types/merge_request_connection_type.rb15
-rw-r--r--app/graphql/types/merge_request_type.rb54
-rw-r--r--app/graphql/types/mutation_type.rb4
-rw-r--r--app/graphql/types/namespace_type.rb8
-rw-r--r--app/graphql/types/notes/diff_position_type.rb42
-rw-r--r--app/graphql/types/notes/note_type.rb14
-rw-r--r--app/graphql/types/permission_types/merge_request.rb4
-rw-r--r--app/graphql/types/project_member_relation_enum.rb12
-rw-r--r--app/graphql/types/project_type.rb71
-rw-r--r--app/graphql/types/query_type.rb10
-rw-r--r--app/graphql/types/snippets/blob_viewer_type.rb14
-rw-r--r--app/graphql/types/sort_enum.rb8
-rw-r--r--app/graphql/types/terraform/state_type.rb8
-rw-r--r--app/graphql/types/terraform/state_version_type.rb35
-rw-r--r--app/graphql/types/todo_type.rb21
-rw-r--r--app/graphql/types/tree/blob_type.rb11
-rw-r--r--app/graphql/types/tree/tree_type.rb31
-rw-r--r--app/graphql/types/user_type.rb12
52 files changed, 651 insertions, 190 deletions
diff --git a/app/graphql/types/alert_management/domain_filter_enum.rb b/app/graphql/types/alert_management/domain_filter_enum.rb
new file mode 100644
index 00000000000..58dbc8bb2cf
--- /dev/null
+++ b/app/graphql/types/alert_management/domain_filter_enum.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+ module AlertManagement
+ class DomainFilterEnum < BaseEnum
+ graphql_name 'AlertManagementDomainFilter'
+ description 'Filters the alerts based on given domain'
+
+ value 'operations', description: 'Alerts for operations domain '
+ value 'threat_monitoring', description: 'Alerts for threat monitoring domain'
+ end
+ end
+end
diff --git a/app/graphql/types/alert_management/prometheus_integration_type.rb b/app/graphql/types/alert_management/prometheus_integration_type.rb
index f605e325b8b..79f265f2f1e 100644
--- a/app/graphql/types/alert_management/prometheus_integration_type.rb
+++ b/app/graphql/types/alert_management/prometheus_integration_type.rb
@@ -2,7 +2,7 @@
module Types
module AlertManagement
- class PrometheusIntegrationType < BaseObject
+ class PrometheusIntegrationType < ::Types::BaseObject
include ::Gitlab::Routing
graphql_name 'AlertManagementPrometheusIntegration'
diff --git a/app/graphql/types/award_emojis/award_emoji_type.rb b/app/graphql/types/award_emojis/award_emoji_type.rb
index fe7affa50cc..cd7a2f34ba6 100644
--- a/app/graphql/types/award_emojis/award_emoji_type.rb
+++ b/app/graphql/types/award_emojis/award_emoji_type.rb
@@ -38,10 +38,11 @@ module Types
field :user,
Types::UserType,
null: false,
- description: 'The user who awarded the emoji',
- resolve: -> (award_emoji, _args, _context) {
- Gitlab::Graphql::Loaders::BatchModelLoader.new(User, award_emoji.user_id).find
- }
+ description: 'The user who awarded the emoji'
+
+ def user
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
+ end
end
end
end
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb
index 5c8aabfe163..c4ce2cecd8b 100644
--- a/app/graphql/types/base_field.rb
+++ b/app/graphql/types/base_field.rb
@@ -12,6 +12,7 @@ module Types
def initialize(*args, **kwargs, &block)
@calls_gitaly = !!kwargs.delete(:calls_gitaly)
@constant_complexity = !!kwargs[:complexity]
+ @requires_argument = !!kwargs.delete(:requires_argument)
kwargs[:complexity] = field_complexity(kwargs[:resolver_class], kwargs[:complexity])
@feature_flag = kwargs[:feature_flag]
kwargs = check_feature_flag(kwargs)
@@ -20,6 +21,10 @@ module Types
super(*args, **kwargs, &block)
end
+ def requires_argument?
+ @requires_argument || arguments.values.any? { |argument| argument.type.non_null? }
+ end
+
# Based on https://github.com/rmosolgo/graphql-ruby/blob/v1.11.4/lib/graphql/schema/field.rb#L538-L563
# Modified to fix https://github.com/rmosolgo/graphql-ruby/issues/3113
def resolve_field(obj, args, ctx)
@@ -73,7 +78,7 @@ module Types
attr_reader :feature_flag
def feature_documentation_message(key, description)
- "#{description}. Available only when feature flag `#{key}` is enabled"
+ "#{description} Available only when feature flag `#{key}` is enabled."
end
def check_feature_flag(args)
diff --git a/app/graphql/types/base_interface.rb b/app/graphql/types/base_interface.rb
index 3451a195c33..4b1f3193136 100644
--- a/app/graphql/types/base_interface.rb
+++ b/app/graphql/types/base_interface.rb
@@ -3,5 +3,7 @@
module Types
module BaseInterface
include GraphQL::Schema::Interface
+
+ field_class ::Types::BaseField
end
end
diff --git a/app/graphql/types/board_list_type.rb b/app/graphql/types/board_list_type.rb
index 6ee76b0d1f1..7999e77eb30 100644
--- a/app/graphql/types/board_list_type.rb
+++ b/app/graphql/types/board_list_type.rb
@@ -19,8 +19,7 @@ module Types
field :label, Types::LabelType, null: true,
description: 'Label of the list'
field :collapsed, GraphQL::BOOLEAN_TYPE, null: true,
- description: 'Indicates if list is collapsed for this user',
- resolve: -> (list, _args, ctx) { list.collapsed?(ctx[:current_user]) }
+ description: 'Indicates if list is collapsed for this user'
field :issues_count, GraphQL::INT_TYPE, null: true,
description: 'Count of issues in the list'
@@ -32,6 +31,10 @@ module Types
metadata[:size]
end
+ def collapsed
+ object.collapsed?(context[:current_user])
+ end
+
def metadata
strong_memoize(:metadata) do
list = self.object
diff --git a/app/graphql/types/board_type.rb b/app/graphql/types/board_type.rb
index 2a7b318e283..f47c744d1bb 100644
--- a/app/graphql/types/board_type.rb
+++ b/app/graphql/types/board_type.rb
@@ -12,6 +12,12 @@ module Types
field :name, type: GraphQL::STRING_TYPE, null: true,
description: 'Name of the board'
+ field :hide_backlog_list, type: GraphQL::BOOLEAN_TYPE, null: true,
+ description: 'Whether or not backlog list is hidden'
+
+ field :hide_closed_list, type: GraphQL::BOOLEAN_TYPE, null: true,
+ description: 'Whether or not closed list is hidden'
+
field :lists,
Types::BoardListType.connection_type,
null: true,
diff --git a/app/graphql/types/ci/analytics_type.rb b/app/graphql/types/ci/analytics_type.rb
new file mode 100644
index 00000000000..c8b12c6a9b8
--- /dev/null
+++ b/app/graphql/types/ci/analytics_type.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ class AnalyticsType < BaseObject
+ graphql_name 'PipelineAnalytics'
+
+ field :week_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ description: 'Total weekly pipeline count'
+ field :week_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ description: 'Total weekly successful pipeline count'
+ field :week_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Labels for the weekly pipeline count'
+ field :month_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ description: 'Total monthly pipeline count'
+ field :month_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ description: 'Total monthly successful pipeline count'
+ field :month_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Labels for the monthly pipeline count'
+ field :year_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ description: 'Total yearly pipeline count'
+ field :year_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ description: 'Total yearly successful pipeline count'
+ field :year_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Labels for the yearly pipeline count'
+ field :pipeline_times_values, [GraphQL::INT_TYPE], null: true,
+ description: 'Pipeline times'
+ field :pipeline_times_labels, [GraphQL::STRING_TYPE], null: true,
+ description: 'Pipeline times labels'
+ end
+ end
+end
diff --git a/app/graphql/types/ci/ci_cd_setting_type.rb b/app/graphql/types/ci/ci_cd_setting_type.rb
new file mode 100644
index 00000000000..207c37f9538
--- /dev/null
+++ b/app/graphql/types/ci/ci_cd_setting_type.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ class CiCdSettingType < BaseObject
+ graphql_name 'ProjectCiCdSetting'
+
+ authorize :admin_project
+
+ field :merge_pipelines_enabled, GraphQL::BOOLEAN_TYPE, null: true,
+ description: 'Whether merge pipelines are enabled.',
+ method: :merge_pipelines_enabled?
+ field :merge_trains_enabled, GraphQL::BOOLEAN_TYPE, null: true,
+ description: 'Whether merge trains are enabled.',
+ method: :merge_trains_enabled?
+ field :project, Types::ProjectType, null: true,
+ description: 'Project the CI/CD settings belong to.'
+ end
+ end
+end
diff --git a/app/graphql/types/ci/config/config_type.rb b/app/graphql/types/ci/config/config_type.rb
new file mode 100644
index 00000000000..e54b345f3d3
--- /dev/null
+++ b/app/graphql/types/ci/config/config_type.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ module Config
+ class ConfigType < BaseObject
+ graphql_name 'CiConfig'
+
+ field :errors, [GraphQL::STRING_TYPE], null: true,
+ description: 'Linting errors'
+ field :merged_yaml, GraphQL::STRING_TYPE, null: true,
+ description: 'Merged CI config YAML'
+ field :stages, [Types::Ci::Config::StageType], null: true,
+ description: 'Stages of the pipeline'
+ field :status, Types::Ci::Config::StatusEnum, null: true,
+ description: 'Status of linting, can be either valid or invalid'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/config/group_type.rb b/app/graphql/types/ci/config/group_type.rb
new file mode 100644
index 00000000000..8b0db2934a4
--- /dev/null
+++ b/app/graphql/types/ci/config/group_type.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ module Config
+ class GroupType < BaseObject
+ graphql_name 'CiConfigGroup'
+
+ field :name, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the job group'
+ field :jobs, [Types::Ci::Config::JobType], null: true,
+ description: 'Jobs in group'
+ field :size, GraphQL::INT_TYPE, null: true,
+ description: 'Size of the job group'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/config/job_type.rb b/app/graphql/types/ci/config/job_type.rb
new file mode 100644
index 00000000000..59bcbd9ef49
--- /dev/null
+++ b/app/graphql/types/ci/config/job_type.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ module Config
+ class JobType < BaseObject
+ graphql_name 'CiConfigJob'
+
+ field :name, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the job'
+ field :group_name, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the job group'
+ field :stage, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the job stage'
+ field :needs, [Types::Ci::Config::NeedType], null: true,
+ description: 'Builds that must complete before the jobs run'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/config/need_type.rb b/app/graphql/types/ci/config/need_type.rb
new file mode 100644
index 00000000000..a442450b9ae
--- /dev/null
+++ b/app/graphql/types/ci/config/need_type.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ module Config
+ class NeedType < BaseObject
+ graphql_name 'CiConfigNeed'
+
+ field :name, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the need'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/config/stage_type.rb b/app/graphql/types/ci/config/stage_type.rb
new file mode 100644
index 00000000000..20618bc41f8
--- /dev/null
+++ b/app/graphql/types/ci/config/stage_type.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ module Config
+ class StageType < BaseObject
+ graphql_name 'CiConfigStage'
+
+ field :name, GraphQL::STRING_TYPE, null: true,
+ description: 'Name of the stage'
+ field :groups, [Types::Ci::Config::GroupType], null: true,
+ description: 'Groups of jobs for the stage'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/config/status_enum.rb b/app/graphql/types/ci/config/status_enum.rb
new file mode 100644
index 00000000000..92b04c61679
--- /dev/null
+++ b/app/graphql/types/ci/config/status_enum.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ module Config
+ class StatusEnum < BaseEnum
+ graphql_name 'CiConfigStatus'
+ description 'Values for YAML processor result'
+
+ value 'VALID', 'The configuration file is valid', value: :valid
+ value 'INVALID', 'The configuration file is not valid', value: :invalid
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/detailed_status_type.rb b/app/graphql/types/ci/detailed_status_type.rb
index 6d8af400ac4..80d73e9b174 100644
--- a/app/graphql/types/ci/detailed_status_type.rb
+++ b/app/graphql/types/ci/detailed_status_type.rb
@@ -25,20 +25,22 @@ module Types
description: 'Tooltip associated with the status',
method: :status_tooltip
field :action, Types::Ci::StatusActionType, null: true,
- description: 'Action information for the status. This includes method, button title, icon, path, and title',
- resolve: -> (obj, _args, _ctx) {
- if obj.has_action?
- {
- button_title: obj.action_button_title,
- icon: obj.action_icon,
- method: obj.action_method,
- path: obj.action_path,
- title: obj.action_title
- }
- else
- nil
- end
- }
+ calls_gitaly: true,
+ description: 'Action information for the status. This includes method, button title, icon, path, and title'
+
+ def action
+ if object.has_action?
+ {
+ button_title: object.action_button_title,
+ icon: object.action_icon,
+ method: object.action_method,
+ path: object.action_path,
+ title: object.action_title
+ }
+ else
+ nil
+ end
+ end
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/ci/group_type.rb b/app/graphql/types/ci/group_type.rb
index d930ae311b7..03fd50d5dbb 100644
--- a/app/graphql/types/ci/group_type.rb
+++ b/app/graphql/types/ci/group_type.rb
@@ -13,8 +13,11 @@ module Types
field :jobs, Ci::JobType.connection_type, null: true,
description: 'Jobs in group'
field :detailed_status, Types::Ci::DetailedStatusType, null: true,
- description: 'Detailed status of the group',
- resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
+ description: 'Detailed status of the group'
+
+ def detailed_status
+ object.detailed_status(context[:current_user])
+ end
end
end
end
diff --git a/app/graphql/types/ci/job_artifact_file_type_enum.rb b/app/graphql/types/ci/job_artifact_file_type_enum.rb
new file mode 100644
index 00000000000..4b484dec590
--- /dev/null
+++ b/app/graphql/types/ci/job_artifact_file_type_enum.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ class JobArtifactFileTypeEnum < BaseEnum
+ graphql_name 'JobArtifactFileType'
+
+ ::Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS.keys.each do |file_type|
+ value file_type.to_s.upcase, value: file_type.to_s
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/job_artifact_type.rb b/app/graphql/types/ci/job_artifact_type.rb
new file mode 100644
index 00000000000..c34a12dcc61
--- /dev/null
+++ b/app/graphql/types/ci/job_artifact_type.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ class JobArtifactType < BaseObject
+ graphql_name 'CiJobArtifact'
+
+ field :download_path, GraphQL::STRING_TYPE, null: true,
+ description: "URL for downloading the artifact's file"
+
+ field :file_type, ::Types::Ci::JobArtifactFileTypeEnum, null: true,
+ description: 'File type of the artifact'
+
+ def download_path
+ ::Gitlab::Routing.url_helpers.download_project_job_artifacts_path(
+ object.project,
+ object.job,
+ file_type: object.file_type
+ )
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index feaff4e81d8..5b6e8fe8567 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -6,18 +6,32 @@ module Types
class JobType < BaseObject
graphql_name 'CiJob'
- field :pipeline, Types::Ci::PipelineType, null: false,
- description: 'Pipeline the job belongs to',
- resolve: -> (build, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, build.pipeline_id).find }
+ field :pipeline, Types::Ci::PipelineType, null: true,
+ description: 'Pipeline the job belongs to'
field :name, GraphQL::STRING_TYPE, null: true,
- description: 'Name of the job'
+ description: 'Name of the job'
field :needs, JobType.connection_type, null: true,
- description: 'Builds that must complete before the jobs run'
+ description: 'Builds that must complete before the jobs run'
field :detailed_status, Types::Ci::DetailedStatusType, null: true,
- description: 'Detailed status of the job',
- resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
+ description: 'Detailed status of the job'
field :scheduled_at, Types::TimeType, null: true,
- description: 'Schedule for the build'
+ description: 'Schedule for the build'
+ field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true,
+ description: 'Artifacts generated by the job'
+
+ def pipeline
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, object.pipeline_id).find
+ end
+
+ def detailed_status
+ object.detailed_status(context[:current_user])
+ end
+
+ def artifacts
+ if object.is_a?(::Ci::Build)
+ object.job_artifacts
+ end
+ end
end
end
end
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index c25db39f600..4709d5e8dd6 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -27,8 +27,7 @@ module Types
description: "Status of the pipeline (#{::Ci::Pipeline.all_state_names.compact.join(', ').upcase})"
field :detailed_status, Types::Ci::DetailedStatusType, null: false,
- description: 'Detailed status of the pipeline',
- resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
+ description: 'Detailed status of the pipeline'
field :config_source, PipelineConfigSourceEnum, null: true,
description: "Config source of the pipeline (#{::Enums::Ci::Pipeline.config_sources.keys.join(', ').upcase})"
@@ -60,8 +59,7 @@ module Types
resolver: Resolvers::Ci::PipelineStagesResolver
field :user, Types::UserType, null: true,
- description: 'Pipeline user',
- resolve: -> (pipeline, _args, _context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, pipeline.user_id).find }
+ description: 'Pipeline user'
field :retryable, GraphQL::BOOLEAN_TYPE,
description: 'Specifies if a pipeline can be retried',
@@ -91,11 +89,25 @@ module Types
method: :triggered_by_pipeline
field :path, GraphQL::STRING_TYPE, null: true,
- description: "Relative path to the pipeline's page",
- resolve: -> (obj, _args, _ctx) { ::Gitlab::Routing.url_helpers.project_pipeline_path(obj.project, obj) }
+ description: "Relative path to the pipeline's page"
field :project, Types::ProjectType, null: true,
description: 'Project the pipeline belongs to'
+
+ field :active, GraphQL::BOOLEAN_TYPE, null: false, method: :active?,
+ description: 'Indicates if the pipeline is active'
+
+ def detailed_status
+ object.detailed_status(context[:current_user])
+ end
+
+ def user
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
+ end
+
+ def path
+ ::Gitlab::Routing.url_helpers.project_pipeline_path(object.project, object)
+ end
end
end
end
diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb
index fc2c72d0d06..fd0bde90836 100644
--- a/app/graphql/types/ci/stage_type.rb
+++ b/app/graphql/types/ci/stage_type.rb
@@ -11,8 +11,11 @@ module Types
field :groups, Ci::GroupType.connection_type, null: true,
description: 'Group of jobs for the stage'
field :detailed_status, Types::Ci::DetailedStatusType, null: true,
- description: 'Detailed status of the stage',
- resolve: -> (obj, _args, ctx) { obj.detailed_status(ctx[:current_user]) }
+ description: 'Detailed status of the stage'
+
+ def detailed_status
+ object.detailed_status(context[:current_user])
+ end
end
end
end
diff --git a/app/graphql/types/commit_type.rb b/app/graphql/types/commit_type.rb
index c24b47f08ef..37d19b4148b 100644
--- a/app/graphql/types/commit_type.rb
+++ b/app/graphql/types/commit_type.rb
@@ -12,6 +12,8 @@ module Types
description: 'ID (global ID) of the commit'
field :sha, type: GraphQL::STRING_TYPE, null: false,
description: 'SHA1 ID of the commit'
+ field :short_id, type: GraphQL::STRING_TYPE, null: false,
+ description: 'Short SHA1 ID of the commit'
field :title, type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true,
description: 'Title of the commit message'
markdown_field :title_html, null: true
@@ -31,10 +33,7 @@ module Types
field :author_name, type: GraphQL::STRING_TYPE, null: true,
description: 'Commit authors name'
field :author_gravatar, type: GraphQL::STRING_TYPE, null: true,
- description: 'Commit authors gravatar',
- resolve: -> (commit, args, context) do
- GravatarService.new.execute(commit.author_email, 40)
- end
+ description: 'Commit authors gravatar'
# models/commit lazy loads the author by email
field :author, type: Types::UserType, null: true,
@@ -44,5 +43,9 @@ module Types
null: true,
description: 'Pipelines of the commit ordered latest first',
resolver: Resolvers::CommitPipelinesResolver
+
+ def author_gravatar
+ GravatarService.new.execute(object.author_email, 40)
+ end
end
end
diff --git a/app/graphql/types/concerns/gitlab_style_deprecations.rb b/app/graphql/types/concerns/gitlab_style_deprecations.rb
index 2c932f4214b..9f087f3812d 100644
--- a/app/graphql/types/concerns/gitlab_style_deprecations.rb
+++ b/app/graphql/types/concerns/gitlab_style_deprecations.rb
@@ -23,8 +23,8 @@ module GitlabStyleDeprecations
raise ArgumentError, '`milestone` must be a `String`' unless milestone.is_a?(String)
deprecated_in = "Deprecated in #{milestone}"
- kwargs[:deprecation_reason] = "#{reason}. #{deprecated_in}"
- kwargs[:description] += ". #{deprecated_in}: #{reason}" if kwargs[:description]
+ kwargs[:deprecation_reason] = "#{reason}. #{deprecated_in}."
+ kwargs[:description] += " #{deprecated_in}: #{reason}." if kwargs[:description]
kwargs
end
diff --git a/app/graphql/types/container_repository_type.rb b/app/graphql/types/container_repository_type.rb
index 45d19fdbc50..8735f8a173d 100644
--- a/app/graphql/types/container_repository_type.rb
+++ b/app/graphql/types/container_repository_type.rb
@@ -19,9 +19,14 @@ module Types
field :status, Types::ContainerRepositoryStatusEnum, null: true, description: 'Status of the container repository.'
field :tags_count, GraphQL::INT_TYPE, null: false, description: 'Number of tags associated with this image.'
field :can_delete, GraphQL::BOOLEAN_TYPE, null: false, description: 'Can the current user delete the container repository.'
+ field :project, Types::ProjectType, null: false, description: 'Project of the container registry'
def can_delete
Ability.allowed?(current_user, :update_container_image, object)
end
+
+ def project
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
+ end
end
end
diff --git a/app/graphql/types/design_management/design_collection_type.rb b/app/graphql/types/design_management/design_collection_type.rb
index 9af1f4db425..26fbac15b30 100644
--- a/app/graphql/types/design_management/design_collection_type.rb
+++ b/app/graphql/types/design_management/design_collection_type.rb
@@ -2,7 +2,7 @@
module Types
module DesignManagement
- class DesignCollectionType < BaseObject
+ class DesignCollectionType < ::Types::BaseObject
graphql_name 'DesignCollection'
description 'A collection of designs'
diff --git a/app/graphql/types/error_tracking/sentry_error_collection_type.rb b/app/graphql/types/error_tracking/sentry_error_collection_type.rb
index 798e0433d06..49d5d62c860 100644
--- a/app/graphql/types/error_tracking/sentry_error_collection_type.rb
+++ b/app/graphql/types/error_tracking/sentry_error_collection_type.rb
@@ -9,27 +9,12 @@ module Types
authorize :read_sentry_issue
field :errors,
- Types::ErrorTracking::SentryErrorType.connection_type,
- connection: false,
- null: true,
description: "Collection of Sentry Errors",
- extensions: [Gitlab::Graphql::Extensions::ExternallyPaginatedArrayExtension],
- resolver: Resolvers::ErrorTracking::SentryErrorsResolver do
- argument :search_term,
- String,
- description: 'Search query for the Sentry error details',
- required: false
- argument :sort,
- String,
- description: 'Attribute to sort on. Options are frequency, first_seen, last_seen. last_seen is default',
- required: false
- end
- field :detailed_error, Types::ErrorTracking::SentryDetailedErrorType,
- null: true,
+ resolver: Resolvers::ErrorTracking::SentryErrorsResolver
+ field :detailed_error,
description: 'Detailed version of a Sentry error on the project',
resolver: Resolvers::ErrorTracking::SentryDetailedErrorResolver
- field :error_stack_trace, Types::ErrorTracking::SentryErrorStackTraceType,
- null: true,
+ field :error_stack_trace,
description: 'Stack Trace of Sentry Error',
resolver: Resolvers::ErrorTracking::SentryErrorStackTraceResolver
field :external_url,
diff --git a/app/graphql/types/group_invitation_type.rb b/app/graphql/types/group_invitation_type.rb
index 0372ce178ff..efb0c8a41c8 100644
--- a/app/graphql/types/group_invitation_type.rb
+++ b/app/graphql/types/group_invitation_type.rb
@@ -11,7 +11,10 @@ module Types
description 'Represents a Group Invitation'
field :group, Types::GroupType, null: true,
- description: 'Group that a User is invited to',
- resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.source_id).find }
+ description: 'Group that a User is invited to'
+
+ def group
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find
+ end
end
end
diff --git a/app/graphql/types/group_member_relation_enum.rb b/app/graphql/types/group_member_relation_enum.rb
new file mode 100644
index 00000000000..aa2e73d4944
--- /dev/null
+++ b/app/graphql/types/group_member_relation_enum.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class GroupMemberRelationEnum < BaseEnum
+ graphql_name 'GroupMemberRelation'
+ description 'Group member relation'
+
+ ::GroupMembersFinder::RELATIONS.each do |member_relation|
+ value member_relation.to_s.upcase, value: member_relation, description: "#{member_relation.to_s.titleize} members"
+ end
+ end
+end
diff --git a/app/graphql/types/group_member_type.rb b/app/graphql/types/group_member_type.rb
index 6cca0a50647..204da5a302a 100644
--- a/app/graphql/types/group_member_type.rb
+++ b/app/graphql/types/group_member_type.rb
@@ -11,7 +11,10 @@ module Types
description 'Represents a Group Membership'
field :group, Types::GroupType, null: true,
- description: 'Group that a User is a member of',
- resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.source_id).find }
+ description: 'Group that a User is a member of'
+
+ def group
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find
+ end
end
end
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index fb028184488..0ee8a19c1a3 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -12,10 +12,7 @@ module Types
description: 'Web URL of the group'
field :avatar_url, GraphQL::STRING_TYPE, null: true,
- description: 'Avatar URL of the group',
- resolve: -> (group, args, ctx) do
- group.avatar_url(only_path: false)
- end
+ description: 'Avatar URL of the group'
field :custom_emoji, Types::CustomEmojiType.connection_type, null: true,
description: 'Custom emoji within this namespace',
@@ -44,8 +41,7 @@ module Types
description: 'Indicates if a group is disabled from getting mentioned'
field :parent, GroupType, null: true,
- description: 'Parent group',
- resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.parent_id).find }
+ description: 'Parent group'
field :issues,
Types::IssueType.connection_type,
@@ -92,10 +88,13 @@ module Types
field :container_repositories,
Types::ContainerRepositoryType.connection_type,
null: true,
- description: 'Container repositories of the project',
+ description: 'Container repositories of the group',
resolver: Resolvers::ContainerRepositoriesResolver,
authorize: :read_container_image
+ field :container_repositories_count, GraphQL::INT_TYPE, null: false,
+ description: 'Number of container repositories in the group'
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
LabelsFinder
@@ -120,6 +119,18 @@ module Types
.execute
end
+ def avatar_url
+ object.avatar_url(only_path: false)
+ end
+
+ def parent
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.parent_id).find
+ end
+
+ def container_repositories_count
+ group.container_repositories.size
+ end
+
private
def group
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 49c84f75e1a..83b8a834801 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -61,9 +61,11 @@ module Types
field :downvotes, GraphQL::INT_TYPE, null: false,
description: 'Number of downvotes the issue has received'
field :user_notes_count, GraphQL::INT_TYPE, null: false,
- description: 'Number of user notes of the issue'
+ description: 'Number of user notes of the issue',
+ resolver: Resolvers::UserNotesCountResolver
field :user_discussions_count, GraphQL::INT_TYPE, null: false,
- description: 'Number of user discussions in the issue'
+ description: 'Number of user discussions in the issue',
+ resolver: Resolvers::UserDiscussionsCountResolver
field :web_path, GraphQL::STRING_TYPE, null: false, method: :issue_path,
description: 'Web path of the issue'
field :web_url, GraphQL::STRING_TYPE, null: false,
@@ -119,26 +121,6 @@ module Types
field :moved_to, Types::IssueType, null: true,
description: 'Updated Issue after it got moved to another project'
- def user_notes_count
- BatchLoader::GraphQL.for(object.id).batch(key: :issue_user_notes_count) do |ids, loader, args|
- counts = Note.count_for_collection(ids, 'Issue').index_by(&:noteable_id)
-
- ids.each do |id|
- loader.call(id, counts[id]&.count || 0)
- end
- end
- end
-
- def user_discussions_count
- BatchLoader::GraphQL.for(object.id).batch(key: :issue_user_discussions_count) do |ids, loader, args|
- counts = Note.count_for_collection(ids, 'Issue', 'COUNT(DISTINCT discussion_id) as count').index_by(&:noteable_id)
-
- ids.each do |id|
- loader.call(id, counts[id]&.count || 0)
- end
- end
- end
-
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
diff --git a/app/graphql/types/jira_import_type.rb b/app/graphql/types/jira_import_type.rb
index cf58a53b40d..b3854487cec 100644
--- a/app/graphql/types/jira_import_type.rb
+++ b/app/graphql/types/jira_import_type.rb
@@ -2,8 +2,7 @@
module Types
# rubocop: disable Graphql/AuthorizeTypes
- # Authorization is at project level for owners or admins,
- # so it is added directly to the Resolvers::JiraImportsResolver
+ # Authorization is at project level for owners or admins
class JiraImportType < BaseObject
graphql_name 'JiraImport'
diff --git a/app/graphql/types/jira_users_mapping_input_type.rb b/app/graphql/types/jira_users_mapping_input_type.rb
index 61cf1474493..d5b4b2f618a 100644
--- a/app/graphql/types/jira_users_mapping_input_type.rb
+++ b/app/graphql/types/jira_users_mapping_input_type.rb
@@ -8,7 +8,7 @@ module Types
argument :jira_account_id,
GraphQL::STRING_TYPE,
required: true,
- description: 'Jira account id of the user'
+ description: 'Jira account ID of the user'
argument :gitlab_id,
GraphQL::INT_TYPE,
required: false,
diff --git a/app/graphql/types/merge_request_connection_type.rb b/app/graphql/types/merge_request_connection_type.rb
new file mode 100644
index 00000000000..da06bb86929
--- /dev/null
+++ b/app/graphql/types/merge_request_connection_type.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop: disable Graphql/AuthorizeTypes
+ class MergeRequestConnectionType < Types::CountableConnectionType
+ field :total_time_to_merge, GraphQL::FLOAT_TYPE, null: true,
+ description: 'Total sum of time to merge, in seconds, for the collection of merge requests'
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def total_time_to_merge
+ object.items.reorder(nil).total_time_to_merge
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+end
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index e68d6706c43..816160e58f7 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -4,7 +4,7 @@ module Types
class MergeRequestType < BaseObject
graphql_name 'MergeRequest'
- connection_type_class(Types::CountableConnectionType)
+ connection_type_class(Types::MergeRequestConnectionType)
implements(Types::Notes::NoteableType)
implements(Types::CurrentUserTodos)
@@ -49,6 +49,8 @@ module Types
description: 'ID of the merge request target project'
field :source_branch, GraphQL::STRING_TYPE, null: false,
description: 'Source branch of the merge request'
+ field :source_branch_protected, GraphQL::BOOLEAN_TYPE, null: false, calls_gitaly: true,
+ description: 'Indicates if the source branch is protected'
field :target_branch, GraphQL::STRING_TYPE, null: false,
description: 'Target branch of the merge request'
field :work_in_progress, GraphQL::BOOLEAN_TYPE, method: :work_in_progress?, null: false,
@@ -67,9 +69,11 @@ module Types
field :merge_commit_sha, GraphQL::STRING_TYPE, null: true,
description: 'SHA of the merge request commit (set once merged)'
field :user_notes_count, GraphQL::INT_TYPE, null: true,
- description: 'User notes count of the merge request'
+ description: 'User notes count of the merge request',
+ resolver: Resolvers::UserNotesCountResolver
field :user_discussions_count, GraphQL::INT_TYPE, null: true,
- description: 'Number of user discussions in the merge request'
+ description: 'Number of user discussions in the merge request',
+ resolver: Resolvers::UserDiscussionsCountResolver
field :should_remove_source_branch, GraphQL::BOOLEAN_TYPE, method: :should_remove_source_branch?, null: true,
description: 'Indicates if the source branch of the merge request will be deleted after merge'
field :force_remove_source_branch, GraphQL::BOOLEAN_TYPE, method: :force_remove_source_branch?, null: true,
@@ -90,6 +94,8 @@ module Types
description: 'Indicates if there is a rebase currently in progress for the merge request'
field :default_merge_commit_message, GraphQL::STRING_TYPE, null: true,
description: 'Default merge commit message of the merge request'
+ field :default_merge_commit_message_with_description, GraphQL::STRING_TYPE, null: true,
+ description: 'Default merge commit message of the merge request with description'
field :merge_ongoing, GraphQL::BOOLEAN_TYPE, method: :merge_ongoing?, null: false,
description: 'Indicates if a merge is currently occurring'
field :source_branch_exists, GraphQL::BOOLEAN_TYPE,
@@ -113,7 +119,7 @@ module Types
description: 'The pipeline running on the branch HEAD of the merge request'
field :pipelines,
null: true,
- description: 'Pipelines for the merge request',
+ description: 'Pipelines for the merge request. Note: for performance reasons, no more than the most recent 500 pipelines will be returned.',
resolver: Resolvers::MergeRequestPipelinesResolver
field :milestone, Types::MilestoneType, null: true,
@@ -130,8 +136,7 @@ module Types
description: 'Labels of the merge request'
field :discussion_locked, GraphQL::BOOLEAN_TYPE,
description: 'Indicates if comments on the merge request are locked to members only',
- null: false,
- resolve: -> (obj, _args, _ctx) { !!obj.discussion_locked }
+ null: false
field :time_estimate, GraphQL::INT_TYPE, null: false,
description: 'Time estimate of the merge request'
field :total_time_spent, GraphQL::INT_TYPE, null: false,
@@ -152,6 +157,18 @@ module Types
field :approved_by, Types::UserType.connection_type, null: true,
description: 'Users who approved the merge request'
+ field :squash_on_merge, GraphQL::BOOLEAN_TYPE, null: false, method: :squash_on_merge?,
+ description: 'Indicates if squash on merge is enabled'
+ field :available_auto_merge_strategies, [GraphQL::STRING_TYPE], null: true, calls_gitaly: true,
+ description: 'Array of available auto merge strategies'
+ field :has_ci, GraphQL::BOOLEAN_TYPE, null: false, method: :has_ci?,
+ description: 'Indicates if the merge request has CI'
+ field :mergeable, GraphQL::BOOLEAN_TYPE, null: false, method: :mergeable?, calls_gitaly: true,
+ description: 'Indicates if the merge request is mergeable'
+ field :commits_without_merge_commits, Types::CommitType.connection_type, null: true,
+ calls_gitaly: true, description: 'Merge request commits excluding merge commits'
+ field :security_auto_fix, GraphQL::BOOLEAN_TYPE, null: true,
+ description: 'Indicates if the merge request is created by @GitLab-Security-Bot.'
def approved_by
object.approved_by_users
@@ -194,6 +211,31 @@ module Types
def commit_count
object&.metrics&.commits_count
end
+
+ def source_branch_protected
+ object.source_project.present? && ProtectedBranch.protected?(object.source_project, object.source_branch)
+ end
+
+ def discussion_locked
+ !!object.discussion_locked
+ end
+
+ def default_merge_commit_message_with_description
+ object.default_merge_commit_message(include_description: true)
+ end
+
+ def available_auto_merge_strategies
+ AutoMergeService.new(object.project, current_user).available_strategies(object)
+ end
+
+ def commits_without_merge_commits
+ object.recent_commits.without_merge_commits
+ end
+
+ def security_auto_fix
+ object.author == User.security_bot
+ end
end
end
+
Types::MergeRequestType.prepend_if_ee('::EE::Types::MergeRequestType')
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 75ccac6d590..9eea81c9d3e 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -31,6 +31,7 @@ module Types
mount_mutation Mutations::Commits::Create, calls_gitaly: true
mount_mutation Mutations::CustomEmoji::Create, feature_flag: :custom_emoji
mount_mutation Mutations::Discussions::ToggleResolve
+ mount_mutation Mutations::Environments::CanaryIngress::Update
mount_mutation Mutations::Issues::Create
mount_mutation Mutations::Issues::SetAssignees
mount_mutation Mutations::Issues::SetConfidential
@@ -65,6 +66,8 @@ module Types
mount_mutation Mutations::Notes::RepositionImageDiffNote
mount_mutation Mutations::Notes::Destroy
mount_mutation Mutations::Releases::Create
+ mount_mutation Mutations::Releases::Update
+ mount_mutation Mutations::Releases::Delete
mount_mutation Mutations::Terraform::State::Delete
mount_mutation Mutations::Terraform::State::Lock
mount_mutation Mutations::Terraform::State::Unlock
@@ -84,6 +87,7 @@ module Types
mount_mutation Mutations::DesignManagement::Move
mount_mutation Mutations::ContainerExpirationPolicies::Update
mount_mutation Mutations::ContainerRepositories::Destroy
+ mount_mutation Mutations::ContainerRepositories::DestroyTags
mount_mutation Mutations::Ci::PipelineCancel
mount_mutation Mutations::Ci::PipelineDestroy
mount_mutation Mutations::Ci::PipelineRetry
diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb
index fbdf049b755..4dec6f4c5e6 100644
--- a/app/graphql/types/namespace_type.rb
+++ b/app/graphql/types/namespace_type.rb
@@ -21,6 +21,7 @@ module Types
field :description, GraphQL::STRING_TYPE, null: true,
description: 'Description of the namespace'
markdown_field :description_html, null: true
+
field :visibility, GraphQL::STRING_TYPE, null: true,
description: 'Visibility of the namespace'
field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true, method: :lfs_enabled?,
@@ -30,12 +31,15 @@ module Types
field :root_storage_statistics, Types::RootStorageStatisticsType,
null: true,
- description: 'Aggregated storage statistics of the namespace. Only available for root namespaces',
- resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(obj.id).find }
+ description: 'Aggregated storage statistics of the namespace. Only available for root namespaces'
field :projects, Types::ProjectType.connection_type, null: false,
description: 'Projects within this namespace',
resolver: ::Resolvers::NamespaceProjectsResolver
+
+ def root_storage_statistics
+ Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(object.id).find
+ end
end
end
diff --git a/app/graphql/types/notes/diff_position_type.rb b/app/graphql/types/notes/diff_position_type.rb
index cc00feba2e6..13d9be49484 100644
--- a/app/graphql/types/notes/diff_position_type.rb
+++ b/app/graphql/types/notes/diff_position_type.rb
@@ -21,25 +21,43 @@ module Types
# Fields for text positions
field :old_line, GraphQL::INT_TYPE, null: true,
- description: 'Line on start SHA that was changed',
- resolve: -> (position, _args, _ctx) { position.old_line if position.on_text? }
+ description: 'Line on start SHA that was changed'
field :new_line, GraphQL::INT_TYPE, null: true,
- description: 'Line on HEAD SHA that was changed',
- resolve: -> (position, _args, _ctx) { position.new_line if position.on_text? }
+ description: 'Line on HEAD SHA that was changed'
# Fields for image positions
field :x, GraphQL::INT_TYPE, null: true,
- description: 'X position of the note',
- resolve: -> (position, _args, _ctx) { position.x if position.on_image? }
+ description: 'X position of the note'
field :y, GraphQL::INT_TYPE, null: true,
- description: 'Y position of the note',
- resolve: -> (position, _args, _ctx) { position.y if position.on_image? }
+ description: 'Y position of the note'
field :width, GraphQL::INT_TYPE, null: true,
- description: 'Total width of the image',
- resolve: -> (position, _args, _ctx) { position.width if position.on_image? }
+ description: 'Total width of the image'
field :height, GraphQL::INT_TYPE, null: true,
- description: 'Total height of the image',
- resolve: -> (position, _args, _ctx) { position.height if position.on_image? }
+ description: 'Total height of the image'
+
+ def old_line
+ object.old_line if object.on_text?
+ end
+
+ def new_line
+ object.new_line if object.on_text?
+ end
+
+ def x
+ object.x if object.on_image?
+ end
+
+ def y
+ object.y if object.on_image?
+ end
+
+ def width
+ object.width if object.on_image?
+ end
+
+ def height
+ object.height if object.on_image?
+ end
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb
index 5d41f0032bd..f4e05e19eca 100644
--- a/app/graphql/types/notes/note_type.rb
+++ b/app/graphql/types/notes/note_type.rb
@@ -16,13 +16,11 @@ module Types
field :project, Types::ProjectType,
null: true,
- description: 'Project associated with the note',
- resolve: -> (note, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, note.project_id).find }
+ description: 'Project associated with the note'
field :author, Types::UserType,
null: false,
- description: 'User who wrote this note',
- resolve: -> (note, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, note.author_id).find }
+ description: 'User who wrote this note'
field :system, GraphQL::BOOLEAN_TYPE,
null: false,
@@ -52,6 +50,14 @@ module Types
def system_note_icon_name
SystemNoteHelper.system_note_icon_name(object) if object.system?
end
+
+ def project
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
+ end
+
+ def author
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
+ end
end
end
end
diff --git a/app/graphql/types/permission_types/merge_request.rb b/app/graphql/types/permission_types/merge_request.rb
index e9c89b0c92e..52c11fe5588 100644
--- a/app/graphql/types/permission_types/merge_request.rb
+++ b/app/graphql/types/permission_types/merge_request.rb
@@ -19,7 +19,9 @@ module Types
permission_field field_name, method: :"can_#{field_name}?", calls_gitaly: true
end
- permission_field :can_merge, calls_gitaly: true, resolve: -> (object, args, context) do
+ permission_field :can_merge, calls_gitaly: true
+
+ def can_merge
object.can_be_merged_by?(context[:current_user])
end
end
diff --git a/app/graphql/types/project_member_relation_enum.rb b/app/graphql/types/project_member_relation_enum.rb
new file mode 100644
index 00000000000..fbad23b956f
--- /dev/null
+++ b/app/graphql/types/project_member_relation_enum.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class ProjectMemberRelationEnum < BaseEnum
+ graphql_name 'ProjectMemberRelation'
+ description 'Project member relation'
+
+ ::MembersFinder::RELATIONS.each do |member_relation|
+ value member_relation.to_s.upcase, value: member_relation, description: "#{member_relation.to_s.titleize} members"
+ end
+ end
+end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 5a436886117..a7d9548610e 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -67,33 +67,25 @@ module Types
description: 'E-mail address of the service desk.'
field :avatar_url, GraphQL::STRING_TYPE, null: true, calls_gitaly: true,
- description: 'URL to avatar image file of the project',
- resolve: -> (project, args, ctx) do
- project.avatar_url(only_path: false)
- end
+ description: 'URL to avatar image file of the project'
%i[issues merge_requests wiki snippets].each do |feature|
field "#{feature}_enabled", GraphQL::BOOLEAN_TYPE, null: true,
- description: "Indicates if #{feature.to_s.titleize.pluralize} are enabled for the current user",
- resolve: -> (project, args, ctx) do
- project.feature_available?(feature, ctx[:current_user])
- end
+ description: "Indicates if #{feature.to_s.titleize.pluralize} are enabled for the current user"
+
+ define_method "#{feature}_enabled" do
+ object.feature_available?(feature, context[:current_user])
+ end
end
field :jobs_enabled, GraphQL::BOOLEAN_TYPE, null: true,
- description: 'Indicates if CI/CD pipeline jobs are enabled for the current user',
- resolve: -> (project, args, ctx) do
- project.feature_available?(:builds, ctx[:current_user])
- end
+ description: 'Indicates if CI/CD pipeline jobs are enabled for the current user'
field :public_jobs, GraphQL::BOOLEAN_TYPE, method: :public_builds, null: true,
description: 'Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts'
field :open_issues_count, GraphQL::INT_TYPE, null: true,
- description: 'Number of open issues for the project',
- resolve: -> (project, args, ctx) do
- project.open_issues_count if project.feature_available?(:issues, ctx[:current_user])
- end
+ description: 'Number of open issues for the project'
field :import_status, GraphQL::STRING_TYPE, null: true,
description: 'Status of import background job of the project'
@@ -115,6 +107,8 @@ module Types
description: 'Indicates if issues referenced by merge requests and commits within the default branch are closed automatically'
field :suggestion_commit_message, GraphQL::STRING_TYPE, null: true,
description: 'The commit message used to apply merge request suggestions'
+ field :squash_read_only, GraphQL::BOOLEAN_TYPE, null: false, method: :squash_readonly?,
+ description: 'Indicates if squash readonly is enabled'
field :namespace, Types::NamespaceType, null: true,
description: 'Namespace of the project'
@@ -123,8 +117,7 @@ module Types
field :statistics, Types::ProjectStatisticsType,
null: true,
- description: 'Statistics of the project',
- resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchProjectStatisticsLoader.new(obj.id).find }
+ description: 'Statistics of the project'
field :repository, Types::RepositoryType, null: true,
description: 'Git repository of the project'
@@ -198,6 +191,11 @@ module Types
description: 'Build pipeline of the project',
resolver: Resolvers::ProjectPipelineResolver
+ field :ci_cd_settings,
+ Types::Ci::CiCdSettingType,
+ null: true,
+ description: 'CI/CD settings for the project'
+
field :sentry_detailed_error,
Types::ErrorTracking::SentryDetailedErrorType,
null: true,
@@ -238,8 +236,7 @@ module Types
field :jira_imports,
Types::JiraImportType.connection_type,
null: true,
- description: 'Jira imports into the project',
- resolver: Resolvers::Projects::JiraImportsResolver
+ description: 'Jira imports into the project'
field :services,
Types::Projects::ServiceType.connection_type,
@@ -296,6 +293,9 @@ module Types
description: 'Container repositories of the project',
resolver: Resolvers::ContainerRepositoriesResolver
+ field :container_repositories_count, GraphQL::INT_TYPE, null: false,
+ description: 'Number of container repositories in the project'
+
field :label,
Types::LabelType,
null: true,
@@ -311,6 +311,13 @@ module Types
description: 'Terraform states associated with the project',
resolver: Resolvers::Terraform::StatesResolver
+ field :pipeline_analytics, Types::Ci::AnalyticsType, null: true,
+ description: 'Pipeline analytics',
+ resolver: Resolvers::ProjectPipelineStatisticsResolver
+
+ field :total_pipeline_duration, GraphQL::INT_TYPE, null: true,
+ description: 'Total pipeline duration for all of the pipelines in a project'
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args|
LabelsFinder
@@ -335,6 +342,30 @@ module Types
.execute
end
+ def avatar_url
+ object.avatar_url(only_path: false)
+ end
+
+ def jobs_enabled
+ object.feature_available?(:builds, context[:current_user])
+ end
+
+ def open_issues_count
+ object.open_issues_count if object.feature_available?(:issues, context[:current_user])
+ end
+
+ def statistics
+ Gitlab::Graphql::Loaders::BatchProjectStatisticsLoader.new(object.id).find
+ end
+
+ def container_repositories_count
+ project.container_repositories.size
+ end
+
+ def total_pipeline_duration
+ object.all_pipelines.total_duration
+ end
+
private
def project
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index d194b0979b3..05bb371088c 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -24,7 +24,6 @@ module Types
field :current_user, Types::UserType,
null: true,
- resolve: -> (_obj, _args, context) { context[:current_user] },
description: "Get information about current user"
field :namespace, Types::NamespaceType,
@@ -92,6 +91,11 @@ module Types
description: 'Get runner setup instructions',
resolver: Resolvers::Ci::RunnerSetupResolver
+ field :ci_config, Types::Ci::Config::ConfigType, null: true,
+ description: 'Get linted and processed contents of a CI config. Should not be requested more than once per request.',
+ resolver: Resolvers::Ci::ConfigResolver,
+ complexity: 126 # AUTHENTICATED_COMPLEXITY / 2 + 1
+
def design_management
DesignManagementObject.new(nil)
end
@@ -116,6 +120,10 @@ module Types
id = ::Types::GlobalIDType[::ContainerRepository].coerce_isolated_input(id)
GitlabSchema.find_by_gid(id)
end
+
+ def current_user
+ context[:current_user]
+ end
end
end
diff --git a/app/graphql/types/snippets/blob_viewer_type.rb b/app/graphql/types/snippets/blob_viewer_type.rb
index 50d0b0522d6..a2ffa144066 100644
--- a/app/graphql/types/snippets/blob_viewer_type.rb
+++ b/app/graphql/types/snippets/blob_viewer_type.rb
@@ -17,14 +17,12 @@ module Types
field :collapsed, GraphQL::BOOLEAN_TYPE,
description: 'Shows whether the blob should be displayed collapsed',
method: :collapsed?,
- null: false,
- resolve: -> (viewer, _args, _ctx) { !!viewer&.collapsed? }
+ null: false
field :too_large, GraphQL::BOOLEAN_TYPE,
description: 'Shows whether the blob too large to be displayed',
method: :too_large?,
- null: false,
- resolve: -> (viewer, _args, _ctx) { !!viewer&.too_large? }
+ null: false
field :render_error, GraphQL::STRING_TYPE,
description: 'Error rendering the blob content',
@@ -38,6 +36,14 @@ module Types
field :loading_partial_name, GraphQL::STRING_TYPE,
description: 'Loading partial name',
null: false
+
+ def collapsed
+ !!object&.collapsed?
+ end
+
+ def too_large
+ !!object&.too_large?
+ end
end
end
end
diff --git a/app/graphql/types/sort_enum.rb b/app/graphql/types/sort_enum.rb
index d0a6eecb672..c3a76330fe9 100644
--- a/app/graphql/types/sort_enum.rb
+++ b/app/graphql/types/sort_enum.rb
@@ -7,10 +7,10 @@ module Types
# Deprecated, as we prefer uppercase enums
# https://gitlab.com/groups/gitlab-org/-/epics/1838
- value 'updated_desc', 'Updated at descending order', deprecated: { reason: 'Use UPDATED_DESC', milestone: '13.5' }
- value 'updated_asc', 'Updated at ascending order', deprecated: { reason: 'Use UPDATED_ASC', milestone: '13.5' }
- value 'created_desc', 'Created at descending order', deprecated: { reason: 'Use CREATED_DESC', milestone: '13.5' }
- value 'created_asc', 'Created at ascending order', deprecated: { reason: 'Use CREATED_ASC', milestone: '13.5' }
+ value 'updated_desc', 'Updated at descending order', value: :updated_desc, deprecated: { reason: 'Use UPDATED_DESC', milestone: '13.5' }
+ value 'updated_asc', 'Updated at ascending order', value: :updated_asc, deprecated: { reason: 'Use UPDATED_ASC', milestone: '13.5' }
+ value 'created_desc', 'Created at descending order', value: :created_desc, deprecated: { reason: 'Use CREATED_DESC', milestone: '13.5' }
+ value 'created_asc', 'Created at ascending order', value: :created_asc, deprecated: { reason: 'Use CREATED_ASC', milestone: '13.5' }
value 'UPDATED_DESC', 'Updated at descending order', value: :updated_desc
value 'UPDATED_ASC', 'Updated at ascending order', value: :updated_asc
diff --git a/app/graphql/types/terraform/state_type.rb b/app/graphql/types/terraform/state_type.rb
index 05b6d130f19..d97e673bf31 100644
--- a/app/graphql/types/terraform/state_type.rb
+++ b/app/graphql/types/terraform/state_type.rb
@@ -19,9 +19,7 @@ module Types
field :locked_by_user, Types::UserType,
null: true,
- authorize: :read_user,
- description: 'The user currently holding a lock on the Terraform state',
- resolve: -> (state, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, state.locked_by_user_id).find }
+ description: 'The user currently holding a lock on the Terraform state'
field :locked_at, Types::TimeType,
null: true,
@@ -39,6 +37,10 @@ module Types
field :updated_at, Types::TimeType,
null: false,
description: 'Timestamp the Terraform state was updated'
+
+ def locked_by_user
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.locked_by_user_id).find
+ end
end
end
end
diff --git a/app/graphql/types/terraform/state_version_type.rb b/app/graphql/types/terraform/state_version_type.rb
index b1fbe42ecaf..a3af5c876ca 100644
--- a/app/graphql/types/terraform/state_version_type.rb
+++ b/app/graphql/types/terraform/state_version_type.rb
@@ -3,6 +3,8 @@
module Types
module Terraform
class StateVersionType < BaseObject
+ include ::API::Helpers::RelatedResourcesHelpers
+
graphql_name 'TerraformStateVersion'
authorize :read_terraform_state
@@ -13,15 +15,20 @@ module Types
field :created_by_user, Types::UserType,
null: true,
- authorize: :read_user,
- description: 'The user that created this version',
- resolve: -> (version, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, version.created_by_user_id).find }
+ description: 'The user that created this version'
+
+ field :download_path, GraphQL::STRING_TYPE,
+ null: true,
+ description: "URL for downloading the version's JSON file"
field :job, Types::Ci::JobType,
null: true,
- authorize: :read_build,
- description: 'The job that created this version',
- resolve: -> (version, _, _) { Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Build, version.ci_build_id).find }
+ description: 'The job that created this version'
+
+ field :serial, GraphQL::INT_TYPE,
+ null: true,
+ description: 'Serial number of the version',
+ method: :version
field :created_at, Types::TimeType,
null: false,
@@ -30,6 +37,22 @@ module Types
field :updated_at, Types::TimeType,
null: false,
description: 'Timestamp the version was updated'
+
+ def created_by_user
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.created_by_user_id).find
+ end
+
+ def download_path
+ expose_path api_v4_projects_terraform_state_versions_path(
+ id: object.project_id,
+ name: object.terraform_state.name,
+ serial: object.version
+ )
+ end
+
+ def job
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Build, object.ci_build_id).find
+ end
end
end
end
diff --git a/app/graphql/types/todo_type.rb b/app/graphql/types/todo_type.rb
index 4f21da3d897..3694980ef93 100644
--- a/app/graphql/types/todo_type.rb
+++ b/app/graphql/types/todo_type.rb
@@ -16,19 +16,16 @@ module Types
field :project, Types::ProjectType,
description: 'The project this todo is associated with',
null: true,
- authorize: :read_project,
- resolve: -> (todo, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, todo.project_id).find }
+ authorize: :read_project
field :group, Types::GroupType,
description: 'Group this todo is associated with',
null: true,
- authorize: :read_group,
- resolve: -> (todo, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, todo.group_id).find }
+ authorize: :read_group
field :author, Types::UserType,
description: 'The author of this todo',
- null: false,
- resolve: -> (todo, args, context) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, todo.author_id).find }
+ null: false
field :action, Types::TodoActionEnum,
description: 'Action of the todo',
@@ -50,5 +47,17 @@ module Types
field :created_at, Types::TimeType,
description: 'Timestamp this todo was created',
null: false
+
+ def project
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
+ end
+
+ def group
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.group_id).find
+ end
+
+ def author
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
+ end
end
end
diff --git a/app/graphql/types/tree/blob_type.rb b/app/graphql/types/tree/blob_type.rb
index cc6bf7b4f00..a7b90d2533b 100644
--- a/app/graphql/types/tree/blob_type.rb
+++ b/app/graphql/types/tree/blob_type.rb
@@ -15,13 +15,14 @@ module Types
field :web_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path of the blob'
field :lfs_oid, GraphQL::STRING_TYPE, null: true,
- description: 'LFS ID of the blob',
- resolve: -> (blob, args, ctx) do
- Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(blob.repository, blob.id).find
- end
+ description: 'LFS ID of the blob'
field :mode, GraphQL::STRING_TYPE, null: true,
description: 'Blob mode in numeric format'
- # rubocop: enable Graphql/AuthorizeTypes
+
+ def lfs_oid
+ Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(object.repository, object.id).find
+ end
end
+ # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/tree/tree_type.rb b/app/graphql/types/tree/tree_type.rb
index b9fb6b28e71..fecd6c0f309 100644
--- a/app/graphql/types/tree/tree_type.rb
+++ b/app/graphql/types/tree/tree_type.rb
@@ -8,27 +8,32 @@ module Types
# Complexity 10 as it triggers a Gitaly call on each render
field :last_commit, Types::CommitType,
- null: true, complexity: 10, calls_gitaly: true, resolver: Resolvers::LastCommitResolver,
- description: 'Last commit for the tree'
+ null: true, complexity: 10, calls_gitaly: true, resolver: Resolvers::LastCommitResolver,
+ description: 'Last commit for the tree'
field :trees, Types::Tree::TreeEntryType.connection_type, null: false,
- description: 'Trees of the tree',
- resolve: -> (obj, args, ctx) do
- Gitlab::Graphql::Representation::TreeEntry.decorate(obj.trees, obj.repository)
- end
+ description: 'Trees of the tree'
field :submodules, Types::Tree::SubmoduleType.connection_type, null: false,
description: 'Sub-modules of the tree',
- calls_gitaly: true, resolve: -> (obj, args, ctx) do
- Gitlab::Graphql::Representation::SubmoduleTreeEntry.decorate(obj.submodules, obj)
- end
+ calls_gitaly: true
field :blobs, Types::Tree::BlobType.connection_type, null: false,
description: 'Blobs of the tree',
- calls_gitaly: true, resolve: -> (obj, args, ctx) do
- Gitlab::Graphql::Representation::TreeEntry.decorate(obj.blobs, obj.repository)
- end
- # rubocop: enable Graphql/AuthorizeTypes
+ calls_gitaly: true
+
+ def trees
+ Gitlab::Graphql::Representation::TreeEntry.decorate(object.trees, object.repository)
+ end
+
+ def submodules
+ Gitlab::Graphql::Representation::SubmoduleTreeEntry.decorate(object.submodules, object)
+ end
+
+ def blobs
+ Gitlab::Graphql::Representation::TreeEntry.decorate(object.blobs, object.repository)
+ end
end
+ # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb
index 783a0d8425a..93503268319 100644
--- a/app/graphql/types/user_type.rb
+++ b/app/graphql/types/user_type.rb
@@ -19,7 +19,10 @@ module Types
field :state, Types::UserStateEnum, null: false,
description: 'State of the user'
field :email, GraphQL::STRING_TYPE, null: true,
- description: 'User email', method: :public_email
+ description: 'User email', method: :public_email,
+ deprecated: { reason: 'Use public_email', milestone: '13.7' }
+ field :public_email, GraphQL::STRING_TYPE, null: true,
+ description: "User's public email"
field :avatar_url, GraphQL::STRING_TYPE, null: true,
description: "URL of the user's avatar"
field :web_url, GraphQL::STRING_TYPE, null: false,
@@ -37,19 +40,24 @@ module Types
feature_flag: :user_group_counts
field :status, Types::UserStatusType, null: true,
description: 'User status'
+ field :location, ::GraphQL::STRING_TYPE, null: true,
+ description: 'The location of the user.'
field :project_memberships, Types::ProjectMemberType.connection_type, null: true,
description: 'Project memberships of the user'
field :starred_projects, Types::ProjectType.connection_type, null: true,
description: 'Projects starred by the user',
resolver: Resolvers::UserStarredProjectsResolver
- # Merge request field: MRs can be either authored or assigned:
+ # Merge request field: MRs can be authored, assigned, or assigned-for-review:
field :authored_merge_requests,
resolver: Resolvers::AuthoredMergeRequestsResolver,
description: 'Merge Requests authored by the user'
field :assigned_merge_requests,
resolver: Resolvers::AssignedMergeRequestsResolver,
description: 'Merge Requests assigned to the user'
+ field :review_requested_merge_requests,
+ resolver: Resolvers::ReviewRequestedMergeRequestsResolver,
+ description: 'Merge Requests assigned to the user for review'
field :snippets,
Types::SnippetType.connection_type,