summaryrefslogtreecommitdiff
path: root/app/graphql
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql')
-rw-r--r--app/graphql/gitlab_schema.rb2
-rw-r--r--app/graphql/mutations/boards/create.rb4
-rw-r--r--app/graphql/mutations/boards/destroy.rb2
-rw-r--r--app/graphql/mutations/boards/issues/issue_move_list.rb45
-rw-r--r--app/graphql/mutations/boards/lists/create.rb2
-rw-r--r--app/graphql/mutations/boards/lists/destroy.rb2
-rw-r--r--app/graphql/mutations/boards/lists/update.rb4
-rw-r--r--app/graphql/mutations/boards/update.rb2
-rw-r--r--app/graphql/mutations/branches/create.rb2
-rw-r--r--app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb21
-rw-r--r--app/graphql/mutations/custom_emoji/create.rb1
-rw-r--r--app/graphql/mutations/merge_requests/accept.rb88
-rw-r--r--app/graphql/mutations/merge_requests/set_wip.rb2
-rw-r--r--app/graphql/mutations/notes/create/diff_note.rb16
-rw-r--r--app/graphql/mutations/notes/update/base.rb12
-rw-r--r--app/graphql/mutations/notes/update/image_diff_note.rb23
-rw-r--r--app/graphql/mutations/notes/update/note.rb13
-rw-r--r--app/graphql/mutations/release_asset_links/create.rb46
-rw-r--r--app/graphql/mutations/release_asset_links/update.rb65
-rw-r--r--app/graphql/mutations/snippets/create.rb2
-rw-r--r--app/graphql/mutations/snippets/update.rb2
-rw-r--r--app/graphql/mutations/todos/restore_many.rb2
-rw-r--r--app/graphql/mutations/user_callouts/create.rb30
-rw-r--r--app/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver.rb (renamed from app/graphql/resolvers/admin/analytics/instance_statistics/measurements_resolver.rb)8
-rw-r--r--app/graphql/resolvers/alert_management/alert_resolver.rb3
-rw-r--r--app/graphql/resolvers/alert_management/http_integrations_resolver.rb23
-rw-r--r--app/graphql/resolvers/base_resolver.rb11
-rw-r--r--app/graphql/resolvers/board_lists_resolver.rb2
-rw-r--r--app/graphql/resolvers/board_resolver.rb2
-rw-r--r--app/graphql/resolvers/boards_resolver.rb2
-rw-r--r--app/graphql/resolvers/branch_commit_resolver.rb11
-rw-r--r--app/graphql/resolvers/ci/config_resolver.rb2
-rw-r--r--app/graphql/resolvers/concerns/resolves_snippets.rb2
-rw-r--r--app/graphql/resolvers/full_path_resolver.rb2
-rw-r--r--app/graphql/resolvers/group_packages_resolver.rb27
-rw-r--r--app/graphql/resolvers/last_commit_resolver.rb2
-rw-r--r--app/graphql/resolvers/metrics/dashboard_resolver.rb21
-rw-r--r--app/graphql/resolvers/namespace_projects_resolver.rb35
-rw-r--r--app/graphql/resolvers/project_merge_requests_resolver.rb2
-rw-r--r--app/graphql/resolvers/project_packages_resolver.rb (renamed from app/graphql/resolvers/packages_resolver.rb)2
-rw-r--r--app/graphql/resolvers/project_pipeline_resolver.rb32
-rw-r--r--app/graphql/resolvers/snippets/blobs_resolver.rb1
-rw-r--r--app/graphql/resolvers/tree_resolver.rb2
-rw-r--r--app/graphql/types/access_level_enum.rb13
-rw-r--r--app/graphql/types/admin/analytics/instance_statistics/measurement_identifier_enum.rb25
-rw-r--r--app/graphql/types/admin/analytics/usage_trends/measurement_identifier_enum.rb25
-rw-r--r--app/graphql/types/admin/analytics/usage_trends/measurement_type.rb (renamed from app/graphql/types/admin/analytics/instance_statistics/measurement_type.rb)8
-rw-r--r--app/graphql/types/alert_management/alert_sort_enum.rb28
-rw-r--r--app/graphql/types/alert_management/alert_type.rb6
-rw-r--r--app/graphql/types/alert_management/domain_filter_enum.rb4
-rw-r--r--app/graphql/types/alert_management/http_integration_type.rb2
-rw-r--r--app/graphql/types/alert_management/integration_type_enum.rb4
-rw-r--r--app/graphql/types/base_argument.rb1
-rw-r--r--app/graphql/types/base_field.rb55
-rw-r--r--app/graphql/types/blob_viewers/type_enum.rb6
-rw-r--r--app/graphql/types/board_list_type.rb8
-rw-r--r--app/graphql/types/board_type.rb4
-rw-r--r--app/graphql/types/boards/board_issue_input_base_type.rb2
-rw-r--r--app/graphql/types/boards/board_issue_input_type.rb2
-rw-r--r--app/graphql/types/ci/config/status_enum.rb4
-rw-r--r--app/graphql/types/ci/job_artifact_file_type_enum.rb3
-rw-r--r--app/graphql/types/ci/job_type.rb4
-rw-r--r--app/graphql/types/ci/pipeline_type.rb7
-rw-r--r--app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb1
-rw-r--r--app/graphql/types/ci_configuration/sast/entity_input_type.rb1
-rw-r--r--app/graphql/types/ci_configuration/sast/input_type.rb2
-rw-r--r--app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb6
-rw-r--r--app/graphql/types/commit_action_mode_enum.rb10
-rw-r--r--app/graphql/types/commit_action_type.rb2
-rw-r--r--app/graphql/types/commit_encoding_enum.rb4
-rw-r--r--app/graphql/types/concerns/gitlab_style_deprecations.rb2
-rw-r--r--app/graphql/types/container_repository_sort_enum.rb4
-rw-r--r--app/graphql/types/current_user_todos.rb5
-rw-r--r--app/graphql/types/design_management/design_version_event_enum.rb2
-rw-r--r--app/graphql/types/diff_paths_input_type.rb2
-rw-r--r--app/graphql/types/error_tracking/sentry_error_status_enum.rb8
-rw-r--r--app/graphql/types/global_id_type.rb42
-rw-r--r--app/graphql/types/group_type.rb4
-rw-r--r--app/graphql/types/issuable_sort_enum.rb12
-rw-r--r--app/graphql/types/issuable_state_enum.rb8
-rw-r--r--app/graphql/types/issue_sort_enum.rb10
-rw-r--r--app/graphql/types/issue_state_event_enum.rb4
-rw-r--r--app/graphql/types/jira_users_mapping_input_type.rb2
-rw-r--r--app/graphql/types/label_type.rb4
-rw-r--r--app/graphql/types/merge_request_sort_enum.rb4
-rw-r--r--app/graphql/types/merge_request_state_enum.rb2
-rw-r--r--app/graphql/types/merge_request_type.rb6
-rw-r--r--app/graphql/types/merge_strategy_enum.rb9
-rw-r--r--app/graphql/types/milestone_state_enum.rb4
-rw-r--r--app/graphql/types/mutation_operation_mode_enum.rb6
-rw-r--r--app/graphql/types/mutation_type.rb15
-rw-r--r--app/graphql/types/notes/diff_image_position_input_type.rb2
-rw-r--r--app/graphql/types/notes/diff_position_base_input_type.rb2
-rw-r--r--app/graphql/types/notes/diff_position_input_type.rb4
-rw-r--r--app/graphql/types/notes/position_type_enum.rb4
-rw-r--r--app/graphql/types/notes/update_diff_image_position_input_type.rb3
-rw-r--r--app/graphql/types/project_type.rb8
-rw-r--r--app/graphql/types/projects/namespace_project_sort_enum.rb4
-rw-r--r--app/graphql/types/query_type.rb12
-rw-r--r--app/graphql/types/range_input_type.rb2
-rw-r--r--app/graphql/types/release_asset_link_input_type.rb17
-rw-r--r--app/graphql/types/release_asset_link_shared_input_arguments.rb25
-rw-r--r--app/graphql/types/release_assets_input_type.rb1
-rw-r--r--app/graphql/types/release_sort_enum.rb8
-rw-r--r--app/graphql/types/snippets/blob_action_input_type.rb2
-rw-r--r--app/graphql/types/snippets/blob_type.rb1
-rw-r--r--app/graphql/types/sort_enum.rb16
-rw-r--r--app/graphql/types/time_type.rb8
-rw-r--r--app/graphql/types/timeframe_input_type.rb2
-rw-r--r--app/graphql/types/todo_action_enum.rb16
-rw-r--r--app/graphql/types/todo_state_enum.rb4
-rw-r--r--app/graphql/types/todo_target_enum.rb10
-rw-r--r--app/graphql/types/tree/blob_type.rb1
-rw-r--r--app/graphql/types/user_callout_feature_name_enum.rb12
-rw-r--r--app/graphql/types/user_callout_type.rb12
-rw-r--r--app/graphql/types/user_state_enum.rb6
-rw-r--r--app/graphql/types/user_type.rb4
-rw-r--r--app/graphql/types/visibility_levels_enum.rb2
118 files changed, 790 insertions, 370 deletions
diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb
index d66a2333d11..7ab5dc36e4a 100644
--- a/app/graphql/gitlab_schema.rb
+++ b/app/graphql/gitlab_schema.rb
@@ -13,8 +13,6 @@ class GitlabSchema < GraphQL::Schema
use GraphQL::Pagination::Connections
use BatchLoader::GraphQL
use Gitlab::Graphql::Authorize
- use Gitlab::Graphql::Present
- use Gitlab::Graphql::CallsGitaly
use Gitlab::Graphql::Pagination::Connections
use Gitlab::Graphql::GenericTracing
use Gitlab::Graphql::Timeout, max_seconds: Gitlab.config.gitlab.graphql_timeout
diff --git a/app/graphql/mutations/boards/create.rb b/app/graphql/mutations/boards/create.rb
index 92bce557446..003c4f7761b 100644
--- a/app/graphql/mutations/boards/create.rb
+++ b/app/graphql/mutations/boards/create.rb
@@ -14,7 +14,7 @@ module Mutations
null: true,
description: 'The board after mutation.'
- authorize :admin_board
+ authorize :admin_issue_board
def resolve(args)
board_parent = authorized_resource_parent_find!(args)
@@ -22,7 +22,7 @@ module Mutations
response = ::Boards::CreateService.new(board_parent, current_user, args).execute
{
- board: response.payload,
+ board: response.success? ? response.payload : nil,
errors: response.errors
}
end
diff --git a/app/graphql/mutations/boards/destroy.rb b/app/graphql/mutations/boards/destroy.rb
index 8ec13b885d5..4a0068edee2 100644
--- a/app/graphql/mutations/boards/destroy.rb
+++ b/app/graphql/mutations/boards/destroy.rb
@@ -14,7 +14,7 @@ module Mutations
required: true,
description: 'The global ID of the board to destroy.'
- authorize :admin_board
+ authorize :admin_issue_board
def resolve(id:)
board = authorized_find!(id: id)
diff --git a/app/graphql/mutations/boards/issues/issue_move_list.rb b/app/graphql/mutations/boards/issues/issue_move_list.rb
index 91dfd9fc3e9..096ac89db1c 100644
--- a/app/graphql/mutations/boards/issues/issue_move_list.rb
+++ b/app/graphql/mutations/boards/issues/issue_move_list.rb
@@ -5,35 +5,38 @@ module Mutations
module Issues
class IssueMoveList < Mutations::Issues::Base
graphql_name 'IssueMoveList'
+ BoardGID = ::Types::GlobalIDType[::Board]
+ ListID = ::GraphQL::ID_TYPE
+ IssueID = ::GraphQL::ID_TYPE
- argument :board_id, GraphQL::ID_TYPE,
- required: true,
- loads: Types::BoardType,
- description: 'Global ID of the board that the issue is in.'
+ argument :board_id, BoardGID,
+ required: true,
+ loads: Types::BoardType,
+ description: 'Global ID of the board that the issue is in.'
argument :project_path, GraphQL::ID_TYPE,
- required: true,
- description: 'Project the issue to mutate is in.'
+ required: true,
+ description: 'Project the issue to mutate is in.'
argument :iid, GraphQL::STRING_TYPE,
- required: true,
- description: 'IID of the issue to mutate.'
+ required: true,
+ description: 'IID of the issue to mutate.'
- argument :from_list_id, GraphQL::ID_TYPE,
- required: false,
- description: 'ID of the board list that the issue will be moved from.'
+ argument :from_list_id, ListID,
+ required: false,
+ description: 'ID of the board list that the issue will be moved from.'
- argument :to_list_id, GraphQL::ID_TYPE,
- required: false,
- description: 'ID of the board list that the issue will be moved to.'
+ argument :to_list_id, ListID,
+ required: false,
+ description: 'ID of the board list that the issue will be moved to.'
- argument :move_before_id, GraphQL::ID_TYPE,
- required: false,
- description: 'ID of issue that should be placed before the current issue.'
+ argument :move_before_id, IssueID,
+ required: false,
+ description: 'ID of issue that should be placed before the current issue.'
- argument :move_after_id, GraphQL::ID_TYPE,
- required: false,
- description: 'ID of issue that should be placed after the current issue.'
+ argument :move_after_id, IssueID,
+ required: false,
+ description: 'ID of issue that should be placed after the current issue.'
def ready?(**args)
if move_arguments(args).blank?
@@ -83,7 +86,7 @@ module Mutations
end
def authorize_board!(board)
- return if Ability.allowed?(current_user, :read_board, board.resource_parent)
+ return if Ability.allowed?(current_user, :read_issue_board, board.resource_parent)
raise_resource_not_available_error!
end
diff --git a/app/graphql/mutations/boards/lists/create.rb b/app/graphql/mutations/boards/lists/create.rb
index f3aae9ac9c8..673fa95fc56 100644
--- a/app/graphql/mutations/boards/lists/create.rb
+++ b/app/graphql/mutations/boards/lists/create.rb
@@ -15,7 +15,7 @@ module Mutations
null: true,
description: 'Issue list in the issue board.'
- authorize :admin_list
+ authorize :admin_issue_board_list
private
diff --git a/app/graphql/mutations/boards/lists/destroy.rb b/app/graphql/mutations/boards/lists/destroy.rb
index 61ffae7c047..a50b5f73455 100644
--- a/app/graphql/mutations/boards/lists/destroy.rb
+++ b/app/graphql/mutations/boards/lists/destroy.rb
@@ -33,7 +33,7 @@ module Mutations
def can_admin_list?(list)
return false unless list.present?
- Ability.allowed?(current_user, :admin_list, list.board)
+ Ability.allowed?(current_user, :admin_issue_board_list, list.board)
end
end
end
diff --git a/app/graphql/mutations/boards/lists/update.rb b/app/graphql/mutations/boards/lists/update.rb
index d30d1d89bb2..504082ec22c 100644
--- a/app/graphql/mutations/boards/lists/update.rb
+++ b/app/graphql/mutations/boards/lists/update.rb
@@ -17,7 +17,7 @@ module Mutations
argument :collapsed, GraphQL::BOOLEAN_TYPE,
required: false,
- description: 'Indicates if list is collapsed for this user.'
+ description: 'Indicates if the list is collapsed for this user.'
field :list,
Types::BoardListType,
@@ -44,7 +44,7 @@ module Mutations
def can_read_list?(list)
return false unless list.present?
- Ability.allowed?(current_user, :read_list, list.board)
+ Ability.allowed?(current_user, :read_issue_board_list, list.board)
end
end
end
diff --git a/app/graphql/mutations/boards/update.rb b/app/graphql/mutations/boards/update.rb
index b4f8179829e..628b3a3fadb 100644
--- a/app/graphql/mutations/boards/update.rb
+++ b/app/graphql/mutations/boards/update.rb
@@ -17,7 +17,7 @@ module Mutations
null: true,
description: 'The board after mutation.'
- authorize :admin_board
+ authorize :admin_issue_board
def resolve(id:, **args)
board = authorized_find!(id: id)
diff --git a/app/graphql/mutations/branches/create.rb b/app/graphql/mutations/branches/create.rb
index 6354976f1ea..a94d3966258 100644
--- a/app/graphql/mutations/branches/create.rb
+++ b/app/graphql/mutations/branches/create.rb
@@ -30,8 +30,6 @@ module Mutations
def resolve(project_path:, name:, ref:)
project = authorized_find!(project_path)
- context.scoped_set!(:branch_project, project)
-
result = ::Branches::CreateService.new(project, current_user)
.execute(name, ref)
diff --git a/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb b/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb
index 2d4983f0d6e..ba644eff36c 100644
--- a/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb
+++ b/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb
@@ -5,6 +5,7 @@ module Mutations
# and optionally support the workflow to allow clients to display and solve CAPTCHAs.
module CanMutateSpammable
extend ActiveSupport::Concern
+ include Spam::Concerns::HasSpamActionResponseFields
# NOTE: The arguments and fields are intentionally named with 'captcha' instead of 'recaptcha',
# so that they can be applied to future alternative CAPTCHA implementations other than
@@ -59,25 +60,5 @@ module Mutations
request: context[:request]
}
end
-
- # with_spam_action_fields(spammable) { {other_fields: true} } -> hash
- #
- # Takes a Spammable and a block as arguments.
- #
- # The block passed should be a hash, which the spam action fields will be merged into.
- def with_spam_action_fields(spammable)
- spam_action_fields = {
- spam: spammable.spam?,
- # NOTE: These fields are intentionally named with 'captcha' instead of 'recaptcha', so
- # that they can be applied to future alternative CAPTCHA implementations other than
- # reCAPTCHA (such as FriendlyCaptcha) without having to change the response field name
- # in the API.
- needs_captcha_response: spammable.render_recaptcha?,
- spam_log_id: spammable.spam_log&.id,
- captcha_site_key: Gitlab::CurrentSettings.recaptcha_site_key
- }
-
- yield.merge(spam_action_fields)
- end
end
end
diff --git a/app/graphql/mutations/custom_emoji/create.rb b/app/graphql/mutations/custom_emoji/create.rb
index 9ec96be0f26..5cf54f8f877 100644
--- a/app/graphql/mutations/custom_emoji/create.rb
+++ b/app/graphql/mutations/custom_emoji/create.rb
@@ -31,6 +31,7 @@ module Mutations
group = authorized_find!(group_path: group_path)
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37911#note_444682238
args[:external] = true
+ args[:creator] = current_user
custom_emoji = group.custom_emoji.create(args)
diff --git a/app/graphql/mutations/merge_requests/accept.rb b/app/graphql/mutations/merge_requests/accept.rb
new file mode 100644
index 00000000000..540be7098ac
--- /dev/null
+++ b/app/graphql/mutations/merge_requests/accept.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module Mutations
+ module MergeRequests
+ class Accept < Base
+ NOT_MERGEABLE = 'This branch cannot be merged'
+ HOOKS_VALIDATION_ERROR = 'Pre-merge hooks failed'
+ SHA_MISMATCH = 'The merge-head is not at the anticipated SHA'
+ MERGE_FAILED = 'The merge failed'
+ ALREADY_SCHEDULED = 'The merge request is already scheduled to be merged'
+
+ graphql_name 'MergeRequestAccept'
+ authorize :accept_merge_request
+ description <<~DESC
+ Accepts a merge request.
+ When accepted, the source branch will be merged into the target branch, either
+ immediately if possible, or using one of the automatic merge strategies.
+ DESC
+
+ argument :strategy,
+ ::Types::MergeStrategyEnum,
+ required: false,
+ as: :auto_merge_strategy,
+ description: 'How to merge this merge request.'
+
+ argument :commit_message, ::GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Custom merge commit message.'
+ argument :squash_commit_message, ::GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Custom squash commit message (if squash is true).'
+ argument :sha, ::GraphQL::STRING_TYPE,
+ required: true,
+ description: 'The HEAD SHA at the time when this merge was requested.'
+
+ argument :should_remove_source_branch, ::GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: 'Should the source branch be removed.'
+ argument :squash, ::GraphQL::BOOLEAN_TYPE,
+ required: false,
+ default_value: false,
+ description: 'Squash commits on the source branch before merge.'
+
+ def resolve(project_path:, iid:, **args)
+ Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42317')
+ merge_request = authorized_find!(project_path: project_path, iid: iid)
+ project = merge_request.target_project
+ merge_params = args.compact.with_indifferent_access
+ merge_service = ::MergeRequests::MergeService.new(project, current_user, merge_params)
+
+ if error = validate(merge_request, merge_service, merge_params)
+ return { merge_request: merge_request, errors: [error] }
+ end
+
+ merge_request.update(merge_error: nil, squash: merge_params[:squash])
+
+ result = if merge_params.key?(:auto_merge_strategy)
+ service = AutoMergeService.new(project, current_user, merge_params)
+ service.execute(merge_request, merge_params[:auto_merge_strategy])
+ else
+ merge_service.execute(merge_request)
+ end
+
+ {
+ merge_request: merge_request,
+ errors: result == :failed ? [MERGE_FAILED] : []
+ }
+ rescue ::MergeRequests::MergeBaseService::MergeError => e
+ {
+ merge_request: merge_request,
+ errors: [e.message]
+ }
+ end
+
+ def validate(merge_request, merge_service, merge_params)
+ if merge_request.auto_merge_enabled?
+ ALREADY_SCHEDULED
+ elsif !merge_request.mergeable?(skip_ci_check: merge_params.key?(:auto_merge_strategy))
+ NOT_MERGEABLE
+ elsif !merge_service.hooks_validation_pass?(merge_request)
+ HOOKS_VALIDATION_ERROR
+ elsif merge_params[:sha] != merge_request.diff_head_sha
+ SHA_MISMATCH
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/merge_requests/set_wip.rb b/app/graphql/mutations/merge_requests/set_wip.rb
index 0b5c20de377..beb042ce93f 100644
--- a/app/graphql/mutations/merge_requests/set_wip.rb
+++ b/app/graphql/mutations/merge_requests/set_wip.rb
@@ -9,7 +9,7 @@ module Mutations
GraphQL::BOOLEAN_TYPE,
required: true,
description: <<~DESC
- Whether or not to set the merge request as a WIP.
+ Whether or not to set the merge request as a draft.
DESC
def resolve(project_path:, iid:, wip: nil)
diff --git a/app/graphql/mutations/notes/create/diff_note.rb b/app/graphql/mutations/notes/create/diff_note.rb
index 9b5f3092006..019e7cb8623 100644
--- a/app/graphql/mutations/notes/create/diff_note.rb
+++ b/app/graphql/mutations/notes/create/diff_note.rb
@@ -11,6 +11,22 @@ module Mutations
required: true,
description: copy_field_description(Types::Notes::NoteType, :position)
+ def ready?(**args)
+ # As both arguments are optional, validate here that one of the
+ # arguments are present.
+ #
+ # This may be able to be done using InputUnions in the future
+ # if this RFC is merged:
+ # https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md
+
+ if args[:position].to_hash.values_at(:old_line, :new_line).compact.blank?
+ raise Gitlab::Graphql::Errors::ArgumentError,
+ 'position oldLine or newLine arguments are required'
+ end
+
+ super(**args)
+ end
+
private
def create_note_params(noteable, args)
diff --git a/app/graphql/mutations/notes/update/base.rb b/app/graphql/mutations/notes/update/base.rb
index 4edb7429b97..571001981a4 100644
--- a/app/graphql/mutations/notes/update/base.rb
+++ b/app/graphql/mutations/notes/update/base.rb
@@ -6,12 +6,18 @@ module Mutations
# This is a Base class for the Note update mutations and is not
# mounted as a GraphQL mutation itself.
class Base < Mutations::Notes::Base
+ QUICK_ACTION_ONLY_WARNING = <<~NB
+ If the body of the Note contains only quick actions,
+ the Note will be destroyed during the update, and no Note will be
+ returned.
+ NB
+
authorize :admin_note
argument :id,
- ::Types::GlobalIDType[::Note],
- required: true,
- description: 'The global ID of the note to update.'
+ ::Types::GlobalIDType[::Note],
+ required: true,
+ description: 'The global ID of the note to update.'
def resolve(args)
note = authorized_find!(id: args[:id])
diff --git a/app/graphql/mutations/notes/update/image_diff_note.rb b/app/graphql/mutations/notes/update/image_diff_note.rb
index f4533cd9edb..6160ee03f4e 100644
--- a/app/graphql/mutations/notes/update/image_diff_note.rb
+++ b/app/graphql/mutations/notes/update/image_diff_note.rb
@@ -5,16 +5,20 @@ module Mutations
module Update
class ImageDiffNote < Mutations::Notes::Update::Base
graphql_name 'UpdateImageDiffNote'
+ description <<~DESC
+ Updates a DiffNote on an image (a `Note` where the `position.positionType` is `"image"`).
+ #{QUICK_ACTION_ONLY_WARNING}
+ DESC
argument :body,
- GraphQL::STRING_TYPE,
- required: false,
- description: copy_field_description(Types::Notes::NoteType, :body)
+ GraphQL::STRING_TYPE,
+ required: false,
+ description: copy_field_description(Types::Notes::NoteType, :body)
argument :position,
- Types::Notes::UpdateDiffImagePositionInputType,
- required: false,
- description: copy_field_description(Types::Notes::NoteType, :position)
+ Types::Notes::UpdateDiffImagePositionInputType,
+ required: false,
+ description: copy_field_description(Types::Notes::NoteType, :position)
def ready?(**args)
# As both arguments are optional, validate here that one of the
@@ -34,10 +38,9 @@ module Mutations
private
def pre_update_checks!(note, _args)
- unless note.is_a?(DiffNote) && note.position.on_image?
- raise Gitlab::Graphql::Errors::ResourceNotAvailable,
- 'Resource is not an ImageDiffNote'
- end
+ return if note.is_a?(DiffNote) && note.position.on_image?
+
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Resource is not an ImageDiffNote'
end
def note_params(note, args)
diff --git a/app/graphql/mutations/notes/update/note.rb b/app/graphql/mutations/notes/update/note.rb
index 73b9b9bc49a..11d8c6e2cb9 100644
--- a/app/graphql/mutations/notes/update/note.rb
+++ b/app/graphql/mutations/notes/update/note.rb
@@ -5,16 +5,17 @@ module Mutations
module Update
class Note < Mutations::Notes::Update::Base
graphql_name 'UpdateNote'
+ description "Updates a Note.\n#{QUICK_ACTION_ONLY_WARNING}"
argument :body,
- GraphQL::STRING_TYPE,
- required: false,
- description: copy_field_description(Types::Notes::NoteType, :body)
+ GraphQL::STRING_TYPE,
+ required: false,
+ description: copy_field_description(Types::Notes::NoteType, :body)
argument :confidential,
- GraphQL::BOOLEAN_TYPE,
- required: false,
- description: 'The confidentiality flag of a note. Default is false.'
+ GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: 'The confidentiality flag of a note. Default is false.'
private
diff --git a/app/graphql/mutations/release_asset_links/create.rb b/app/graphql/mutations/release_asset_links/create.rb
new file mode 100644
index 00000000000..02704efb47c
--- /dev/null
+++ b/app/graphql/mutations/release_asset_links/create.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Mutations
+ module ReleaseAssetLinks
+ class Create < BaseMutation
+ include FindsProject
+
+ graphql_name 'ReleaseAssetLinkCreate'
+
+ authorize :create_release
+
+ include Types::ReleaseAssetLinkSharedInputArguments
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: true,
+ description: 'Full path of the project the asset link is associated with.'
+
+ argument :tag_name, GraphQL::STRING_TYPE,
+ required: true, as: :tag,
+ description: "Name of the associated release's tag."
+
+ field :link,
+ Types::ReleaseAssetLinkType,
+ null: true,
+ description: 'The asset link after mutation.'
+
+ def resolve(project_path:, tag:, **link_attrs)
+ project = authorized_find!(project_path)
+ release = project.releases.find_by_tag(tag)
+
+ if release.nil?
+ message = _('Release with tag "%{tag}" was not found') % { tag: tag }
+ return { link: nil, errors: [message] }
+ end
+
+ new_link = release.links.create(link_attrs)
+
+ unless new_link.persisted?
+ return { link: nil, errors: new_link.errors.full_messages }
+ end
+
+ { link: new_link, errors: [] }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/release_asset_links/update.rb b/app/graphql/mutations/release_asset_links/update.rb
new file mode 100644
index 00000000000..1d9460bde78
--- /dev/null
+++ b/app/graphql/mutations/release_asset_links/update.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module Mutations
+ module ReleaseAssetLinks
+ class Update < BaseMutation
+ graphql_name 'ReleaseAssetLinkUpdate'
+
+ authorize :update_release
+
+ ReleaseAssetLinkID = ::Types::GlobalIDType[::Releases::Link]
+
+ argument :id, ReleaseAssetLinkID,
+ required: true,
+ description: 'ID of the release asset link to update.'
+
+ argument :name, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Name of the asset link.'
+
+ argument :url, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'URL of the asset link.'
+
+ argument :direct_asset_path, GraphQL::STRING_TYPE,
+ required: false, as: :filepath,
+ description: 'Relative path for a direct asset link.'
+
+ argument :link_type, Types::ReleaseAssetLinkTypeEnum,
+ required: false,
+ description: 'The type of the asset link.'
+
+ field :link,
+ Types::ReleaseAssetLinkType,
+ null: true,
+ description: 'The asset link after mutation.'
+
+ def ready?(**args)
+ if args.key?(:link_type) && args[:link_type].nil?
+ raise Gitlab::Graphql::Errors::ArgumentError,
+ 'if the linkType argument is provided, it cannot be null'
+ end
+
+ super
+ end
+
+ def resolve(id:, **link_attrs)
+ link = authorized_find!(id)
+
+ unless link.update(link_attrs)
+ return { link: nil, errors: link.errors.full_messages }
+ end
+
+ { link: link, errors: [] }
+ end
+
+ def find_object(id)
+ # TODO: remove this line when the compatibility layer is removed
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ id = ReleaseAssetLinkID.coerce_isolated_input(id)
+
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb
index 73eac9f0f3b..7f2dd448b8b 100644
--- a/app/graphql/mutations/snippets/create.rb
+++ b/app/graphql/mutations/snippets/create.rb
@@ -56,7 +56,7 @@ module Mutations
end
snippet = service_response.payload[:snippet]
- with_spam_action_fields(snippet) do
+ with_spam_action_response_fields(snippet) do
{
snippet: service_response.success? ? snippet : nil,
errors: errors_on_object(snippet)
diff --git a/app/graphql/mutations/snippets/update.rb b/app/graphql/mutations/snippets/update.rb
index af8e6f384b7..9f9f8bca848 100644
--- a/app/graphql/mutations/snippets/update.rb
+++ b/app/graphql/mutations/snippets/update.rb
@@ -45,7 +45,7 @@ module Mutations
end
snippet = service_response.payload[:snippet]
- with_spam_action_fields(snippet) do
+ with_spam_action_response_fields(snippet) do
{
snippet: service_response.success? ? snippet : snippet.reset,
errors: errors_on_object(snippet)
diff --git a/app/graphql/mutations/todos/restore_many.rb b/app/graphql/mutations/todos/restore_many.rb
index dc02ffadada..41ccbd77aa6 100644
--- a/app/graphql/mutations/todos/restore_many.rb
+++ b/app/graphql/mutations/todos/restore_many.rb
@@ -60,7 +60,7 @@ module Mutations
def authorized_find_all_pending_by_current_user(ids)
return Todo.none if ids.blank? || current_user.nil?
- Todo.for_ids(ids).for_user(current_user).done
+ Todo.id_in(ids).for_user(current_user).done
end
def restore(todos)
diff --git a/app/graphql/mutations/user_callouts/create.rb b/app/graphql/mutations/user_callouts/create.rb
new file mode 100644
index 00000000000..0d3dcacda41
--- /dev/null
+++ b/app/graphql/mutations/user_callouts/create.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Mutations
+ module UserCallouts
+ class Create < ::Mutations::BaseMutation
+ graphql_name 'UserCalloutCreate'
+
+ argument :feature_name,
+ GraphQL::STRING_TYPE,
+ required: true,
+ description: "The feature name you want to dismiss the callout for."
+
+ field :user_callout, Types::UserCalloutType,
+ null: false,
+ description: 'The user callout dismissed.'
+
+ def resolve(feature_name:)
+ callout = Users::DismissUserCalloutService.new(
+ container: nil, current_user: current_user, params: { feature_name: feature_name }
+ ).execute
+ errors = errors_on_object(callout)
+
+ {
+ user_callout: callout,
+ errors: errors
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/admin/analytics/instance_statistics/measurements_resolver.rb b/app/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver.rb
index 9df07df24d8..a5f81149d4e 100644
--- a/app/graphql/resolvers/admin/analytics/instance_statistics/measurements_resolver.rb
+++ b/app/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver.rb
@@ -3,13 +3,13 @@
module Resolvers
module Admin
module Analytics
- module InstanceStatistics
+ module UsageTrends
class MeasurementsResolver < BaseResolver
include Gitlab::Graphql::Authorize::AuthorizeResource
- type Types::Admin::Analytics::InstanceStatistics::MeasurementType, null: true
+ type Types::Admin::Analytics::UsageTrends::MeasurementType, null: true
- argument :identifier, Types::Admin::Analytics::InstanceStatistics::MeasurementIdentifierEnum,
+ argument :identifier, Types::Admin::Analytics::UsageTrends::MeasurementIdentifierEnum,
required: true,
description: 'The type of measurement/statistics to retrieve.'
@@ -24,7 +24,7 @@ module Resolvers
def resolve(identifier:, recorded_before: nil, recorded_after: nil)
authorize!
- ::Analytics::InstanceStatistics::Measurement
+ ::Analytics::UsageTrends::Measurement
.recorded_after(recorded_after)
.recorded_before(recorded_before)
.with_identifier(identifier)
diff --git a/app/graphql/resolvers/alert_management/alert_resolver.rb b/app/graphql/resolvers/alert_management/alert_resolver.rb
index d60cabde62b..008641ed88a 100644
--- a/app/graphql/resolvers/alert_management/alert_resolver.rb
+++ b/app/graphql/resolvers/alert_management/alert_resolver.rb
@@ -43,7 +43,8 @@ module Resolvers
def preloads
{
assignees: [:assignees],
- notes: [:ordered_notes, { ordered_notes: [:system_note_metadata, :project, :noteable] }]
+ notes: [:ordered_notes, { ordered_notes: [:system_note_metadata, :project, :noteable] }],
+ issue: [:issue]
}
end
end
diff --git a/app/graphql/resolvers/alert_management/http_integrations_resolver.rb b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
new file mode 100644
index 00000000000..94a72bca7c7
--- /dev/null
+++ b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module AlertManagement
+ class HttpIntegrationsResolver < BaseResolver
+ alias_method :project, :synchronized_object
+
+ type Types::AlertManagement::HttpIntegrationType.connection_type, null: true
+
+ def resolve(**args)
+ http_integrations
+ end
+
+ private
+
+ def http_integrations
+ return [] unless Ability.allowed?(current_user, :admin_operations, project)
+
+ ::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb
index 5db618254cb..67bba079512 100644
--- a/app/graphql/resolvers/base_resolver.rb
+++ b/app/graphql/resolvers/base_resolver.rb
@@ -12,8 +12,17 @@ module Resolvers
@requires_argument = true
end
+ def self.calls_gitaly!
+ @calls_gitaly = true
+ end
+
def self.field_options
- super.merge(requires_argument: @requires_argument)
+ extra_options = {
+ requires_argument: @requires_argument,
+ calls_gitaly: @calls_gitaly
+ }.compact
+
+ super.merge(extra_options)
end
def self.singular_type
diff --git a/app/graphql/resolvers/board_lists_resolver.rb b/app/graphql/resolvers/board_lists_resolver.rb
index a97ac3220d5..e66f7b97b40 100644
--- a/app/graphql/resolvers/board_lists_resolver.rb
+++ b/app/graphql/resolvers/board_lists_resolver.rb
@@ -9,7 +9,7 @@ module Resolvers
type Types::BoardListType, null: true
extras [:lookahead]
- authorize :read_list
+ authorize :read_issue_board_list
argument :id, Types::GlobalIDType[List],
required: false,
diff --git a/app/graphql/resolvers/board_resolver.rb b/app/graphql/resolvers/board_resolver.rb
index 2c2922c3fbf..637d690e4cd 100644
--- a/app/graphql/resolvers/board_resolver.rb
+++ b/app/graphql/resolvers/board_resolver.rb
@@ -13,7 +13,7 @@ module Resolvers
def resolve(id: nil)
return unless parent
- ::Boards::ListService.new(parent, context[:current_user], board_id: extract_board_id(id)).execute.first
+ ::Boards::BoardsFinder.new(parent, context[:current_user], board_id: extract_board_id(id)).execute.first
rescue ActiveRecord::RecordNotFound
nil
end
diff --git a/app/graphql/resolvers/boards_resolver.rb b/app/graphql/resolvers/boards_resolver.rb
index be2f22175dc..679f2b4cceb 100644
--- a/app/graphql/resolvers/boards_resolver.rb
+++ b/app/graphql/resolvers/boards_resolver.rb
@@ -16,7 +16,7 @@ module Resolvers
return Board.none unless parent
- ::Boards::ListService.new(parent, context[:current_user], board_id: extract_board_id(id)).execute
+ ::Boards::BoardsFinder.new(parent, context[:current_user], board_id: extract_board_id(id)).execute
rescue ActiveRecord::RecordNotFound
Board.none
end
diff --git a/app/graphql/resolvers/branch_commit_resolver.rb b/app/graphql/resolvers/branch_commit_resolver.rb
index 11c49e17bc5..ba235251950 100644
--- a/app/graphql/resolvers/branch_commit_resolver.rb
+++ b/app/graphql/resolvers/branch_commit_resolver.rb
@@ -7,11 +7,16 @@ module Resolvers
alias_method :branch, :object
def resolve(**args)
- return unless branch
+ commit = branch&.dereferenced_target
+ return unless commit
- commit = branch.dereferenced_target
+ lazy_project = BatchLoader::GraphQL.for(commit.repository.gl_project_path).batch do |paths, loader|
+ paths.each { |path| loader.call(path, Project.find_by_full_path(path)) }
+ end
- ::Commit.new(commit, context[:branch_project]) if commit
+ ::Gitlab::Graphql::Lazy.with_value(lazy_project) do |project|
+ ::Commit.new(commit, project) if project
+ end
end
end
end
diff --git a/app/graphql/resolvers/ci/config_resolver.rb b/app/graphql/resolvers/ci/config_resolver.rb
index 852bb47e215..f8670649e48 100644
--- a/app/graphql/resolvers/ci/config_resolver.rb
+++ b/app/graphql/resolvers/ci/config_resolver.rb
@@ -16,7 +16,7 @@ module Resolvers
argument :content, GraphQL::STRING_TYPE,
required: true,
- description: "Contents of '.gitlab-ci.yml'."
+ description: "Contents of `.gitlab-ci.yml`."
argument :dry_run, GraphQL::BOOLEAN_TYPE,
required: false,
diff --git a/app/graphql/resolvers/concerns/resolves_snippets.rb b/app/graphql/resolvers/concerns/resolves_snippets.rb
index 0bc38188b9a..445f3567b1d 100644
--- a/app/graphql/resolvers/concerns/resolves_snippets.rb
+++ b/app/graphql/resolvers/concerns/resolves_snippets.rb
@@ -8,7 +8,7 @@ module ResolvesSnippets
argument :ids, [::Types::GlobalIDType[::Snippet]],
required: false,
- description: 'Array of global snippet ids, e.g., "gid://gitlab/ProjectSnippet/1".'
+ description: 'Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`.'
argument :visibility, Types::Snippets::VisibilityScopesEnum,
required: false,
diff --git a/app/graphql/resolvers/full_path_resolver.rb b/app/graphql/resolvers/full_path_resolver.rb
index d01cdf749a1..b5e90da78b2 100644
--- a/app/graphql/resolvers/full_path_resolver.rb
+++ b/app/graphql/resolvers/full_path_resolver.rb
@@ -7,7 +7,7 @@ module Resolvers
prepended do
argument :full_path, GraphQL::ID_TYPE,
required: true,
- description: 'The full path of the project, group or namespace, e.g., "gitlab-org/gitlab-foss".'
+ description: 'The full path of the project, group or namespace, e.g., `gitlab-org/gitlab-foss`.'
end
def model_by_full_path(model, full_path)
diff --git a/app/graphql/resolvers/group_packages_resolver.rb b/app/graphql/resolvers/group_packages_resolver.rb
new file mode 100644
index 00000000000..d441cd80249
--- /dev/null
+++ b/app/graphql/resolvers/group_packages_resolver.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class GroupPackagesResolver < BaseResolver
+ type Types::Packages::PackageType.connection_type, null: true
+
+ def ready?(**args)
+ context[self.class] ||= { executions: 0 }
+ context[self.class][:executions] += 1
+ raise GraphQL::ExecutionError, "Packages can be requested only for one group at a time" if context[self.class][:executions] > 1
+
+ super
+ end
+
+ def resolve(**args)
+ return unless packages_available?
+
+ ::Packages::GroupPackagesFinder.new(current_user, object).execute
+ end
+
+ private
+
+ def packages_available?
+ ::Gitlab.config.packages.enabled
+ end
+ end
+end
diff --git a/app/graphql/resolvers/last_commit_resolver.rb b/app/graphql/resolvers/last_commit_resolver.rb
index dd89c322617..00c43bdfee6 100644
--- a/app/graphql/resolvers/last_commit_resolver.rb
+++ b/app/graphql/resolvers/last_commit_resolver.rb
@@ -4,6 +4,8 @@ module Resolvers
class LastCommitResolver < BaseResolver
type Types::CommitType, null: true
+ calls_gitaly!
+
alias_method :tree, :object
def resolve(**args)
diff --git a/app/graphql/resolvers/metrics/dashboard_resolver.rb b/app/graphql/resolvers/metrics/dashboard_resolver.rb
index f569cb0b2c3..a82a4a95254 100644
--- a/app/graphql/resolvers/metrics/dashboard_resolver.rb
+++ b/app/graphql/resolvers/metrics/dashboard_resolver.rb
@@ -3,19 +3,30 @@
module Resolvers
module Metrics
class DashboardResolver < Resolvers::BaseResolver
+ type Types::Metrics::DashboardType, null: true
+ calls_gitaly!
+
argument :path, GraphQL::STRING_TYPE,
required: true,
- description: "Path to a file which defines metrics dashboard eg: 'config/prometheus/common_metrics.yml'."
-
- type Types::Metrics::DashboardType, null: true
+ description: "Path to a file which defines metrics dashboard " \
+ "eg: 'config/prometheus/common_metrics.yml'."
alias_method :environment, :object
def resolve(**args)
return unless environment
- ::PerformanceMonitoring::PrometheusDashboard
- .find_for(project: environment.project, user: context[:current_user], path: args[:path], options: { environment: environment })
+ ::PerformanceMonitoring::PrometheusDashboard.find_for(**args, **service_params)
+ end
+
+ private
+
+ def service_params
+ {
+ project: environment.project,
+ user: current_user,
+ options: { environment: environment }
+ }
end
end
end
diff --git a/app/graphql/resolvers/namespace_projects_resolver.rb b/app/graphql/resolvers/namespace_projects_resolver.rb
index da44b9b5623..7320c3ce141 100644
--- a/app/graphql/resolvers/namespace_projects_resolver.rb
+++ b/app/graphql/resolvers/namespace_projects_resolver.rb
@@ -17,23 +17,23 @@ module Resolvers
default_value: nil,
description: 'Sort projects by this criteria.'
+ argument :ids, [GraphQL::ID_TYPE],
+ required: false,
+ default_value: nil,
+ description: 'Filter projects by IDs.'
+
type Types::ProjectType, null: true
- def resolve(include_subgroups:, sort:, search:)
+ def resolve(args)
# The namespace could have been loaded in batch by `BatchLoader`.
# At this point we need the `id` or the `full_path` of the namespace
# to query for projects, so make sure it's loaded and not `nil` before continuing.
- return Project.none if namespace.nil?
-
- query = include_subgroups ? namespace.all_projects.with_route : namespace.projects.with_route
- return query unless search.present?
-
- if sort == :similarity
- query.sorted_by_similarity_desc(search, include_in_select: true).merge(Project.search(search))
- else
- query.merge(Project.search(search))
- end
+ ::Namespaces::ProjectsFinder.new(
+ namespace: namespace,
+ current_user: current_user,
+ params: finder_params(args)
+ ).execute
end
def self.resolver_complexity(args, child_complexity:)
@@ -48,6 +48,19 @@ module Resolvers
object.respond_to?(:sync) ? object.sync : object
end
end
+
+ def finder_params(args)
+ {
+ include_subgroups: args.dig(:include_subgroups),
+ sort: args.dig(:sort),
+ search: args.dig(:search),
+ ids: parse_gids(args.dig(:ids))
+ }
+ end
+
+ def parse_gids(gids)
+ gids&.map { |gid| GitlabSchema.parse_gid(gid, expected_type: ::Project).model_id }
+ end
end
end
diff --git a/app/graphql/resolvers/project_merge_requests_resolver.rb b/app/graphql/resolvers/project_merge_requests_resolver.rb
index 9628a6dfd7a..66c020a0c14 100644
--- a/app/graphql/resolvers/project_merge_requests_resolver.rb
+++ b/app/graphql/resolvers/project_merge_requests_resolver.rb
@@ -10,7 +10,7 @@ module Resolvers
def resolve(**args)
scope = super
- if only_count_is_selected_with_merged_at_filter?(args) && Feature.enabled?(:optimized_merge_request_count_with_merged_at_filter, default_enabled: :yaml)
+ if only_count_is_selected_with_merged_at_filter?(args)
MergeRequest::MetricsFinder
.new(current_user, args.merge(target_project: project))
.execute
diff --git a/app/graphql/resolvers/packages_resolver.rb b/app/graphql/resolvers/project_packages_resolver.rb
index 3eeed48ff7e..288e14b41d0 100644
--- a/app/graphql/resolvers/packages_resolver.rb
+++ b/app/graphql/resolvers/project_packages_resolver.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module Resolvers
- class PackagesResolver < BaseResolver
+ class ProjectPackagesResolver < BaseResolver
type Types::Packages::PackageType.connection_type, null: true
def resolve(**args)
diff --git a/app/graphql/resolvers/project_pipeline_resolver.rb b/app/graphql/resolvers/project_pipeline_resolver.rb
index b604a408928..8fca6b829c0 100644
--- a/app/graphql/resolvers/project_pipeline_resolver.rb
+++ b/app/graphql/resolvers/project_pipeline_resolver.rb
@@ -7,14 +7,34 @@ module Resolvers
alias_method :project, :object
argument :iid, GraphQL::ID_TYPE,
- required: true,
- description: 'IID of the Pipeline, e.g., "1".'
+ required: false,
+ description: 'IID of the Pipeline. For example, "1".'
- def resolve(iid:)
- BatchLoader::GraphQL.for(iid).batch(key: project) do |iids, loader, args|
- finder = ::Ci::PipelinesFinder.new(project, context[:current_user], iids: iids)
+ argument :sha, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'SHA of the Pipeline. For example, "dyd0f15ay83993f5ab66k927w28673882x99100b".'
- finder.execute.each { |pipeline| loader.call(pipeline.iid.to_s, pipeline) }
+ def ready?(iid: nil, sha: nil)
+ unless iid.present? ^ sha.present?
+ raise Gitlab::Graphql::Errors::ArgumentError, 'Provide one of an IID or SHA'
+ end
+
+ super
+ end
+
+ def resolve(iid: nil, sha: nil)
+ if iid
+ BatchLoader::GraphQL.for(iid).batch(key: project) do |iids, loader, args|
+ finder = ::Ci::PipelinesFinder.new(project, current_user, iids: iids)
+
+ finder.execute.each { |pipeline| loader.call(pipeline.iid.to_s, pipeline) }
+ end
+ else
+ BatchLoader::GraphQL.for(sha).batch(key: project) do |shas, loader, args|
+ finder = ::Ci::PipelinesFinder.new(project, current_user, shas: shas)
+
+ finder.execute.each { |pipeline| loader.call(pipeline.sha.to_s, pipeline) }
+ end
end
end
end
diff --git a/app/graphql/resolvers/snippets/blobs_resolver.rb b/app/graphql/resolvers/snippets/blobs_resolver.rb
index 672214df7d5..569b82149d3 100644
--- a/app/graphql/resolvers/snippets/blobs_resolver.rb
+++ b/app/graphql/resolvers/snippets/blobs_resolver.rb
@@ -8,6 +8,7 @@ module Resolvers
type Types::Snippets::BlobType.connection_type, null: true
authorize :read_snippet
+ calls_gitaly!
alias_method :snippet, :object
diff --git a/app/graphql/resolvers/tree_resolver.rb b/app/graphql/resolvers/tree_resolver.rb
index 7a70c35897d..c07d9187d4d 100644
--- a/app/graphql/resolvers/tree_resolver.rb
+++ b/app/graphql/resolvers/tree_resolver.rb
@@ -4,6 +4,8 @@ module Resolvers
class TreeResolver < BaseResolver
type Types::Tree::TreeType, null: true
+ calls_gitaly!
+
argument :path, GraphQL::STRING_TYPE,
required: false,
default_value: '',
diff --git a/app/graphql/types/access_level_enum.rb b/app/graphql/types/access_level_enum.rb
index 6754d3d28ce..b7eb35ddfc9 100644
--- a/app/graphql/types/access_level_enum.rb
+++ b/app/graphql/types/access_level_enum.rb
@@ -5,11 +5,12 @@ module Types
graphql_name 'AccessLevelEnum'
description 'Access level to a resource'
- value 'NO_ACCESS', value: Gitlab::Access::NO_ACCESS
- value 'GUEST', value: Gitlab::Access::GUEST
- value 'REPORTER', value: Gitlab::Access::REPORTER
- value 'DEVELOPER', value: Gitlab::Access::DEVELOPER
- value 'MAINTAINER', value: Gitlab::Access::MAINTAINER
- value 'OWNER', value: Gitlab::Access::OWNER
+ value 'NO_ACCESS', value: Gitlab::Access::NO_ACCESS, description: 'No access'
+ value 'MINIMAL_ACCESS', value: Gitlab::Access::MINIMAL_ACCESS, description: 'Minimal access'
+ value 'GUEST', value: Gitlab::Access::GUEST, description: 'Guest access'
+ value 'REPORTER', value: Gitlab::Access::REPORTER, description: 'Reporter access'
+ value 'DEVELOPER', value: Gitlab::Access::DEVELOPER, description: 'Developer access'
+ value 'MAINTAINER', value: Gitlab::Access::MAINTAINER, description: 'Maintainer access'
+ value 'OWNER', value: Gitlab::Access::OWNER, description: 'Owner access'
end
end
diff --git a/app/graphql/types/admin/analytics/instance_statistics/measurement_identifier_enum.rb b/app/graphql/types/admin/analytics/instance_statistics/measurement_identifier_enum.rb
deleted file mode 100644
index c6ca5963588..00000000000
--- a/app/graphql/types/admin/analytics/instance_statistics/measurement_identifier_enum.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-module Types
- module Admin
- module Analytics
- module InstanceStatistics
- class MeasurementIdentifierEnum < BaseEnum
- graphql_name 'MeasurementIdentifier'
- description 'Possible identifier types for a measurement'
-
- value 'PROJECTS', 'Project count', value: 'projects'
- value 'USERS', 'User count', value: 'users'
- value 'ISSUES', 'Issue count', value: 'issues'
- value 'MERGE_REQUESTS', 'Merge request count', value: 'merge_requests'
- value 'GROUPS', 'Group count', value: 'groups'
- value 'PIPELINES', 'Pipeline count', value: 'pipelines'
- value 'PIPELINES_SUCCEEDED', 'Pipeline count with success status', value: 'pipelines_succeeded'
- value 'PIPELINES_FAILED', 'Pipeline count with failed status', value: 'pipelines_failed'
- value 'PIPELINES_CANCELED', 'Pipeline count with canceled status', value: 'pipelines_canceled'
- value 'PIPELINES_SKIPPED', 'Pipeline count with skipped status', value: 'pipelines_skipped'
- end
- end
- end
- end
-end
diff --git a/app/graphql/types/admin/analytics/usage_trends/measurement_identifier_enum.rb b/app/graphql/types/admin/analytics/usage_trends/measurement_identifier_enum.rb
new file mode 100644
index 00000000000..33bec5278fe
--- /dev/null
+++ b/app/graphql/types/admin/analytics/usage_trends/measurement_identifier_enum.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Types
+ module Admin
+ module Analytics
+ module UsageTrends
+ class MeasurementIdentifierEnum < BaseEnum
+ graphql_name 'MeasurementIdentifier'
+ description 'Possible identifier types for a measurement'
+
+ value 'PROJECTS', 'Project count.', value: 'projects'
+ value 'USERS', 'User count.', value: 'users'
+ value 'ISSUES', 'Issue count.', value: 'issues'
+ value 'MERGE_REQUESTS', 'Merge request count.', value: 'merge_requests'
+ value 'GROUPS', 'Group count.', value: 'groups'
+ value 'PIPELINES', 'Pipeline count.', value: 'pipelines'
+ value 'PIPELINES_SUCCEEDED', 'Pipeline count with success status.', value: 'pipelines_succeeded'
+ value 'PIPELINES_FAILED', 'Pipeline count with failed status.', value: 'pipelines_failed'
+ value 'PIPELINES_CANCELED', 'Pipeline count with canceled status.', value: 'pipelines_canceled'
+ value 'PIPELINES_SKIPPED', 'Pipeline count with skipped status.', value: 'pipelines_skipped'
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/admin/analytics/instance_statistics/measurement_type.rb b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
index 17a5af8d36b..c8ca702706f 100644
--- a/app/graphql/types/admin/analytics/instance_statistics/measurement_type.rb
+++ b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
@@ -3,13 +3,13 @@
module Types
module Admin
module Analytics
- module InstanceStatistics
+ module UsageTrends
class MeasurementType < BaseObject
include Gitlab::Graphql::Authorize::AuthorizeResource
- graphql_name 'InstanceStatisticsMeasurement'
+ graphql_name 'UsageTrendsMeasurement'
description 'Represents a recorded measurement (object count) for the Admins'
- authorize :read_instance_statistics_measurements
+ authorize :read_usage_trends_measurement
field :recorded_at, Types::TimeType, null: true,
description: 'The time the measurement was recorded.'
@@ -17,7 +17,7 @@ module Types
field :count, GraphQL::INT_TYPE, null: false,
description: 'Object count.'
- field :identifier, Types::Admin::Analytics::InstanceStatistics::MeasurementIdentifierEnum, null: false,
+ field :identifier, Types::Admin::Analytics::UsageTrends::MeasurementIdentifierEnum, null: false,
description: 'The type of objects being measured.'
end
end
diff --git a/app/graphql/types/alert_management/alert_sort_enum.rb b/app/graphql/types/alert_management/alert_sort_enum.rb
index 51e7bef0a7f..11a5cb95722 100644
--- a/app/graphql/types/alert_management/alert_sort_enum.rb
+++ b/app/graphql/types/alert_management/alert_sort_enum.rb
@@ -6,20 +6,20 @@ module Types
graphql_name 'AlertManagementAlertSort'
description 'Values for sorting alerts'
- value 'STARTED_AT_ASC', 'Start time by ascending order', value: :started_at_asc
- value 'STARTED_AT_DESC', 'Start time by descending order', value: :started_at_desc
- value 'ENDED_AT_ASC', 'End time by ascending order', value: :ended_at_asc
- value 'ENDED_AT_DESC', 'End time by descending order', value: :ended_at_desc
- value 'CREATED_TIME_ASC', 'Created time by ascending order', value: :created_at_asc
- value 'CREATED_TIME_DESC', 'Created time by descending order', value: :created_at_desc
- value 'UPDATED_TIME_ASC', 'Created time by ascending order', value: :updated_at_asc
- value 'UPDATED_TIME_DESC', 'Created time by descending order', value: :updated_at_desc
- value 'EVENT_COUNT_ASC', 'Events count by ascending order', value: :event_count_asc
- value 'EVENT_COUNT_DESC', 'Events count by descending order', value: :event_count_desc
- value 'SEVERITY_ASC', 'Severity from less critical to more critical', value: :severity_asc
- value 'SEVERITY_DESC', 'Severity from more critical to less critical', value: :severity_desc
- value 'STATUS_ASC', 'Status by order: Ignored > Resolved > Acknowledged > Triggered', value: :status_asc
- value 'STATUS_DESC', 'Status by order: Triggered > Acknowledged > Resolved > Ignored', value: :status_desc
+ value 'STARTED_AT_ASC', 'Start time by ascending order.', value: :started_at_asc
+ value 'STARTED_AT_DESC', 'Start time by descending order.', value: :started_at_desc
+ value 'ENDED_AT_ASC', 'End time by ascending order.', value: :ended_at_asc
+ value 'ENDED_AT_DESC', 'End time by descending order.', value: :ended_at_desc
+ value 'CREATED_TIME_ASC', 'Created time by ascending order.', value: :created_at_asc
+ value 'CREATED_TIME_DESC', 'Created time by descending order.', value: :created_at_desc
+ value 'UPDATED_TIME_ASC', 'Created time by ascending order.', value: :updated_at_asc
+ value 'UPDATED_TIME_DESC', 'Created time by descending order.', value: :updated_at_desc
+ value 'EVENT_COUNT_ASC', 'Events count by ascending order.', value: :event_count_asc
+ value 'EVENT_COUNT_DESC', 'Events count by descending order.', value: :event_count_desc
+ value 'SEVERITY_ASC', 'Severity from less critical to more critical.', value: :severity_asc
+ value 'SEVERITY_DESC', 'Severity from more critical to less critical.', value: :severity_desc
+ value 'STATUS_ASC', 'Status by order: Ignored > Resolved > Acknowledged > Triggered.', value: :status_asc
+ value 'STATUS_DESC', 'Status by order: Triggered > Acknowledged > Resolved > Ignored.', value: :status_desc
end
end
end
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index 6b7e7030c1f..5a2a5c68c8d 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -20,8 +20,14 @@ module Types
field :issue_iid,
GraphQL::ID_TYPE,
null: true,
+ deprecated: { reason: 'Use issue field', milestone: '13.10' },
description: 'Internal ID of the GitLab issue attached to the alert.'
+ field :issue,
+ Types::IssueType,
+ null: true,
+ description: 'Issue attached to the alert.'
+
field :title,
GraphQL::STRING_TYPE,
null: true,
diff --git a/app/graphql/types/alert_management/domain_filter_enum.rb b/app/graphql/types/alert_management/domain_filter_enum.rb
index a798cfb9ee9..3ee01e4c391 100644
--- a/app/graphql/types/alert_management/domain_filter_enum.rb
+++ b/app/graphql/types/alert_management/domain_filter_enum.rb
@@ -6,8 +6,8 @@ module Types
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'
+ 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/http_integration_type.rb b/app/graphql/types/alert_management/http_integration_type.rb
index 88782050b94..0d5bb50a77c 100644
--- a/app/graphql/types/alert_management/http_integration_type.rb
+++ b/app/graphql/types/alert_management/http_integration_type.rb
@@ -20,3 +20,5 @@ module Types
end
end
end
+
+Types::AlertManagement::HttpIntegrationType.prepend_ee_mod
diff --git a/app/graphql/types/alert_management/integration_type_enum.rb b/app/graphql/types/alert_management/integration_type_enum.rb
index 2f9be549e58..94f38e03409 100644
--- a/app/graphql/types/alert_management/integration_type_enum.rb
+++ b/app/graphql/types/alert_management/integration_type_enum.rb
@@ -6,8 +6,8 @@ module Types
graphql_name 'AlertManagementIntegrationType'
description 'Values of types of integrations'
- value 'PROMETHEUS', 'Prometheus integration', value: :prometheus
- value 'HTTP', 'Integration with any monitoring tool', value: :http
+ value 'PROMETHEUS', 'Prometheus integration.', value: :prometheus
+ value 'HTTP', 'Integration with any monitoring tool.', value: :http
end
end
end
diff --git a/app/graphql/types/base_argument.rb b/app/graphql/types/base_argument.rb
index 11774d0b59d..4ad9e8c0e40 100644
--- a/app/graphql/types/base_argument.rb
+++ b/app/graphql/types/base_argument.rb
@@ -6,7 +6,6 @@ module Types
def initialize(*args, **kwargs, &block)
kwargs = gitlab_deprecation(kwargs)
- kwargs.delete(:deprecation_reason)
super(*args, **kwargs, &block)
end
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb
index f145b9d45c3..78ab6890923 100644
--- a/app/graphql/types/base_field.rb
+++ b/app/graphql/types/base_field.rb
@@ -9,48 +9,29 @@ module Types
DEFAULT_COMPLEXITY = 1
- def initialize(*args, **kwargs, &block)
+ def initialize(**kwargs, &block)
@calls_gitaly = !!kwargs.delete(:calls_gitaly)
- @constant_complexity = !!kwargs[:complexity]
+ @constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0
@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)
kwargs = gitlab_deprecation(kwargs)
- super(*args, **kwargs, &block)
+ super(**kwargs, &block)
+
+ # We want to avoid the overhead of this in prod
+ extension ::Gitlab::Graphql::CallsGitaly::FieldExtension if Gitlab.dev_or_test_env?
+
+ extension ::Gitlab::Graphql::Present::FieldExtension
end
- def requires_argument?
- @requires_argument || arguments.values.any? { |argument| argument.type.non_null? }
+ def may_call_gitaly?
+ @constant_complexity || @calls_gitaly
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)
- ctx.schema.after_lazy(obj) do |after_obj|
- query_ctx = ctx.query.context
- inner_obj = after_obj&.object
-
- ctx.schema.after_lazy(to_ruby_args(after_obj, args, ctx)) do |ruby_args|
- if authorized?(inner_obj, ruby_args, query_ctx)
- if @resolve_proc
- # We pass `after_obj` here instead of `inner_obj` because extensions expect a GraphQL::Schema::Object
- with_extensions(after_obj, ruby_args, query_ctx) do |extended_obj, extended_args|
- # Since `extended_obj` is now a GraphQL::Schema::Object, we need to get the inner object and pass that to `@resolve_proc`
- extended_obj = extended_obj.object if extended_obj.is_a?(GraphQL::Schema::Object)
-
- @resolve_proc.call(extended_obj, args, ctx)
- end
- else
- public_send_field(after_obj, ruby_args, query_ctx)
- end
- else
- err = GraphQL::UnauthorizedFieldError.new(object: inner_obj, type: obj.class, context: ctx, field: self)
- query_ctx.schema.unauthorized_field(err)
- end
- end
- end
+ def requires_argument?
+ @requires_argument || arguments.values.any? { |argument| argument.type.non_null? }
end
def base_complexity
@@ -82,8 +63,10 @@ module Types
end
def check_feature_flag(args)
- args[:description] = feature_documentation_message(args[:feature_flag], args[:description]) if args[:feature_flag].present?
- args.delete(:feature_flag)
+ ff = args.delete(:feature_flag)
+ return args unless ff.present?
+
+ args[:description] = feature_documentation_message(ff, args[:description])
args
end
@@ -106,7 +89,9 @@ module Types
# items which can be loaded.
proc do |ctx, args, child_complexity|
# Resolvers may add extra complexity depending on used arguments
- complexity = child_complexity + self.resolver&.try(:resolver_complexity, args, child_complexity: child_complexity).to_i
+ complexity = child_complexity + resolver&.try(
+ :resolver_complexity, args, child_complexity: child_complexity
+ ).to_i
complexity += 1 if calls_gitaly?
complexity += complexity * connection_complexity_multiplier(ctx, args)
@@ -121,7 +106,7 @@ module Types
page_size = field_defn.connection_max_page_size || ctx.schema.default_max_page_size
limit_value = [args[:first], args[:last], page_size].compact.min
- multiplier = self.resolver&.try(:complexity_multiplier, args).to_f
+ multiplier = resolver&.try(:complexity_multiplier, args).to_f
limit_value * multiplier
end
end
diff --git a/app/graphql/types/blob_viewers/type_enum.rb b/app/graphql/types/blob_viewers/type_enum.rb
index 35e659197e5..3cb5c76d881 100644
--- a/app/graphql/types/blob_viewers/type_enum.rb
+++ b/app/graphql/types/blob_viewers/type_enum.rb
@@ -6,9 +6,9 @@ module Types
graphql_name 'BlobViewersType'
description 'Types of blob viewers'
- value 'rich', value: :rich
- value 'simple', value: :simple
- value 'auxiliary', value: :auxiliary
+ value 'rich', value: :rich, description: 'Rich blob viewers type.'
+ value 'simple', value: :simple, description: 'Simple blob viewers type.'
+ value 'auxiliary', value: :auxiliary, description: 'Auxiliary blob viewers type.'
end
end
end
diff --git a/app/graphql/types/board_list_type.rb b/app/graphql/types/board_list_type.rb
index 46b49c5d8a4..f215aa255de 100644
--- a/app/graphql/types/board_list_type.rb
+++ b/app/graphql/types/board_list_type.rb
@@ -8,6 +8,8 @@ module Types
graphql_name 'BoardList'
description 'Represents a list for an issue board'
+ alias_method :list, :object
+
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID (global ID) of the list.'
field :title, GraphQL::STRING_TYPE, null: false,
@@ -19,7 +21,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.'
+ description: 'Indicates if the list is collapsed for this user.'
field :issues_count, GraphQL::INT_TYPE, null: true,
description: 'Count of issues in the list.'
@@ -37,12 +39,10 @@ module Types
def metadata
strong_memoize(:metadata) do
- list = self.object
- user = context[:current_user]
params = (context[:issue_filters] || {}).merge(board_id: list.board_id, id: list.id)
::Boards::Issues::ListService
- .new(list.board.resource_parent, user, params)
+ .new(list.board.resource_parent, current_user, params)
.metadata
end
end
diff --git a/app/graphql/types/board_type.rb b/app/graphql/types/board_type.rb
index f8bd31d5fa0..f33f3f5e537 100644
--- a/app/graphql/types/board_type.rb
+++ b/app/graphql/types/board_type.rb
@@ -3,9 +3,9 @@
module Types
class BoardType < BaseObject
graphql_name 'Board'
- description 'Represents a project or group board'
+ description 'Represents a project or group issue board'
accepts ::Board
- authorize :read_board
+ authorize :read_issue_board
present_using BoardPresenter
diff --git a/app/graphql/types/boards/board_issue_input_base_type.rb b/app/graphql/types/boards/board_issue_input_base_type.rb
index dab1414760b..b762cef6e58 100644
--- a/app/graphql/types/boards/board_issue_input_base_type.rb
+++ b/app/graphql/types/boards/board_issue_input_base_type.rb
@@ -2,7 +2,6 @@
module Types
module Boards
- # rubocop: disable Graphql/AuthorizeTypes
class BoardIssueInputBaseType < BaseInputObject
argument :label_name, GraphQL::STRING_TYPE.to_list_type,
required: false,
@@ -28,7 +27,6 @@ module Types
required: false,
description: 'Filter by reaction emoji.'
end
- # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/boards/board_issue_input_type.rb b/app/graphql/types/boards/board_issue_input_type.rb
index 62a402ee724..9cc0f484a16 100644
--- a/app/graphql/types/boards/board_issue_input_type.rb
+++ b/app/graphql/types/boards/board_issue_input_type.rb
@@ -2,7 +2,6 @@
module Types
module Boards
- # rubocop: disable Graphql/AuthorizeTypes
class NegatedBoardIssueInputType < BoardIssueInputBaseType
end
@@ -17,7 +16,6 @@ module Types
required: false,
description: 'Search query for issue title or description.'
end
- # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/ci/config/status_enum.rb b/app/graphql/types/ci/config/status_enum.rb
index 92b04c61679..1ba207531b8 100644
--- a/app/graphql/types/ci/config/status_enum.rb
+++ b/app/graphql/types/ci/config/status_enum.rb
@@ -7,8 +7,8 @@ module Types
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
+ value 'VALID', 'The configuration file is valid.', value: :valid
+ value 'INVALID', 'The configuration file is not valid.', value: :invalid
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
index 4b484dec590..5099b0d4850 100644
--- a/app/graphql/types/ci/job_artifact_file_type_enum.rb
+++ b/app/graphql/types/ci/job_artifact_file_type_enum.rb
@@ -6,7 +6,8 @@ module Types
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
+ description = file_type == :codequality ? "CODE QUALITY" : file_type.to_s.titleize.upcase # This is needed as doc lint will not allow codequality as one word
+ value file_type.to_s.upcase, value: file_type.to_s, description: "#{description} job artifact file type."
end
end
end
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index ba463cdd9c1..c86337eea89 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -18,6 +18,10 @@ module Types
description: 'Schedule for the build.'
field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true,
description: 'Artifacts generated by the job.'
+ field :finished_at, Types::TimeType, null: true,
+ description: 'When a job has finished running.'
+ field :duration, GraphQL::INT_TYPE, null: true,
+ description: 'Duration of the job in seconds.'
def pipeline
Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, object.pipeline_id).find
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index 2c386c9b564..49be200a788 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -95,6 +95,9 @@ module Types
field :path, GraphQL::STRING_TYPE, null: true,
description: "Relative path to the pipeline's page."
+ field :commit_path, GraphQL::STRING_TYPE, null: true,
+ description: 'Path to the commit that triggered the pipeline.'
+
field :project, Types::ProjectType, null: true,
description: 'Project the pipeline belongs to.'
@@ -109,6 +112,10 @@ module Types
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find
end
+ def commit_path
+ ::Gitlab::Routing.url_helpers.project_commit_path(object.project, object.sha)
+ end
+
def path
::Gitlab::Routing.url_helpers.project_pipeline_path(object.project, object)
end
diff --git a/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb b/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb
index 9835a7ef208..ccb72283cf6 100644
--- a/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb
+++ b/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb
@@ -3,7 +3,6 @@
module Types
module CiConfiguration
module Sast
- # rubocop: disable Graphql/AuthorizeTypes
class AnalyzersEntityInputType < BaseInputObject
graphql_name 'SastCiConfigurationAnalyzersEntityInput'
description 'Represents the analyzers entity in SAST CI configuration'
diff --git a/app/graphql/types/ci_configuration/sast/entity_input_type.rb b/app/graphql/types/ci_configuration/sast/entity_input_type.rb
index 39b3efb3db8..9fce120889b 100644
--- a/app/graphql/types/ci_configuration/sast/entity_input_type.rb
+++ b/app/graphql/types/ci_configuration/sast/entity_input_type.rb
@@ -3,7 +3,6 @@
module Types
module CiConfiguration
module Sast
- # rubocop: disable Graphql/AuthorizeTypes
class EntityInputType < BaseInputObject
graphql_name 'SastCiConfigurationEntityInput'
description 'Represents an entity in SAST CI configuration'
diff --git a/app/graphql/types/ci_configuration/sast/input_type.rb b/app/graphql/types/ci_configuration/sast/input_type.rb
index 615436683f6..a86bdfca4da 100644
--- a/app/graphql/types/ci_configuration/sast/input_type.rb
+++ b/app/graphql/types/ci_configuration/sast/input_type.rb
@@ -3,7 +3,7 @@
module Types
module CiConfiguration
module Sast
- class InputType < BaseInputObject # rubocop:disable Graphql/AuthorizeTypes
+ class InputType < BaseInputObject
graphql_name 'SastCiConfigurationInput'
description 'Represents a CI configuration of SAST'
diff --git a/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb b/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb
index 3a208f9d3e4..76d2a314c13 100644
--- a/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb
+++ b/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb
@@ -7,9 +7,9 @@ module Types
graphql_name 'SastUiComponentSize'
description 'Size of UI component in SAST configuration page'
- value 'SMALL'
- value 'MEDIUM'
- value 'LARGE'
+ value 'SMALL', description: "The size of UI component in SAST configuration page is small."
+ value 'MEDIUM', description: "The size of UI component in SAST configuration page is medium."
+ value 'LARGE', description: "The size of UI component in SAST configuration page is large."
end
end
end
diff --git a/app/graphql/types/commit_action_mode_enum.rb b/app/graphql/types/commit_action_mode_enum.rb
index 77658a85b51..ea3d49c9822 100644
--- a/app/graphql/types/commit_action_mode_enum.rb
+++ b/app/graphql/types/commit_action_mode_enum.rb
@@ -5,10 +5,10 @@ module Types
graphql_name 'CommitActionMode'
description 'Mode of a commit action'
- value 'CREATE', description: 'Create command', value: :create
- value 'DELETE', description: 'Delete command', value: :delete
- value 'MOVE', description: 'Move command', value: :move
- value 'UPDATE', description: 'Update command', value: :update
- value 'CHMOD', description: 'Chmod command', value: :chmod
+ value 'CREATE', description: 'Create command.', value: :create
+ value 'DELETE', description: 'Delete command.', value: :delete
+ value 'MOVE', description: 'Move command.', value: :move
+ value 'UPDATE', description: 'Update command.', value: :update
+ value 'CHMOD', description: 'Chmod command.', value: :chmod
end
end
diff --git a/app/graphql/types/commit_action_type.rb b/app/graphql/types/commit_action_type.rb
index e14e7157752..cc1f45478e4 100644
--- a/app/graphql/types/commit_action_type.rb
+++ b/app/graphql/types/commit_action_type.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
module Types
- # rubocop: disable Graphql/AuthorizeTypes
class CommitActionType < BaseInputObject
argument :action, type: Types::CommitActionModeEnum, required: true,
description: 'The action to perform, create, delete, move, update, chmod.'
@@ -18,5 +17,4 @@ module Types
argument :encoding, type: Types::CommitEncodingEnum, required: false,
description: 'Encoding of the file. Default is text.'
end
- # rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/commit_encoding_enum.rb b/app/graphql/types/commit_encoding_enum.rb
index 0ea89b82db7..c51c1e864fb 100644
--- a/app/graphql/types/commit_encoding_enum.rb
+++ b/app/graphql/types/commit_encoding_enum.rb
@@ -4,7 +4,7 @@ module Types
class CommitEncodingEnum < BaseEnum
graphql_name 'CommitEncoding'
- value 'TEXT', description: 'Text encoding', value: :text
- value 'BASE64', description: 'Base64 encoding', value: :base64
+ value 'TEXT', description: 'Text encoding.', value: :text
+ value 'BASE64', description: 'Base64 encoding.', value: :base64
end
end
diff --git a/app/graphql/types/concerns/gitlab_style_deprecations.rb b/app/graphql/types/concerns/gitlab_style_deprecations.rb
index 9f087f3812d..ad195354930 100644
--- a/app/graphql/types/concerns/gitlab_style_deprecations.rb
+++ b/app/graphql/types/concerns/gitlab_style_deprecations.rb
@@ -10,7 +10,7 @@ module GitlabStyleDeprecations
def gitlab_deprecation(kwargs)
if kwargs[:deprecation_reason].present?
raise ArgumentError, 'Use `deprecated` property instead of `deprecation_reason`. ' \
- 'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-fields-and-enum-values'
+ 'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-fields-arguments-and-enum-values'
end
deprecation = kwargs.delete(:deprecated)
diff --git a/app/graphql/types/container_repository_sort_enum.rb b/app/graphql/types/container_repository_sort_enum.rb
index 96210c0546b..4f2e15fd32f 100644
--- a/app/graphql/types/container_repository_sort_enum.rb
+++ b/app/graphql/types/container_repository_sort_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'ContainerRepositorySort'
description 'Values for sorting container repositories'
- value 'NAME_ASC', 'Name by ascending order', value: :name_asc
- value 'NAME_DESC', 'Name by descending order', value: :name_desc
+ value 'NAME_ASC', 'Name by ascending order.', value: :name_asc
+ value 'NAME_DESC', 'Name by descending order.', value: :name_desc
end
end
diff --git a/app/graphql/types/current_user_todos.rb b/app/graphql/types/current_user_todos.rb
index 79a430af1d7..2551db875b0 100644
--- a/app/graphql/types/current_user_todos.rb
+++ b/app/graphql/types/current_user_todos.rb
@@ -16,9 +16,10 @@ module Types
end
def current_user_todos(state: nil)
- state ||= %i(done pending) # TodosFinder treats a `nil` state param as `pending`
+ state ||= %i[done pending] # TodosFinder treats a `nil` state param as `pending`
+ klass = unpresented.class
- TodosFinder.new(current_user, state: state, type: object.class.name, target_id: object.id).execute
+ TodosFinder.new(current_user, state: state, type: klass.name, target_id: object.id).execute
end
end
end
diff --git a/app/graphql/types/design_management/design_version_event_enum.rb b/app/graphql/types/design_management/design_version_event_enum.rb
index ea4bc1ffbfa..354b34c9f9f 100644
--- a/app/graphql/types/design_management/design_version_event_enum.rb
+++ b/app/graphql/types/design_management/design_version_event_enum.rb
@@ -8,7 +8,7 @@ module Types
NONE = 'NONE'
- value NONE, 'No change'
+ value NONE, 'No change.'
::DesignManagement::Action.events.keys.each do |event_name|
value event_name.upcase, value: event_name, description: "A #{event_name} event"
diff --git a/app/graphql/types/diff_paths_input_type.rb b/app/graphql/types/diff_paths_input_type.rb
index 864cec1ab07..d148b7656eb 100644
--- a/app/graphql/types/diff_paths_input_type.rb
+++ b/app/graphql/types/diff_paths_input_type.rb
@@ -1,12 +1,10 @@
# frozen_string_literal: true
module Types
- # rubocop: disable Graphql/AuthorizeTypes
class DiffPathsInputType < BaseInputObject
argument :old_path, GraphQL::STRING_TYPE, required: false,
description: 'The path of the file on the start sha.'
argument :new_path, GraphQL::STRING_TYPE, required: false,
description: 'The path of the file on the head sha.'
end
- # rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/error_tracking/sentry_error_status_enum.rb b/app/graphql/types/error_tracking/sentry_error_status_enum.rb
index df68eef4f3c..10579bcbfb1 100644
--- a/app/graphql/types/error_tracking/sentry_error_status_enum.rb
+++ b/app/graphql/types/error_tracking/sentry_error_status_enum.rb
@@ -6,10 +6,10 @@ module Types
graphql_name 'SentryErrorStatus'
description 'State of a Sentry error'
- value 'RESOLVED', value: 'resolved', description: 'Error has been resolved'
- value 'RESOLVED_IN_NEXT_RELEASE', value: 'resolvedInNextRelease', description: 'Error has been ignored until next release'
- value 'UNRESOLVED', value: 'unresolved', description: 'Error is unresolved'
- value 'IGNORED', value: 'ignored', description: 'Error has been ignored'
+ value 'RESOLVED', value: 'resolved', description: 'Error has been resolved.'
+ value 'RESOLVED_IN_NEXT_RELEASE', value: 'resolvedInNextRelease', description: 'Error has been ignored until next release.'
+ value 'UNRESOLVED', value: 'unresolved', description: 'Error is unresolved.'
+ value 'IGNORED', value: 'ignored', description: 'Error has been ignored.'
end
end
end
diff --git a/app/graphql/types/global_id_type.rb b/app/graphql/types/global_id_type.rb
index ed28c3ffd7e..750bd1bfe8d 100644
--- a/app/graphql/types/global_id_type.rb
+++ b/app/graphql/types/global_id_type.rb
@@ -19,7 +19,14 @@ end
module Types
class GlobalIDType < BaseScalar
graphql_name 'GlobalID'
- description 'A global identifier'
+ description <<~DESC
+ A global identifier.
+
+ A global identifier represents an object uniquely across the application.
+ An example of such an identifier is "gid://gitlab/User/1".
+
+ Global identifiers are encoded as strings.
+ DESC
# @param value [GID]
# @return [String]
@@ -46,35 +53,40 @@ module Types
@id_types[model_class] ||= Class.new(self) do
graphql_name "#{model_class.name.gsub(/::/, '')}ID"
- description "Identifier of #{model_class.name}."
+ description <<~MD
+ A `#{graphql_name}` is a global ID. It is encoded as a string.
+
+ An example `#{graphql_name}` is: `"#{::Gitlab::GlobalId.build(model_name: model_class.name, id: 1)}"`.
+ MD
- self.define_singleton_method(:to_s) do
+ define_singleton_method(:to_s) do
graphql_name
end
- self.define_singleton_method(:inspect) do
+ define_singleton_method(:inspect) do
graphql_name
end
- self.define_singleton_method(:coerce_result) do |gid, ctx|
+ define_singleton_method(:coerce_result) do |gid, ctx|
global_id = ::Gitlab::GlobalId.as_global_id(gid, model_name: model_class.name)
- if suitable?(global_id)
- global_id.to_s
- else
- raise GraphQL::CoercionError, "Expected a #{model_class.name} ID, got #{global_id}"
- end
+ next global_id.to_s if suitable?(global_id)
+
+ raise GraphQL::CoercionError, "Expected a #{model_class.name} ID, got #{global_id}"
end
- self.define_singleton_method(:suitable?) do |gid|
- gid&.model_class&.ancestors&.include?(model_class)
+ define_singleton_method(:suitable?) do |gid|
+ next false if gid.nil?
+
+ gid.model_name.safe_constantize.present? &&
+ gid.model_class.ancestors.include?(model_class)
end
- self.define_singleton_method(:coerce_input) do |string, ctx|
+ define_singleton_method(:coerce_input) do |string, ctx|
gid = super(string, ctx)
- raise GraphQL::CoercionError, "#{string.inspect} does not represent an instance of #{model_class.name}" unless suitable?(gid)
+ next gid if suitable?(gid)
- gid
+ raise GraphQL::CoercionError, "#{string.inspect} does not represent an instance of #{model_class.name}"
end
end
end
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 0aaeb8d20df..7a84e76657b 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -95,6 +95,10 @@ module Types
field :container_repositories_count, GraphQL::INT_TYPE, null: false,
description: 'Number of container repositories in the group.'
+ field :packages,
+ description: 'Packages of the group.',
+ resolver: Resolvers::GroupPackagesResolver
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
LabelsFinder
diff --git a/app/graphql/types/issuable_sort_enum.rb b/app/graphql/types/issuable_sort_enum.rb
index a6d52124d99..f6e17d8988e 100644
--- a/app/graphql/types/issuable_sort_enum.rb
+++ b/app/graphql/types/issuable_sort_enum.rb
@@ -5,11 +5,11 @@ module Types
graphql_name 'IssuableSort'
description 'Values for sorting issuables'
- value 'PRIORITY_ASC', 'Priority by ascending order', value: :priority_asc
- value 'PRIORITY_DESC', 'Priority by descending order', value: :priority_desc
- value 'LABEL_PRIORITY_ASC', 'Label priority by ascending order', value: :label_priority_asc
- value 'LABEL_PRIORITY_DESC', 'Label priority by descending order', value: :label_priority_desc
- value 'MILESTONE_DUE_ASC', 'Milestone due date by ascending order', value: :milestone_due_asc
- value 'MILESTONE_DUE_DESC', 'Milestone due date by descending order', value: :milestone_due_desc
+ value 'PRIORITY_ASC', 'Priority by ascending order.', value: :priority_asc
+ value 'PRIORITY_DESC', 'Priority by descending order.', value: :priority_desc
+ value 'LABEL_PRIORITY_ASC', 'Label priority by ascending order.', value: :label_priority_asc
+ value 'LABEL_PRIORITY_DESC', 'Label priority by descending order.', value: :label_priority_desc
+ value 'MILESTONE_DUE_ASC', 'Milestone due date by ascending order.', value: :milestone_due_asc
+ value 'MILESTONE_DUE_DESC', 'Milestone due date by descending order.', value: :milestone_due_desc
end
end
diff --git a/app/graphql/types/issuable_state_enum.rb b/app/graphql/types/issuable_state_enum.rb
index 543b7f8e5b2..5a1b11b3bdc 100644
--- a/app/graphql/types/issuable_state_enum.rb
+++ b/app/graphql/types/issuable_state_enum.rb
@@ -5,9 +5,9 @@ module Types
graphql_name 'IssuableState'
description 'State of a GitLab issue or merge request'
- value 'opened'
- value 'closed'
- value 'locked'
- value 'all'
+ value 'opened', description: 'In open state.'
+ value 'closed', description: 'In closed state.'
+ value 'locked', description: 'Discussion has been locked.'
+ value 'all', description: 'All available.'
end
end
diff --git a/app/graphql/types/issue_sort_enum.rb b/app/graphql/types/issue_sort_enum.rb
index 08762264b1b..bf900fe3525 100644
--- a/app/graphql/types/issue_sort_enum.rb
+++ b/app/graphql/types/issue_sort_enum.rb
@@ -5,11 +5,11 @@ module Types
graphql_name 'IssueSort'
description 'Values for sorting issues'
- value 'DUE_DATE_ASC', 'Due date by ascending order', value: :due_date_asc
- value 'DUE_DATE_DESC', 'Due date by descending order', value: :due_date_desc
- value 'RELATIVE_POSITION_ASC', 'Relative position by ascending order', value: :relative_position_asc
- value 'SEVERITY_ASC', 'Severity from less critical to more critical', value: :severity_asc
- value 'SEVERITY_DESC', 'Severity from more critical to less critical', value: :severity_desc
+ value 'DUE_DATE_ASC', 'Due date by ascending order.', value: :due_date_asc
+ value 'DUE_DATE_DESC', 'Due date by descending order.', value: :due_date_desc
+ value 'RELATIVE_POSITION_ASC', 'Relative position by ascending order.', value: :relative_position_asc
+ value 'SEVERITY_ASC', 'Severity from less critical to more critical.', value: :severity_asc
+ value 'SEVERITY_DESC', 'Severity from more critical to less critical.', value: :severity_desc
end
end
diff --git a/app/graphql/types/issue_state_event_enum.rb b/app/graphql/types/issue_state_event_enum.rb
index 6a9d840831d..165b9c28367 100644
--- a/app/graphql/types/issue_state_event_enum.rb
+++ b/app/graphql/types/issue_state_event_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'IssueStateEvent'
description 'Values for issue state events'
- value 'REOPEN', 'Reopens the issue', value: 'reopen'
- value 'CLOSE', 'Closes the issue', value: 'close'
+ value 'REOPEN', 'Reopens the issue.', value: 'reopen'
+ value 'CLOSE', 'Closes the issue.', value: 'close'
end
end
diff --git a/app/graphql/types/jira_users_mapping_input_type.rb b/app/graphql/types/jira_users_mapping_input_type.rb
index 0c26ea87df2..61e3240ecf3 100644
--- a/app/graphql/types/jira_users_mapping_input_type.rb
+++ b/app/graphql/types/jira_users_mapping_input_type.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
module Types
- # rubocop: disable Graphql/AuthorizeTypes
class JiraUsersMappingInputType < BaseInputObject
graphql_name 'JiraUsersMappingInputType'
@@ -14,5 +13,4 @@ module Types
required: false,
description: 'Id of the GitLab user.'
end
- # rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/label_type.rb b/app/graphql/types/label_type.rb
index 94fd15e075c..4e8718a80da 100644
--- a/app/graphql/types/label_type.rb
+++ b/app/graphql/types/label_type.rb
@@ -19,5 +19,9 @@ module Types
description: 'Background color of the label.'
field :text_color, GraphQL::STRING_TYPE, null: false,
description: 'Text color of the label.'
+ field :created_at, Types::TimeType, null: false,
+ description: 'When this label was created.'
+ field :updated_at, Types::TimeType, null: false,
+ description: 'When this label was last updated.'
end
end
diff --git a/app/graphql/types/merge_request_sort_enum.rb b/app/graphql/types/merge_request_sort_enum.rb
index c64ae367a76..92a71998d91 100644
--- a/app/graphql/types/merge_request_sort_enum.rb
+++ b/app/graphql/types/merge_request_sort_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'MergeRequestSort'
description 'Values for sorting merge requests'
- value 'MERGED_AT_ASC', 'Merge time by ascending order', value: :merged_at_asc
- value 'MERGED_AT_DESC', 'Merge time by descending order', value: :merged_at_desc
+ value 'MERGED_AT_ASC', 'Merge time by ascending order.', value: :merged_at_asc
+ value 'MERGED_AT_DESC', 'Merge time by descending order.', value: :merged_at_desc
end
end
diff --git a/app/graphql/types/merge_request_state_enum.rb b/app/graphql/types/merge_request_state_enum.rb
index c14b9f80a53..a2d7bd0306c 100644
--- a/app/graphql/types/merge_request_state_enum.rb
+++ b/app/graphql/types/merge_request_state_enum.rb
@@ -5,6 +5,6 @@ module Types
graphql_name 'MergeRequestState'
description 'State of a GitLab merge request'
- value 'merged', description: "Merge Request has been merged"
+ value 'merged', description: "Merge Request has been merged."
end
end
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index 10f324e901a..449286915f2 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -54,7 +54,7 @@ module Types
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,
- description: 'Indicates if the merge request is a work in progress (WIP).'
+ description: 'Indicates if the merge request is a draft.'
field :merge_when_pipeline_succeeds, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if the merge has been set to be merged when its pipeline succeeds (MWPS).'
field :diff_head_sha, GraphQL::STRING_TYPE, null: true,
@@ -108,6 +108,10 @@ module Types
null: false, calls_gitaly: true,
method: :target_branch_exists?,
description: 'Indicates if the target branch of the merge request exists.'
+ field :diverged_from_target_branch, GraphQL::BOOLEAN_TYPE,
+ null: false, calls_gitaly: true,
+ method: :diverged_from_target_branch?,
+ description: 'Indicates if the source branch is behind the target branch.'
field :mergeable_discussions_state, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if all discussions in the merge request have been resolved, allowing the merge request to be merged.'
field :web_url, GraphQL::STRING_TYPE, null: true,
diff --git a/app/graphql/types/merge_strategy_enum.rb b/app/graphql/types/merge_strategy_enum.rb
new file mode 100644
index 00000000000..2120dc576eb
--- /dev/null
+++ b/app/graphql/types/merge_strategy_enum.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Types
+ class MergeStrategyEnum < BaseEnum
+ AutoMergeService.all_strategies_ordered_by_preference.each do |strat|
+ value strat.upcase, value: strat, description: "Use the #{strat} merge strategy."
+ end
+ end
+end
diff --git a/app/graphql/types/milestone_state_enum.rb b/app/graphql/types/milestone_state_enum.rb
index e3b60395c9b..f3797f8f9e5 100644
--- a/app/graphql/types/milestone_state_enum.rb
+++ b/app/graphql/types/milestone_state_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'MilestoneStateEnum'
description 'Current state of milestone'
- value 'active', description: 'Milestone is currently active'
- value 'closed', description: 'Milestone is closed'
+ value 'active', description: 'Milestone is currently active.'
+ value 'closed', description: 'Milestone is closed.'
end
end
diff --git a/app/graphql/types/mutation_operation_mode_enum.rb b/app/graphql/types/mutation_operation_mode_enum.rb
index 37e83e7a2e1..75c1d7cd4a6 100644
--- a/app/graphql/types/mutation_operation_mode_enum.rb
+++ b/app/graphql/types/mutation_operation_mode_enum.rb
@@ -7,8 +7,8 @@ module Types
# Suggested param name for the enum: `operation_mode`
- value 'REPLACE', 'Performs a replace operation'
- value 'APPEND', 'Performs an append operation'
- value 'REMOVE', 'Performs a removal operation'
+ value 'REPLACE', 'Performs a replace operation.'
+ value 'APPEND', 'Performs an append operation.'
+ value 'REMOVE', 'Performs a removal operation.'
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 166f5617da2..76ffddf416f 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -24,6 +24,7 @@ module Types
mount_mutation Mutations::AwardEmojis::Toggle
mount_mutation Mutations::Boards::Create
mount_mutation Mutations::Boards::Destroy
+ mount_mutation Mutations::Boards::Update
mount_mutation Mutations::Boards::Issues::IssueMoveList
mount_mutation Mutations::Boards::Lists::Create
mount_mutation Mutations::Boards::Lists::Update
@@ -43,6 +44,7 @@ module Types
mount_mutation Mutations::Issues::Update
mount_mutation Mutations::Issues::Move
mount_mutation Mutations::Labels::Create
+ mount_mutation Mutations::MergeRequests::Accept
mount_mutation Mutations::MergeRequests::Create
mount_mutation Mutations::MergeRequests::Update
mount_mutation Mutations::MergeRequests::SetLabels
@@ -57,19 +59,15 @@ module Types
mount_mutation Mutations::Notes::Create::Note, calls_gitaly: true
mount_mutation Mutations::Notes::Create::DiffNote, calls_gitaly: true
mount_mutation Mutations::Notes::Create::ImageDiffNote, calls_gitaly: true
- mount_mutation Mutations::Notes::Update::Note,
- description: 'Updates a Note. If the body of the Note contains only quick actions, ' \
- 'the Note will be destroyed during the update, and no Note will be ' \
- 'returned'
- mount_mutation Mutations::Notes::Update::ImageDiffNote,
- description: 'Updates a DiffNote on an image (a `Note` where the `position.positionType` is `"image"`). ' \
- 'If the body of the Note contains only quick actions, the Note will be ' \
- 'destroyed during the update, and no Note will be returned'
+ mount_mutation Mutations::Notes::Update::Note
+ mount_mutation Mutations::Notes::Update::ImageDiffNote
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::ReleaseAssetLinks::Create
+ mount_mutation Mutations::ReleaseAssetLinks::Update
mount_mutation Mutations::Terraform::State::Delete
mount_mutation Mutations::Terraform::State::Lock
mount_mutation Mutations::Terraform::State::Unlock
@@ -95,6 +93,7 @@ module Types
mount_mutation Mutations::Ci::Pipeline::Retry
mount_mutation Mutations::Ci::CiCdSettingsUpdate
mount_mutation Mutations::Namespace::PackageSettings::Update
+ mount_mutation Mutations::UserCallouts::Create
end
end
diff --git a/app/graphql/types/notes/diff_image_position_input_type.rb b/app/graphql/types/notes/diff_image_position_input_type.rb
index 23b53b20815..dd5c8f20cc3 100644
--- a/app/graphql/types/notes/diff_image_position_input_type.rb
+++ b/app/graphql/types/notes/diff_image_position_input_type.rb
@@ -2,7 +2,6 @@
module Types
module Notes
- # rubocop: disable Graphql/AuthorizeTypes
class DiffImagePositionInputType < DiffPositionBaseInputType
graphql_name 'DiffImagePositionInput'
@@ -15,6 +14,5 @@ module Types
argument :height, GraphQL::INT_TYPE, required: true,
description: copy_field_description(Types::Notes::DiffPositionType, :height)
end
- # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/notes/diff_position_base_input_type.rb b/app/graphql/types/notes/diff_position_base_input_type.rb
index a9b4e1a8948..c8f9f9028cc 100644
--- a/app/graphql/types/notes/diff_position_base_input_type.rb
+++ b/app/graphql/types/notes/diff_position_base_input_type.rb
@@ -2,7 +2,6 @@
module Types
module Notes
- # rubocop: disable Graphql/AuthorizeTypes
class DiffPositionBaseInputType < BaseInputObject
argument :head_sha, GraphQL::STRING_TYPE, required: true,
description: copy_field_description(Types::DiffRefsType, :head_sha)
@@ -17,6 +16,5 @@ module Types
description: 'The paths of the file that was changed. ' \
'Both of the properties of this input are optional, but at least one of them is required'
end
- # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/notes/diff_position_input_type.rb b/app/graphql/types/notes/diff_position_input_type.rb
index 02c91e173cb..7ec5fd9e086 100644
--- a/app/graphql/types/notes/diff_position_input_type.rb
+++ b/app/graphql/types/notes/diff_position_input_type.rb
@@ -2,15 +2,13 @@
module Types
module Notes
- # rubocop: disable Graphql/AuthorizeTypes
class DiffPositionInputType < DiffPositionBaseInputType
graphql_name 'DiffPositionInput'
argument :old_line, GraphQL::INT_TYPE, required: false,
description: copy_field_description(Types::Notes::DiffPositionType, :old_line)
- argument :new_line, GraphQL::INT_TYPE, required: true,
+ argument :new_line, GraphQL::INT_TYPE, required: false,
description: copy_field_description(Types::Notes::DiffPositionType, :new_line)
end
- # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/notes/position_type_enum.rb b/app/graphql/types/notes/position_type_enum.rb
index abdb2cfc804..9939f6511ce 100644
--- a/app/graphql/types/notes/position_type_enum.rb
+++ b/app/graphql/types/notes/position_type_enum.rb
@@ -6,8 +6,8 @@ module Types
graphql_name 'DiffPositionType'
description 'Type of file the position refers to'
- value 'text'
- value 'image'
+ value 'text', description: "A text file"
+ value 'image', description: "An image"
end
end
end
diff --git a/app/graphql/types/notes/update_diff_image_position_input_type.rb b/app/graphql/types/notes/update_diff_image_position_input_type.rb
index 1b915b65ae9..ab27f6b9ad3 100644
--- a/app/graphql/types/notes/update_diff_image_position_input_type.rb
+++ b/app/graphql/types/notes/update_diff_image_position_input_type.rb
@@ -3,8 +3,6 @@
module Types
module Notes
# InputType used for updateImageDiffNote mutation.
- #
- # rubocop: disable Graphql/AuthorizeTypes
class UpdateDiffImagePositionInputType < BaseInputObject
graphql_name 'UpdateDiffImagePositionInput'
@@ -32,6 +30,5 @@ module Types
end
end
end
- # rubocop: enable Graphql/AuthorizeTypes
end
end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 7205c615271..9a3f2e311e6 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -181,7 +181,7 @@ module Types
field :packages,
description: 'Packages of the project.',
- resolver: Resolvers::PackagesResolver
+ resolver: Resolvers::ProjectPackagesResolver
field :pipelines,
null: true,
@@ -273,6 +273,12 @@ module Types
description: 'Integrations which can receive alerts for the project.',
resolver: Resolvers::AlertManagement::IntegrationsResolver
+ field :alert_management_http_integrations,
+ Types::AlertManagement::HttpIntegrationType.connection_type,
+ null: true,
+ description: 'HTTP Integrations which can receive alerts for the project.',
+ resolver: Resolvers::AlertManagement::HttpIntegrationsResolver
+
field :releases,
Types::ReleaseType.connection_type,
null: true,
diff --git a/app/graphql/types/projects/namespace_project_sort_enum.rb b/app/graphql/types/projects/namespace_project_sort_enum.rb
index ede29748beb..bd7058196dd 100644
--- a/app/graphql/types/projects/namespace_project_sort_enum.rb
+++ b/app/graphql/types/projects/namespace_project_sort_enum.rb
@@ -6,8 +6,8 @@ module Types
graphql_name 'NamespaceProjectSort'
description 'Values for sorting projects'
- value 'SIMILARITY', 'Most similar to the search query', value: :similarity
- value 'STORAGE', 'Sort by storage size', value: :storage
+ value 'SIMILARITY', 'Most similar to the search query.', value: :similarity
+ value 'STORAGE', 'Sort by storage size.', value: :storage
end
end
end
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index 1d1ab4f2e17..74818bfcd42 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -78,14 +78,20 @@ module Types
field :issue, Types::IssueType,
null: true,
- description: 'Find an issue.' do
+ description: 'Find an Issue.' do
argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'The global ID of the Issue.'
end
- field :instance_statistics_measurements, Types::Admin::Analytics::InstanceStatistics::MeasurementType.connection_type,
+ field :instance_statistics_measurements, Types::Admin::Analytics::UsageTrends::MeasurementType.connection_type,
null: true,
description: 'Get statistics on the instance.',
- resolver: Resolvers::Admin::Analytics::InstanceStatistics::MeasurementsResolver
+ deprecated: { reason: 'This field was renamed. Use the `usageTrendsMeasurements` field instead', milestone: '13.10' },
+ resolver: Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver
+
+ field :usage_trends_measurements, Types::Admin::Analytics::UsageTrends::MeasurementType.connection_type,
+ null: true,
+ description: 'Get statistics on the instance.',
+ resolver: Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver
field :ci_application_settings, Types::Ci::ApplicationSettingType,
null: true,
diff --git a/app/graphql/types/range_input_type.rb b/app/graphql/types/range_input_type.rb
index b75c3669fbf..e31b8ecd811 100644
--- a/app/graphql/types/range_input_type.rb
+++ b/app/graphql/types/range_input_type.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
module Types
- # rubocop: disable Graphql/AuthorizeTypes
class RangeInputType < BaseInputObject
def self.[](type, closed = true)
@subtypes ||= {}
@@ -25,5 +24,4 @@ module Types
to_h
end
end
- # rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/release_asset_link_input_type.rb b/app/graphql/types/release_asset_link_input_type.rb
index 242d19b683f..17d05a73797 100644
--- a/app/graphql/types/release_asset_link_input_type.rb
+++ b/app/graphql/types/release_asset_link_input_type.rb
@@ -1,25 +1,10 @@
# frozen_string_literal: true
module Types
- # rubocop: disable Graphql/AuthorizeTypes
class ReleaseAssetLinkInputType < BaseInputObject
graphql_name 'ReleaseAssetLinkInput'
description 'Fields that are available when modifying a release asset link'
- argument :name, GraphQL::STRING_TYPE,
- required: true,
- description: 'Name of the asset link.'
-
- argument :url, GraphQL::STRING_TYPE,
- required: true,
- description: 'URL of the asset link.'
-
- argument :direct_asset_path, GraphQL::STRING_TYPE,
- required: false, as: :filepath,
- description: 'Relative path for a direct asset link.'
-
- argument :link_type, Types::ReleaseAssetLinkTypeEnum,
- required: false, default_value: 'other',
- description: 'The type of the asset link.'
+ include Types::ReleaseAssetLinkSharedInputArguments
end
end
diff --git a/app/graphql/types/release_asset_link_shared_input_arguments.rb b/app/graphql/types/release_asset_link_shared_input_arguments.rb
new file mode 100644
index 00000000000..4aa247e47cc
--- /dev/null
+++ b/app/graphql/types/release_asset_link_shared_input_arguments.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Types
+ module ReleaseAssetLinkSharedInputArguments
+ extend ActiveSupport::Concern
+
+ included do
+ argument :name, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Name of the asset link.'
+
+ argument :url, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'URL of the asset link.'
+
+ argument :direct_asset_path, GraphQL::STRING_TYPE,
+ required: false, as: :filepath,
+ description: 'Relative path for a direct asset link.'
+
+ argument :link_type, Types::ReleaseAssetLinkTypeEnum,
+ required: false, default_value: 'other',
+ description: 'The type of the asset link.'
+ end
+ end
+end
diff --git a/app/graphql/types/release_assets_input_type.rb b/app/graphql/types/release_assets_input_type.rb
index f50be89d43f..2c8d3de3495 100644
--- a/app/graphql/types/release_assets_input_type.rb
+++ b/app/graphql/types/release_assets_input_type.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
module Types
- # rubocop: disable Graphql/AuthorizeTypes
class ReleaseAssetsInputType < BaseInputObject
graphql_name 'ReleaseAssetsInput'
description 'Fields that are available when modifying release assets'
diff --git a/app/graphql/types/release_sort_enum.rb b/app/graphql/types/release_sort_enum.rb
index 2f9af1bced9..f51b73d89f1 100644
--- a/app/graphql/types/release_sort_enum.rb
+++ b/app/graphql/types/release_sort_enum.rb
@@ -9,10 +9,10 @@ module Types
# Borrowed from Types::SortEnum
# These values/descriptions should stay in-sync as much as possible.
- value 'CREATED_DESC', 'Created at descending order', value: :created_desc
- value 'CREATED_ASC', 'Created at ascending order', value: :created_asc
+ value 'CREATED_DESC', 'Created at descending order.', value: :created_desc
+ value 'CREATED_ASC', 'Created at ascending order.', value: :created_asc
- value 'RELEASED_AT_DESC', 'Released at by descending order', value: :released_at_desc
- value 'RELEASED_AT_ASC', 'Released at by ascending order', value: :released_at_asc
+ value 'RELEASED_AT_DESC', 'Released at by descending order.', value: :released_at_desc
+ value 'RELEASED_AT_ASC', 'Released at by ascending order.', value: :released_at_asc
end
end
diff --git a/app/graphql/types/snippets/blob_action_input_type.rb b/app/graphql/types/snippets/blob_action_input_type.rb
index c4289375f6b..13eade3dcc4 100644
--- a/app/graphql/types/snippets/blob_action_input_type.rb
+++ b/app/graphql/types/snippets/blob_action_input_type.rb
@@ -2,7 +2,7 @@
module Types
module Snippets
- class BlobActionInputType < BaseInputObject # rubocop:disable Graphql/AuthorizeTypes
+ class BlobActionInputType < BaseInputObject
graphql_name 'SnippetBlobActionInputType'
description 'Represents an action to perform over a snippet file'
diff --git a/app/graphql/types/snippets/blob_type.rb b/app/graphql/types/snippets/blob_type.rb
index fb0c1d9409b..fb9ee380705 100644
--- a/app/graphql/types/snippets/blob_type.rb
+++ b/app/graphql/types/snippets/blob_type.rb
@@ -14,7 +14,6 @@ module Types
field :plain_data, GraphQL::STRING_TYPE,
description: 'Blob plain highlighted data.',
- calls_gitaly: true,
null: true
field :raw_path, GraphQL::STRING_TYPE,
diff --git a/app/graphql/types/sort_enum.rb b/app/graphql/types/sort_enum.rb
index c3a76330fe9..ff994039b6d 100644
--- a/app/graphql/types/sort_enum.rb
+++ b/app/graphql/types/sort_enum.rb
@@ -7,14 +7,14 @@ module Types
# Deprecated, as we prefer uppercase enums
# https://gitlab.com/groups/gitlab-org/-/epics/1838
- 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, 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
- value 'CREATED_DESC', 'Created at descending order', value: :created_desc
- value 'CREATED_ASC', 'Created at ascending order', value: :created_asc
+ value 'UPDATED_DESC', 'Updated at descending order.', value: :updated_desc
+ value 'UPDATED_ASC', 'Updated at ascending order.', value: :updated_asc
+ value 'CREATED_DESC', 'Created at descending order.', value: :created_desc
+ value 'CREATED_ASC', 'Created at ascending order.', value: :created_asc
end
end
diff --git a/app/graphql/types/time_type.rb b/app/graphql/types/time_type.rb
index c31e4873df0..2db14953308 100644
--- a/app/graphql/types/time_type.rb
+++ b/app/graphql/types/time_type.rb
@@ -3,7 +3,13 @@
module Types
class TimeType < BaseScalar
graphql_name 'Time'
- description 'Time represented in ISO 8601'
+ description <<~DESC
+ Time represented in ISO 8601.
+
+ For example: "2021-03-09T14:58:50+00:00".
+
+ See `https://www.iso.org/iso-8601-date-and-time-format.html`.
+ DESC
def self.coerce_input(value, ctx)
Time.parse(value)
diff --git a/app/graphql/types/timeframe_input_type.rb b/app/graphql/types/timeframe_input_type.rb
index 79c1bc5cf01..02a0ec7df7a 100644
--- a/app/graphql/types/timeframe_input_type.rb
+++ b/app/graphql/types/timeframe_input_type.rb
@@ -1,10 +1,8 @@
# frozen_string_literal: true
module Types
- # rubocop: disable Graphql/AuthorizeTypes
class TimeframeInputType < RangeInputType[::Types::DateType]
graphql_name 'Timeframe'
description 'A time-frame defined as a closed inclusive range of two dates'
end
- # rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/todo_action_enum.rb b/app/graphql/types/todo_action_enum.rb
index 0e538838474..ef43b6eb464 100644
--- a/app/graphql/types/todo_action_enum.rb
+++ b/app/graphql/types/todo_action_enum.rb
@@ -2,12 +2,14 @@
module Types
class TodoActionEnum < BaseEnum
- value 'assigned', value: 1
- value 'mentioned', value: 2
- value 'build_failed', value: 3
- value 'marked', value: 4
- value 'approval_required', value: 5
- value 'unmergeable', value: 6
- value 'directly_addressed', value: 7
+ value 'assigned', value: 1, description: 'User was assigned.'
+ value 'mentioned', value: 2, description: 'User was mentioned.'
+ value 'build_failed', value: 3, description: 'Build triggered by the user failed.'
+ value 'marked', value: 4, description: 'User added a TODO.'
+ value 'approval_required', value: 5, description: 'User was set as an approver.'
+ value 'unmergeable', value: 6, description: 'Merge request authored by the user could not be merged.'
+ value 'directly_addressed', value: 7, description: 'User was directly addressed.'
+ value 'merge_train_removed', value: 8, description: 'Merge request authored by the user was removed from the merge train.'
+ value 'review_requested', value: 9, description: 'Review was requested from the user.'
end
end
diff --git a/app/graphql/types/todo_state_enum.rb b/app/graphql/types/todo_state_enum.rb
index 29a28b5208d..604e2a62f70 100644
--- a/app/graphql/types/todo_state_enum.rb
+++ b/app/graphql/types/todo_state_enum.rb
@@ -2,7 +2,7 @@
module Types
class TodoStateEnum < BaseEnum
- value 'pending'
- value 'done'
+ value 'pending', description: "The state of the todo is pending."
+ value 'done', description: "The state of the todo is done."
end
end
diff --git a/app/graphql/types/todo_target_enum.rb b/app/graphql/types/todo_target_enum.rb
index b797722fef8..ebf65e99936 100644
--- a/app/graphql/types/todo_target_enum.rb
+++ b/app/graphql/types/todo_target_enum.rb
@@ -2,11 +2,11 @@
module Types
class TodoTargetEnum < BaseEnum
- value 'COMMIT', value: 'Commit', description: 'A Commit'
- value 'ISSUE', value: 'Issue', description: 'An Issue'
- value 'MERGEREQUEST', value: 'MergeRequest', description: 'A MergeRequest'
- value 'DESIGN', value: 'DesignManagement::Design', description: 'A Design'
- value 'ALERT', value: 'AlertManagement::Alert', description: 'An Alert'
+ value 'COMMIT', value: 'Commit', description: 'A Commit.'
+ value 'ISSUE', value: 'Issue', description: 'An Issue.'
+ value 'MERGEREQUEST', value: 'MergeRequest', description: 'A MergeRequest.'
+ value 'DESIGN', value: 'DesignManagement::Design', description: 'A Design.'
+ value 'ALERT', value: 'AlertManagement::Alert', description: 'An Alert.'
end
end
diff --git a/app/graphql/types/tree/blob_type.rb b/app/graphql/types/tree/blob_type.rb
index 3823bd94083..d192c8d3c57 100644
--- a/app/graphql/types/tree/blob_type.rb
+++ b/app/graphql/types/tree/blob_type.rb
@@ -15,6 +15,7 @@ module Types
field :web_path, GraphQL::STRING_TYPE, null: true,
description: 'Web path of the blob.'
field :lfs_oid, GraphQL::STRING_TYPE, null: true,
+ calls_gitaly: true,
description: 'LFS ID of the blob.'
field :mode, GraphQL::STRING_TYPE, null: true,
description: 'Blob mode in numeric format.'
diff --git a/app/graphql/types/user_callout_feature_name_enum.rb b/app/graphql/types/user_callout_feature_name_enum.rb
new file mode 100644
index 00000000000..410ca5e1c95
--- /dev/null
+++ b/app/graphql/types/user_callout_feature_name_enum.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class UserCalloutFeatureNameEnum < BaseEnum
+ graphql_name 'UserCalloutFeatureNameEnum'
+ description 'Name of the feature that the callout is for.'
+
+ ::UserCallout.feature_names.keys.each do |feature_name|
+ value feature_name.upcase, value: feature_name, description: "Callout feature name for #{feature_name}."
+ end
+ end
+end
diff --git a/app/graphql/types/user_callout_type.rb b/app/graphql/types/user_callout_type.rb
new file mode 100644
index 00000000000..12f4fdea878
--- /dev/null
+++ b/app/graphql/types/user_callout_type.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Types
+ class UserCalloutType < BaseObject # rubocop:disable Graphql/AuthorizeTypes
+ graphql_name 'UserCallout'
+
+ field :feature_name, UserCalloutFeatureNameEnum, null: false,
+ description: 'Name of the feature that the callout is for.'
+ field :dismissed_at, Types::TimeType, null: true,
+ description: 'Date when the callout was dismissed.'
+ end
+end
diff --git a/app/graphql/types/user_state_enum.rb b/app/graphql/types/user_state_enum.rb
index d34936b4c48..5adec17672e 100644
--- a/app/graphql/types/user_state_enum.rb
+++ b/app/graphql/types/user_state_enum.rb
@@ -5,8 +5,8 @@ module Types
graphql_name 'UserState'
description 'Possible states of a user'
- value 'active', 'The user is active and is able to use the system', value: 'active'
- value 'blocked', 'The user has been blocked and is prevented from using the system', value: 'blocked'
- value 'deactivated', 'The user is no longer active and is unable to use the system', value: 'deactivated'
+ value 'active', 'The user is active and is able to use the system.', value: 'active'
+ value 'blocked', 'The user has been blocked and is prevented from using the system.', value: 'blocked'
+ value 'deactivated', 'The user is no longer active and is unable to use the system.', value: 'deactivated'
end
end
diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb
index 0cefc84633d..2cc7d379240 100644
--- a/app/graphql/types/user_type.rb
+++ b/app/graphql/types/user_type.rb
@@ -67,5 +67,9 @@ module Types
null: true,
description: 'Snippets authored by the user.',
resolver: Resolvers::Users::SnippetsResolver
+ field :callouts,
+ Types::UserCalloutType.connection_type,
+ null: true,
+ description: 'User callouts that belong to the user.'
end
end
diff --git a/app/graphql/types/visibility_levels_enum.rb b/app/graphql/types/visibility_levels_enum.rb
index d5ace24455e..07718679bef 100644
--- a/app/graphql/types/visibility_levels_enum.rb
+++ b/app/graphql/types/visibility_levels_enum.rb
@@ -3,7 +3,7 @@
module Types
class VisibilityLevelsEnum < BaseEnum
Gitlab::VisibilityLevel.string_options.each do |name, int_value|
- value name.downcase, value: int_value
+ value name.downcase, value: int_value, description: "#{name.titleize} visibility level."
end
end
end