diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-18 13:34:06 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-18 13:34:06 +0300 |
commit | 859a6fb938bb9ee2a317c46dfa4fcc1af49608f0 (patch) | |
tree | d7f2700abe6b4ffcb2dcfc80631b2d87d0609239 /app/graphql | |
parent | 446d496a6d000c73a304be52587cd9bbc7493136 (diff) |
Add latest changes from gitlab-org/gitlab@13-9-stable-eev13.9.0-rc42
Diffstat (limited to 'app/graphql')
190 files changed, 1761 insertions, 1160 deletions
diff --git a/app/graphql/mutations/alert_management/base.rb b/app/graphql/mutations/alert_management/base.rb index 3a57cb9670d..86908c1449c 100644 --- a/app/graphql/mutations/alert_management/base.rb +++ b/app/graphql/mutations/alert_management/base.rb @@ -21,7 +21,7 @@ module Mutations field :todo, Types::TodoType, null: true, - description: "The todo after mutation." + description: "The to-do item after mutation." field :issue, Types::IssueType, diff --git a/app/graphql/mutations/alert_management/http_integration/create.rb b/app/graphql/mutations/alert_management/http_integration/create.rb index ff165d7f302..2d7bffb4333 100644 --- a/app/graphql/mutations/alert_management/http_integration/create.rb +++ b/app/graphql/mutations/alert_management/http_integration/create.rb @@ -4,7 +4,7 @@ module Mutations module AlertManagement module HttpIntegration class Create < HttpIntegrationBase - include ResolvesProject + include FindsProject graphql_name 'HttpIntegrationCreate' @@ -21,27 +21,14 @@ module Mutations description: 'Whether the integration is receiving alerts.' def resolve(args) - @project = authorized_find!(full_path: args[:project_path]) + project = authorized_find!(args[:project_path]) response ::AlertManagement::HttpIntegrations::CreateService.new( project, current_user, - http_integration_params(args) + http_integration_params(project, args) ).execute end - - private - - attr_reader :project - - def find_object(full_path:) - resolve_project(full_path: full_path) - end - - # overriden in EE - def http_integration_params(args) - args.slice(:name, :active) - end end end end diff --git a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb index 147df982bec..e33b7bb399a 100644 --- a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb +++ b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb @@ -23,7 +23,14 @@ module Mutations errors: result.errors } end + + # overriden in EE + def http_integration_params(_project, args) + args.slice(:name, :active) + end end end end end + +Mutations::AlertManagement::HttpIntegration::HttpIntegrationBase.prepend_if_ee('::EE::Mutations::AlertManagement::HttpIntegration::HttpIntegrationBase') diff --git a/app/graphql/mutations/alert_management/http_integration/update.rb b/app/graphql/mutations/alert_management/http_integration/update.rb index 431fccaa5e5..b1e4ce841ee 100644 --- a/app/graphql/mutations/alert_management/http_integration/update.rb +++ b/app/graphql/mutations/alert_management/http_integration/update.rb @@ -24,10 +24,12 @@ module Mutations response ::AlertManagement::HttpIntegrations::UpdateService.new( integration, current_user, - args.slice(:name, :active) + http_integration_params(integration.project, args) ).execute end end end end end + +Mutations::AlertManagement::HttpIntegration::Update.prepend_if_ee('::EE::Mutations::AlertManagement::HttpIntegration::Update') diff --git a/app/graphql/mutations/alert_management/prometheus_integration/create.rb b/app/graphql/mutations/alert_management/prometheus_integration/create.rb index c676cde90b4..87e6bc46937 100644 --- a/app/graphql/mutations/alert_management/prometheus_integration/create.rb +++ b/app/graphql/mutations/alert_management/prometheus_integration/create.rb @@ -4,7 +4,7 @@ module Mutations module AlertManagement module PrometheusIntegration class Create < PrometheusIntegrationBase - include ResolvesProject + include FindsProject graphql_name 'PrometheusIntegrationCreate' @@ -21,7 +21,7 @@ module Mutations description: 'Endpoint at which prometheus can be queried.' def resolve(args) - project = authorized_find!(full_path: args[:project_path]) + project = authorized_find!(args[:project_path]) return integration_exists if project.prometheus_service @@ -37,10 +37,6 @@ module Mutations private - def find_object(full_path:) - resolve_project(full_path: full_path) - end - def integration_exists response(nil, message: _('Multiple Prometheus integrations are not supported')) end diff --git a/app/graphql/mutations/boards/lists/base.rb b/app/graphql/mutations/boards/lists/base.rb deleted file mode 100644 index 34c138bddc9..00000000000 --- a/app/graphql/mutations/boards/lists/base.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Mutations - module Boards - module Lists - class Base < BaseMutation - include Mutations::ResolvesIssuable - - argument :board_id, ::Types::GlobalIDType[::Board], - required: true, - description: 'Global ID of the issue board to mutate.' - - field :list, - Types::BoardListType, - null: true, - description: 'List of the issue board.' - - authorize :admin_list - - private - - def find_object(id:) - GitlabSchema.object_from_id(id, expected_type: ::Board) - end - end - end - end -end diff --git a/app/graphql/mutations/boards/lists/base_create.rb b/app/graphql/mutations/boards/lists/base_create.rb new file mode 100644 index 00000000000..a21c7feece3 --- /dev/null +++ b/app/graphql/mutations/boards/lists/base_create.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module Mutations + module Boards + module Lists + class BaseCreate < BaseMutation + argument :backlog, GraphQL::BOOLEAN_TYPE, + required: false, + description: 'Create the backlog list.' + + argument :label_id, ::Types::GlobalIDType[::Label], + required: false, + description: 'Global ID of an existing label.' + + def ready?(**args) + if args.slice(*mutually_exclusive_args).size != 1 + arg_str = mutually_exclusive_args.map { |x| x.to_s.camelize(:lower) }.join(' or ') + raise Gitlab::Graphql::Errors::ArgumentError, "one and only one of #{arg_str} is required" + end + + super + end + + def resolve(**args) + board = authorized_find!(id: args[:board_id]) + params = create_list_params(args) + + response = create_list(board, params) + + { + list: response.success? ? response.payload[:list] : nil, + errors: response.errors + } + end + + private + + def create_list(board, params) + raise NotImplementedError + end + + def create_list_params(args) + params = args.slice(*mutually_exclusive_args).with_indifferent_access + params[:label_id] &&= ::GitlabSchema.parse_gid(params[:label_id], expected_type: ::Label).model_id + + params + end + + def mutually_exclusive_args + [:backlog, :label_id] + end + end + end + end +end diff --git a/app/graphql/mutations/boards/lists/create.rb b/app/graphql/mutations/boards/lists/create.rb index 9eb9a4d4b87..f3aae9ac9c8 100644 --- a/app/graphql/mutations/boards/lists/create.rb +++ b/app/graphql/mutations/boards/lists/create.rb @@ -3,59 +3,32 @@ module Mutations module Boards module Lists - class Create < Base + class Create < BaseCreate graphql_name 'BoardListCreate' - argument :backlog, GraphQL::BOOLEAN_TYPE, - required: false, - description: 'Create the backlog list.' + argument :board_id, ::Types::GlobalIDType[::Board], + required: true, + description: 'Global ID of the issue board to mutate.' - argument :label_id, ::Types::GlobalIDType[::Label], - required: false, - description: 'Global ID of an existing label.' + field :list, + Types::BoardListType, + null: true, + description: 'Issue list in the issue board.' - def ready?(**args) - if args.slice(*mutually_exclusive_args).size != 1 - arg_str = mutually_exclusive_args.map { |x| x.to_s.camelize(:lower) }.join(' or ') - raise Gitlab::Graphql::Errors::ArgumentError, "one and only one of #{arg_str} is required" - end + authorize :admin_list - super - end - - def resolve(**args) - board = authorized_find!(id: args[:board_id]) - params = create_list_params(args) - - response = create_list(board, params) + private - { - list: response.success? ? response.payload[:list] : nil, - errors: response.errors - } + def find_object(id:) + GitlabSchema.object_from_id(id, expected_type: ::Board) end - private - def create_list(board, params) create_list_service = ::Boards::Lists::CreateService.new(board.resource_parent, current_user, params) create_list_service.execute(board) end - - # Overridden in EE - def create_list_params(args) - params = args.slice(*mutually_exclusive_args).with_indifferent_access - params[:label_id] &&= ::GitlabSchema.parse_gid(params[:label_id], expected_type: ::Label).model_id - - params - end - - # Overridden in EE - def mutually_exclusive_args - [:backlog, :label_id] - end end end end diff --git a/app/graphql/mutations/branches/create.rb b/app/graphql/mutations/branches/create.rb index 9fe9bef5403..6354976f1ea 100644 --- a/app/graphql/mutations/branches/create.rb +++ b/app/graphql/mutations/branches/create.rb @@ -3,7 +3,7 @@ module Mutations module Branches class Create < BaseMutation - include ResolvesProject + include FindsProject graphql_name 'CreateBranch' @@ -28,7 +28,7 @@ module Mutations authorize :push_code def resolve(project_path:, name:, ref:) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) context.scoped_set!(:branch_project, project) @@ -40,12 +40,6 @@ module Mutations errors: Array.wrap(result[:message]) } end - - private - - def find_object(full_path:) - resolve_project(full_path: full_path) - end end end end diff --git a/app/graphql/mutations/commits/create.rb b/app/graphql/mutations/commits/create.rb index ae14401558b..84933fee5d2 100644 --- a/app/graphql/mutations/commits/create.rb +++ b/app/graphql/mutations/commits/create.rb @@ -3,7 +3,7 @@ module Mutations module Commits class Create < BaseMutation - include ResolvesProject + include FindsProject graphql_name 'CommitCreate' @@ -37,7 +37,7 @@ module Mutations authorize :push_code def resolve(project_path:, branch:, message:, actions:, **args) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) attributes = { commit_message: message, @@ -53,12 +53,6 @@ module Mutations errors: Array.wrap(result[:message]) } end - - private - - def find_object(full_path:) - resolve_project(full_path: full_path) - end end end end diff --git a/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb b/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb new file mode 100644 index 00000000000..2d4983f0d6e --- /dev/null +++ b/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +module Mutations + # This concern can be mixed into a mutation to provide support for spam checking, + # and optionally support the workflow to allow clients to display and solve CAPTCHAs. + module CanMutateSpammable + extend ActiveSupport::Concern + + # 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 + # reCAPTCHA (e.g. FriendlyCaptcha) without having to change the names and descriptions in the API. + included do + argument :captcha_response, GraphQL::STRING_TYPE, + required: false, + description: 'A valid CAPTCHA response value obtained by using the provided captchaSiteKey with a CAPTCHA API to present a challenge to be solved on the client. Required to resubmit if the previous operation returned "NeedsCaptchaResponse: true".' + + argument :spam_log_id, GraphQL::INT_TYPE, + required: false, + description: 'The spam log ID which must be passed along with a valid CAPTCHA response for the operation to be completed. Required to resubmit if the previous operation returned "NeedsCaptchaResponse: true".' + + field :spam, + GraphQL::BOOLEAN_TYPE, + null: true, + description: 'Indicates whether the operation was detected as definite spam. There is no option to resubmit the request with a CAPTCHA response.' + + field :needs_captcha_response, + GraphQL::BOOLEAN_TYPE, + null: true, + description: 'Indicates whether the operation was detected as possible spam and not completed. If CAPTCHA is enabled, the request must be resubmitted with a valid CAPTCHA response and spam_log_id included for the operation to be completed. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.' + + field :spam_log_id, + GraphQL::INT_TYPE, + null: true, + description: 'The spam log ID which must be passed along with a valid CAPTCHA response for an operation to be completed. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.' + + field :captcha_site_key, + GraphQL::STRING_TYPE, + null: true, + description: 'The CAPTCHA site key which must be used to render a challenge for the user to solve to obtain a valid captchaResponse value. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.' + end + + private + + # additional_spam_params -> hash + # + # Used from a spammable mutation's #resolve method to generate + # the required additional spam/recaptcha params which must be merged into the params + # passed to the constructor of a service, where they can then be used in the service + # to perform spam checking via SpamActionService. + # + # Also accesses the #context of the mutation's Resolver superclass to obtain the request. + # + # Example: + # + # existing_args.merge!(additional_spam_params) + def additional_spam_params + { + api: true, + 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/concerns/mutations/resolves_resource_parent.rb b/app/graphql/mutations/concerns/mutations/resolves_resource_parent.rb index e2b3f4b046f..b8ef675c3d4 100644 --- a/app/graphql/mutations/concerns/mutations/resolves_resource_parent.rb +++ b/app/graphql/mutations/concerns/mutations/resolves_resource_parent.rb @@ -9,11 +9,11 @@ module Mutations included do argument :project_path, GraphQL::ID_TYPE, required: false, - description: 'The project full path the resource is associated with.' + description: 'Full path of the project with which the resource is associated.' argument :group_path, GraphQL::ID_TYPE, required: false, - description: 'The group full path the resource is associated with.' + description: 'Full path of the group with which the resource is associated.' end def ready?(**args) diff --git a/app/graphql/mutations/concerns/mutations/spammable_mutation_fields.rb b/app/graphql/mutations/concerns/mutations/spammable_mutation_fields.rb deleted file mode 100644 index e5df8565618..00000000000 --- a/app/graphql/mutations/concerns/mutations/spammable_mutation_fields.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -module Mutations - module SpammableMutationFields - extend ActiveSupport::Concern - - included do - field :spam, - GraphQL::BOOLEAN_TYPE, - null: true, - description: 'Indicates whether the operation returns a record detected as spam.' - end - - def with_spam_params(&block) - request = Feature.enabled?(:snippet_spam) ? context[:request] : nil - - yield.merge({ api: true, request: request }) - end - - def with_spam_fields(spammable, &block) - { spam: spammable.spam? }.merge!(yield) - end - end -end diff --git a/app/graphql/mutations/container_expiration_policies/update.rb b/app/graphql/mutations/container_expiration_policies/update.rb index 37cf2fa6bf3..f61d852bb6c 100644 --- a/app/graphql/mutations/container_expiration_policies/update.rb +++ b/app/graphql/mutations/container_expiration_policies/update.rb @@ -3,7 +3,7 @@ module Mutations module ContainerExpirationPolicies class Update < Mutations::BaseMutation - include ResolvesProject + include FindsProject graphql_name 'UpdateContainerExpirationPolicy' @@ -50,7 +50,7 @@ module Mutations description: 'The container expiration policy after mutation.' def resolve(project_path:, **args) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) result = ::ContainerExpirationPolicies::UpdateService .new(container: project, current_user: current_user, params: args) @@ -61,12 +61,6 @@ module Mutations errors: result.errors } end - - private - - def find_object(full_path:) - resolve_project(full_path: full_path) - end end end end diff --git a/app/graphql/mutations/discussions/toggle_resolve.rb b/app/graphql/mutations/discussions/toggle_resolve.rb index c9834c946b2..6639252ec67 100644 --- a/app/graphql/mutations/discussions/toggle_resolve.rb +++ b/app/graphql/mutations/discussions/toggle_resolve.rb @@ -69,7 +69,7 @@ module Mutations end def unresolve!(discussion) - discussion.unresolve! + ::Discussions::UnresolveService.new(discussion, current_user).execute end end end diff --git a/app/graphql/mutations/issues/create.rb b/app/graphql/mutations/issues/create.rb index 18b80ff1736..37fddd92832 100644 --- a/app/graphql/mutations/issues/create.rb +++ b/app/graphql/mutations/issues/create.rb @@ -3,7 +3,7 @@ module Mutations module Issues class Create < BaseMutation - include ResolvesProject + include FindsProject graphql_name 'CreateIssue' authorize :create_issue @@ -70,7 +70,7 @@ module Mutations end def resolve(project_path:, **attributes) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) params = build_create_issue_params(attributes.merge(author_id: current_user.id)) issue = ::Issues::CreateService.new(project, current_user, params).execute @@ -98,10 +98,6 @@ module Mutations def mutually_exclusive_label_args [:labels, :label_ids] end - - def find_object(full_path:) - resolve_project(full_path: full_path) - end end end end diff --git a/app/graphql/mutations/jira_import/import_users.rb b/app/graphql/mutations/jira_import/import_users.rb index 616ef390657..af2bb18161f 100644 --- a/app/graphql/mutations/jira_import/import_users.rb +++ b/app/graphql/mutations/jira_import/import_users.rb @@ -3,10 +3,12 @@ module Mutations module JiraImport class ImportUsers < BaseMutation - include ResolvesProject + include FindsProject graphql_name 'JiraImportUsers' + authorize :admin_project + field :jira_users, [Types::JiraUserType], null: true, @@ -20,7 +22,7 @@ module Mutations description: 'The index of the record the import should started at, default 0 (50 records returned).' def resolve(project_path:, start_at: 0) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) service_response = ::JiraImport::UsersImporter.new(context[:current_user], project, start_at.to_i).execute @@ -29,16 +31,6 @@ module Mutations errors: service_response.errors } end - - private - - def find_object(full_path:) - resolve_project(full_path: full_path) - end - - def authorized_resource?(project) - Ability.allowed?(context[:current_user], :admin_project, project) - end end end end diff --git a/app/graphql/mutations/jira_import/start.rb b/app/graphql/mutations/jira_import/start.rb index 3d50ebde13a..e31aaf53a09 100644 --- a/app/graphql/mutations/jira_import/start.rb +++ b/app/graphql/mutations/jira_import/start.rb @@ -3,10 +3,12 @@ module Mutations module JiraImport class Start < BaseMutation - include ResolvesProject + include FindsProject graphql_name 'JiraImportStart' + authorize :admin_project + field :jira_import, Types::JiraImportType, null: true, @@ -27,7 +29,7 @@ module Mutations description: 'The mapping of Jira to GitLab users.' def resolve(project_path:, jira_project_key:, users_mapping:) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) mapping = users_mapping.to_ary.map { |map| map.to_hash } service_response = ::JiraImport::StartImportService @@ -40,16 +42,6 @@ module Mutations errors: service_response.errors } end - - private - - def find_object(full_path:) - resolve_project(full_path: full_path) - end - - def authorized_resource?(project) - Ability.allowed?(context[:current_user], :admin_project, project) - end end end end diff --git a/app/graphql/mutations/merge_requests/create.rb b/app/graphql/mutations/merge_requests/create.rb index 64fa8417e50..9ac8f70be95 100644 --- a/app/graphql/mutations/merge_requests/create.rb +++ b/app/graphql/mutations/merge_requests/create.rb @@ -3,7 +3,7 @@ module Mutations module MergeRequests class Create < BaseMutation - include ResolvesProject + include FindsProject graphql_name 'MergeRequestCreate' @@ -39,7 +39,7 @@ module Mutations authorize :create_merge_request_from def resolve(project_path:, **attributes) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) params = attributes.merge(author_id: current_user.id) merge_request = ::MergeRequests::CreateService.new(project, current_user, params).execute @@ -49,12 +49,6 @@ module Mutations errors: errors_on_object(merge_request) } end - - private - - def find_object(full_path:) - resolve_project(full_path: full_path) - end end end end diff --git a/app/graphql/mutations/merge_requests/reviewer_rereview.rb b/app/graphql/mutations/merge_requests/reviewer_rereview.rb new file mode 100644 index 00000000000..f6f4881654e --- /dev/null +++ b/app/graphql/mutations/merge_requests/reviewer_rereview.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Mutations + module MergeRequests + class ReviewerRereview < Base + graphql_name 'MergeRequestReviewerRereview' + + argument :user_id, ::Types::GlobalIDType[::User], + loads: Types::UserType, + required: true, + description: <<~DESC + The user ID for the user that has been requested for a new review. + DESC + + def resolve(project_path:, iid:, user:) + merge_request = authorized_find!(project_path: project_path, iid: iid) + + result = ::MergeRequests::RequestReviewService.new(merge_request.project, current_user).execute(merge_request, user) + + { + merge_request: merge_request, + errors: Array(result[:message]) + } + end + end + end +end diff --git a/app/graphql/mutations/merge_requests/update.rb b/app/graphql/mutations/merge_requests/update.rb index 4721ebab41b..6a94d2f37b2 100644 --- a/app/graphql/mutations/merge_requests/update.rb +++ b/app/graphql/mutations/merge_requests/update.rb @@ -19,9 +19,14 @@ module Mutations required: false, description: copy_field_description(Types::MergeRequestType, :description) - def resolve(args) - merge_request = authorized_find!(**args.slice(:project_path, :iid)) - attributes = args.slice(:title, :description, :target_branch).compact + argument :state, ::Types::MergeRequestStateEventEnum, + required: false, + as: :state_event, + description: 'The action to perform to change the state.' + + def resolve(project_path:, iid:, **args) + merge_request = authorized_find!(project_path: project_path, iid: iid) + attributes = args.compact ::MergeRequests::UpdateService .new(merge_request.project, current_user, attributes) diff --git a/app/graphql/mutations/notes/create/base.rb b/app/graphql/mutations/notes/create/base.rb index 2351af01813..a157a5abdf2 100644 --- a/app/graphql/mutations/notes/create/base.rb +++ b/app/graphql/mutations/notes/create/base.rb @@ -25,6 +25,7 @@ module Mutations def resolve(args) noteable = authorized_find!(id: args[:noteable_id]) + verify_rate_limit!(current_user) note = ::Notes::CreateService.new( noteable.project, @@ -54,6 +55,20 @@ module Mutations confidential: args[:confidential] } end + + def verify_rate_limit!(current_user) + return unless rate_limit_throttled? + + raise Gitlab::Graphql::Errors::ResourceNotAvailable, + 'This endpoint has been requested too many times. Try again later.' + end + + def rate_limit_throttled? + rate_limiter = ::Gitlab::ApplicationRateLimiter + allowlist = Gitlab::CurrentSettings.current_application_settings.notes_create_limit_allowlist + + rate_limiter.throttled?(:notes_create, scope: [current_user], users_allowlist: allowlist) + end end end end diff --git a/app/graphql/mutations/releases/base.rb b/app/graphql/mutations/releases/base.rb index dd1724fe320..610e9cd9cde 100644 --- a/app/graphql/mutations/releases/base.rb +++ b/app/graphql/mutations/releases/base.rb @@ -3,17 +3,11 @@ module Mutations module Releases class Base < BaseMutation - include ResolvesProject + include FindsProject argument :project_path, GraphQL::ID_TYPE, required: true, description: 'Full path of the project the release is associated with.' - - private - - def find_object(full_path:) - resolve_project(full_path: full_path) - end end end end diff --git a/app/graphql/mutations/releases/create.rb b/app/graphql/mutations/releases/create.rb index 91ac256033e..914c1302094 100644 --- a/app/graphql/mutations/releases/create.rb +++ b/app/graphql/mutations/releases/create.rb @@ -41,7 +41,7 @@ module Mutations authorize :create_release def resolve(project_path:, assets: nil, **scalars) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) params = { **scalars, diff --git a/app/graphql/mutations/releases/delete.rb b/app/graphql/mutations/releases/delete.rb index e887b702cce..020c9133b58 100644 --- a/app/graphql/mutations/releases/delete.rb +++ b/app/graphql/mutations/releases/delete.rb @@ -17,7 +17,7 @@ module Mutations authorize :destroy_release def resolve(project_path:, tag:) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) params = { tag: tag }.with_indifferent_access diff --git a/app/graphql/mutations/releases/update.rb b/app/graphql/mutations/releases/update.rb index dff743254bd..35f2a7b3d4b 100644 --- a/app/graphql/mutations/releases/update.rb +++ b/app/graphql/mutations/releases/update.rb @@ -47,7 +47,7 @@ module Mutations end def resolve(project_path:, **scalars) - project = authorized_find!(full_path: project_path) + project = authorized_find!(project_path) params = scalars.with_indifferent_access diff --git a/app/graphql/mutations/security/ci_configuration/configure_sast.rb b/app/graphql/mutations/security/ci_configuration/configure_sast.rb new file mode 100644 index 00000000000..e4a3f815396 --- /dev/null +++ b/app/graphql/mutations/security/ci_configuration/configure_sast.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Mutations + module Security + module CiConfiguration + class ConfigureSast < BaseMutation + include FindsProject + + graphql_name 'ConfigureSast' + + argument :project_path, GraphQL::ID_TYPE, + required: true, + description: 'Full path of the project.' + + argument :configuration, ::Types::CiConfiguration::Sast::InputType, + required: true, + description: 'SAST CI configuration for the project.' + + field :status, GraphQL::STRING_TYPE, null: false, + description: 'Status of creating the commit for the supplied SAST CI configuration.' + + field :success_path, GraphQL::STRING_TYPE, null: true, + description: 'Redirect path to use when the response is successful.' + + authorize :push_code + + def resolve(project_path:, configuration:) + project = authorized_find!(project_path) + + result = ::Security::CiConfiguration::SastCreateService.new(project, current_user, configuration).execute + prepare_response(result) + end + + private + + def prepare_response(result) + { + status: result[:status], + success_path: result[:success_path], + errors: Array(result[:errors]) + } + end + end + end + end +end diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb index b4485e28c5a..73eac9f0f3b 100644 --- a/app/graphql/mutations/snippets/create.rb +++ b/app/graphql/mutations/snippets/create.rb @@ -3,7 +3,8 @@ module Mutations module Snippets class Create < BaseMutation - include SpammableMutationFields + include ServiceCompatibility + include CanMutateSpammable authorize :create_snippet @@ -45,18 +46,17 @@ module Mutations authorize!(:global) end - service_response = ::Snippets::CreateService.new(project, - current_user, - create_params(args)).execute + process_args_for_params!(args) - snippet = service_response.payload[:snippet] + service_response = ::Snippets::CreateService.new(project, current_user, args).execute # Only when the user is not an api user and the operation was successful if !api_user? && service_response.success? ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user) end - with_spam_fields(snippet) do + snippet = service_response.payload[:snippet] + with_spam_action_fields(snippet) do { snippet: service_response.success? ? snippet : nil, errors: errors_on_object(snippet) @@ -70,18 +70,25 @@ module Mutations Project.find_by_full_path(full_path) end - def create_params(args) - with_spam_params do - args.tap do |create_args| - # We need to rename `blob_actions` into `snippet_actions` because - # it's the expected key param - create_args[:snippet_actions] = create_args.delete(:blob_actions)&.map(&:to_h) - - # We need to rename `uploaded_files` into `files` because - # it's the expected key param - create_args[:files] = create_args.delete(:uploaded_files) - end + # process_args_for_params!(args) -> nil + # + # Modifies/adds/deletes mutation resolve args as necessary to be passed as params to service layer. + def process_args_for_params!(args) + convert_blob_actions_to_snippet_actions!(args) + + # We need to rename `uploaded_files` into `files` because + # it's the expected key param + args[:files] = args.delete(:uploaded_files) + + if Feature.enabled?(:snippet_spam) + args.merge!(additional_spam_params) + else + args[:disable_spam_action_service] = true end + + # Return nil to make it explicit that this method is mutating the args parameter, and that + # the return value is not relevant and is not to be used. + nil end end end diff --git a/app/graphql/mutations/snippets/service_compatibility.rb b/app/graphql/mutations/snippets/service_compatibility.rb new file mode 100644 index 00000000000..0e7ee5d78bf --- /dev/null +++ b/app/graphql/mutations/snippets/service_compatibility.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Mutations + module Snippets + # Translates graphql mutation field params to be compatible with those expected by the service layer + module ServiceCompatibility + extend ActiveSupport::Concern + + # convert_blob_actions_to_snippet_actions!(args) -> nil + # + # Converts the blob_actions mutation argument into the + # snippet_actions hash which the service layer expects + def convert_blob_actions_to_snippet_actions!(args) + # We need to rename `blob_actions` into `snippet_actions` because + # it's the expected key param + args[:snippet_actions] = args.delete(:blob_actions)&.map(&:to_h) + + # Return nil to make it explicit that this method is mutating the args parameter + nil + end + end + end +end diff --git a/app/graphql/mutations/snippets/update.rb b/app/graphql/mutations/snippets/update.rb index 930440fbd35..af8e6f384b7 100644 --- a/app/graphql/mutations/snippets/update.rb +++ b/app/graphql/mutations/snippets/update.rb @@ -3,7 +3,8 @@ module Mutations module Snippets class Update < Base - include SpammableMutationFields + include ServiceCompatibility + include CanMutateSpammable graphql_name 'UpdateSnippet' @@ -30,19 +31,23 @@ module Mutations def resolve(id:, **args) snippet = authorized_find!(id: id) - result = ::Snippets::UpdateService.new(snippet.project, - current_user, - update_params(args)).execute(snippet) - snippet = result.payload[:snippet] + process_args_for_params!(args) + + service_response = ::Snippets::UpdateService.new(snippet.project, current_user, args).execute(snippet) + + # TODO: DRY this up - From here down, this is all duplicated with Mutations::Snippets::Create#resolve, except for + # `snippet.reset`, which is required in order to return the object in its non-dirty, unmodified, database state + # See issue here: https://gitlab.com/gitlab-org/gitlab/-/issues/300250 # Only when the user is not an api user and the operation was successful - if !api_user? && result.success? + if !api_user? && service_response.success? ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user) end - with_spam_fields(snippet) do + snippet = service_response.payload[:snippet] + with_spam_action_fields(snippet) do { - snippet: result.success? ? snippet : snippet.reset, + snippet: service_response.success? ? snippet : snippet.reset, errors: errors_on_object(snippet) } end @@ -50,18 +55,25 @@ module Mutations private - def ability_name - 'update' - end + # process_args_for_params!(args) -> nil + # + # Modifies/adds/deletes mutation resolve args as necessary to be passed as params to service layer. + def process_args_for_params!(args) + convert_blob_actions_to_snippet_actions!(args) - def update_params(args) - with_spam_params do - args.tap do |update_args| - # We need to rename `blob_actions` into `snippet_actions` because - # it's the expected key param - update_args[:snippet_actions] = update_args.delete(:blob_actions)&.map(&:to_h) - end + if Feature.enabled?(:snippet_spam) + args.merge!(additional_spam_params) + else + args[:disable_spam_action_service] = true end + + # Return nil to make it explicit that this method is mutating the args parameter, and that + # the return value is not relevant and is not to be used. + nil + end + + def ability_name + 'update' end end end diff --git a/app/graphql/mutations/todos/create.rb b/app/graphql/mutations/todos/create.rb index 814f7ec4fc4..b6250b0228c 100644 --- a/app/graphql/mutations/todos/create.rb +++ b/app/graphql/mutations/todos/create.rb @@ -14,7 +14,7 @@ module Mutations field :todo, Types::TodoType, null: true, - description: 'The to-do created.' + description: 'The to-do item created.' def resolve(target_id:) id = ::Types::GlobalIDType[Todoable].coerce_isolated_input(target_id) diff --git a/app/graphql/mutations/todos/mark_all_done.rb b/app/graphql/mutations/todos/mark_all_done.rb index c8359953567..22a5893d4ec 100644 --- a/app/graphql/mutations/todos/mark_all_done.rb +++ b/app/graphql/mutations/todos/mark_all_done.rb @@ -10,12 +10,12 @@ module Mutations field :updated_ids, [::Types::GlobalIDType[::Todo]], null: false, - deprecated: { reason: 'Use todos', milestone: '13.2' }, - description: 'Ids of the updated todos.' + deprecated: { reason: 'Use to-do items', milestone: '13.2' }, + description: 'IDs of the updated to-do items.' field :todos, [::Types::TodoType], null: false, - description: 'Updated todos.' + description: 'Updated to-do items.' def resolve authorize!(current_user) diff --git a/app/graphql/mutations/todos/mark_done.rb b/app/graphql/mutations/todos/mark_done.rb index 95144abb040..a78cc91da68 100644 --- a/app/graphql/mutations/todos/mark_done.rb +++ b/app/graphql/mutations/todos/mark_done.rb @@ -10,11 +10,11 @@ module Mutations argument :id, ::Types::GlobalIDType[::Todo], required: true, - description: 'The global ID of the todo to mark as done.' + description: 'The global ID of the to-do item to mark as done.' field :todo, Types::TodoType, null: false, - description: 'The requested todo.' + description: 'The requested to-do item.' def resolve(id:) todo = authorized_find!(id: id) diff --git a/app/graphql/mutations/todos/restore.rb b/app/graphql/mutations/todos/restore.rb index e496627aec2..70c33c439c4 100644 --- a/app/graphql/mutations/todos/restore.rb +++ b/app/graphql/mutations/todos/restore.rb @@ -10,11 +10,11 @@ module Mutations argument :id, ::Types::GlobalIDType[::Todo], required: true, - description: 'The global ID of the todo to restore.' + description: 'The global ID of the to-do item to restore.' field :todo, Types::TodoType, null: false, - description: 'The requested todo.' + description: 'The requested to-do item.' def resolve(id:) todo = authorized_find!(id: id) diff --git a/app/graphql/mutations/todos/restore_many.rb b/app/graphql/mutations/todos/restore_many.rb index 9263c1d9afe..dc02ffadada 100644 --- a/app/graphql/mutations/todos/restore_many.rb +++ b/app/graphql/mutations/todos/restore_many.rb @@ -10,16 +10,16 @@ module Mutations argument :ids, [::Types::GlobalIDType[::Todo]], required: true, - description: 'The global IDs of the todos to restore (a maximum of 50 is supported at once).' + description: 'The global IDs of the to-do items to restore (a maximum of 50 is supported at once).' field :updated_ids, [::Types::GlobalIDType[Todo]], null: false, - description: 'The IDs of the updated todo items.', - deprecated: { reason: 'Use todos', milestone: '13.2' } + description: 'The IDs of the updated to-do items.', + deprecated: { reason: 'Use to-do items', milestone: '13.2' } field :todos, [::Types::TodoType], null: false, - description: 'Updated todos.' + description: 'Updated to-do items.' def resolve(ids:) check_update_amount_limit!(ids) @@ -46,7 +46,7 @@ module Mutations end def raise_too_many_todos_requested_error - raise Gitlab::Graphql::Errors::ArgumentError, 'Too many todos requested.' + raise Gitlab::Graphql::Errors::ArgumentError, 'Too many to-do items requested.' end def check_update_amount_limit!(ids) diff --git a/app/graphql/queries/container_registry/get_container_repositories.query.graphql b/app/graphql/queries/container_registry/get_container_repositories.query.graphql index 6171233c446..4683ef9dfdb 100644 --- a/app/graphql/queries/container_registry/get_container_repositories.query.graphql +++ b/app/graphql/queries/container_registry/get_container_repositories.query.graphql @@ -6,11 +6,19 @@ query getProjectContainerRepositories( $after: String $before: String $isGroupPage: Boolean! + $sort: ContainerRepositorySort ) { project(fullPath: $fullPath) @skip(if: $isGroupPage) { __typename containerRepositoriesCount - containerRepositories(name: $name, after: $after, before: $before, first: $first, last: $last) { + containerRepositories( + name: $name + after: $after + before: $before + first: $first + last: $last + sort: $sort + ) { __typename nodes { id @@ -35,7 +43,14 @@ query getProjectContainerRepositories( group(fullPath: $fullPath) @include(if: $isGroupPage) { __typename containerRepositoriesCount - containerRepositories(name: $name, after: $after, before: $before, first: $first, last: $last) { + containerRepositories( + name: $name + after: $after + before: $before + first: $first + last: $last + sort: $sort + ) { __typename nodes { id diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb index 539e37db1c2..5db618254cb 100644 --- a/app/graphql/resolvers/base_resolver.rb +++ b/app/graphql/resolvers/base_resolver.rb @@ -118,7 +118,7 @@ module Resolvers end def offset_pagination(relation) - ::Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection.new(relation) + ::Gitlab::Graphql::Pagination::OffsetPaginatedRelation.new(relation) end override :object diff --git a/app/graphql/resolvers/board_lists_resolver.rb b/app/graphql/resolvers/board_lists_resolver.rb index 7bdff8ba61f..a97ac3220d5 100644 --- a/app/graphql/resolvers/board_lists_resolver.rb +++ b/app/graphql/resolvers/board_lists_resolver.rb @@ -28,7 +28,7 @@ module Resolvers context.scoped_set!(:issue_filters, issue_filters(issue_filters)) if load_preferences?(lookahead) - List.preload_preferences_for_user(lists, context[:current_user]) + List.preload_preferences_for_user(lists, current_user) end offset_pagination(lists) @@ -39,7 +39,7 @@ module Resolvers def board_lists(id) service = ::Boards::Lists::ListService.new( board.resource_parent, - context[:current_user], + current_user, list_id: extract_list_id(id) ) @@ -47,7 +47,8 @@ module Resolvers end def load_preferences?(lookahead) - lookahead&.selection(:edges)&.selection(:node)&.selects?(:collapsed) + lookahead&.selection(:edges)&.selection(:node)&.selects?(:collapsed) || + lookahead&.selection(:nodes)&.selects?(:collapsed) end def extract_list_id(gid) diff --git a/app/graphql/resolvers/board_resolver.rb b/app/graphql/resolvers/board_resolver.rb index 582707cc1e4..2c2922c3fbf 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(create_default_board: false).first + ::Boards::ListService.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 cdb15dc8f37..be2f22175dc 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(create_default_board: false) + ::Boards::ListService.new(parent, context[:current_user], board_id: extract_board_id(id)).execute rescue ActiveRecord::RecordNotFound Board.none end diff --git a/app/graphql/resolvers/ci/config_resolver.rb b/app/graphql/resolvers/ci/config_resolver.rb index 72d3ae30d73..852bb47e215 100644 --- a/app/graphql/resolvers/ci/config_resolver.rb +++ b/app/graphql/resolvers/ci/config_resolver.rb @@ -29,6 +29,12 @@ module Resolvers .new(project: project, current_user: context[:current_user]) .validate(content, dry_run: dry_run) + response(result).merge(merged_yaml: result.merged_yaml) + end + + private + + def response(result) if result.errors.empty? { status: :valid, @@ -43,8 +49,6 @@ module Resolvers end end - private - def make_jobs(config_jobs) config_jobs.map do |job| { diff --git a/app/graphql/resolvers/container_repositories_resolver.rb b/app/graphql/resolvers/container_repositories_resolver.rb index 8042a368e33..17af2a2f070 100644 --- a/app/graphql/resolvers/container_repositories_resolver.rb +++ b/app/graphql/resolvers/container_repositories_resolver.rb @@ -10,8 +10,13 @@ module Resolvers required: false, description: 'Filter the container repositories by their name.' - def resolve(name: nil) - ContainerRepositoriesFinder.new(user: current_user, subject: object, params: { name: name }) + argument :sort, Types::ContainerRepositorySortEnum, + description: 'Sort container repositories by this criteria.', + required: false, + default_value: :created_desc + + def resolve(name: nil, sort: nil) + ContainerRepositoriesFinder.new(user: current_user, subject: object, params: { name: name, sort: sort }) .execute .tap { track_event(:list_repositories, :container) } end diff --git a/app/graphql/resolvers/group_labels_resolver.rb b/app/graphql/resolvers/group_labels_resolver.rb new file mode 100644 index 00000000000..5c2f950bbc0 --- /dev/null +++ b/app/graphql/resolvers/group_labels_resolver.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Resolvers + class GroupLabelsResolver < LabelsResolver + type Types::LabelType.connection_type, null: true + + argument :include_descendant_groups, GraphQL::BOOLEAN_TYPE, + required: false, + description: 'Include labels from descendant groups.', + default_value: false + + argument :only_group_labels, GraphQL::BOOLEAN_TYPE, + required: false, + description: 'Include only group level labels.', + default_value: false + end +end diff --git a/app/graphql/resolvers/labels_resolver.rb b/app/graphql/resolvers/labels_resolver.rb new file mode 100644 index 00000000000..1b523b8a240 --- /dev/null +++ b/app/graphql/resolvers/labels_resolver.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Resolvers + class LabelsResolver < BaseResolver + include Gitlab::Graphql::Authorize::AuthorizeResource + + authorize :read_label + + type Types::LabelType.connection_type, null: true + + argument :search_term, GraphQL::STRING_TYPE, + required: false, + description: 'A search term to find labels with.' + + argument :include_ancestor_groups, GraphQL::BOOLEAN_TYPE, + required: false, + description: 'Include labels from ancestor groups.', + default_value: false + + def resolve(**args) + return Label.none if parent.nil? + + authorize!(parent) + + # LabelsFinder uses `search` param, so we transform `search_term` into `search` + args[:search] = args.delete(:search_term) + LabelsFinder.new(current_user, parent_param.merge(args)).execute + end + + private + + def parent + object.respond_to?(:sync) ? object.sync : object + end + + def parent_param + key = case parent + when Group then :group + when Project then :project + else raise "Unexpected parent type: #{parent.class}" + end + + { "#{key}": parent } + end + end +end diff --git a/app/graphql/resolvers/package_details_resolver.rb b/app/graphql/resolvers/package_details_resolver.rb index dcf4430e55f..e688e34599a 100644 --- a/app/graphql/resolvers/package_details_resolver.rb +++ b/app/graphql/resolvers/package_details_resolver.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true module Resolvers - # No return types defined because they can be different. - # rubocop: disable Graphql/ResolverType class PackageDetailsResolver < BaseResolver + type ::Types::Packages::PackageType, null: true + argument :id, ::Types::GlobalIDType[::Packages::Package], required: true, description: 'The global ID of the package.' diff --git a/app/graphql/resolvers/packages_resolver.rb b/app/graphql/resolvers/packages_resolver.rb index d19099e94d4..3eeed48ff7e 100644 --- a/app/graphql/resolvers/packages_resolver.rb +++ b/app/graphql/resolvers/packages_resolver.rb @@ -2,7 +2,7 @@ module Resolvers class PackagesResolver < BaseResolver - type Types::Packages::PackageType, null: true + type Types::Packages::PackageType.connection_type, null: true def resolve(**args) return unless packages_available? diff --git a/app/graphql/resolvers/project_merge_requests_resolver.rb b/app/graphql/resolvers/project_merge_requests_resolver.rb index 830649d5e52..9628a6dfd7a 100644 --- a/app/graphql/resolvers/project_merge_requests_resolver.rb +++ b/app/graphql/resolvers/project_merge_requests_resolver.rb @@ -6,5 +6,38 @@ module Resolvers accept_assignee accept_author accept_reviewer + + 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) + MergeRequest::MetricsFinder + .new(current_user, args.merge(target_project: project)) + .execute + else + scope + end + end + + def only_count_is_selected_with_merged_at_filter?(args) + return unless lookahead + + argument_names = args.compact.except(:lookahead, :sort, :merged_before, :merged_after).keys + + # no extra filtering arguments are provided + return unless argument_names.empty? + return unless args[:merged_after] || args[:merged_before] + + # Detecting a specific query pattern: + # mergeRequests(mergedAfter: "X", mergedBefore: "Y") { + # count + # totalTimeToMerge + # } + allowed_selected_fields = [:count, :total_time_to_merge] + selected_fields = lookahead.selections.map(&:field).map(&:original_name) - [:__typename] # ignore __typename meta field + + # only the allowed_selected_fields are present + (selected_fields - allowed_selected_fields).empty? + end end end diff --git a/app/graphql/resolvers/snippets/blobs_resolver.rb b/app/graphql/resolvers/snippets/blobs_resolver.rb index 868d34ae7ad..672214df7d5 100644 --- a/app/graphql/resolvers/snippets/blobs_resolver.rb +++ b/app/graphql/resolvers/snippets/blobs_resolver.rb @@ -15,13 +15,10 @@ module Resolvers required: false, description: 'Paths of the blobs.' - def resolve(**args) + def resolve(paths: []) authorize!(snippet) - return [snippet.blob] if snippet.empty_repo? - paths = Array(args.fetch(:paths, [])) - if paths.empty? snippet.blobs else diff --git a/app/graphql/resolvers/terraform/states_resolver.rb b/app/graphql/resolvers/terraform/states_resolver.rb index 38b26a948b1..f543eb182e8 100644 --- a/app/graphql/resolvers/terraform/states_resolver.rb +++ b/app/graphql/resolvers/terraform/states_resolver.rb @@ -3,20 +3,20 @@ module Resolvers module Terraform class StatesResolver < BaseResolver - type Types::Terraform::StateType, null: true + type Types::Terraform::StateType.connection_type, null: true alias_method :project, :object - def resolve(**args) - return ::Terraform::State.none unless can_read_terraform_states? - - project.terraform_states.ordered_by_name + when_single do + argument :name, GraphQL::STRING_TYPE, + required: true, + description: 'Name of the Terraform state.' end - private - - def can_read_terraform_states? - current_user.can?(:read_terraform_state, project) + def resolve(**args) + ::Terraform::StatesFinder + .new(project, current_user, params: args) + .execute end end end diff --git a/app/graphql/types/access_level_type.rb b/app/graphql/types/access_level_type.rb index c7f915f5038..21c3669979c 100644 --- a/app/graphql/types/access_level_type.rb +++ b/app/graphql/types/access_level_type.rb @@ -7,11 +7,11 @@ module Types description 'Represents the access level of a relationship between a User and object that it is related to' field :integer_value, GraphQL::INT_TYPE, null: true, - description: 'Integer representation of access level', + description: 'Integer representation of access level.', method: :to_i field :string_value, Types::AccessLevelEnum, null: true, - description: 'String representation of access level', + description: 'String representation of access level.', method: :to_i end end diff --git a/app/graphql/types/admin/analytics/instance_statistics/measurement_type.rb b/app/graphql/types/admin/analytics/instance_statistics/measurement_type.rb index eab42c2b78d..17a5af8d36b 100644 --- a/app/graphql/types/admin/analytics/instance_statistics/measurement_type.rb +++ b/app/graphql/types/admin/analytics/instance_statistics/measurement_type.rb @@ -12,13 +12,13 @@ module Types authorize :read_instance_statistics_measurements field :recorded_at, Types::TimeType, null: true, - description: 'The time the measurement was recorded' + description: 'The time the measurement was recorded.' field :count, GraphQL::INT_TYPE, null: false, - description: 'Object count' + description: 'Object count.' field :identifier, Types::Admin::Analytics::InstanceStatistics::MeasurementIdentifierEnum, null: false, - description: 'The type of objects being measured' + description: 'The type of objects being measured.' end end end diff --git a/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb b/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb index 93dd49b3c38..996300edad3 100644 --- a/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb +++ b/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb @@ -12,17 +12,17 @@ module Types field :completed, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Whether or not the entire queue was processed in time; if not, retrying the same request is safe' + description: 'Whether or not the entire queue was processed in time; if not, retrying the same request is safe.' field :deleted_jobs, GraphQL::INT_TYPE, null: true, - description: 'The number of matching jobs deleted' + description: 'The number of matching jobs deleted.' field :queue_size, GraphQL::INT_TYPE, null: true, - description: 'The queue size after processing' + description: 'The queue size after processing.' end end end diff --git a/app/graphql/types/alert_management/alert_status_counts_type.rb b/app/graphql/types/alert_management/alert_status_counts_type.rb index a84be705445..14a81735fa5 100644 --- a/app/graphql/types/alert_management/alert_status_counts_type.rb +++ b/app/graphql/types/alert_management/alert_status_counts_type.rb @@ -19,12 +19,12 @@ module Types field :open, GraphQL::INT_TYPE, null: true, - description: 'Number of alerts with status TRIGGERED or ACKNOWLEDGED for the project' + description: 'Number of alerts with status TRIGGERED or ACKNOWLEDGED for the project.' field :all, GraphQL::INT_TYPE, null: true, - description: 'Total number of alerts for the project' + description: 'Total number of alerts for the project.' end end end diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb index 623762de208..6b7e7030c1f 100644 --- a/app/graphql/types/alert_management/alert_type.rb +++ b/app/graphql/types/alert_management/alert_type.rb @@ -15,115 +15,115 @@ module Types field :iid, GraphQL::ID_TYPE, null: false, - description: 'Internal ID of the alert' + description: 'Internal ID of the alert.' field :issue_iid, GraphQL::ID_TYPE, null: true, - description: 'Internal ID of the GitLab issue attached to the alert' + description: 'Internal ID of the GitLab issue attached to the alert.' field :title, GraphQL::STRING_TYPE, null: true, - description: 'Title of the alert' + description: 'Title of the alert.' field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description of the alert' + description: 'Description of the alert.' field :severity, AlertManagement::SeverityEnum, null: true, - description: 'Severity of the alert' + description: 'Severity of the alert.' field :status, AlertManagement::StatusEnum, null: true, - description: 'Status of the alert', + description: 'Status of the alert.', method: :status_name field :service, GraphQL::STRING_TYPE, null: true, - description: 'Service the alert came from' + description: 'Service the alert came from.' field :monitoring_tool, GraphQL::STRING_TYPE, null: true, - description: 'Monitoring tool the alert came from' + description: 'Monitoring tool the alert came from.' field :hosts, [GraphQL::STRING_TYPE], null: true, - description: 'List of hosts the alert came from' + description: 'List of hosts the alert came from.' field :started_at, Types::TimeType, null: true, - description: 'Timestamp the alert was raised' + description: 'Timestamp the alert was raised.' field :ended_at, Types::TimeType, null: true, - description: 'Timestamp the alert ended' + description: 'Timestamp the alert ended.' field :environment, Types::EnvironmentType, null: true, - description: 'Environment for the alert' + description: 'Environment for the alert.' field :event_count, GraphQL::INT_TYPE, null: true, - description: 'Number of events of this alert', + description: 'Number of events of this alert.', method: :events field :details, # rubocop:disable Graphql/JSONType GraphQL::Types::JSON, null: true, - description: 'Alert details' + description: 'Alert details.' field :created_at, Types::TimeType, null: true, - description: 'Timestamp the alert was created' + description: 'Timestamp the alert was created.' field :updated_at, Types::TimeType, null: true, - description: 'Timestamp the alert was last updated' + description: 'Timestamp the alert was last updated.' field :assignees, Types::UserType.connection_type, null: true, - description: 'Assignees of the alert' + description: 'Assignees of the alert.' field :metrics_dashboard_url, GraphQL::STRING_TYPE, null: true, - description: 'URL for metrics embed for the alert' + description: 'URL for metrics embed for the alert.' field :runbook, GraphQL::STRING_TYPE, null: true, - description: 'Runbook for the alert as defined in alert details' + description: 'Runbook for the alert as defined in alert details.' field :todos, Types::TodoType.connection_type, null: true, - description: 'Todos of the current user for the alert', + description: 'To-do items of the current user for the alert.', resolver: Resolvers::TodoResolver field :details_url, GraphQL::STRING_TYPE, null: false, - description: 'The URL of the alert detail page' + description: 'The URL of the alert detail page.' field :prometheus_alert, Types::PrometheusAlertType, null: true, - description: 'The alert condition for Prometheus' + description: 'The alert condition for Prometheus.' def notes object.ordered_notes diff --git a/app/graphql/types/alert_management/integration_type.rb b/app/graphql/types/alert_management/integration_type.rb index bf599885584..d26d7348765 100644 --- a/app/graphql/types/alert_management/integration_type.rb +++ b/app/graphql/types/alert_management/integration_type.rb @@ -9,37 +9,37 @@ module Types field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the integration' + description: 'ID of the integration.' field :type, AlertManagement::IntegrationTypeEnum, null: false, - description: 'Type of integration' + description: 'Type of integration.' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the integration' + description: 'Name of the integration.' field :active, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Whether the endpoint is currently accepting alerts' + description: 'Whether the endpoint is currently accepting alerts.' field :token, GraphQL::STRING_TYPE, null: true, - description: 'Token used to authenticate alert notification requests' + description: 'Token used to authenticate alert notification requests.' field :url, GraphQL::STRING_TYPE, null: true, - description: 'Endpoint which accepts alert notifications' + description: 'Endpoint which accepts alert notifications.' field :api_url, GraphQL::STRING_TYPE, null: true, - description: 'URL at which Prometheus metrics can be queried to populate the metrics dashboard' + description: 'URL at which Prometheus metrics can be queried to populate the metrics dashboard.' definition_methods do def resolve_type(object, context) diff --git a/app/graphql/types/award_emojis/award_emoji_type.rb b/app/graphql/types/award_emojis/award_emoji_type.rb index cd7a2f34ba6..9409304e28f 100644 --- a/app/graphql/types/award_emojis/award_emoji_type.rb +++ b/app/graphql/types/award_emojis/award_emoji_type.rb @@ -13,32 +13,32 @@ module Types field :name, GraphQL::STRING_TYPE, null: false, - description: 'The emoji name' + description: 'The emoji name.' field :description, GraphQL::STRING_TYPE, null: false, - description: 'The emoji description' + description: 'The emoji description.' field :unicode, GraphQL::STRING_TYPE, null: false, - description: 'The emoji in unicode' + description: 'The emoji in Unicode.' field :emoji, GraphQL::STRING_TYPE, null: false, - description: 'The emoji as an icon' + description: 'The emoji as an icon.' field :unicode_version, GraphQL::STRING_TYPE, null: false, - description: 'The unicode version for this emoji' + description: 'The Unicode version for this emoji.' field :user, Types::UserType, null: false, - description: 'The user who awarded the emoji' + description: 'The user who awarded the emoji.' def user Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.user_id).find diff --git a/app/graphql/types/base_enum.rb b/app/graphql/types/base_enum.rb index cbd45b46dd6..4d470aceca4 100644 --- a/app/graphql/types/base_enum.rb +++ b/app/graphql/types/base_enum.rb @@ -21,7 +21,7 @@ module Types graphql_name(enum_mod.name) if use_name description(enum_mod.description) if use_description - enum_mod.definition.each { |key, content| value(key.to_s.upcase, content) } + enum_mod.definition.each { |key, content| value(key.to_s.upcase, **content) } end def value(*args, **kwargs, &block) diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb index c4ce2cecd8b..f145b9d45c3 100644 --- a/app/graphql/types/base_field.rb +++ b/app/graphql/types/base_field.rb @@ -30,7 +30,7 @@ module Types def resolve_field(obj, args, ctx) ctx.schema.after_lazy(obj) do |after_obj| query_ctx = ctx.query.context - inner_obj = after_obj && after_obj.object + 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) diff --git a/app/graphql/types/board_list_type.rb b/app/graphql/types/board_list_type.rb index 7999e77eb30..46b49c5d8a4 100644 --- a/app/graphql/types/board_list_type.rb +++ b/app/graphql/types/board_list_type.rb @@ -9,22 +9,22 @@ module Types description 'Represents a list for an issue board' field :id, GraphQL::ID_TYPE, null: false, - description: 'ID (global ID) of the list' + description: 'ID (global ID) of the list.' field :title, GraphQL::STRING_TYPE, null: false, - description: 'Title of the list' + description: 'Title of the list.' field :list_type, GraphQL::STRING_TYPE, null: false, - description: 'Type of the list' + description: 'Type of the list.' field :position, GraphQL::INT_TYPE, null: true, - description: 'Position of list within the board' + description: 'Position of list within the board.' field :label, Types::LabelType, null: true, - description: 'Label of the list' + description: 'Label of the list.' field :collapsed, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if list is collapsed for this user' + description: 'Indicates if list is collapsed for this user.' field :issues_count, GraphQL::INT_TYPE, null: true, - description: 'Count of issues in the list' + description: 'Count of issues in the list.' field :issues, ::Types::IssueType.connection_type, null: true, - description: 'Board issues', + description: 'Board issues.', resolver: ::Resolvers::BoardListIssuesResolver def issues_count diff --git a/app/graphql/types/board_type.rb b/app/graphql/types/board_type.rb index f576fd83840..f8bd31d5fa0 100644 --- a/app/graphql/types/board_type.rb +++ b/app/graphql/types/board_type.rb @@ -10,20 +10,20 @@ module Types present_using BoardPresenter field :id, type: GraphQL::ID_TYPE, null: false, - description: 'ID (global ID) of the board' + description: 'ID (global ID) of the board.' field :name, type: GraphQL::STRING_TYPE, null: true, - description: 'Name of the board' + description: 'Name of the board.' field :hide_backlog_list, type: GraphQL::BOOLEAN_TYPE, null: true, - description: 'Whether or not backlog list is hidden' + description: 'Whether or not backlog list is hidden.' field :hide_closed_list, type: GraphQL::BOOLEAN_TYPE, null: true, - description: 'Whether or not closed list is hidden' + description: 'Whether or not closed list is hidden.' field :lists, Types::BoardListType.connection_type, null: true, - description: 'Lists of the board', + description: 'Lists of the board.', resolver: Resolvers::BoardListsResolver, extras: [:lookahead] 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 1187b3352cd..dab1414760b 100644 --- a/app/graphql/types/boards/board_issue_input_base_type.rb +++ b/app/graphql/types/boards/board_issue_input_base_type.rb @@ -6,27 +6,27 @@ module Types class BoardIssueInputBaseType < BaseInputObject argument :label_name, GraphQL::STRING_TYPE.to_list_type, required: false, - description: 'Filter by label name' + description: 'Filter by label name.' argument :milestone_title, GraphQL::STRING_TYPE, required: false, - description: 'Filter by milestone title' + description: 'Filter by milestone title.' argument :assignee_username, GraphQL::STRING_TYPE.to_list_type, required: false, - description: 'Filter by assignee username' + description: 'Filter by assignee username.' argument :author_username, GraphQL::STRING_TYPE, required: false, - description: 'Filter by author username' + description: 'Filter by author username.' argument :release_tag, GraphQL::STRING_TYPE, required: false, - description: 'Filter by release tag' + description: 'Filter by release tag.' argument :my_reaction_emoji, GraphQL::STRING_TYPE, required: false, - description: 'Filter by reaction emoji' + description: 'Filter by reaction emoji.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/boards/board_issue_input_type.rb b/app/graphql/types/boards/board_issue_input_type.rb index 40d065d8ea9..62a402ee724 100644 --- a/app/graphql/types/boards/board_issue_input_type.rb +++ b/app/graphql/types/boards/board_issue_input_type.rb @@ -11,11 +11,11 @@ module Types argument :not, NegatedBoardIssueInputType, required: false, - description: 'List of negated params. Warning: this argument is experimental and a subject to change in future' + description: 'List of negated params. Warning: this argument is experimental and a subject to change in future.' argument :search, GraphQL::STRING_TYPE, required: false, - description: 'Search query for issue title or description' + description: 'Search query for issue title or description.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/branch_type.rb b/app/graphql/types/branch_type.rb index b15038a46de..b788ba79769 100644 --- a/app/graphql/types/branch_type.rb +++ b/app/graphql/types/branch_type.rb @@ -8,11 +8,11 @@ module Types field :name, GraphQL::STRING_TYPE, null: false, - description: 'Name of the branch' + description: 'Name of the branch.' field :commit, Types::CommitType, null: true, resolver: Resolvers::BranchCommitResolver, - description: 'Commit for the branch' + description: 'Commit for the branch.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/ci/analytics_type.rb b/app/graphql/types/ci/analytics_type.rb index c8b12c6a9b8..ba987b133bd 100644 --- a/app/graphql/types/ci/analytics_type.rb +++ b/app/graphql/types/ci/analytics_type.rb @@ -7,27 +7,27 @@ module Types graphql_name 'PipelineAnalytics' field :week_pipelines_totals, [GraphQL::INT_TYPE], null: true, - description: 'Total weekly pipeline count' + description: 'Total weekly pipeline count.' field :week_pipelines_successful, [GraphQL::INT_TYPE], null: true, - description: 'Total weekly successful pipeline count' + description: 'Total weekly successful pipeline count.' field :week_pipelines_labels, [GraphQL::STRING_TYPE], null: true, - description: 'Labels for the weekly pipeline count' + description: 'Labels for the weekly pipeline count.' field :month_pipelines_totals, [GraphQL::INT_TYPE], null: true, - description: 'Total monthly pipeline count' + description: 'Total monthly pipeline count.' field :month_pipelines_successful, [GraphQL::INT_TYPE], null: true, - description: 'Total monthly successful pipeline count' + description: 'Total monthly successful pipeline count.' field :month_pipelines_labels, [GraphQL::STRING_TYPE], null: true, - description: 'Labels for the monthly pipeline count' + description: 'Labels for the monthly pipeline count.' field :year_pipelines_totals, [GraphQL::INT_TYPE], null: true, - description: 'Total yearly pipeline count' + description: 'Total yearly pipeline count.' field :year_pipelines_successful, [GraphQL::INT_TYPE], null: true, - description: 'Total yearly successful pipeline count' + description: 'Total yearly successful pipeline count.' field :year_pipelines_labels, [GraphQL::STRING_TYPE], null: true, - description: 'Labels for the yearly pipeline count' + description: 'Labels for the yearly pipeline count.' field :pipeline_times_values, [GraphQL::INT_TYPE], null: true, - description: 'Pipeline times' + description: 'Pipeline times.' field :pipeline_times_labels, [GraphQL::STRING_TYPE], null: true, - description: 'Pipeline times labels' + description: 'Pipeline times labels.' end end end diff --git a/app/graphql/types/ci/application_setting_type.rb b/app/graphql/types/ci/application_setting_type.rb new file mode 100644 index 00000000000..8616280057c --- /dev/null +++ b/app/graphql/types/ci/application_setting_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module Ci + class ApplicationSettingType < BaseObject + graphql_name 'CiApplicationSettings' + + authorize :read_application_setting + + field :keep_latest_artifact, GraphQL::BOOLEAN_TYPE, null: true, + description: 'Whether to keep the latest jobs artifacts.' + end + end +end diff --git a/app/graphql/types/ci/ci_cd_setting_type.rb b/app/graphql/types/ci/ci_cd_setting_type.rb index e80771cdf9d..b34a91446a2 100644 --- a/app/graphql/types/ci/ci_cd_setting_type.rb +++ b/app/graphql/types/ci/ci_cd_setting_type.rb @@ -14,7 +14,8 @@ module Types description: 'Whether merge trains are enabled.', method: :merge_trains_enabled? field :keep_latest_artifact, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Whether to keep the latest builds artifacts.' + description: 'Whether to keep the latest builds artifacts.', + method: :keep_latest_artifacts_available? field :project, Types::ProjectType, null: true, description: 'Project the CI/CD settings belong to.' end diff --git a/app/graphql/types/ci/config/config_type.rb b/app/graphql/types/ci/config/config_type.rb index 29093c6d3c9..88caf21c376 100644 --- a/app/graphql/types/ci/config/config_type.rb +++ b/app/graphql/types/ci/config/config_type.rb @@ -8,13 +8,13 @@ module Types graphql_name 'CiConfig' field :errors, [GraphQL::STRING_TYPE], null: true, - description: 'Linting errors' + description: 'Linting errors.' field :merged_yaml, GraphQL::STRING_TYPE, null: true, - description: 'Merged CI config YAML' + description: 'Merged CI configuration YAML.' field :stages, Types::Ci::Config::StageType.connection_type, null: true, - description: 'Stages of the pipeline' + description: 'Stages of the pipeline.' field :status, Types::Ci::Config::StatusEnum, null: true, - description: 'Status of linting, can be either valid or invalid' + description: 'Status of linting, can be either valid or invalid.' end end end diff --git a/app/graphql/types/ci/config/group_type.rb b/app/graphql/types/ci/config/group_type.rb index 8e133bbcba8..11be701e73f 100644 --- a/app/graphql/types/ci/config/group_type.rb +++ b/app/graphql/types/ci/config/group_type.rb @@ -8,11 +8,11 @@ module Types graphql_name 'CiConfigGroup' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the job group' + description: 'Name of the job group.' field :jobs, Types::Ci::Config::JobType.connection_type, null: true, - description: 'Jobs in group' + description: 'Jobs in group.' field :size, GraphQL::INT_TYPE, null: true, - description: 'Size of the job group' + description: 'Size of the job group.' end end end diff --git a/app/graphql/types/ci/config/need_type.rb b/app/graphql/types/ci/config/need_type.rb index a442450b9ae..01f73100409 100644 --- a/app/graphql/types/ci/config/need_type.rb +++ b/app/graphql/types/ci/config/need_type.rb @@ -8,7 +8,7 @@ module Types graphql_name 'CiConfigNeed' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the need' + description: 'Name of the need.' end end end diff --git a/app/graphql/types/ci/config/stage_type.rb b/app/graphql/types/ci/config/stage_type.rb index 2008c553629..060efb7d45c 100644 --- a/app/graphql/types/ci/config/stage_type.rb +++ b/app/graphql/types/ci/config/stage_type.rb @@ -8,9 +8,9 @@ module Types graphql_name 'CiConfigStage' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the stage' + description: 'Name of the stage.' field :groups, Types::Ci::Config::GroupType.connection_type, null: true, - description: 'Groups of jobs for the stage' + description: 'Groups of jobs for the stage.' end end end diff --git a/app/graphql/types/ci/detailed_status_type.rb b/app/graphql/types/ci/detailed_status_type.rb index 80d73e9b174..0b643a6b676 100644 --- a/app/graphql/types/ci/detailed_status_type.rb +++ b/app/graphql/types/ci/detailed_status_type.rb @@ -7,26 +7,27 @@ module Types graphql_name 'DetailedStatus' field :group, GraphQL::STRING_TYPE, null: true, - description: 'Group of the status' + description: 'Group of the status.' field :icon, GraphQL::STRING_TYPE, null: true, - description: 'Icon of the status' + description: 'Icon of the status.' field :favicon, GraphQL::STRING_TYPE, null: true, - description: 'Favicon of the status' + description: 'Favicon of the status.' field :details_path, GraphQL::STRING_TYPE, null: true, - description: 'Path of the details for the status' + description: 'Path of the details for the status.' field :has_details, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if the status has further details', + description: 'Indicates if the status has further details.', method: :has_details? field :label, GraphQL::STRING_TYPE, null: true, - description: 'Label of the status' + calls_gitaly: true, + description: 'Label of the status.' field :text, GraphQL::STRING_TYPE, null: true, - description: 'Text of the status' + description: 'Text of the status.' field :tooltip, GraphQL::STRING_TYPE, null: true, - description: 'Tooltip associated with the status', + description: 'Tooltip associated with the status.', method: :status_tooltip field :action, Types::Ci::StatusActionType, null: true, - calls_gitaly: true, - description: 'Action information for the status. This includes method, button title, icon, path, and title' + calls_gitaly: true, + description: 'Action information for the status. This includes method, button title, icon, path, and title.' def action if object.has_action? diff --git a/app/graphql/types/ci/group_type.rb b/app/graphql/types/ci/group_type.rb index 03fd50d5dbb..d6d4252e8d7 100644 --- a/app/graphql/types/ci/group_type.rb +++ b/app/graphql/types/ci/group_type.rb @@ -7,13 +7,13 @@ module Types graphql_name 'CiGroup' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the job group' + description: 'Name of the job group.' field :size, GraphQL::INT_TYPE, null: true, - description: 'Size of the group' + description: 'Size of the group.' field :jobs, Ci::JobType.connection_type, null: true, - description: 'Jobs in group' + description: 'Jobs in group.' field :detailed_status, Types::Ci::DetailedStatusType, null: true, - description: 'Detailed status of the group' + description: 'Detailed status of the group.' def detailed_status object.detailed_status(context[:current_user]) diff --git a/app/graphql/types/ci/job_artifact_type.rb b/app/graphql/types/ci/job_artifact_type.rb index c34a12dcc61..7dc93041b53 100644 --- a/app/graphql/types/ci/job_artifact_type.rb +++ b/app/graphql/types/ci/job_artifact_type.rb @@ -7,10 +7,10 @@ module Types graphql_name 'CiJobArtifact' field :download_path, GraphQL::STRING_TYPE, null: true, - description: "URL for downloading the artifact's file" + description: "URL for downloading the artifact's file." field :file_type, ::Types::Ci::JobArtifactFileTypeEnum, null: true, - description: 'File type of the artifact' + description: 'File type of the artifact.' def download_path ::Gitlab::Routing.url_helpers.download_project_job_artifacts_path( diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb index f8bf1732e63..ba463cdd9c1 100644 --- a/app/graphql/types/ci/job_type.rb +++ b/app/graphql/types/ci/job_type.rb @@ -7,17 +7,17 @@ module Types authorize :read_commit_status field :pipeline, Types::Ci::PipelineType, null: true, - description: 'Pipeline the job belongs to' + description: 'Pipeline the job belongs to.' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the job' + description: 'Name of the job.' field :needs, BuildNeedType.connection_type, null: true, - description: 'References to builds that must complete before the jobs run' + description: 'References to builds that must complete before the jobs run.' field :detailed_status, Types::Ci::DetailedStatusType, null: true, - description: 'Detailed status of the job' + description: 'Detailed status of the job.' field :scheduled_at, Types::TimeType, null: true, - description: 'Schedule for the build' + description: 'Schedule for the build.' field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true, - description: 'Artifacts generated by the job' + description: 'Artifacts generated by the job.' 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 4709d5e8dd6..2c386c9b564 100644 --- a/app/graphql/types/ci/pipeline_type.rb +++ b/app/graphql/types/ci/pipeline_type.rb @@ -8,94 +8,98 @@ module Types connection_type_class(Types::CountableConnectionType) authorize :read_pipeline + present_using ::Ci::PipelinePresenter expose_permissions Types::PermissionTypes::Ci::Pipeline field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the pipeline' + description: 'ID of the pipeline.' field :iid, GraphQL::STRING_TYPE, null: false, - description: 'Internal ID of the pipeline' + description: 'Internal ID of the pipeline.' field :sha, GraphQL::STRING_TYPE, null: false, - description: "SHA of the pipeline's commit" + description: "SHA of the pipeline's commit." field :before_sha, GraphQL::STRING_TYPE, null: true, - description: 'Base SHA of the source branch' + description: 'Base SHA of the source branch.' field :status, PipelineStatusEnum, null: false, description: "Status of the pipeline (#{::Ci::Pipeline.all_state_names.compact.join(', ').upcase})" + field :warnings, GraphQL::BOOLEAN_TYPE, null: false, method: :has_warnings?, + description: "Indicates if a pipeline has warnings." + field :detailed_status, Types::Ci::DetailedStatusType, null: false, - description: 'Detailed status of the pipeline' + description: 'Detailed status of the pipeline.' field :config_source, PipelineConfigSourceEnum, null: true, - description: "Config source of the pipeline (#{::Enums::Ci::Pipeline.config_sources.keys.join(', ').upcase})" + description: "Configuration source of the pipeline (#{::Enums::Ci::Pipeline.config_sources.keys.join(', ').upcase})" field :duration, GraphQL::INT_TYPE, null: true, - description: 'Duration of the pipeline in seconds' + description: 'Duration of the pipeline in seconds.' field :coverage, GraphQL::FLOAT_TYPE, null: true, - description: 'Coverage percentage' + description: 'Coverage percentage.' field :created_at, Types::TimeType, null: false, - description: "Timestamp of the pipeline's creation" + description: "Timestamp of the pipeline's creation." field :updated_at, Types::TimeType, null: false, - description: "Timestamp of the pipeline's last activity" + description: "Timestamp of the pipeline's last activity." field :started_at, Types::TimeType, null: true, - description: 'Timestamp when the pipeline was started' + description: 'Timestamp when the pipeline was started.' field :finished_at, Types::TimeType, null: true, - description: "Timestamp of the pipeline's completion" + description: "Timestamp of the pipeline's completion." field :committed_at, Types::TimeType, null: true, - description: "Timestamp of the pipeline's commit" + description: "Timestamp of the pipeline's commit." field :stages, Types::Ci::StageType.connection_type, null: true, - description: 'Stages of the pipeline', + description: 'Stages of the pipeline.', extras: [:lookahead], resolver: Resolvers::Ci::PipelineStagesResolver field :user, Types::UserType, null: true, - description: 'Pipeline user' + description: 'Pipeline user.' field :retryable, GraphQL::BOOLEAN_TYPE, - description: 'Specifies if a pipeline can be retried', + description: 'Specifies if a pipeline can be retried.', method: :retryable?, null: false field :cancelable, GraphQL::BOOLEAN_TYPE, - description: 'Specifies if a pipeline can be canceled', + description: 'Specifies if a pipeline can be canceled.', method: :cancelable?, null: false field :jobs, ::Types::Ci::JobType.connection_type, null: true, - description: 'Jobs belonging to the pipeline', + description: 'Jobs belonging to the pipeline.', resolver: ::Resolvers::Ci::JobsResolver field :source_job, Types::Ci::JobType, null: true, - description: 'Job where pipeline was triggered from' + description: 'Job where pipeline was triggered from.' field :downstream, Types::Ci::PipelineType.connection_type, null: true, - description: 'Pipelines this pipeline will trigger', + description: 'Pipelines this pipeline will trigger.', method: :triggered_pipelines_with_preloads field :upstream, Types::Ci::PipelineType, null: true, - description: 'Pipeline that triggered the pipeline', + description: 'Pipeline that triggered the pipeline.', method: :triggered_by_pipeline field :path, GraphQL::STRING_TYPE, null: true, - description: "Relative path to the pipeline's page" + description: "Relative path to the pipeline's page." field :project, Types::ProjectType, null: true, - description: 'Project the pipeline belongs to' + description: 'Project the pipeline belongs to.' field :active, GraphQL::BOOLEAN_TYPE, null: false, method: :active?, - description: 'Indicates if the pipeline is active' + description: 'Indicates if the pipeline is active.' def detailed_status object.detailed_status(context[:current_user]) diff --git a/app/graphql/types/ci/runner_architecture_type.rb b/app/graphql/types/ci/runner_architecture_type.rb index 526348abd9d..229974d4d13 100644 --- a/app/graphql/types/ci/runner_architecture_type.rb +++ b/app/graphql/types/ci/runner_architecture_type.rb @@ -7,9 +7,9 @@ module Types graphql_name 'RunnerArchitecture' field :name, GraphQL::STRING_TYPE, null: false, - description: 'Name of the runner platform architecture' + description: 'Name of the runner platform architecture.' field :download_location, GraphQL::STRING_TYPE, null: false, - description: 'Download location for the runner for the platform architecture' + description: 'Download location for the runner for the platform architecture.' end end end diff --git a/app/graphql/types/ci/runner_platform_type.rb b/app/graphql/types/ci/runner_platform_type.rb index 64719bc4908..5636f88835e 100644 --- a/app/graphql/types/ci/runner_platform_type.rb +++ b/app/graphql/types/ci/runner_platform_type.rb @@ -7,11 +7,11 @@ module Types graphql_name 'RunnerPlatform' field :name, GraphQL::STRING_TYPE, null: false, - description: 'Name slug of the runner platform' + description: 'Name slug of the runner platform.' field :human_readable_name, GraphQL::STRING_TYPE, null: false, - description: 'Human readable name of the runner platform' + description: 'Human readable name of the runner platform.' field :architectures, Types::Ci::RunnerArchitectureType.connection_type, null: true, - description: 'Runner architectures supported for the platform' + description: 'Runner architectures supported for the platform.' end end end diff --git a/app/graphql/types/ci/runner_setup_type.rb b/app/graphql/types/ci/runner_setup_type.rb index 66abcf65adf..61a2ea2a411 100644 --- a/app/graphql/types/ci/runner_setup_type.rb +++ b/app/graphql/types/ci/runner_setup_type.rb @@ -7,9 +7,9 @@ module Types graphql_name 'RunnerSetup' field :install_instructions, GraphQL::STRING_TYPE, null: false, - description: 'Instructions for installing the runner on the specified architecture' + description: 'Instructions for installing the runner on the specified architecture.' field :register_instructions, GraphQL::STRING_TYPE, null: true, - description: 'Instructions for registering the runner' + description: 'Instructions for registering the runner.' end end end diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb index 695e7c61bd9..836f2430890 100644 --- a/app/graphql/types/ci/stage_type.rb +++ b/app/graphql/types/ci/stage_type.rb @@ -7,12 +7,12 @@ module Types graphql_name 'CiStage' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the stage' + description: 'Name of the stage.' field :groups, Ci::GroupType.connection_type, null: true, extras: [:lookahead], - description: 'Group of jobs for the stage' + description: 'Group of jobs for the stage.' field :detailed_status, Types::Ci::DetailedStatusType, null: true, - description: 'Detailed status of the stage' + description: 'Detailed status of the stage.' def detailed_status object.detailed_status(context[:current_user]) diff --git a/app/graphql/types/ci/status_action_type.rb b/app/graphql/types/ci/status_action_type.rb index 08cbb6d3b59..9f7299c0270 100644 --- a/app/graphql/types/ci/status_action_type.rb +++ b/app/graphql/types/ci/status_action_type.rb @@ -6,16 +6,16 @@ module Types graphql_name 'StatusAction' field :button_title, GraphQL::STRING_TYPE, null: true, - description: 'Title for the button, for example: Retry this job' + description: 'Title for the button, for example: Retry this job.' field :icon, GraphQL::STRING_TYPE, null: true, - description: 'Icon used in the action button' + description: 'Icon used in the action button.' field :method, GraphQL::STRING_TYPE, null: true, - description: 'Method for the action, for example: :post', + description: 'Method for the action, for example: :post.', resolver_method: :action_method field :path, GraphQL::STRING_TYPE, null: true, - description: 'Path for the action' + description: 'Path for the action.' field :title, GraphQL::STRING_TYPE, null: true, - description: 'Title for the action, for example: Retry' + description: 'Title for the action, for example: Retry.' def action_method object[:method] 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 new file mode 100644 index 00000000000..9835a7ef208 --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +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' + + argument :name, GraphQL::STRING_TYPE, required: true, + description: 'Name of analyzer.' + + argument :enabled, GraphQL::BOOLEAN_TYPE, required: true, + description: 'State of the analyzer.' + + argument :variables, [::Types::CiConfiguration::Sast::EntityInputType], + description: 'List of variables for the analyzer.', + required: false + end + end + end +end diff --git a/app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb b/app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb new file mode 100644 index 00000000000..3c6202ca7e0 --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Types + module CiConfiguration + module Sast + # rubocop: disable Graphql/AuthorizeTypes + class AnalyzersEntityType < BaseObject + graphql_name 'SastCiConfigurationAnalyzersEntity' + description 'Represents an analyzer entity in SAST CI configuration' + + field :name, GraphQL::STRING_TYPE, null: true, + description: 'Name of the analyzer.' + + field :label, GraphQL::STRING_TYPE, null: true, + description: 'Analyzer label used in the config UI.' + + field :enabled, GraphQL::BOOLEAN_TYPE, null: true, + description: 'Indicates whether an analyzer is enabled.' + + field :description, GraphQL::STRING_TYPE, null: true, + description: 'Analyzer description that is displayed on the form.' + + field :variables, ::Types::CiConfiguration::Sast::EntityType.connection_type, null: true, + description: 'List of supported variables.' + end + end + end +end diff --git a/app/graphql/types/ci_configuration/sast/entity_input_type.rb b/app/graphql/types/ci_configuration/sast/entity_input_type.rb new file mode 100644 index 00000000000..39b3efb3db8 --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/entity_input_type.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Types + module CiConfiguration + module Sast + # rubocop: disable Graphql/AuthorizeTypes + class EntityInputType < BaseInputObject + graphql_name 'SastCiConfigurationEntityInput' + description 'Represents an entity in SAST CI configuration' + + argument :field, GraphQL::STRING_TYPE, required: true, + description: 'CI keyword of entity.' + + argument :default_value, GraphQL::STRING_TYPE, required: true, + description: 'Default value that is used if value is empty.' + + argument :value, GraphQL::STRING_TYPE, required: true, + description: 'Current value of the entity.' + end + end + end +end diff --git a/app/graphql/types/ci_configuration/sast/entity_type.rb b/app/graphql/types/ci_configuration/sast/entity_type.rb new file mode 100644 index 00000000000..eeb9025391f --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/entity_type.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Types + module CiConfiguration + module Sast + # rubocop: disable Graphql/AuthorizeTypes + class EntityType < BaseObject + graphql_name 'SastCiConfigurationEntity' + description 'Represents an entity in SAST CI configuration' + + field :field, GraphQL::STRING_TYPE, null: true, + description: 'CI keyword of entity.' + + field :label, GraphQL::STRING_TYPE, null: true, + description: 'Label for entity used in the form.' + + field :type, GraphQL::STRING_TYPE, null: true, + description: 'Type of the field value.' + + field :options, ::Types::CiConfiguration::Sast::OptionsEntityType.connection_type, null: true, + description: 'Different possible values of the field.' + + field :default_value, GraphQL::STRING_TYPE, null: true, + description: 'Default value that is used if value is empty.' + + field :description, GraphQL::STRING_TYPE, null: true, + description: 'Entity description that is displayed on the form.' + + field :value, GraphQL::STRING_TYPE, null: true, + description: 'Current value of the entity.' + + field :size, ::Types::CiConfiguration::Sast::UiComponentSizeEnum, null: true, + description: 'Size of the UI component.' + end + end + end +end diff --git a/app/graphql/types/ci_configuration/sast/input_type.rb b/app/graphql/types/ci_configuration/sast/input_type.rb new file mode 100644 index 00000000000..615436683f6 --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/input_type.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Types + module CiConfiguration + module Sast + class InputType < BaseInputObject # rubocop:disable Graphql/AuthorizeTypes + graphql_name 'SastCiConfigurationInput' + description 'Represents a CI configuration of SAST' + + argument :global, [::Types::CiConfiguration::Sast::EntityInputType], + description: 'List of global entities related to SAST configuration.', + required: false + + argument :pipeline, [::Types::CiConfiguration::Sast::EntityInputType], + description: 'List of pipeline entities related to SAST configuration.', + required: false + + argument :analyzers, [::Types::CiConfiguration::Sast::AnalyzersEntityInputType], + description: 'List of analyzers and related variables for the SAST configuration.', + required: false + end + end + end +end diff --git a/app/graphql/types/ci_configuration/sast/options_entity_type.rb b/app/graphql/types/ci_configuration/sast/options_entity_type.rb new file mode 100644 index 00000000000..86d104a7fda --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/options_entity_type.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Types + module CiConfiguration + module Sast + # rubocop: disable Graphql/AuthorizeTypes + class OptionsEntityType < BaseObject + graphql_name 'SastCiConfigurationOptionsEntity' + description 'Represents an entity for options in SAST CI configuration' + + field :label, GraphQL::STRING_TYPE, null: true, + description: 'Label of option entity.' + + field :value, GraphQL::STRING_TYPE, null: true, + description: 'Value of option entity.' + end + end + end +end diff --git a/app/graphql/types/ci_configuration/sast/type.rb b/app/graphql/types/ci_configuration/sast/type.rb new file mode 100644 index 00000000000..35d11584ac7 --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/type.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Types + module CiConfiguration + module Sast + # rubocop: disable Graphql/AuthorizeTypes + class Type < BaseObject + graphql_name 'SastCiConfiguration' + description 'Represents a CI configuration of SAST' + + field :global, ::Types::CiConfiguration::Sast::EntityType.connection_type, null: true, + description: 'List of global entities related to SAST configuration.' + + field :pipeline, ::Types::CiConfiguration::Sast::EntityType.connection_type, null: true, + description: 'List of pipeline entities related to SAST configuration.' + + field :analyzers, ::Types::CiConfiguration::Sast::AnalyzersEntityType.connection_type, null: true, + description: 'List of analyzers entities attached to SAST configuration.' + end + end + end +end 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 new file mode 100644 index 00000000000..3a208f9d3e4 --- /dev/null +++ b/app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + module CiConfiguration + module Sast + class UiComponentSizeEnum < BaseEnum + graphql_name 'SastUiComponentSize' + description 'Size of UI component in SAST configuration page' + + value 'SMALL' + value 'MEDIUM' + value 'LARGE' + end + end + end +end diff --git a/app/graphql/types/commit_action_type.rb b/app/graphql/types/commit_action_type.rb index 7674abb11eb..e14e7157752 100644 --- a/app/graphql/types/commit_action_type.rb +++ b/app/graphql/types/commit_action_type.rb @@ -4,19 +4,19 @@ 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' + description: 'The action to perform, create, delete, move, update, chmod.' argument :file_path, type: GraphQL::STRING_TYPE, required: true, - description: 'Full path to the file' + description: 'Full path to the file.' argument :content, type: GraphQL::STRING_TYPE, required: false, - description: 'Content of the file' + description: 'Content of the file.' argument :previous_path, type: GraphQL::STRING_TYPE, required: false, - description: 'Original full path to the file being moved' + description: 'Original full path to the file being moved.' argument :last_commit_id, type: GraphQL::STRING_TYPE, required: false, - description: 'Last known file commit ID' + description: 'Last known file commit ID.' argument :execute_filemode, type: GraphQL::BOOLEAN_TYPE, required: false, - description: 'Enables/disables the execute flag on the file' + description: 'Enables/disables the execute flag on the file.' argument :encoding, type: Types::CommitEncodingEnum, required: false, - description: 'Encoding of the file. Default is text' + description: 'Encoding of the file. Default is text.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/commit_type.rb b/app/graphql/types/commit_type.rb index 37d19b4148b..d137901380b 100644 --- a/app/graphql/types/commit_type.rb +++ b/app/graphql/types/commit_type.rb @@ -9,39 +9,39 @@ module Types present_using CommitPresenter field :id, type: GraphQL::ID_TYPE, null: false, - description: 'ID (global ID) of the commit' + description: 'ID (global ID) of the commit.' field :sha, type: GraphQL::STRING_TYPE, null: false, - description: 'SHA1 ID of the commit' + description: 'SHA1 ID of the commit.' field :short_id, type: GraphQL::STRING_TYPE, null: false, - description: 'Short SHA1 ID of the commit' + description: 'Short SHA1 ID of the commit.' field :title, type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true, - description: 'Title of the commit message' + description: 'Title of the commit message.' markdown_field :title_html, null: true field :description, type: GraphQL::STRING_TYPE, null: true, - description: 'Description of the commit message' + description: 'Description of the commit message.' markdown_field :description_html, null: true field :message, type: GraphQL::STRING_TYPE, null: true, - description: 'Raw commit message' + description: 'Raw commit message.' field :authored_date, type: Types::TimeType, null: true, - description: 'Timestamp of when the commit was authored' + description: 'Timestamp of when the commit was authored.' field :web_url, type: GraphQL::STRING_TYPE, null: false, - description: 'Web URL of the commit' + description: 'Web URL of the commit.' field :web_path, type: GraphQL::STRING_TYPE, null: false, - description: 'Web path of the commit' + description: 'Web path of the commit.' field :signature_html, type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true, - description: 'Rendered HTML of the commit signature' + description: 'Rendered HTML of the commit signature.' field :author_name, type: GraphQL::STRING_TYPE, null: true, - description: 'Commit authors name' + description: 'Commit authors name.' field :author_gravatar, type: GraphQL::STRING_TYPE, null: true, - description: 'Commit authors gravatar' + description: 'Commit authors gravatar.' # models/commit lazy loads the author by email field :author, type: Types::UserType, null: true, - description: 'Author of the commit' + description: 'Author of the commit.' field :pipelines, null: true, - description: 'Pipelines of the commit ordered latest first', + description: 'Pipelines of the commit ordered latest first.', resolver: Resolvers::CommitPipelinesResolver def author_gravatar diff --git a/app/graphql/types/container_expiration_policy_type.rb b/app/graphql/types/container_expiration_policy_type.rb index f19aa964377..2b01474617a 100644 --- a/app/graphql/types/container_expiration_policy_type.rb +++ b/app/graphql/types/container_expiration_policy_type.rb @@ -8,14 +8,14 @@ module Types authorize :destroy_container_image - field :created_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was created' - field :updated_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was updated' - field :enabled, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether this container expiration policy is enabled' - field :older_than, Types::ContainerExpirationPolicyOlderThanEnum, null: true, description: 'Tags older that this will expire' - field :cadence, Types::ContainerExpirationPolicyCadenceEnum, null: false, description: 'This container expiration policy schedule' - field :keep_n, Types::ContainerExpirationPolicyKeepEnum, null: true, description: 'Number of tags to retain' - field :name_regex, Types::UntrustedRegexp, null: true, description: 'Tags with names matching this regex pattern will expire' - field :name_regex_keep, Types::UntrustedRegexp, null: true, description: 'Tags with names matching this regex pattern will be preserved' - field :next_run_at, Types::TimeType, null: true, description: 'Next time that this container expiration policy will get executed' + field :created_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was created.' + field :updated_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was updated.' + field :enabled, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether this container expiration policy is enabled.' + field :older_than, Types::ContainerExpirationPolicyOlderThanEnum, null: true, description: 'Tags older that this will expire.' + field :cadence, Types::ContainerExpirationPolicyCadenceEnum, null: false, description: 'This container expiration policy schedule.' + field :keep_n, Types::ContainerExpirationPolicyKeepEnum, null: true, description: 'Number of tags to retain.' + field :name_regex, Types::UntrustedRegexp, null: true, description: 'Tags with names matching this regex pattern will expire.' + field :name_regex_keep, Types::UntrustedRegexp, null: true, description: 'Tags with names matching this regex pattern will be preserved.' + field :next_run_at, Types::TimeType, null: true, description: 'Next time that this container expiration policy will get executed.' end end diff --git a/app/graphql/types/container_repository_details_type.rb b/app/graphql/types/container_repository_details_type.rb index 34523f3ea4a..1a9f57e701f 100644 --- a/app/graphql/types/container_repository_details_type.rb +++ b/app/graphql/types/container_repository_details_type.rb @@ -11,7 +11,7 @@ module Types field :tags, Types::ContainerRepositoryTagType.connection_type, null: true, - description: 'Tags of the container repository', + description: 'Tags of the container repository.', max_page_size: 20 def can_delete diff --git a/app/graphql/types/container_repository_sort_enum.rb b/app/graphql/types/container_repository_sort_enum.rb new file mode 100644 index 00000000000..96210c0546b --- /dev/null +++ b/app/graphql/types/container_repository_sort_enum.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Types + class ContainerRepositorySortEnum < SortEnum + 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 + end +end diff --git a/app/graphql/types/container_repository_type.rb b/app/graphql/types/container_repository_type.rb index 8735f8a173d..48c2b9f460f 100644 --- a/app/graphql/types/container_repository_type.rb +++ b/app/graphql/types/container_repository_type.rb @@ -19,7 +19,7 @@ module Types field :status, Types::ContainerRepositoryStatusEnum, null: true, description: 'Status of the container repository.' field :tags_count, GraphQL::INT_TYPE, null: false, description: 'Number of tags associated with this image.' field :can_delete, GraphQL::BOOLEAN_TYPE, null: false, description: 'Can the current user delete the container repository.' - field :project, Types::ProjectType, null: false, description: 'Project of the container registry' + field :project, Types::ProjectType, null: false, description: 'Project of the container registry.' def can_delete Ability.allowed?(current_user, :update_container_image, object) diff --git a/app/graphql/types/countable_connection_type.rb b/app/graphql/types/countable_connection_type.rb index f67194d99b3..0a9699a4570 100644 --- a/app/graphql/types/countable_connection_type.rb +++ b/app/graphql/types/countable_connection_type.rb @@ -4,7 +4,7 @@ module Types # rubocop: disable Graphql/AuthorizeTypes class CountableConnectionType < GraphQL::Types::Relay::BaseConnection field :count, GraphQL::INT_TYPE, null: false, - description: 'Total count of collection' + description: 'Total count of collection.' def count # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/graphql/types/current_user_todos.rb b/app/graphql/types/current_user_todos.rb index e610286c1a9..79a430af1d7 100644 --- a/app/graphql/types/current_user_todos.rb +++ b/app/graphql/types/current_user_todos.rb @@ -8,10 +8,10 @@ module Types field_class Types::BaseField field :current_user_todos, Types::TodoType.connection_type, - description: 'Todos for the current user', + description: 'To-do items for the current user.', null: false do argument :state, Types::TodoStateEnum, - description: 'State of the todos', + description: 'State of the to-do items.', required: false end diff --git a/app/graphql/types/custom_emoji_type.rb b/app/graphql/types/custom_emoji_type.rb index f7d1a7800bc..246b60ce184 100644 --- a/app/graphql/types/custom_emoji_type.rb +++ b/app/graphql/types/custom_emoji_type.rb @@ -9,19 +9,19 @@ module Types field :id, ::Types::GlobalIDType[::CustomEmoji], null: false, - description: 'The ID of the emoji' + description: 'The ID of the emoji.' field :name, GraphQL::STRING_TYPE, null: false, - description: 'The name of the emoji' + description: 'The name of the emoji.' field :url, GraphQL::STRING_TYPE, null: false, method: :file, - description: 'The link to file of the emoji' + description: 'The link to file of the emoji.' field :external, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Whether the emoji is an external link' + description: 'Whether the emoji is an external link.' end end diff --git a/app/graphql/types/design_management/design_at_version_type.rb b/app/graphql/types/design_management/design_at_version_type.rb index e10a0de1715..4240b8f3aae 100644 --- a/app/graphql/types/design_management/design_at_version_type.rb +++ b/app/graphql/types/design_management/design_at_version_type.rb @@ -18,12 +18,12 @@ module Types field :version, Types::DesignManagement::VersionType, null: false, - description: 'The version this design-at-versions is pinned to' + description: 'The version this design-at-versions is pinned to.' field :design, Types::DesignManagement::DesignType, null: false, - description: 'The underlying design' + description: 'The underlying design.' def cached_stateful_version(_parent) version diff --git a/app/graphql/types/design_management/design_collection_type.rb b/app/graphql/types/design_management/design_collection_type.rb index 26fbac15b30..570eac907f3 100644 --- a/app/graphql/types/design_management/design_collection_type.rb +++ b/app/graphql/types/design_management/design_collection_type.rb @@ -9,40 +9,40 @@ module Types authorize :read_design field :project, Types::ProjectType, null: false, - description: 'Project associated with the design collection' + description: 'Project associated with the design collection.' field :issue, Types::IssueType, null: false, - description: 'Issue associated with the design collection' + description: 'Issue associated with the design collection.' field :designs, Types::DesignManagement::DesignType.connection_type, null: false, resolver: Resolvers::DesignManagement::DesignsResolver, - description: 'All designs for the design collection', + description: 'All designs for the design collection.', complexity: 5 field :versions, Types::DesignManagement::VersionType.connection_type, resolver: Resolvers::DesignManagement::VersionsResolver, - description: 'All versions related to all designs, ordered newest first' + description: 'All versions related to all designs, ordered newest first.' field :version, Types::DesignManagement::VersionType, resolver: Resolvers::DesignManagement::VersionsResolver.single, - description: 'A specific version' + description: 'A specific version.' field :design_at_version, ::Types::DesignManagement::DesignAtVersionType, null: true, resolver: ::Resolvers::DesignManagement::DesignAtVersionResolver, - description: 'Find a design as of a version' + description: 'Find a design as of a version.' field :design, ::Types::DesignManagement::DesignType, null: true, resolver: ::Resolvers::DesignManagement::DesignResolver, - description: 'Find a specific design' + description: 'Find a specific design.' field :copy_state, ::Types::DesignManagement::DesignCollectionCopyStateEnum, null: true, - description: 'Copy state of the design collection' + description: 'Copy state of the design collection.' end end end diff --git a/app/graphql/types/design_management/design_fields.rb b/app/graphql/types/design_management/design_fields.rb index b03b3927392..b770e30f5be 100644 --- a/app/graphql/types/design_management/design_fields.rb +++ b/app/graphql/types/design_management/design_fields.rb @@ -7,12 +7,12 @@ module Types field_class Types::BaseField - field :id, GraphQL::ID_TYPE, description: 'The ID of this design', null: false - field :project, Types::ProjectType, null: false, description: 'The project the design belongs to' - field :issue, Types::IssueType, null: false, description: 'The issue the design belongs to' - field :filename, GraphQL::STRING_TYPE, null: false, description: 'The filename of the design' - field :full_path, GraphQL::STRING_TYPE, null: false, description: 'The full path to the design file' - field :image, GraphQL::STRING_TYPE, null: false, extras: [:parent], description: 'The URL of the full-sized image' + field :id, GraphQL::ID_TYPE, description: 'The ID of this design.', null: false + field :project, Types::ProjectType, null: false, description: 'The project the design belongs to.' + field :issue, Types::IssueType, null: false, description: 'The issue the design belongs to.' + field :filename, GraphQL::STRING_TYPE, null: false, description: 'The filename of the design.' + field :full_path, GraphQL::STRING_TYPE, null: false, description: 'The full path to the design file.' + field :image, GraphQL::STRING_TYPE, null: false, extras: [:parent], description: 'The URL of the full-sized image.' field :image_v432x230, GraphQL::STRING_TYPE, null: true, extras: [:parent], description: 'The URL of the design resized to fit within the bounds of 432x230. ' \ 'This will be `null` if the image has not been generated' @@ -20,16 +20,16 @@ module Types null: false, calls_gitaly: true, extras: [:parent], - description: 'The diff refs for this design' + description: 'The diff refs for this design.' field :event, Types::DesignManagement::DesignVersionEventEnum, null: false, extras: [:parent], - description: 'How this design was changed in the current version' + description: 'How this design was changed in the current version.' field :notes_count, GraphQL::INT_TYPE, null: false, method: :user_notes_count, - description: 'The total count of user-created notes for this design' + description: 'The total count of user-created notes for this design.' def diff_refs(parent:) version = cached_stateful_version(parent) diff --git a/app/graphql/types/design_management/design_type.rb b/app/graphql/types/design_management/design_type.rb index bab22015dc4..44e87905f92 100644 --- a/app/graphql/types/design_management/design_type.rb +++ b/app/graphql/types/design_management/design_type.rb @@ -17,7 +17,7 @@ module Types field :versions, Types::DesignManagement::VersionType.connection_type, resolver: Resolvers::DesignManagement::VersionsResolver, - description: "All versions related to this design ordered newest first", + description: "All versions related to this design ordered newest first.", extras: [:parent] # Returns a `DesignManagement::Version` for this query based on the diff --git a/app/graphql/types/design_management/version_type.rb b/app/graphql/types/design_management/version_type.rb index c774f5d1bdf..4bc71aef0f4 100644 --- a/app/graphql/types/design_management/version_type.rb +++ b/app/graphql/types/design_management/version_type.rb @@ -12,25 +12,25 @@ module Types authorize :read_design field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the design version' + description: 'ID of the design version.' field :sha, GraphQL::ID_TYPE, null: false, - description: 'SHA of the design version' + description: 'SHA of the design version.' field :designs, ::Types::DesignManagement::DesignType.connection_type, null: false, - description: 'All designs that were changed in the version' + description: 'All designs that were changed in the version.' field :designs_at_version, ::Types::DesignManagement::DesignAtVersionType.connection_type, null: false, - description: 'All designs that are visible at this version, as of this version', + description: 'All designs that are visible at this version, as of this version.', resolver: ::Resolvers::DesignManagement::Version::DesignsAtVersionResolver field :design_at_version, ::Types::DesignManagement::DesignAtVersionType, null: false, - description: 'A particular design as of this version, provided it is visible at this version', + description: 'A particular design as of this version, provided it is visible at this version.', resolver: ::Resolvers::DesignManagement::Version::DesignsAtVersionResolver.single end end diff --git a/app/graphql/types/design_management_type.rb b/app/graphql/types/design_management_type.rb index ec85b8a0c1f..be0fb8253ca 100644 --- a/app/graphql/types/design_management_type.rb +++ b/app/graphql/types/design_management_type.rb @@ -8,11 +8,11 @@ module Types field :version, ::Types::DesignManagement::VersionType, null: true, resolver: ::Resolvers::DesignManagement::VersionResolver, - description: 'Find a version' + description: 'Find a version.' field :design_at_version, ::Types::DesignManagement::DesignAtVersionType, null: true, resolver: ::Resolvers::DesignManagement::DesignAtVersionResolver, - description: 'Find a design as of a version' + description: 'Find a design as of a version.' end end diff --git a/app/graphql/types/diff_paths_input_type.rb b/app/graphql/types/diff_paths_input_type.rb index 43feddd9827..864cec1ab07 100644 --- a/app/graphql/types/diff_paths_input_type.rb +++ b/app/graphql/types/diff_paths_input_type.rb @@ -4,9 +4,9 @@ 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' + 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' + description: 'The path of the file on the head sha.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/diff_refs_type.rb b/app/graphql/types/diff_refs_type.rb index 4049a204f66..3c8f934f1eb 100644 --- a/app/graphql/types/diff_refs_type.rb +++ b/app/graphql/types/diff_refs_type.rb @@ -7,11 +7,11 @@ module Types graphql_name 'DiffRefs' field :head_sha, GraphQL::STRING_TYPE, null: false, - description: 'SHA of the HEAD at the time the comment was made' + description: 'SHA of the HEAD at the time the comment was made.' field :base_sha, GraphQL::STRING_TYPE, null: true, - description: 'Merge base of the branch the comment was made on' + description: 'Merge base of the branch the comment was made on.' field :start_sha, GraphQL::STRING_TYPE, null: false, - description: 'SHA of the branch being compared against' + description: 'SHA of the branch being compared against.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/diff_stats_summary_type.rb b/app/graphql/types/diff_stats_summary_type.rb index 956400fd21b..78c0e2f2b4c 100644 --- a/app/graphql/types/diff_stats_summary_type.rb +++ b/app/graphql/types/diff_stats_summary_type.rb @@ -9,13 +9,13 @@ module Types description 'Aggregated summary of changes' field :additions, GraphQL::INT_TYPE, null: false, - description: 'Number of lines added' + description: 'Number of lines added.' field :deletions, GraphQL::INT_TYPE, null: false, - description: 'Number of lines deleted' + description: 'Number of lines deleted.' field :changes, GraphQL::INT_TYPE, null: false, - description: 'Number of lines changed' + description: 'Number of lines changed.' field :file_count, GraphQL::INT_TYPE, null: false, - description: 'Number of files changed' + description: 'Number of files changed.' def changes object[:additions] + object[:deletions] diff --git a/app/graphql/types/diff_stats_type.rb b/app/graphql/types/diff_stats_type.rb index 6c79a4c389d..8a6840e5a94 100644 --- a/app/graphql/types/diff_stats_type.rb +++ b/app/graphql/types/diff_stats_type.rb @@ -9,11 +9,11 @@ module Types description 'Changes to a single file' field :path, GraphQL::STRING_TYPE, null: false, - description: 'File path, relative to repository root' + description: 'File path, relative to repository root.' field :additions, GraphQL::INT_TYPE, null: false, - description: 'Number of lines added to this file' + description: 'Number of lines added to this file.' field :deletions, GraphQL::INT_TYPE, null: false, - description: 'Number of lines deleted from this file' + description: 'Number of lines deleted from this file.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/environment_type.rb b/app/graphql/types/environment_type.rb index e3885668643..2e6417f08ea 100644 --- a/app/graphql/types/environment_type.rb +++ b/app/graphql/types/environment_type.rb @@ -10,24 +10,24 @@ module Types authorize :read_environment field :name, GraphQL::STRING_TYPE, null: false, - description: 'Human-readable name of the environment' + description: 'Human-readable name of the environment.' field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the environment' + description: 'ID of the environment.' field :state, GraphQL::STRING_TYPE, null: false, - description: 'State of the environment, for example: available/stopped' + description: 'State of the environment, for example: available/stopped.' field :path, GraphQL::STRING_TYPE, null: false, description: 'The path to the environment.' field :metrics_dashboard, Types::Metrics::DashboardType, null: true, - description: 'Metrics dashboard schema for the environment', + description: 'Metrics dashboard schema for the environment.', resolver: Resolvers::Metrics::DashboardResolver field :latest_opened_most_severe_alert, Types::AlertManagement::AlertType, null: true, - description: 'The most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned' + description: 'The most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned.' end end diff --git a/app/graphql/types/error_tracking/sentry_detailed_error_type.rb b/app/graphql/types/error_tracking/sentry_detailed_error_type.rb index cfde9fa0d6a..59bd97e3448 100644 --- a/app/graphql/types/error_tracking/sentry_detailed_error_type.rb +++ b/app/graphql/types/error_tracking/sentry_detailed_error_type.rb @@ -12,93 +12,93 @@ module Types field :id, GraphQL::ID_TYPE, null: false, - description: 'ID (global ID) of the error' + description: 'ID (global ID) of the error.' field :sentry_id, GraphQL::STRING_TYPE, method: :id, null: false, - description: 'ID (Sentry ID) of the error' + description: 'ID (Sentry ID) of the error.' field :title, GraphQL::STRING_TYPE, null: false, - description: 'Title of the error' + description: 'Title of the error.' field :type, GraphQL::STRING_TYPE, null: false, - description: 'Type of the error' + description: 'Type of the error.' field :user_count, GraphQL::INT_TYPE, null: false, - description: 'Count of users affected by the error' + description: 'Count of users affected by the error.' field :count, GraphQL::INT_TYPE, null: false, - description: 'Count of occurrences' + description: 'Count of occurrences.' field :first_seen, Types::TimeType, null: false, - description: 'Timestamp when the error was first seen' + description: 'Timestamp when the error was first seen.' field :last_seen, Types::TimeType, null: false, - description: 'Timestamp when the error was last seen' + description: 'Timestamp when the error was last seen.' field :message, GraphQL::STRING_TYPE, null: true, - description: 'Sentry metadata message of the error' + description: 'Sentry metadata message of the error.' field :culprit, GraphQL::STRING_TYPE, null: false, - description: 'Culprit of the error' + description: 'Culprit of the error.' field :external_base_url, GraphQL::STRING_TYPE, null: false, - description: 'External Base URL of the Sentry Instance' + description: 'External Base URL of the Sentry Instance.' field :external_url, GraphQL::STRING_TYPE, null: false, - description: 'External URL of the error' + description: 'External URL of the error.' field :sentry_project_id, GraphQL::ID_TYPE, method: :project_id, null: false, - description: 'ID of the project (Sentry project)' + description: 'ID of the project (Sentry project).' field :sentry_project_name, GraphQL::STRING_TYPE, method: :project_name, null: false, - description: 'Name of the project affected by the error' + description: 'Name of the project affected by the error.' field :sentry_project_slug, GraphQL::STRING_TYPE, method: :project_slug, null: false, - description: 'Slug of the project affected by the error' + description: 'Slug of the project affected by the error.' field :short_id, GraphQL::STRING_TYPE, null: false, - description: 'Short ID (Sentry ID) of the error' + description: 'Short ID (Sentry ID) of the error.' field :status, Types::ErrorTracking::SentryErrorStatusEnum, null: false, - description: 'Status of the error' + description: 'Status of the error.' field :frequency, [Types::ErrorTracking::SentryErrorFrequencyType], null: false, - description: 'Last 24hr stats of the error' + description: 'Last 24hr stats of the error.' field :first_release_last_commit, GraphQL::STRING_TYPE, null: true, - description: 'Commit the error was first seen' + description: 'Commit the error was first seen.' field :last_release_last_commit, GraphQL::STRING_TYPE, null: true, - description: 'Commit the error was last seen' + description: 'Commit the error was last seen.' field :first_release_short_version, GraphQL::STRING_TYPE, null: true, - description: 'Release short version the error was first seen' + description: 'Release short version the error was first seen.' field :last_release_short_version, GraphQL::STRING_TYPE, null: true, - description: 'Release short version the error was last seen' + description: 'Release short version the error was last seen.' field :first_release_version, GraphQL::STRING_TYPE, null: true, - description: 'Release version the error was first seen' + description: 'Release version the error was first seen.' field :last_release_version, GraphQL::STRING_TYPE, null: true, - description: 'Release version the error was last seen' + description: 'Release version the error was last seen.' field :gitlab_commit, GraphQL::STRING_TYPE, null: true, - description: 'GitLab commit SHA attributed to the Error based on the release version' + description: 'GitLab commit SHA attributed to the Error based on the release version.' field :gitlab_commit_path, GraphQL::STRING_TYPE, null: true, - description: 'Path to the GitLab page for the GitLab commit attributed to the error' + description: 'Path to the GitLab page for the GitLab commit attributed to the error.' field :gitlab_issue_path, GraphQL::STRING_TYPE, method: :gitlab_issue, null: true, - description: 'URL of GitLab Issue' + description: 'URL of GitLab Issue.' field :tags, Types::ErrorTracking::SentryErrorTagsType, null: false, - description: 'Tags associated with the Sentry Error' + description: 'Tags associated with the Sentry Error.' end end end diff --git a/app/graphql/types/error_tracking/sentry_error_collection_type.rb b/app/graphql/types/error_tracking/sentry_error_collection_type.rb index 49d5d62c860..d3941b7c410 100644 --- a/app/graphql/types/error_tracking/sentry_error_collection_type.rb +++ b/app/graphql/types/error_tracking/sentry_error_collection_type.rb @@ -9,18 +9,18 @@ module Types authorize :read_sentry_issue field :errors, - description: "Collection of Sentry Errors", + description: "Collection of Sentry Errors.", resolver: Resolvers::ErrorTracking::SentryErrorsResolver field :detailed_error, - description: 'Detailed version of a Sentry error on the project', + description: 'Detailed version of a Sentry error on the project.', resolver: Resolvers::ErrorTracking::SentryDetailedErrorResolver field :error_stack_trace, - description: 'Stack Trace of Sentry Error', + description: 'Stack Trace of Sentry Error.', resolver: Resolvers::ErrorTracking::SentryErrorStackTraceResolver field :external_url, GraphQL::STRING_TYPE, null: true, - description: "External URL for Sentry" + description: "External URL for Sentry." end end end diff --git a/app/graphql/types/error_tracking/sentry_error_frequency_type.rb b/app/graphql/types/error_tracking/sentry_error_frequency_type.rb index a44ca0684b6..05af1391af3 100644 --- a/app/graphql/types/error_tracking/sentry_error_frequency_type.rb +++ b/app/graphql/types/error_tracking/sentry_error_frequency_type.rb @@ -8,10 +8,10 @@ module Types field :time, Types::TimeType, null: false, - description: "Time the error frequency stats were recorded" + description: "Time the error frequency stats were recorded." field :count, GraphQL::INT_TYPE, null: false, - description: "Count of errors received since the previously recorded time" + description: "Count of errors received since the previously recorded time." end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb b/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb index e6d02c948d5..0b3c4cf55b9 100644 --- a/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb +++ b/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb @@ -10,11 +10,11 @@ module Types field :line, GraphQL::INT_TYPE, null: false, - description: 'Line number of the context' + description: 'Line number of the context.' field :code, GraphQL::STRING_TYPE, null: false, - description: 'Code number of the context' + description: 'Code number of the context.' def line object[0] diff --git a/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb b/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb index 2e6c40b233b..c9915d052f9 100644 --- a/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb +++ b/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb @@ -9,19 +9,19 @@ module Types field :function, GraphQL::STRING_TYPE, null: true, - description: 'Function in which the Sentry error occurred' + description: 'Function in which the Sentry error occurred.' field :col, GraphQL::STRING_TYPE, null: true, - description: 'Function in which the Sentry error occurred' + description: 'Function in which the Sentry error occurred.' field :line, GraphQL::STRING_TYPE, null: true, - description: 'Function in which the Sentry error occurred' + description: 'Function in which the Sentry error occurred.' field :file_name, GraphQL::STRING_TYPE, null: true, - description: 'File in which the Sentry error occurred' + description: 'File in which the Sentry error occurred.' field :trace_context, [Types::ErrorTracking::SentryErrorStackTraceContextType], null: true, - description: 'Context of the Sentry error' + description: 'Context of the Sentry error.' def function object['function'] diff --git a/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb b/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb index 1bbe7e0c77b..52959a9329b 100644 --- a/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb +++ b/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb @@ -10,13 +10,13 @@ module Types field :issue_id, GraphQL::STRING_TYPE, null: false, - description: 'ID of the Sentry error' + description: 'ID of the Sentry error.' field :date_received, GraphQL::STRING_TYPE, null: false, - description: 'Time the stack trace was received by Sentry' + description: 'Time the stack trace was received by Sentry.' field :stack_trace_entries, [Types::ErrorTracking::SentryErrorStackTraceEntryType], null: false, - description: 'Stack trace entries for the Sentry error' + description: 'Stack trace entries for the Sentry error.' end end end diff --git a/app/graphql/types/error_tracking/sentry_error_tags_type.rb b/app/graphql/types/error_tracking/sentry_error_tags_type.rb index e6d96571561..e2b051998c5 100644 --- a/app/graphql/types/error_tracking/sentry_error_tags_type.rb +++ b/app/graphql/types/error_tracking/sentry_error_tags_type.rb @@ -9,10 +9,10 @@ module Types field :level, GraphQL::STRING_TYPE, null: true, - description: "Severity level of the Sentry Error" + description: "Severity level of the Sentry Error." field :logger, GraphQL::STRING_TYPE, null: true, - description: "Logger of the Sentry Error" + description: "Logger of the Sentry Error." end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/error_tracking/sentry_error_type.rb b/app/graphql/types/error_tracking/sentry_error_type.rb index 693ab0c4f8f..c0e09fb8c65 100644 --- a/app/graphql/types/error_tracking/sentry_error_type.rb +++ b/app/graphql/types/error_tracking/sentry_error_type.rb @@ -11,59 +11,59 @@ module Types field :id, GraphQL::ID_TYPE, null: false, - description: 'ID (global ID) of the error' + description: 'ID (global ID) of the error.' field :sentry_id, GraphQL::STRING_TYPE, method: :id, null: false, - description: 'ID (Sentry ID) of the error' + description: 'ID (Sentry ID) of the error.' field :first_seen, Types::TimeType, null: false, - description: 'Timestamp when the error was first seen' + description: 'Timestamp when the error was first seen.' field :last_seen, Types::TimeType, null: false, - description: 'Timestamp when the error was last seen' + description: 'Timestamp when the error was last seen.' field :title, GraphQL::STRING_TYPE, null: false, - description: 'Title of the error' + description: 'Title of the error.' field :type, GraphQL::STRING_TYPE, null: false, - description: 'Type of the error' + description: 'Type of the error.' field :user_count, GraphQL::INT_TYPE, null: false, - description: 'Count of users affected by the error' + description: 'Count of users affected by the error.' field :count, GraphQL::INT_TYPE, null: false, - description: 'Count of occurrences' + description: 'Count of occurrences.' field :message, GraphQL::STRING_TYPE, null: true, - description: 'Sentry metadata message of the error' + description: 'Sentry metadata message of the error.' field :culprit, GraphQL::STRING_TYPE, null: false, - description: 'Culprit of the error' + description: 'Culprit of the error.' field :external_url, GraphQL::STRING_TYPE, null: false, - description: 'External URL of the error' + description: 'External URL of the error.' field :short_id, GraphQL::STRING_TYPE, null: false, - description: 'Short ID (Sentry ID) of the error' + description: 'Short ID (Sentry ID) of the error.' field :status, Types::ErrorTracking::SentryErrorStatusEnum, null: false, - description: 'Status of the error' + description: 'Status of the error.' field :frequency, [Types::ErrorTracking::SentryErrorFrequencyType], null: false, - description: 'Last 24hr stats of the error' + description: 'Last 24hr stats of the error.' field :sentry_project_id, GraphQL::ID_TYPE, method: :project_id, null: false, - description: 'ID of the project (Sentry project)' + description: 'ID of the project (Sentry project).' field :sentry_project_name, GraphQL::STRING_TYPE, method: :project_name, null: false, - description: 'Name of the project affected by the error' + description: 'Name of the project affected by the error.' field :sentry_project_slug, GraphQL::STRING_TYPE, method: :project_slug, null: false, - description: 'Slug of the project affected by the error' + description: 'Slug of the project affected by the error.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/event_action_enum.rb b/app/graphql/types/event_action_enum.rb new file mode 100644 index 00000000000..79931fa48cb --- /dev/null +++ b/app/graphql/types/event_action_enum.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Types + class EventActionEnum < BaseEnum + graphql_name 'EventAction' + description 'Event action' + + ::Event.actions.keys.each do |target_type| + value target_type.upcase, value: target_type, description: "#{target_type.titleize} action" + end + end +end diff --git a/app/graphql/types/event_type.rb b/app/graphql/types/event_type.rb new file mode 100644 index 00000000000..2a4c2e7c60a --- /dev/null +++ b/app/graphql/types/event_type.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Types + class EventType < BaseObject + graphql_name 'Event' + description 'Representing an event' + + present_using EventPresenter + + authorize :read_event + + field :id, GraphQL::ID_TYPE, + description: 'ID of the event.', + null: false + + field :author, Types::UserType, + description: 'Author of this event.', + null: false + + field :action, Types::EventActionEnum, + description: 'Action of the event.', + null: false + + field :created_at, Types::TimeType, + description: 'When this event was created.', + null: false + + field :updated_at, Types::TimeType, + description: 'When this event was updated.', + null: false + + def author + Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find + end + end +end diff --git a/app/graphql/types/eventable_type.rb b/app/graphql/types/eventable_type.rb new file mode 100644 index 00000000000..eba2154e7fa --- /dev/null +++ b/app/graphql/types/eventable_type.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Types + module EventableType + include Types::BaseInterface + + field :events, Types::EventType.connection_type, null: true, description: 'A list of events associated with the object.' + end +end diff --git a/app/graphql/types/evidence_type.rb b/app/graphql/types/evidence_type.rb index a2fc9953c67..6e56ad7d407 100644 --- a/app/graphql/types/evidence_type.rb +++ b/app/graphql/types/evidence_type.rb @@ -10,12 +10,12 @@ module Types present_using Releases::EvidencePresenter field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the evidence' + description: 'ID of the evidence.' field :sha, GraphQL::STRING_TYPE, null: true, - description: 'SHA1 ID of the evidence hash' + description: 'SHA1 ID of the evidence hash.' field :filepath, GraphQL::STRING_TYPE, null: true, - description: 'URL from where the evidence can be downloaded' + description: 'URL from where the evidence can be downloaded.' field :collected_at, Types::TimeType, null: true, - description: 'Timestamp when the evidence was collected' + description: 'Timestamp when the evidence was collected.' end end diff --git a/app/graphql/types/global_id_type.rb b/app/graphql/types/global_id_type.rb index 4c51d4248dd..ed28c3ffd7e 100644 --- a/app/graphql/types/global_id_type.rb +++ b/app/graphql/types/global_id_type.rb @@ -46,7 +46,7 @@ module Types @id_types[model_class] ||= Class.new(self) do graphql_name "#{model_class.name.gsub(/::/, '')}ID" - description "Identifier of #{model_class.name}" + description "Identifier of #{model_class.name}." self.define_singleton_method(:to_s) do graphql_name diff --git a/app/graphql/types/grafana_integration_type.rb b/app/graphql/types/grafana_integration_type.rb index 6625af36f82..630d3a10e36 100644 --- a/app/graphql/types/grafana_integration_type.rb +++ b/app/graphql/types/grafana_integration_type.rb @@ -7,14 +7,14 @@ module Types authorize :admin_operations field :id, GraphQL::ID_TYPE, null: false, - description: 'Internal ID of the Grafana integration' + description: 'Internal ID of the Grafana integration.' field :grafana_url, GraphQL::STRING_TYPE, null: false, - description: 'URL for the Grafana host for the Grafana integration' + description: 'URL for the Grafana host for the Grafana integration.' field :enabled, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates whether Grafana integration is enabled' + description: 'Indicates whether Grafana integration is enabled.' field :created_at, Types::TimeType, null: false, - description: 'Timestamp of the issue\'s creation' + description: 'Timestamp of the issue\'s creation.' field :updated_at, Types::TimeType, null: false, - description: 'Timestamp of the issue\'s last activity' + description: 'Timestamp of the issue\'s last activity.' end end diff --git a/app/graphql/types/group_invitation_type.rb b/app/graphql/types/group_invitation_type.rb index efb0c8a41c8..06a997bbc14 100644 --- a/app/graphql/types/group_invitation_type.rb +++ b/app/graphql/types/group_invitation_type.rb @@ -11,7 +11,7 @@ module Types description 'Represents a Group Invitation' field :group, Types::GroupType, null: true, - description: 'Group that a User is invited to' + description: 'Group that a User is invited to.' def group Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find diff --git a/app/graphql/types/group_member_type.rb b/app/graphql/types/group_member_type.rb index 204da5a302a..8b8e69d795d 100644 --- a/app/graphql/types/group_member_type.rb +++ b/app/graphql/types/group_member_type.rb @@ -11,7 +11,7 @@ module Types description 'Represents a Group Membership' field :group, Types::GroupType, null: true, - description: 'Group that a User is a member of' + description: 'Group that a User is a member of.' def group Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb index 0ee8a19c1a3..0aaeb8d20df 100644 --- a/app/graphql/types/group_type.rb +++ b/app/graphql/types/group_type.rb @@ -9,91 +9,91 @@ module Types expose_permissions Types::PermissionTypes::Group field :web_url, GraphQL::STRING_TYPE, null: false, - description: 'Web URL of the group' + description: 'Web URL of the group.' field :avatar_url, GraphQL::STRING_TYPE, null: true, - description: 'Avatar URL of the group' + description: 'Avatar URL of the group.' field :custom_emoji, Types::CustomEmojiType.connection_type, null: true, - description: 'Custom emoji within this namespace', + description: 'Custom emoji within this namespace.', feature_flag: :custom_emoji field :share_with_group_lock, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if sharing a project with another group within this group is prevented' + description: 'Indicates if sharing a project with another group within this group is prevented.' field :project_creation_level, GraphQL::STRING_TYPE, null: true, method: :project_creation_level_str, - description: 'The permission level required to create projects in the group' + description: 'The permission level required to create projects in the group.' field :subgroup_creation_level, GraphQL::STRING_TYPE, null: true, method: :subgroup_creation_level_str, - description: 'The permission level required to create subgroups within the group' + description: 'The permission level required to create subgroups within the group.' field :require_two_factor_authentication, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if all users in this group are required to set up two-factor authentication' + description: 'Indicates if all users in this group are required to set up two-factor authentication.' field :two_factor_grace_period, GraphQL::INT_TYPE, null: true, - description: 'Time before two-factor authentication is enforced' + description: 'Time before two-factor authentication is enforced.' field :auto_devops_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates whether Auto DevOps is enabled for all projects within this group' + description: 'Indicates whether Auto DevOps is enabled for all projects within this group.' field :emails_disabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if a group has email notifications disabled' + description: 'Indicates if a group has email notifications disabled.' field :mentions_disabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if a group is disabled from getting mentioned' + description: 'Indicates if a group is disabled from getting mentioned.' field :parent, GroupType, null: true, - description: 'Parent group' + description: 'Parent group.' field :issues, Types::IssueType.connection_type, null: true, - description: 'Issues for projects in this group', + description: 'Issues for projects in this group.', resolver: Resolvers::GroupIssuesResolver field :merge_requests, Types::MergeRequestType.connection_type, null: true, - description: 'Merge requests for projects in this group', + description: 'Merge requests for projects in this group.', resolver: Resolvers::GroupMergeRequestsResolver field :milestones, Types::MilestoneType.connection_type, null: true, - description: 'Milestones of the group', + description: 'Milestones of the group.', resolver: Resolvers::GroupMilestonesResolver field :boards, Types::BoardType.connection_type, null: true, - description: 'Boards of the group', + description: 'Boards of the group.', max_page_size: 2000, resolver: Resolvers::BoardsResolver field :board, Types::BoardType, null: true, - description: 'A single board of the group', + description: 'A single board of the group.', resolver: Resolvers::BoardResolver field :label, Types::LabelType, null: true, - description: 'A label available on this group' do + description: 'A label available on this group.' do argument :title, GraphQL::STRING_TYPE, required: true, - description: 'Title of the label' + description: 'Title of the label.' end field :group_members, - description: 'A membership of a user within this group', + description: 'A membership of a user within this group.', resolver: Resolvers::GroupMembersResolver field :container_repositories, Types::ContainerRepositoryType.connection_type, null: true, - description: 'Container repositories of the group', + description: 'Container repositories of the group.', resolver: Resolvers::ContainerRepositoriesResolver, authorize: :read_container_image field :container_repositories_count, GraphQL::INT_TYPE, null: false, - description: 'Number of container repositories in the group' + description: 'Number of container repositories in the group.' def label(title:) BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args| @@ -107,17 +107,8 @@ module Types field :labels, Types::LabelType.connection_type, null: true, - description: 'Labels available on this group' do - argument :search_term, GraphQL::STRING_TYPE, - required: false, - description: 'A search term to find labels with' - end - - def labels(search_term: nil) - LabelsFinder - .new(current_user, group: group, search: search_term) - .execute - end + description: 'Labels available on this group.', + resolver: Resolvers::GroupLabelsResolver def avatar_url object.avatar_url(only_path: false) diff --git a/app/graphql/types/invitation_interface.rb b/app/graphql/types/invitation_interface.rb index a29716c292e..b1f69f043f2 100644 --- a/app/graphql/types/invitation_interface.rb +++ b/app/graphql/types/invitation_interface.rb @@ -5,25 +5,25 @@ module Types include BaseInterface field :email, GraphQL::STRING_TYPE, null: false, - description: 'Email of the member to invite' + description: 'Email of the member to invite.' field :access_level, Types::AccessLevelType, null: true, - description: 'GitLab::Access level' + description: 'GitLab::Access level.' field :created_by, Types::UserType, null: true, - description: 'User that authorized membership' + description: 'User that authorized membership.' field :created_at, Types::TimeType, null: true, - description: 'Date and time the membership was created' + description: 'Date and time the membership was created.' field :updated_at, Types::TimeType, null: true, - description: 'Date and time the membership was last updated' + description: 'Date and time the membership was last updated.' field :expires_at, Types::TimeType, null: true, - description: 'Date and time the membership expires' + description: 'Date and time the membership expires.' field :user, Types::UserType, null: true, - description: 'User that is associated with the member object' + description: 'User that is associated with the member object.' definition_methods do def resolve_type(object, context) diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb index 78fb20650e9..f15ab69f2d4 100644 --- a/app/graphql/types/issue_type.rb +++ b/app/graphql/types/issue_type.rb @@ -16,113 +16,113 @@ module Types present_using IssuePresenter field :id, GraphQL::ID_TYPE, null: false, - description: "ID of the issue" + description: "ID of the issue." field :iid, GraphQL::ID_TYPE, null: false, - description: "Internal ID of the issue" + description: "Internal ID of the issue." field :title, GraphQL::STRING_TYPE, null: false, - description: 'Title of the issue' + description: 'Title of the issue.' markdown_field :title_html, null: true field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description of the issue' + description: 'Description of the issue.' markdown_field :description_html, null: true field :state, IssueStateEnum, null: false, - description: 'State of the issue' + description: 'State of the issue.' field :reference, GraphQL::STRING_TYPE, null: false, - description: 'Internal reference of the issue. Returned in shortened format by default', + description: 'Internal reference of the issue. Returned in shortened format by default.', method: :to_reference do argument :full, GraphQL::BOOLEAN_TYPE, required: false, default_value: false, - description: 'Boolean option specifying whether the reference should be returned in full' + description: 'Boolean option specifying whether the reference should be returned in full.' end field :author, Types::UserType, null: false, - description: 'User that created the issue' + description: 'User that created the issue.' field :assignees, Types::UserType.connection_type, null: true, - description: 'Assignees of the issue' + description: 'Assignees of the issue.' field :updated_by, Types::UserType, null: true, - description: 'User that last updated the issue' + description: 'User that last updated the issue.' field :labels, Types::LabelType.connection_type, null: true, - description: 'Labels of the issue' + description: 'Labels of the issue.' field :milestone, Types::MilestoneType, null: true, - description: 'Milestone of the issue' + description: 'Milestone of the issue.' field :due_date, Types::TimeType, null: true, - description: 'Due date of the issue' + description: 'Due date of the issue.' field :confidential, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates the issue is confidential' + description: 'Indicates the issue is confidential.' field :discussion_locked, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates discussion is locked on the issue' + description: 'Indicates discussion is locked on the issue.' field :upvotes, GraphQL::INT_TYPE, null: false, - description: 'Number of upvotes the issue has received' + description: 'Number of upvotes the issue has received.' field :downvotes, GraphQL::INT_TYPE, null: false, - description: 'Number of downvotes the issue has received' + description: 'Number of downvotes the issue has received.' field :user_notes_count, GraphQL::INT_TYPE, null: false, - description: 'Number of user notes of the issue', + description: 'Number of user notes of the issue.', resolver: Resolvers::UserNotesCountResolver field :user_discussions_count, GraphQL::INT_TYPE, null: false, - description: 'Number of user discussions in the issue', + description: 'Number of user discussions in the issue.', resolver: Resolvers::UserDiscussionsCountResolver field :web_path, GraphQL::STRING_TYPE, null: false, method: :issue_path, - description: 'Web path of the issue' + description: 'Web path of the issue.' field :web_url, GraphQL::STRING_TYPE, null: false, - description: 'Web URL of the issue' + description: 'Web URL of the issue.' field :relative_position, GraphQL::INT_TYPE, null: true, - description: 'Relative position of the issue (used for positioning in epic tree and issue boards)' + description: 'Relative position of the issue (used for positioning in epic tree and issue boards).' field :participants, Types::UserType.connection_type, null: true, complexity: 5, - description: 'List of participants in the issue' + description: 'List of participants in the issue.' field :emails_disabled, GraphQL::BOOLEAN_TYPE, null: false, method: :project_emails_disabled?, - description: 'Indicates if a project has email notifications disabled: `true` if email notifications are disabled' + description: 'Indicates if a project has email notifications disabled: `true` if email notifications are disabled.' field :subscribed, GraphQL::BOOLEAN_TYPE, method: :subscribed?, null: false, complexity: 5, - description: 'Indicates the currently logged in user is subscribed to the issue' + description: 'Indicates the currently logged in user is subscribed to the issue.' field :time_estimate, GraphQL::INT_TYPE, null: false, - description: 'Time estimate of the issue' + description: 'Time estimate of the issue.' field :total_time_spent, GraphQL::INT_TYPE, null: false, - description: 'Total time reported as spent on the issue' + description: 'Total time reported as spent on the issue.' field :human_time_estimate, GraphQL::STRING_TYPE, null: true, - description: 'Human-readable time estimate of the issue' + description: 'Human-readable time estimate of the issue.' field :human_total_time_spent, GraphQL::STRING_TYPE, null: true, - description: 'Human-readable total time reported as spent on the issue' + description: 'Human-readable total time reported as spent on the issue.' field :closed_at, Types::TimeType, null: true, - description: 'Timestamp of when the issue was closed' + description: 'Timestamp of when the issue was closed.' field :created_at, Types::TimeType, null: false, - description: 'Timestamp of when the issue was created' + description: 'Timestamp of when the issue was created.' field :updated_at, Types::TimeType, null: false, - description: 'Timestamp of when the issue was last updated' + description: 'Timestamp of when the issue was last updated.' field :task_completion_status, Types::TaskCompletionStatus, null: false, - description: 'Task completion status of the issue' + description: 'Task completion status of the issue.' field :design_collection, Types::DesignManagement::DesignCollectionType, null: true, - description: 'Collection of design images associated with this issue' + description: 'Collection of design images associated with this issue.' field :type, Types::IssueTypeEnum, null: true, method: :issue_type, - description: 'Type of the issue' + description: 'Type of the issue.' field :alert_management_alert, Types::AlertManagement::AlertType, null: true, - description: 'Alert associated to this issue' + description: 'Alert associated to this issue.' field :severity, Types::IssuableSeverityEnum, null: true, - description: 'Severity level of the incident' + description: 'Severity level of the incident.' field :moved, GraphQL::BOOLEAN_TYPE, method: :moved?, null: true, - description: 'Indicates if issue got moved from other project' + description: 'Indicates if issue got moved from other project.' field :moved_to, Types::IssueType, null: true, - description: 'Updated Issue after it got moved to another project' + description: 'Updated Issue after it got moved to another project.' field :create_note_email, GraphQL::STRING_TYPE, null: true, - description: 'User specific email address for the issue' + description: 'User specific email address for the issue.' def author Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find diff --git a/app/graphql/types/jira_import_type.rb b/app/graphql/types/jira_import_type.rb index b3854487cec..6fa115933ac 100644 --- a/app/graphql/types/jira_import_type.rb +++ b/app/graphql/types/jira_import_type.rb @@ -7,19 +7,19 @@ module Types graphql_name 'JiraImport' field :created_at, Types::TimeType, null: true, - description: 'Timestamp of when the Jira import was created' + description: 'Timestamp of when the Jira import was created.' field :scheduled_at, Types::TimeType, null: true, - description: 'Timestamp of when the Jira import was scheduled' + description: 'Timestamp of when the Jira import was scheduled.' field :scheduled_by, Types::UserType, null: true, - description: 'User that started the Jira import' + description: 'User that started the Jira import.' field :jira_project_key, GraphQL::STRING_TYPE, null: false, - description: 'Project key for the imported Jira project' + description: 'Project key for the imported Jira project.' field :imported_issues_count, GraphQL::INT_TYPE, null: false, - description: 'Count of issues that were successfully imported' + description: 'Count of issues that were successfully imported.' field :failed_to_import_count, GraphQL::INT_TYPE, null: false, - description: 'Count of issues that failed to import' + description: 'Count of issues that failed to import.' field :total_issue_count, GraphQL::INT_TYPE, null: false, - description: 'Total count of issues that were attempted to import' + description: 'Total count of issues that were attempted to import.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/jira_user_type.rb b/app/graphql/types/jira_user_type.rb index 394820d23be..7ccb7ad6791 100644 --- a/app/graphql/types/jira_user_type.rb +++ b/app/graphql/types/jira_user_type.rb @@ -7,17 +7,17 @@ module Types graphql_name 'JiraUser' field :jira_account_id, GraphQL::STRING_TYPE, null: false, - description: 'Account ID of the Jira user' + description: 'Account ID of the Jira user.' field :jira_display_name, GraphQL::STRING_TYPE, null: false, - description: 'Display name of the Jira user' + description: 'Display name of the Jira user.' field :jira_email, GraphQL::STRING_TYPE, null: true, - description: 'Email of the Jira user, returned only for users with public emails' + description: 'Email of the Jira user, returned only for users with public emails.' field :gitlab_id, GraphQL::INT_TYPE, null: true, - description: 'ID of the matched GitLab user' + description: 'ID of the matched GitLab user.' field :gitlab_username, GraphQL::STRING_TYPE, null: true, - description: 'Username of the matched GitLab user' + description: 'Username of the matched GitLab user.' field :gitlab_name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the matched GitLab user' + description: 'Name of the matched GitLab user.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/jira_users_mapping_input_type.rb b/app/graphql/types/jira_users_mapping_input_type.rb index d5b4b2f618a..0c26ea87df2 100644 --- a/app/graphql/types/jira_users_mapping_input_type.rb +++ b/app/graphql/types/jira_users_mapping_input_type.rb @@ -8,11 +8,11 @@ module Types argument :jira_account_id, GraphQL::STRING_TYPE, required: true, - description: 'Jira account ID of the user' + description: 'Jira account ID of the user.' argument :gitlab_id, GraphQL::INT_TYPE, required: false, - description: 'Id of the GitLab user' + 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 28dee2a9db5..94fd15e075c 100644 --- a/app/graphql/types/label_type.rb +++ b/app/graphql/types/label_type.rb @@ -9,15 +9,15 @@ module Types authorize :read_label field :id, GraphQL::ID_TYPE, null: false, - description: 'Label ID' + description: 'Label ID.' field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description of the label (Markdown rendered as HTML for caching)' + description: 'Description of the label (Markdown rendered as HTML for caching).' markdown_field :description_html, null: true field :title, GraphQL::STRING_TYPE, null: false, - description: 'Content of the label' + description: 'Content of the label.' field :color, GraphQL::STRING_TYPE, null: false, - description: 'Background color of the label' + description: 'Background color of the label.' field :text_color, GraphQL::STRING_TYPE, null: false, - description: 'Text color of the label' + description: 'Text color of the label.' end end diff --git a/app/graphql/types/member_interface.rb b/app/graphql/types/member_interface.rb index 615a45413cb..1c7257487d9 100644 --- a/app/graphql/types/member_interface.rb +++ b/app/graphql/types/member_interface.rb @@ -5,25 +5,25 @@ module Types include BaseInterface field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the member' + description: 'ID of the member.' field :access_level, Types::AccessLevelType, null: true, - description: 'GitLab::Access level' + description: 'GitLab::Access level.' field :created_by, Types::UserType, null: true, - description: 'User that authorized membership' + description: 'User that authorized membership.' field :created_at, Types::TimeType, null: true, - description: 'Date and time the membership was created' + description: 'Date and time the membership was created.' field :updated_at, Types::TimeType, null: true, - description: 'Date and time the membership was last updated' + description: 'Date and time the membership was last updated.' field :expires_at, Types::TimeType, null: true, - description: 'Date and time the membership expires' + description: 'Date and time the membership expires.' field :user, Types::UserType, null: false, - description: 'User that is associated with the member object' + description: 'User that is associated with the member object.' definition_methods do def resolve_type(object, context) diff --git a/app/graphql/types/merge_request_connection_type.rb b/app/graphql/types/merge_request_connection_type.rb index da06bb86929..d009b67bc0f 100644 --- a/app/graphql/types/merge_request_connection_type.rb +++ b/app/graphql/types/merge_request_connection_type.rb @@ -4,7 +4,7 @@ module Types # rubocop: disable Graphql/AuthorizeTypes class MergeRequestConnectionType < Types::CountableConnectionType field :total_time_to_merge, GraphQL::FLOAT_TYPE, null: true, - description: 'Total sum of time to merge, in seconds, for the collection of merge requests' + description: 'Total sum of time to merge, in seconds, for the collection of merge requests.' # rubocop: disable CodeReuse/ActiveRecord def total_time_to_merge diff --git a/app/graphql/types/merge_request_state_enum.rb b/app/graphql/types/merge_request_state_enum.rb index 92f52726ab3..c14b9f80a53 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' + value 'merged', description: "Merge Request has been merged" end end diff --git a/app/graphql/types/merge_request_state_event_enum.rb b/app/graphql/types/merge_request_state_event_enum.rb new file mode 100644 index 00000000000..ebb8b9638db --- /dev/null +++ b/app/graphql/types/merge_request_state_event_enum.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + class MergeRequestStateEventEnum < BaseEnum + graphql_name 'MergeRequestNewState' + description 'New state to apply to a merge request.' + + value 'OPEN', + value: 'reopen', + description: 'Open the merge request if it is closed.' + + value 'CLOSED', + value: 'close', + description: 'Close the merge request if it is open.' + end +end diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb index ee7d5780f7a..10f324e901a 100644 --- a/app/graphql/types/merge_request_type.rb +++ b/app/graphql/types/merge_request_type.rb @@ -16,169 +16,169 @@ module Types present_using MergeRequestPresenter field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the merge request' + description: 'ID of the merge request.' field :iid, GraphQL::STRING_TYPE, null: false, - description: 'Internal ID of the merge request' + description: 'Internal ID of the merge request.' field :title, GraphQL::STRING_TYPE, null: false, - description: 'Title of the merge request' + description: 'Title of the merge request.' markdown_field :title_html, null: true field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description of the merge request (Markdown rendered as HTML for caching)' + description: 'Description of the merge request (Markdown rendered as HTML for caching).' markdown_field :description_html, null: true field :state, MergeRequestStateEnum, null: false, - description: 'State of the merge request' + description: 'State of the merge request.' field :created_at, Types::TimeType, null: false, - description: 'Timestamp of when the merge request was created' + description: 'Timestamp of when the merge request was created.' field :updated_at, Types::TimeType, null: false, - description: 'Timestamp of when the merge request was last updated' + description: 'Timestamp of when the merge request was last updated.' field :merged_at, Types::TimeType, null: true, complexity: 5, - description: 'Timestamp of when the merge request was merged, null if not merged' + description: 'Timestamp of when the merge request was merged, null if not merged.' field :source_project, Types::ProjectType, null: true, - description: 'Source project of the merge request' + description: 'Source project of the merge request.' field :target_project, Types::ProjectType, null: false, - description: 'Target project of the merge request' + description: 'Target project of the merge request.' field :diff_refs, Types::DiffRefsType, null: true, - description: 'References of the base SHA, the head SHA, and the start SHA for this merge request' + description: 'References of the base SHA, the head SHA, and the start SHA for this merge request.' field :project, Types::ProjectType, null: false, - description: 'Alias for target_project' + description: 'Alias for target_project.' field :project_id, GraphQL::INT_TYPE, null: false, method: :target_project_id, - description: 'ID of the merge request project' + description: 'ID of the merge request project.' field :source_project_id, GraphQL::INT_TYPE, null: true, - description: 'ID of the merge request source project' + description: 'ID of the merge request source project.' field :target_project_id, GraphQL::INT_TYPE, null: false, - description: 'ID of the merge request target project' + description: 'ID of the merge request target project.' field :source_branch, GraphQL::STRING_TYPE, null: false, - description: 'Source branch of the merge request' + description: 'Source branch of the merge request.' field :source_branch_protected, GraphQL::BOOLEAN_TYPE, null: false, calls_gitaly: true, - description: 'Indicates if the source branch is protected' + description: 'Indicates if the source branch is protected.' field :target_branch, GraphQL::STRING_TYPE, null: false, - description: 'Target branch of the merge request' + 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 work in progress (WIP).' 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)' + 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, - description: 'Diff head SHA of the merge request' + description: 'Diff head SHA of the merge request.' field :diff_stats, [Types::DiffStatsType], null: true, calls_gitaly: true, - description: 'Details about which files were changed in this merge request' do - argument :path, GraphQL::STRING_TYPE, required: false, description: 'A specific file-path' + description: 'Details about which files were changed in this merge request.' do + argument :path, GraphQL::STRING_TYPE, required: false, description: 'A specific file-path.' end field :diff_stats_summary, Types::DiffStatsSummaryType, null: true, calls_gitaly: true, - description: 'Summary of which files were changed in this merge request' + description: 'Summary of which files were changed in this merge request.' field :merge_commit_sha, GraphQL::STRING_TYPE, null: true, - description: 'SHA of the merge request commit (set once merged)' + description: 'SHA of the merge request commit (set once merged).' field :user_notes_count, GraphQL::INT_TYPE, null: true, - description: 'User notes count of the merge request', + description: 'User notes count of the merge request.', resolver: Resolvers::UserNotesCountResolver field :user_discussions_count, GraphQL::INT_TYPE, null: true, - description: 'Number of user discussions in the merge request', + description: 'Number of user discussions in the merge request.', resolver: Resolvers::UserDiscussionsCountResolver field :should_remove_source_branch, GraphQL::BOOLEAN_TYPE, method: :should_remove_source_branch?, null: true, - description: 'Indicates if the source branch of the merge request will be deleted after merge' + description: 'Indicates if the source branch of the merge request will be deleted after merge.' field :force_remove_source_branch, GraphQL::BOOLEAN_TYPE, method: :force_remove_source_branch?, null: true, - description: 'Indicates if the project settings will lead to source branch deletion after merge' + description: 'Indicates if the project settings will lead to source branch deletion after merge.' field :merge_status, GraphQL::STRING_TYPE, method: :public_merge_status, null: true, - description: 'Status of the merge request' + description: 'Status of the merge request.' field :in_progress_merge_commit_sha, GraphQL::STRING_TYPE, null: true, - description: 'Commit SHA of the merge request if merge is in progress' + description: 'Commit SHA of the merge request if merge is in progress.' field :merge_error, GraphQL::STRING_TYPE, null: true, - description: 'Error message due to a merge error' + description: 'Error message due to a merge error.' field :allow_collaboration, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if members of the target project can push to the fork' + description: 'Indicates if members of the target project can push to the fork.' field :should_be_rebased, GraphQL::BOOLEAN_TYPE, method: :should_be_rebased?, null: false, calls_gitaly: true, - description: 'Indicates if the merge request will be rebased' + description: 'Indicates if the merge request will be rebased.' field :rebase_commit_sha, GraphQL::STRING_TYPE, null: true, - description: 'Rebase commit SHA of the merge request' + description: 'Rebase commit SHA of the merge request.' field :rebase_in_progress, GraphQL::BOOLEAN_TYPE, method: :rebase_in_progress?, null: false, calls_gitaly: true, - description: 'Indicates if there is a rebase currently in progress for the merge request' + description: 'Indicates if there is a rebase currently in progress for the merge request.' field :default_merge_commit_message, GraphQL::STRING_TYPE, null: true, - description: 'Default merge commit message of the merge request' + description: 'Default merge commit message of the merge request.' field :default_merge_commit_message_with_description, GraphQL::STRING_TYPE, null: true, - description: 'Default merge commit message of the merge request with description' + description: 'Default merge commit message of the merge request with description.' field :default_squash_commit_message, GraphQL::STRING_TYPE, null: true, calls_gitaly: true, - description: 'Default squash commit message of the merge request' + description: 'Default squash commit message of the merge request.' field :merge_ongoing, GraphQL::BOOLEAN_TYPE, method: :merge_ongoing?, null: false, - description: 'Indicates if a merge is currently occurring' + description: 'Indicates if a merge is currently occurring.' field :source_branch_exists, GraphQL::BOOLEAN_TYPE, null: false, calls_gitaly: true, method: :source_branch_exists?, - description: 'Indicates if the source branch of the merge request exists' + description: 'Indicates if the source branch of the merge request exists.' field :target_branch_exists, GraphQL::BOOLEAN_TYPE, null: false, calls_gitaly: true, method: :target_branch_exists?, - description: 'Indicates if the target branch of the merge request exists' + description: 'Indicates if the target branch of the merge request exists.' 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' + 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, - description: 'Web URL of the merge request' + description: 'Web URL of the merge request.' field :upvotes, GraphQL::INT_TYPE, null: false, - description: 'Number of upvotes for the merge request' + description: 'Number of upvotes for the merge request.' field :downvotes, GraphQL::INT_TYPE, null: false, - description: 'Number of downvotes for the merge request' + description: 'Number of downvotes for the merge request.' field :head_pipeline, Types::Ci::PipelineType, null: true, method: :actual_head_pipeline, - description: 'The pipeline running on the branch HEAD of the merge request' + description: 'The pipeline running on the branch HEAD of the merge request.' field :pipelines, null: true, description: 'Pipelines for the merge request. Note: for performance reasons, no more than the most recent 500 pipelines will be returned.', resolver: Resolvers::MergeRequestPipelinesResolver field :milestone, Types::MilestoneType, null: true, - description: 'The milestone of the merge request' + description: 'The milestone of the merge request.' field :assignees, Types::UserType.connection_type, null: true, complexity: 5, - description: 'Assignees of the merge request' + description: 'Assignees of the merge request.' field :reviewers, Types::UserType.connection_type, null: true, complexity: 5, description: 'Users from whom a review has been requested.' field :author, Types::UserType, null: true, - description: 'User who created this merge request' + description: 'User who created this merge request.' field :participants, Types::UserType.connection_type, null: true, complexity: 15, description: 'Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes.' field :subscribed, GraphQL::BOOLEAN_TYPE, method: :subscribed?, null: false, complexity: 5, - description: 'Indicates if the currently logged in user is subscribed to this merge request' + description: 'Indicates if the currently logged in user is subscribed to this merge request.' field :labels, Types::LabelType.connection_type, null: true, complexity: 5, - description: 'Labels of the merge request' + description: 'Labels of the merge request.' field :discussion_locked, GraphQL::BOOLEAN_TYPE, - description: 'Indicates if comments on the merge request are locked to members only', + description: 'Indicates if comments on the merge request are locked to members only.', null: false field :time_estimate, GraphQL::INT_TYPE, null: false, - description: 'Time estimate of the merge request' + description: 'Time estimate of the merge request.' field :total_time_spent, GraphQL::INT_TYPE, null: false, - description: 'Total time reported as spent on the merge request' + description: 'Total time reported as spent on the merge request.' field :reference, GraphQL::STRING_TYPE, null: false, method: :to_reference, - description: 'Internal reference of the merge request. Returned in shortened format by default' do + description: 'Internal reference of the merge request. Returned in shortened format by default.' do argument :full, GraphQL::BOOLEAN_TYPE, required: false, default_value: false, - description: 'Boolean option specifying whether the reference should be returned in full' + description: 'Boolean option specifying whether the reference should be returned in full.' end field :task_completion_status, Types::TaskCompletionStatus, null: false, description: Types::TaskCompletionStatus.description - field :commit_count, GraphQL::INT_TYPE, null: true, - description: 'Number of commits in the merge request' + field :commit_count, GraphQL::INT_TYPE, null: true, method: :commits_count, + description: 'Number of commits in the merge request.' field :conflicts, GraphQL::BOOLEAN_TYPE, null: false, method: :cannot_be_merged?, - description: 'Indicates if the merge request has conflicts' + description: 'Indicates if the merge request has conflicts.' field :auto_merge_enabled, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates if auto merge is enabled for the merge request' + description: 'Indicates if auto merge is enabled for the merge request.' field :approved_by, Types::UserType.connection_type, null: true, - description: 'Users who approved the merge request' + description: 'Users who approved the merge request.' field :squash_on_merge, GraphQL::BOOLEAN_TYPE, null: false, method: :squash_on_merge?, - description: 'Indicates if squash on merge is enabled' + description: 'Indicates if squash on merge is enabled.' field :squash, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates if squash on merge is enabled' + description: 'Indicates if squash on merge is enabled.' field :available_auto_merge_strategies, [GraphQL::STRING_TYPE], null: true, calls_gitaly: true, - description: 'Array of available auto merge strategies' + description: 'Array of available auto merge strategies.' field :has_ci, GraphQL::BOOLEAN_TYPE, null: false, method: :has_ci?, - description: 'Indicates if the merge request has CI' + description: 'Indicates if the merge request has CI.' field :mergeable, GraphQL::BOOLEAN_TYPE, null: false, method: :mergeable?, calls_gitaly: true, - description: 'Indicates if the merge request is mergeable' + description: 'Indicates if the merge request is mergeable.' field :commits_without_merge_commits, Types::CommitType.connection_type, null: true, - calls_gitaly: true, description: 'Merge request commits excluding merge commits' + calls_gitaly: true, description: 'Merge request commits excluding merge commits.' field :security_auto_fix, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates if the merge request is created by @GitLab-Security-Bot.' field :auto_merge_strategy, GraphQL::STRING_TYPE, null: true, - description: 'Selected auto merge strategy' + description: 'Selected auto merge strategy.' field :merge_user, Types::UserType, null: true, - description: 'User who merged this merge request' + description: 'User who merged this merge request.' def approved_by object.approved_by_users @@ -218,10 +218,6 @@ module Types BatchLoaders::MergeRequestDiffSummaryBatchLoader.load_for(object) end - def commit_count - object&.metrics&.commits_count - end - def source_branch_protected object.source_project.present? && ProtectedBranch.protected?(object.source_project, object.source_branch) end @@ -247,7 +243,7 @@ module Types end def reviewers - object.reviewers if object.allows_reviewers? + object.reviewers end end end diff --git a/app/graphql/types/metadata_type.rb b/app/graphql/types/metadata_type.rb index 1998b036a53..0c360d4f292 100644 --- a/app/graphql/types/metadata_type.rb +++ b/app/graphql/types/metadata_type.rb @@ -7,8 +7,8 @@ module Types authorize :read_instance_metadata field :version, GraphQL::STRING_TYPE, null: false, - description: 'Version' + description: 'Version.' field :revision, GraphQL::STRING_TYPE, null: false, - description: 'Revision' + description: 'Revision.' end end diff --git a/app/graphql/types/metrics/dashboard_type.rb b/app/graphql/types/metrics/dashboard_type.rb index 47502356773..40d2c2f195c 100644 --- a/app/graphql/types/metrics/dashboard_type.rb +++ b/app/graphql/types/metrics/dashboard_type.rb @@ -8,13 +8,13 @@ module Types graphql_name 'MetricsDashboard' field :path, GraphQL::STRING_TYPE, null: true, - description: 'Path to a file with the dashboard definition' + description: 'Path to a file with the dashboard definition.' field :schema_validation_warnings, [GraphQL::STRING_TYPE], null: true, - description: 'Dashboard schema validation warnings' + description: 'Dashboard schema validation warnings.' field :annotations, Types::Metrics::Dashboards::AnnotationType.connection_type, null: true, - description: 'Annotations added to the dashboard', + description: 'Annotations added to the dashboard.', resolver: Resolvers::Metrics::Dashboards::AnnotationResolver # In order to maintain backward compatibility we need to return NULL when there are no warnings diff --git a/app/graphql/types/metrics/dashboards/annotation_type.rb b/app/graphql/types/metrics/dashboards/annotation_type.rb index 0f8f95c187b..b9e040dd063 100644 --- a/app/graphql/types/metrics/dashboards/annotation_type.rb +++ b/app/graphql/types/metrics/dashboards/annotation_type.rb @@ -8,19 +8,19 @@ module Types graphql_name 'MetricsDashboardAnnotation' field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description of the annotation' + description: 'Description of the annotation.' field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the annotation' + description: 'ID of the annotation.' field :panel_id, GraphQL::STRING_TYPE, null: true, - description: 'ID of a dashboard panel to which the annotation should be scoped' + description: 'ID of a dashboard panel to which the annotation should be scoped.' field :starting_at, Types::TimeType, null: true, - description: 'Timestamp marking start of annotated time span' + description: 'Timestamp marking start of annotated time span.' field :ending_at, Types::TimeType, null: true, - description: 'Timestamp marking end of annotated time span' + description: 'Timestamp marking end of annotated time span.' def panel_id object.panel_xid diff --git a/app/graphql/types/milestone_state_enum.rb b/app/graphql/types/milestone_state_enum.rb index 032571ac88f..e3b60395c9b 100644 --- a/app/graphql/types/milestone_state_enum.rb +++ b/app/graphql/types/milestone_state_enum.rb @@ -2,7 +2,10 @@ module Types class MilestoneStateEnum < BaseEnum - value 'active' - value 'closed' + graphql_name 'MilestoneStateEnum' + description 'Current state of milestone' + + value 'active', description: 'Milestone is currently active' + value 'closed', description: 'Milestone is closed' end end diff --git a/app/graphql/types/milestone_stats_type.rb b/app/graphql/types/milestone_stats_type.rb index ef533af59e7..e313b880e0d 100644 --- a/app/graphql/types/milestone_stats_type.rb +++ b/app/graphql/types/milestone_stats_type.rb @@ -8,9 +8,9 @@ module Types authorize :read_milestone field :total_issues_count, GraphQL::INT_TYPE, null: true, - description: 'Total number of issues associated with the milestone' + description: 'Total number of issues associated with the milestone.' field :closed_issues_count, GraphQL::INT_TYPE, null: true, - description: 'Number of closed issues associated with the milestone' + description: 'Number of closed issues associated with the milestone.' end end diff --git a/app/graphql/types/milestone_type.rb b/app/graphql/types/milestone_type.rb index 8603043804e..c3816116e2b 100644 --- a/app/graphql/types/milestone_type.rb +++ b/app/graphql/types/milestone_type.rb @@ -12,46 +12,46 @@ module Types alias_method :milestone, :object field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the milestone' + description: 'ID of the milestone.' field :title, GraphQL::STRING_TYPE, null: false, - description: 'Title of the milestone' + description: 'Title of the milestone.' field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description of the milestone' + description: 'Description of the milestone.' field :state, Types::MilestoneStateEnum, null: false, - description: 'State of the milestone' + description: 'State of the milestone.' field :web_path, GraphQL::STRING_TYPE, null: false, method: :milestone_path, - description: 'Web path of the milestone' + description: 'Web path of the milestone.' field :due_date, Types::TimeType, null: true, - description: 'Timestamp of the milestone due date' + description: 'Timestamp of the milestone due date.' field :start_date, Types::TimeType, null: true, - description: 'Timestamp of the milestone start date' + description: 'Timestamp of the milestone start date.' field :created_at, Types::TimeType, null: false, - description: 'Timestamp of milestone creation' + description: 'Timestamp of milestone creation.' field :updated_at, Types::TimeType, null: false, - description: 'Timestamp of last milestone update' + description: 'Timestamp of last milestone update.' field :project_milestone, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates if milestone is at project level', + description: 'Indicates if milestone is at project level.', method: :project_milestone? field :group_milestone, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates if milestone is at group level', + description: 'Indicates if milestone is at group level.', method: :group_milestone? field :subgroup_milestone, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates if milestone is at subgroup level', + description: 'Indicates if milestone is at subgroup level.', method: :subgroup_milestone? field :stats, Types::MilestoneStatsType, null: true, - description: 'Milestone statistics' + description: 'Milestone statistics.' def stats return unless Feature.enabled?(:graphql_milestone_stats, milestone.project || milestone.group, default_enabled: true) diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index f9dd11cbe37..166f5617da2 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -15,6 +15,7 @@ module Types mount_mutation Mutations::AlertManagement::HttpIntegration::Update mount_mutation Mutations::AlertManagement::HttpIntegration::ResetToken mount_mutation Mutations::AlertManagement::HttpIntegration::Destroy + mount_mutation Mutations::Security::CiConfiguration::ConfigureSast mount_mutation Mutations::AlertManagement::PrometheusIntegration::Create mount_mutation Mutations::AlertManagement::PrometheusIntegration::Update mount_mutation Mutations::AlertManagement::PrometheusIntegration::ResetToken @@ -50,6 +51,7 @@ module Types mount_mutation Mutations::MergeRequests::SetSubscription mount_mutation Mutations::MergeRequests::SetWip, calls_gitaly: true mount_mutation Mutations::MergeRequests::SetAssignees + mount_mutation Mutations::MergeRequests::ReviewerRereview mount_mutation Mutations::Metrics::Dashboard::Annotations::Create mount_mutation Mutations::Metrics::Dashboard::Annotations::Delete mount_mutation Mutations::Notes::Create::Note, calls_gitaly: true @@ -97,5 +99,4 @@ module Types end ::Types::MutationType.prepend(::Types::DeprecatedMutations) -::Types::MutationType.prepend_if_ee('EE::Types::DeprecatedMutations') ::Types::MutationType.prepend_if_ee('::EE::Types::MutationType') diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb index ab614d92b06..da983399a11 100644 --- a/app/graphql/types/namespace_type.rb +++ b/app/graphql/types/namespace_type.rb @@ -7,40 +7,40 @@ module Types authorize :read_namespace field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the namespace' + description: 'ID of the namespace.' field :name, GraphQL::STRING_TYPE, null: false, - description: 'Name of the namespace' + description: 'Name of the namespace.' field :path, GraphQL::STRING_TYPE, null: false, - description: 'Path of the namespace' + description: 'Path of the namespace.' field :full_name, GraphQL::STRING_TYPE, null: false, - description: 'Full name of the namespace' + description: 'Full name of the namespace.' field :full_path, GraphQL::ID_TYPE, null: false, - description: 'Full path of the namespace' + description: 'Full path of the namespace.' field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description of the namespace' + description: 'Description of the namespace.' markdown_field :description_html, null: true field :visibility, GraphQL::STRING_TYPE, null: true, - description: 'Visibility of the namespace' + description: 'Visibility of the namespace.' field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true, method: :lfs_enabled?, - description: 'Indicates if Large File Storage (LFS) is enabled for namespace' + description: 'Indicates if Large File Storage (LFS) is enabled for namespace.' field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if users can request access to namespace' + description: 'Indicates if users can request access to namespace.' field :root_storage_statistics, Types::RootStorageStatisticsType, null: true, - description: 'Aggregated storage statistics of the namespace. Only available for root namespaces' + description: 'Aggregated storage statistics of the namespace. Only available for root namespaces.' field :projects, Types::ProjectType.connection_type, null: false, - description: 'Projects within this namespace', + description: 'Projects within this namespace.', resolver: ::Resolvers::NamespaceProjectsResolver field :package_settings, Types::Namespace::PackageSettingsType, null: true, - description: 'The package settings for the namespace' + description: 'The package settings for the namespace.' def root_storage_statistics Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(object.id).find diff --git a/app/graphql/types/notes/diff_position_type.rb b/app/graphql/types/notes/diff_position_type.rb index 13d9be49484..67747a13dcf 100644 --- a/app/graphql/types/notes/diff_position_type.rb +++ b/app/graphql/types/notes/diff_position_type.rb @@ -8,32 +8,32 @@ module Types graphql_name 'DiffPosition' field :diff_refs, Types::DiffRefsType, null: false, - description: 'Information about the branch, HEAD, and base at the time of commenting' + description: 'Information about the branch, HEAD, and base at the time of commenting.' field :file_path, GraphQL::STRING_TYPE, null: false, - description: 'Path of the file that was changed' + description: 'Path of the file that was changed.' field :old_path, GraphQL::STRING_TYPE, null: true, - description: 'Path of the file on the start SHA' + description: 'Path of the file on the start SHA.' field :new_path, GraphQL::STRING_TYPE, null: true, - description: 'Path of the file on the HEAD SHA' + description: 'Path of the file on the HEAD SHA.' field :position_type, Types::Notes::PositionTypeEnum, null: false, - description: 'Type of file the position refers to' + description: 'Type of file the position refers to.' # Fields for text positions field :old_line, GraphQL::INT_TYPE, null: true, - description: 'Line on start SHA that was changed' + description: 'Line on start SHA that was changed.' field :new_line, GraphQL::INT_TYPE, null: true, - description: 'Line on HEAD SHA that was changed' + description: 'Line on HEAD SHA that was changed.' # Fields for image positions field :x, GraphQL::INT_TYPE, null: true, - description: 'X position of the note' + description: 'X position of the note.' field :y, GraphQL::INT_TYPE, null: true, - description: 'Y position of the note' + description: 'Y position of the note.' field :width, GraphQL::INT_TYPE, null: true, - description: 'Total width of the image' + description: 'Total width of the image.' field :height, GraphQL::INT_TYPE, null: true, - description: 'Total height of the image' + description: 'Total height of the image.' def old_line object.old_line if object.on_text? diff --git a/app/graphql/types/notes/discussion_type.rb b/app/graphql/types/notes/discussion_type.rb index a51d253097d..17cb4debd63 100644 --- a/app/graphql/types/notes/discussion_type.rb +++ b/app/graphql/types/notes/discussion_type.rb @@ -3,24 +3,26 @@ module Types module Notes class DiscussionType < BaseObject + DiscussionID = ::Types::GlobalIDType[::Discussion] + graphql_name 'Discussion' authorize :read_note implements(Types::ResolvableInterface) - field :id, GraphQL::ID_TYPE, null: false, - description: "ID of this discussion" - field :reply_id, GraphQL::ID_TYPE, null: false, - description: 'ID used to reply to this discussion' + field :id, DiscussionID, null: false, + description: "ID of this discussion." + field :reply_id, DiscussionID, null: false, + description: 'ID used to reply to this discussion.' field :created_at, Types::TimeType, null: false, - description: "Timestamp of the discussion's creation" + description: "Timestamp of the discussion's creation." field :notes, Types::Notes::NoteType.connection_type, null: false, - description: 'All notes in the discussion' + description: 'All notes in the discussion.' - # The gem we use to generate Global IDs is hard-coded to work with - # `id` properties. To generate a GID for the `reply_id` property, - # we must use the ::Gitlab::GlobalId module. + # DiscussionID.coerce_result is suitable here, but will always mark this + # as being a 'Discussion'. Using `GlobalId.build` guarantees that we get + # the correct class, and that it matches `id`. def reply_id ::Gitlab::GlobalId.build(object, id: object.reply_id) end diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb index 84b61340e93..751cf7c10f1 100644 --- a/app/graphql/types/notes/note_type.rb +++ b/app/graphql/types/notes/note_type.rb @@ -11,44 +11,44 @@ module Types implements(Types::ResolvableInterface) - field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the note' + field :id, ::Types::GlobalIDType[::Note], null: false, + description: 'ID of the note.' field :project, Types::ProjectType, null: true, - description: 'Project associated with the note' + description: 'Project associated with the note.' field :author, Types::UserType, null: false, - description: 'User who wrote this note' + description: 'User who wrote this note.' field :system, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates whether this note was created by the system or by a user' + description: 'Indicates whether this note was created by the system or by a user.' field :system_note_icon_name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the icon corresponding to a system note' + description: 'Name of the icon corresponding to a system note.' field :body, GraphQL::STRING_TYPE, null: false, method: :note, - description: 'Content of the note' + description: 'Content of the note.' markdown_field :body_html, null: true, method: :note field :created_at, Types::TimeType, null: false, - description: 'Timestamp of the note creation' + description: 'Timestamp of the note creation.' field :updated_at, Types::TimeType, null: false, - description: "Timestamp of the note's last activity" + description: "Timestamp of the note's last activity." field :discussion, Types::Notes::DiscussionType, null: true, - description: 'The discussion this note is a part of' + description: 'The discussion this note is a part of.' field :position, Types::Notes::DiffPositionType, null: true, - description: 'The position of this note on a diff' + description: 'The position of this note on a diff.' field :confidential, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if this note is confidential', + description: 'Indicates if this note is confidential.', method: :confidential? field :url, GraphQL::STRING_TYPE, null: true, - description: 'URL to view this Note in the Web UI' + description: 'URL to view this Note in the Web UI.' def url ::Gitlab::UrlBuilder.build(object) diff --git a/app/graphql/types/notes/noteable_type.rb b/app/graphql/types/notes/noteable_type.rb index 602634d9292..f8626d249a1 100644 --- a/app/graphql/types/notes/noteable_type.rb +++ b/app/graphql/types/notes/noteable_type.rb @@ -5,8 +5,8 @@ module Types module NoteableType include Types::BaseInterface - field :notes, Types::Notes::NoteType.connection_type, null: false, description: "All notes on this noteable" - field :discussions, Types::Notes::DiscussionType.connection_type, null: false, description: "All discussions on this noteable" + field :notes, Types::Notes::NoteType.connection_type, null: false, description: "All notes on this noteable." + field :discussions, Types::Notes::DiscussionType.connection_type, null: false, description: "All discussions on this noteable." def self.resolve_type(object, context) case object diff --git a/app/graphql/types/packages/composer/details_type.rb b/app/graphql/types/packages/composer/details_type.rb deleted file mode 100644 index 8c6845a6fb3..00000000000 --- a/app/graphql/types/packages/composer/details_type.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Types - module Packages - module Composer - class DetailsType < Types::Packages::PackageType - graphql_name 'PackageComposerDetails' - description 'Details of a Composer package' - - authorize :read_package - - field :composer_metadatum, Types::Packages::Composer::MetadatumType, null: false, description: 'The Composer metadatum.' - end - end - end -end diff --git a/app/graphql/types/packages/composer/metadatum_type.rb b/app/graphql/types/packages/composer/metadatum_type.rb index a97818b1fb8..9d4ce3cebd4 100644 --- a/app/graphql/types/packages/composer/metadatum_type.rb +++ b/app/graphql/types/packages/composer/metadatum_type.rb @@ -4,8 +4,8 @@ module Types module Packages module Composer class MetadatumType < BaseObject - graphql_name 'PackageComposerMetadatumType' - description 'Composer metadatum' + graphql_name 'ComposerMetadata' + description 'Composer metadata' authorize :read_package diff --git a/app/graphql/types/packages/metadata_type.rb b/app/graphql/types/packages/metadata_type.rb new file mode 100644 index 00000000000..26c43b51a69 --- /dev/null +++ b/app/graphql/types/packages/metadata_type.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Types + module Packages + class MetadataType < BaseUnion + graphql_name 'PackageMetadata' + description 'Represents metadata associated with a Package' + + possible_types ::Types::Packages::Composer::MetadatumType + + def self.resolve_type(object, context) + case object + when ::Packages::Composer::Metadatum + ::Types::Packages::Composer::MetadatumType + else + # NOTE: This method must be kept in sync with `PackageWithoutVersionsType#metadata`, + # which must never produce data that this discriminator cannot handle. + raise 'Unsupported metadata type' + end + end + end + end +end diff --git a/app/graphql/types/packages/package_type.rb b/app/graphql/types/packages/package_type.rb index b13d16e91c6..331898a1e84 100644 --- a/app/graphql/types/packages/package_type.rb +++ b/app/graphql/types/packages/package_type.rb @@ -2,26 +2,13 @@ module Types module Packages - class PackageType < BaseObject + class PackageType < PackageWithoutVersionsType graphql_name 'Package' description 'Represents a package in the Package Registry' - authorize :read_package - field :id, GraphQL::ID_TYPE, null: false, description: 'The ID of the package.' - field :name, GraphQL::STRING_TYPE, null: false, description: 'The name of the package.' - field :created_at, Types::TimeType, null: false, description: 'The created date.' - field :updated_at, Types::TimeType, null: false, description: 'The updated date.' - field :version, GraphQL::STRING_TYPE, null: true, description: 'The version of the package.' - field :package_type, Types::Packages::PackageTypeEnum, null: false, description: 'The type of the package.' - field :tags, Types::Packages::PackageTagType.connection_type, null: true, description: 'The package tags.' - field :project, Types::ProjectType, null: false, description: 'Project where the package is stored.' - field :pipelines, Types::Ci::PipelineType.connection_type, null: true, description: 'Pipelines that built the package.' - field :versions, Types::Packages::PackageType.connection_type, null: true, description: 'The other versions of the package.' - - def project - Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find - end + field :versions, ::Types::Packages::PackageWithoutVersionsType.connection_type, null: true, + description: 'The other versions of the package.' end end end diff --git a/app/graphql/types/packages/package_type_enum.rb b/app/graphql/types/packages/package_type_enum.rb index 9713c9d49b1..e2b5cf3163e 100644 --- a/app/graphql/types/packages/package_type_enum.rb +++ b/app/graphql/types/packages/package_type_enum.rb @@ -5,7 +5,7 @@ module Types class PackageTypeEnum < BaseEnum PACKAGE_TYPE_NAMES = { pypi: 'PyPI', - npm: 'NPM' + npm: 'npm' }.freeze ::Packages::Package.package_types.keys.each do |package_type| diff --git a/app/graphql/types/packages/package_without_versions_type.rb b/app/graphql/types/packages/package_without_versions_type.rb new file mode 100644 index 00000000000..9c6bb37e6cc --- /dev/null +++ b/app/graphql/types/packages/package_without_versions_type.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Types + module Packages + class PackageWithoutVersionsType < ::Types::BaseObject + graphql_name 'PackageWithoutVersions' + description 'Represents a version of a package in the Package Registry' + + authorize :read_package + + field :id, ::Types::GlobalIDType[::Packages::Package], null: false, + description: 'ID of the package.' + + field :name, GraphQL::STRING_TYPE, null: false, description: 'Name of the package.' + field :created_at, Types::TimeType, null: false, description: 'Date of creation.' + field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.' + field :version, GraphQL::STRING_TYPE, null: true, description: 'Version string.' + field :package_type, Types::Packages::PackageTypeEnum, null: false, description: 'Package type.' + field :tags, Types::Packages::PackageTagType.connection_type, null: true, description: 'Package tags.' + field :project, Types::ProjectType, null: false, description: 'Project where the package is stored.' + field :pipelines, Types::Ci::PipelineType.connection_type, null: true, + description: 'Pipelines that built the package.' + field :metadata, Types::Packages::MetadataType, null: true, + description: 'Package metadata.' + + def project + Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find + end + + # NOTE: This method must be kept in sync with the union + # type: `Types::Packages::MetadataType`. + # + # `Types::Packages::MetadataType.resolve_type(metadata, ctx)` must never raise. + def metadata + case object.package_type + when 'composer' + object.composer_metadatum + else + nil + end + end + end + end +end diff --git a/app/graphql/types/project_invitation_type.rb b/app/graphql/types/project_invitation_type.rb index a5367a4f204..507dc2d59c3 100644 --- a/app/graphql/types/project_invitation_type.rb +++ b/app/graphql/types/project_invitation_type.rb @@ -12,7 +12,7 @@ module Types authorize :read_project field :project, Types::ProjectType, null: true, - description: 'Project ID for the project of the invitation' + description: 'Project ID for the project of the invitation.' def project Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.source_id).find diff --git a/app/graphql/types/project_member_type.rb b/app/graphql/types/project_member_type.rb index 01731531ae2..1f00df84641 100644 --- a/app/graphql/types/project_member_type.rb +++ b/app/graphql/types/project_member_type.rb @@ -12,7 +12,7 @@ module Types authorize :read_project field :project, Types::ProjectType, null: true, - description: 'Project that User is a member of' + description: 'Project that User is a member of.' def project Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.source_id).find diff --git a/app/graphql/types/project_statistics_type.rb b/app/graphql/types/project_statistics_type.rb index 26cb5ab59b5..ee8476f50de 100644 --- a/app/graphql/types/project_statistics_type.rb +++ b/app/graphql/types/project_statistics_type.rb @@ -7,23 +7,23 @@ module Types authorize :read_statistics field :commit_count, GraphQL::FLOAT_TYPE, null: false, - description: 'Commit count of the project' + description: 'Commit count of the project.' field :storage_size, GraphQL::FLOAT_TYPE, null: false, - description: 'Storage size of the project in bytes' + description: 'Storage size of the project in bytes.' field :repository_size, GraphQL::FLOAT_TYPE, null: false, - description: 'Repository size of the project in bytes' + description: 'Repository size of the project in bytes.' field :lfs_objects_size, GraphQL::FLOAT_TYPE, null: false, - description: 'Large File Storage (LFS) object size of the project in bytes' + description: 'Large File Storage (LFS) object size of the project in bytes.' field :build_artifacts_size, GraphQL::FLOAT_TYPE, null: false, - description: 'Build artifacts size of the project in bytes' + description: 'Build artifacts size of the project in bytes.' field :packages_size, GraphQL::FLOAT_TYPE, null: false, - description: 'Packages size of the project in bytes' + description: 'Packages size of the project in bytes.' field :wiki_size, GraphQL::FLOAT_TYPE, null: true, - description: 'Wiki size of the project in bytes' + description: 'Wiki size of the project in bytes.' field :snippets_size, GraphQL::FLOAT_TYPE, null: true, - description: 'Snippets size of the project in bytes' + description: 'Snippets size of the project in bytes.' field :uploads_size, GraphQL::FLOAT_TYPE, null: true, - description: 'Uploads size of the project in bytes' + description: 'Uploads size of the project in bytes.' end end diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index f66d8926a9f..7205c615271 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -9,54 +9,58 @@ module Types expose_permissions Types::PermissionTypes::Project field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the project' + description: 'ID of the project.' field :full_path, GraphQL::ID_TYPE, null: false, - description: 'Full path of the project' + description: 'Full path of the project.' field :path, GraphQL::STRING_TYPE, null: false, - description: 'Path of the project' + description: 'Path of the project.' + + field :sast_ci_configuration, Types::CiConfiguration::Sast::Type, null: true, + calls_gitaly: true, + description: 'SAST CI configuration for the project.' field :name_with_namespace, GraphQL::STRING_TYPE, null: false, - description: 'Full name of the project with its namespace' + description: 'Full name of the project with its namespace.' field :name, GraphQL::STRING_TYPE, null: false, - description: 'Name of the project (without namespace)' + description: 'Name of the project (without namespace).' field :description, GraphQL::STRING_TYPE, null: true, - description: 'Short description of the project' + description: 'Short description of the project.' markdown_field :description_html, null: true field :tag_list, GraphQL::STRING_TYPE, null: true, - description: 'List of project topics (not Git tags)' + description: 'List of project topics (not Git tags).' field :ssh_url_to_repo, GraphQL::STRING_TYPE, null: true, - description: 'URL to connect to the project via SSH' + description: 'URL to connect to the project via SSH.' field :http_url_to_repo, GraphQL::STRING_TYPE, null: true, - description: 'URL to connect to the project via HTTPS' + description: 'URL to connect to the project via HTTPS.' field :web_url, GraphQL::STRING_TYPE, null: true, - description: 'Web URL of the project' + description: 'Web URL of the project.' field :star_count, GraphQL::INT_TYPE, null: false, - description: 'Number of times the project has been starred' + description: 'Number of times the project has been starred.' field :forks_count, GraphQL::INT_TYPE, null: false, calls_gitaly: true, # 4 times - description: 'Number of times the project has been forked' + description: 'Number of times the project has been forked.' field :created_at, Types::TimeType, null: true, - description: 'Timestamp of the project creation' + description: 'Timestamp of the project creation.' field :last_activity_at, Types::TimeType, null: true, - description: 'Timestamp of the project last activity' + description: 'Timestamp of the project last activity.' field :archived, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates the archived status of the project' + description: 'Indicates the archived status of the project.' field :visibility, GraphQL::STRING_TYPE, null: true, - description: 'Visibility of the project' + description: 'Visibility of the project.' field :container_registry_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if the project stores Docker container images in a container registry' + description: 'Indicates if the project stores Docker container images in a container registry.' field :shared_runners_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if shared runners are enabled for the project' + description: 'Indicates if shared runners are enabled for the project.' field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if the project has Large File Storage (LFS) enabled' + description: 'Indicates if the project has Large File Storage (LFS) enabled.' field :merge_requests_ff_only_enabled, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates if no merge commits should be created and all merges should instead be fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded.' @@ -67,7 +71,7 @@ module Types description: 'E-mail address of the service desk.' field :avatar_url, GraphQL::STRING_TYPE, null: true, calls_gitaly: true, - description: 'URL to avatar image file of the project' + description: 'URL to avatar image file of the project.' %i[issues merge_requests wiki snippets].each do |feature| field "#{feature}_enabled", GraphQL::BOOLEAN_TYPE, null: true, @@ -79,240 +83,246 @@ module Types end field :jobs_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if CI/CD pipeline jobs are enabled for the current user' + description: 'Indicates if CI/CD pipeline jobs are enabled for the current user.' field :public_jobs, GraphQL::BOOLEAN_TYPE, method: :public_builds, null: true, - description: 'Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts' + description: 'Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts.' field :open_issues_count, GraphQL::INT_TYPE, null: true, - description: 'Number of open issues for the project' + description: 'Number of open issues for the project.' field :import_status, GraphQL::STRING_TYPE, null: true, - description: 'Status of import background job of the project' + description: 'Status of import background job of the project.' field :jira_import_status, GraphQL::STRING_TYPE, null: true, - description: 'Status of Jira import background job of the project' + description: 'Status of Jira import background job of the project.' field :only_allow_merge_if_pipeline_succeeds, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if merge requests of the project can only be merged with successful jobs' + description: 'Indicates if merge requests of the project can only be merged with successful jobs.' field :allow_merge_on_skipped_pipeline, GraphQL::BOOLEAN_TYPE, null: true, - description: 'If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of the project can also be merged with skipped jobs' + description: 'If `only_allow_merge_if_pipeline_succeeds` is true, indicates if merge requests of the project can also be merged with skipped jobs.' field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if users can request member access to the project' + description: 'Indicates if users can request member access to the project.' field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if merge requests of the project can only be merged when all the discussions are resolved' + description: 'Indicates if merge requests of the project can only be merged when all the discussions are resolved.' field :printing_merge_request_link_enabled, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line' + description: 'Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line.' field :remove_source_branch_after_merge, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if `Delete source branch` option should be enabled by default for all new merge requests of the project' + description: 'Indicates if `Delete source branch` option should be enabled by default for all new merge requests of the project.' field :autoclose_referenced_issues, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if issues referenced by merge requests and commits within the default branch are closed automatically' + description: 'Indicates if issues referenced by merge requests and commits within the default branch are closed automatically.' field :suggestion_commit_message, GraphQL::STRING_TYPE, null: true, - description: 'The commit message used to apply merge request suggestions' + description: 'The commit message used to apply merge request suggestions.' field :squash_read_only, GraphQL::BOOLEAN_TYPE, null: false, method: :squash_readonly?, - description: 'Indicates if squash readonly is enabled' + description: 'Indicates if `squashReadOnly` is enabled.' field :namespace, Types::NamespaceType, null: true, - description: 'Namespace of the project' + description: 'Namespace of the project.' field :group, Types::GroupType, null: true, - description: 'Group of the project' + description: 'Group of the project.' field :statistics, Types::ProjectStatisticsType, null: true, - description: 'Statistics of the project' + description: 'Statistics of the project.' field :repository, Types::RepositoryType, null: true, - description: 'Git repository of the project' + description: 'Git repository of the project.' field :merge_requests, Types::MergeRequestType.connection_type, null: true, - description: 'Merge requests of the project', + description: 'Merge requests of the project.', extras: [:lookahead], resolver: Resolvers::ProjectMergeRequestsResolver field :merge_request, Types::MergeRequestType, null: true, - description: 'A single merge request of the project', + description: 'A single merge request of the project.', resolver: Resolvers::MergeRequestsResolver.single field :issues, Types::IssueType.connection_type, null: true, - description: 'Issues of the project', + description: 'Issues of the project.', extras: [:lookahead], resolver: Resolvers::IssuesResolver field :issue_status_counts, Types::IssueStatusCountsType, null: true, - description: 'Counts of issues by status for the project', + description: 'Counts of issues by status for the project.', extras: [:lookahead], resolver: Resolvers::IssueStatusCountsResolver field :milestones, Types::MilestoneType.connection_type, null: true, - description: 'Milestones of the project', + description: 'Milestones of the project.', resolver: Resolvers::ProjectMilestonesResolver field :project_members, - description: 'Members of the project', + description: 'Members of the project.', resolver: Resolvers::ProjectMembersResolver field :environments, Types::EnvironmentType.connection_type, null: true, - description: 'Environments of the project', + description: 'Environments of the project.', resolver: Resolvers::EnvironmentsResolver field :environment, Types::EnvironmentType, null: true, - description: 'A single environment of the project', + description: 'A single environment of the project.', resolver: Resolvers::EnvironmentsResolver.single field :issue, Types::IssueType, null: true, - description: 'A single issue of the project', + description: 'A single issue of the project.', resolver: Resolvers::IssuesResolver.single - field :packages, Types::Packages::PackageType.connection_type, null: true, - description: 'Packages of the project', + field :packages, + description: 'Packages of the project.', resolver: Resolvers::PackagesResolver field :pipelines, null: true, - description: 'Build pipelines of the project', + description: 'Build pipelines of the project.', extras: [:lookahead], resolver: Resolvers::ProjectPipelinesResolver field :pipeline, Types::Ci::PipelineType, null: true, - description: 'Build pipeline of the project', + description: 'Build pipeline of the project.', resolver: Resolvers::ProjectPipelineResolver field :ci_cd_settings, Types::Ci::CiCdSettingType, null: true, - description: 'CI/CD settings for the project' + description: 'CI/CD settings for the project.' field :sentry_detailed_error, Types::ErrorTracking::SentryDetailedErrorType, null: true, - description: 'Detailed version of a Sentry error on the project', + description: 'Detailed version of a Sentry error on the project.', resolver: Resolvers::ErrorTracking::SentryDetailedErrorResolver field :grafana_integration, Types::GrafanaIntegrationType, null: true, - description: 'Grafana integration details for the project', + description: 'Grafana integration details for the project.', resolver: Resolvers::Projects::GrafanaIntegrationResolver field :snippets, Types::SnippetType.connection_type, null: true, - description: 'Snippets of the project', + description: 'Snippets of the project.', resolver: Resolvers::Projects::SnippetsResolver field :sentry_errors, Types::ErrorTracking::SentryErrorCollectionType, null: true, - description: 'Paginated collection of Sentry errors on the project', + description: 'Paginated collection of Sentry errors on the project.', resolver: Resolvers::ErrorTracking::SentryErrorCollectionResolver field :boards, Types::BoardType.connection_type, null: true, - description: 'Boards of the project', + description: 'Boards of the project.', max_page_size: 2000, resolver: Resolvers::BoardsResolver field :board, Types::BoardType, null: true, - description: 'A single board of the project', + description: 'A single board of the project.', resolver: Resolvers::BoardResolver field :jira_imports, Types::JiraImportType.connection_type, null: true, - description: 'Jira imports into the project' + description: 'Jira imports into the project.' field :services, Types::Projects::ServiceType.connection_type, null: true, - description: 'Project services', + description: 'Project services.', resolver: Resolvers::Projects::ServicesResolver field :alert_management_alerts, Types::AlertManagement::AlertType.connection_type, null: true, - description: 'Alert Management alerts of the project', + description: 'Alert Management alerts of the project.', extras: [:lookahead], resolver: Resolvers::AlertManagement::AlertResolver field :alert_management_alert, Types::AlertManagement::AlertType, null: true, - description: 'A single Alert Management alert of the project', + description: 'A single Alert Management alert of the project.', resolver: Resolvers::AlertManagement::AlertResolver.single field :alert_management_alert_status_counts, Types::AlertManagement::AlertStatusCountsType, null: true, - description: 'Counts of alerts by status for the project', + description: 'Counts of alerts by status for the project.', resolver: Resolvers::AlertManagement::AlertStatusCountsResolver field :alert_management_integrations, Types::AlertManagement::IntegrationType.connection_type, null: true, - description: 'Integrations which can receive alerts for the project', + description: 'Integrations which can receive alerts for the project.', resolver: Resolvers::AlertManagement::IntegrationsResolver field :releases, Types::ReleaseType.connection_type, null: true, - description: 'Releases of the project', + description: 'Releases of the project.', resolver: Resolvers::ReleasesResolver field :release, Types::ReleaseType, null: true, - description: 'A single release of the project', + description: 'A single release of the project.', resolver: Resolvers::ReleasesResolver.single, authorize: :download_code field :container_expiration_policy, Types::ContainerExpirationPolicyType, null: true, - description: 'The container expiration policy of the project' + description: 'The container expiration policy of the project.' field :container_repositories, Types::ContainerRepositoryType.connection_type, null: true, - description: 'Container repositories of the project', + description: 'Container repositories of the project.', resolver: Resolvers::ContainerRepositoriesResolver field :container_repositories_count, GraphQL::INT_TYPE, null: false, - description: 'Number of container repositories in the project' + description: 'Number of container repositories in the project.' field :label, Types::LabelType, null: true, - description: 'A label available on this project' do + description: 'A label available on this project.' do argument :title, GraphQL::STRING_TYPE, required: true, - description: 'Title of the label' + description: 'Title of the label.' end + field :terraform_state, + Types::Terraform::StateType, + null: true, + description: 'Find a single Terraform state by name.', + resolver: Resolvers::Terraform::StatesResolver.single + field :terraform_states, Types::Terraform::StateType.connection_type, null: true, - description: 'Terraform states associated with the project', + description: 'Terraform states associated with the project.', resolver: Resolvers::Terraform::StatesResolver field :pipeline_analytics, Types::Ci::AnalyticsType, null: true, - description: 'Pipeline analytics', + description: 'Pipeline analytics.', resolver: Resolvers::ProjectPipelineStatisticsResolver def label(title:) @@ -327,17 +337,8 @@ module Types field :labels, Types::LabelType.connection_type, null: true, - description: 'Labels available on this project' do - argument :search_term, GraphQL::STRING_TYPE, - required: false, - description: 'A search term to find labels with' - end - - def labels(search_term: nil) - LabelsFinder - .new(current_user, project: project, search: search_term) - .execute - end + description: 'Labels available on this project.', + resolver: Resolvers::LabelsResolver def avatar_url object.avatar_url(only_path: false) @@ -359,6 +360,12 @@ module Types project.container_repositories.size end + def sast_ci_configuration + return unless Ability.allowed?(current_user, :download_code, object) + + ::Security::CiConfiguration::SastParserService.new(object).configuration + end + private def project diff --git a/app/graphql/types/projects/service_type.rb b/app/graphql/types/projects/service_type.rb index 4ae7cb77904..9ce325c4655 100644 --- a/app/graphql/types/projects/service_type.rb +++ b/app/graphql/types/projects/service_type.rb @@ -9,9 +9,9 @@ module Types # TODO: Add all the fields that we want to expose for the project services integrations # https://gitlab.com/gitlab-org/gitlab/-/issues/213088 field :type, GraphQL::STRING_TYPE, null: true, - description: 'Class name of the service' + description: 'Class name of the service.' field :active, GraphQL::BOOLEAN_TYPE, null: true, - description: 'Indicates if the service is active' + description: 'Indicates if the service is active.' definition_methods do def resolve_type(object, context) diff --git a/app/graphql/types/projects/service_type_enum.rb b/app/graphql/types/projects/service_type_enum.rb index 34e06c67be6..fcb36fc233d 100644 --- a/app/graphql/types/projects/service_type_enum.rb +++ b/app/graphql/types/projects/service_type_enum.rb @@ -6,7 +6,7 @@ module Types graphql_name 'ServiceType' ::Service.available_services_types(include_dev: false).each do |service_type| - value service_type.underscore.upcase, value: service_type + value service_type.underscore.upcase, value: service_type, description: "#{service_type} type" end end end diff --git a/app/graphql/types/projects/services/jira_project_type.rb b/app/graphql/types/projects/services/jira_project_type.rb index ccf9107f398..90abce2b4c3 100644 --- a/app/graphql/types/projects/services/jira_project_type.rb +++ b/app/graphql/types/projects/services/jira_project_type.rb @@ -8,12 +8,12 @@ module Types graphql_name 'JiraProject' field :key, GraphQL::STRING_TYPE, null: false, - description: 'Key of the Jira project' + description: 'Key of the Jira project.' field :project_id, GraphQL::INT_TYPE, null: false, - description: 'ID of the Jira project', + description: 'ID of the Jira project.', method: :id field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the Jira project' + description: 'Name of the Jira project.' end # rubocop:enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/projects/services/jira_service_type.rb b/app/graphql/types/projects/services/jira_service_type.rb index cb0712249e3..425a283c674 100644 --- a/app/graphql/types/projects/services/jira_service_type.rb +++ b/app/graphql/types/projects/services/jira_service_type.rb @@ -13,7 +13,7 @@ module Types field :projects, Types::Projects::Services::JiraProjectType.connection_type, null: true, - description: 'List of all Jira projects fetched through Jira REST API', + description: 'List of all Jira projects fetched through Jira REST API.', resolver: Resolvers::Projects::JiraProjectsResolver end end diff --git a/app/graphql/types/prometheus_alert_type.rb b/app/graphql/types/prometheus_alert_type.rb index 1d09a8dbeb7..8e800536675 100644 --- a/app/graphql/types/prometheus_alert_type.rb +++ b/app/graphql/types/prometheus_alert_type.rb @@ -10,11 +10,11 @@ module Types present_using PrometheusAlertPresenter field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the alert condition' + description: 'ID of the alert condition.' field :humanized_text, GraphQL::STRING_TYPE, null: false, - description: 'The human-readable text of the alert condition' + description: 'The human-readable text of the alert condition.' end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 0e0c060f374..1d1ab4f2e17 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -10,90 +10,93 @@ module Types field :project, Types::ProjectType, null: true, resolver: Resolvers::ProjectResolver, - description: "Find a project" + description: "Find a project." field :projects, Types::ProjectType.connection_type, null: true, resolver: Resolvers::ProjectsResolver, - description: "Find projects visible to the current user" + description: "Find projects visible to the current user." field :group, Types::GroupType, null: true, resolver: Resolvers::GroupResolver, - description: "Find a group" + description: "Find a group." field :current_user, Types::UserType, null: true, - description: "Get information about current user" + description: "Get information about current user." field :namespace, Types::NamespaceType, null: true, resolver: Resolvers::NamespaceResolver, - description: "Find a namespace" + description: "Find a namespace." field :metadata, Types::MetadataType, null: true, resolver: Resolvers::MetadataResolver, - description: 'Metadata about GitLab' + description: 'Metadata about GitLab.' field :snippets, Types::SnippetType.connection_type, null: true, resolver: Resolvers::SnippetsResolver, - description: 'Find Snippets visible to the current user' + description: 'Find Snippets visible to the current user.' field :design_management, Types::DesignManagementType, null: false, - description: 'Fields related to design management' + description: 'Fields related to design management.' field :milestone, ::Types::MilestoneType, null: true, - description: 'Find a milestone' do - argument :id, ::Types::GlobalIDType[Milestone], required: true, description: 'Find a milestone by its ID' + description: 'Find a milestone.' do + argument :id, ::Types::GlobalIDType[Milestone], required: true, description: 'Find a milestone by its ID.' end field :container_repository, Types::ContainerRepositoryDetailsType, null: true, - description: 'Find a container repository' do - argument :id, ::Types::GlobalIDType[::ContainerRepository], required: true, description: 'The global ID of the container repository' + description: 'Find a container repository.' do + argument :id, ::Types::GlobalIDType[::ContainerRepository], required: true, description: 'The global ID of the container repository.' end - field :package_composer_details, Types::Packages::Composer::DetailsType, - null: true, - description: 'Find a composer package', + field :package, + description: 'Find a package.', resolver: Resolvers::PackageDetailsResolver field :user, Types::UserType, null: true, - description: 'Find a user', + description: 'Find a user.', resolver: Resolvers::UserResolver field :users, Types::UserType.connection_type, null: true, - description: 'Find users', + description: 'Find users.', resolver: Resolvers::UsersResolver field :echo, GraphQL::STRING_TYPE, null: false, - description: 'Text to echo back', + description: 'Text to echo back.', resolver: Resolvers::EchoResolver field :issue, Types::IssueType, null: true, - description: 'Find an issue' do - argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'The global ID of the Issue' + 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, null: true, - description: 'Get statistics on the instance', + description: 'Get statistics on the instance.', resolver: Resolvers::Admin::Analytics::InstanceStatistics::MeasurementsResolver + field :ci_application_settings, Types::Ci::ApplicationSettingType, + null: true, + description: 'CI related settings that apply to the entire instance.' + field :runner_platforms, Types::Ci::RunnerPlatformType.connection_type, - null: true, description: 'Supported runner platforms', + null: true, description: 'Supported runner platforms.', resolver: Resolvers::Ci::RunnerPlatformsResolver field :runner_setup, Types::Ci::RunnerSetupType, null: true, - description: 'Get runner setup instructions', + description: 'Get runner setup instructions.', resolver: Resolvers::Ci::RunnerSetupResolver field :ci_config, Types::Ci::Config::ConfigType, null: true, @@ -129,6 +132,14 @@ module Types def current_user context[:current_user] end + + def ci_application_settings + application_settings + end + + def application_settings + Gitlab::CurrentSettings.current_application_settings + end end end diff --git a/app/graphql/types/range_input_type.rb b/app/graphql/types/range_input_type.rb index 766e523a99e..b75c3669fbf 100644 --- a/app/graphql/types/range_input_type.rb +++ b/app/graphql/types/range_input_type.rb @@ -9,11 +9,11 @@ module Types @subtypes[[type, closed]] ||= Class.new(self) do argument :start, type, required: closed, - description: 'The start of the range' + description: 'The start of the range.' argument :end, type, required: closed, - description: 'The end of the range' + description: 'The end of the range.' end end diff --git a/app/graphql/types/release_asset_link_input_type.rb b/app/graphql/types/release_asset_link_input_type.rb index d13861fad8f..242d19b683f 100644 --- a/app/graphql/types/release_asset_link_input_type.rb +++ b/app/graphql/types/release_asset_link_input_type.rb @@ -8,18 +8,18 @@ module Types argument :name, GraphQL::STRING_TYPE, required: true, - description: 'Name of the asset link' + description: 'Name of the asset link.' argument :url, GraphQL::STRING_TYPE, required: true, - description: 'URL of the asset link' + 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' + 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' + description: 'The type of the asset link.' end end diff --git a/app/graphql/types/release_asset_link_type.rb b/app/graphql/types/release_asset_link_type.rb index 8fb051f5627..c27e1cf19b3 100644 --- a/app/graphql/types/release_asset_link_type.rb +++ b/app/graphql/types/release_asset_link_type.rb @@ -8,18 +8,18 @@ module Types authorize :read_release field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the link' + description: 'ID of the link.' field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the link' + description: 'Name of the link.' field :url, GraphQL::STRING_TYPE, null: true, - description: 'URL of the link' + description: 'URL of the link.' field :link_type, Types::ReleaseAssetLinkTypeEnum, null: true, - description: 'Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`' + description: 'Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`.' field :external, GraphQL::BOOLEAN_TYPE, null: true, method: :external?, - description: 'Indicates the link points to an external resource' + description: 'Indicates the link points to an external resource.' field :direct_asset_url, GraphQL::STRING_TYPE, null: true, - description: 'Direct asset URL of the link' + description: 'Direct asset URL of the link.' def direct_asset_url return object.url unless object.filepath diff --git a/app/graphql/types/release_assets_input_type.rb b/app/graphql/types/release_assets_input_type.rb index 3fcb517e044..f50be89d43f 100644 --- a/app/graphql/types/release_assets_input_type.rb +++ b/app/graphql/types/release_assets_input_type.rb @@ -8,6 +8,6 @@ module Types argument :links, [Types::ReleaseAssetLinkInputType], required: false, - description: 'A list of asset links to associate to the release' + description: 'A list of asset links to associate to the release.' end end diff --git a/app/graphql/types/release_assets_type.rb b/app/graphql/types/release_assets_type.rb index d6042bdbc0b..79c132358e0 100644 --- a/app/graphql/types/release_assets_type.rb +++ b/app/graphql/types/release_assets_type.rb @@ -12,10 +12,10 @@ module Types present_using ReleasePresenter field :count, GraphQL::INT_TYPE, null: true, method: :assets_count, - description: 'Number of assets of the release' + description: 'Number of assets of the release.' field :links, Types::ReleaseAssetLinkType.connection_type, null: true, - description: 'Asset links of the release' + description: 'Asset links of the release.' field :sources, Types::ReleaseSourceType.connection_type, null: true, - description: 'Sources of the release' + description: 'Sources of the release.' end end diff --git a/app/graphql/types/release_links_type.rb b/app/graphql/types/release_links_type.rb index 619bb1e6c3a..a51b80e1e13 100644 --- a/app/graphql/types/release_links_type.rb +++ b/app/graphql/types/release_links_type.rb @@ -11,19 +11,19 @@ module Types present_using ReleasePresenter field :self_url, GraphQL::STRING_TYPE, null: true, - description: 'HTTP URL of the release' + description: 'HTTP URL of the release.' field :edit_url, GraphQL::STRING_TYPE, null: true, - description: "HTTP URL of the release's edit page", + description: "HTTP URL of the release's edit page.", authorize: :update_release field :opened_merge_requests_url, GraphQL::STRING_TYPE, null: true, - description: 'HTTP URL of the merge request page, filtered by this release and `state=open`' + description: 'HTTP URL of the merge request page, filtered by this release and `state=open`.' field :merged_merge_requests_url, GraphQL::STRING_TYPE, null: true, - description: 'HTTP URL of the merge request page , filtered by this release and `state=merged`' + description: 'HTTP URL of the merge request page , filtered by this release and `state=merged`.' field :closed_merge_requests_url, GraphQL::STRING_TYPE, null: true, - description: 'HTTP URL of the merge request page , filtered by this release and `state=closed`' + description: 'HTTP URL of the merge request page , filtered by this release and `state=closed`.' field :opened_issues_url, GraphQL::STRING_TYPE, null: true, - description: 'HTTP URL of the issues page, filtered by this release and `state=open`' + description: 'HTTP URL of the issues page, filtered by this release and `state=open`.' field :closed_issues_url, GraphQL::STRING_TYPE, null: true, - description: 'HTTP URL of the issues page, filtered by this release and `state=closed`' + description: 'HTTP URL of the issues page, filtered by this release and `state=closed`.' end end diff --git a/app/graphql/types/release_source_type.rb b/app/graphql/types/release_source_type.rb index 891da472116..10fc202514d 100644 --- a/app/graphql/types/release_source_type.rb +++ b/app/graphql/types/release_source_type.rb @@ -8,8 +8,8 @@ module Types authorize :download_code field :format, GraphQL::STRING_TYPE, null: true, - description: 'Format of the source' + description: 'Format of the source.' field :url, GraphQL::STRING_TYPE, null: true, - description: 'Download URL of the source' + description: 'Download URL of the source.' end end diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb index e7afa7ce7f7..81813a10a3e 100644 --- a/app/graphql/types/release_type.rb +++ b/app/graphql/types/release_type.rb @@ -14,34 +14,34 @@ module Types present_using ReleasePresenter field :tag_name, GraphQL::STRING_TYPE, null: true, method: :tag, - description: 'Name of the tag associated with the release', + description: 'Name of the tag associated with the release.', authorize: :download_code field :tag_path, GraphQL::STRING_TYPE, null: true, - description: 'Relative web path to the tag associated with the release', + description: 'Relative web path to the tag associated with the release.', authorize: :download_code field :description, GraphQL::STRING_TYPE, null: true, - description: 'Description (also known as "release notes") of the release' + description: 'Description (also known as "release notes") of the release.' markdown_field :description_html, null: true field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the release' + description: 'Name of the release.' field :created_at, Types::TimeType, null: true, - description: 'Timestamp of when the release was created' + description: 'Timestamp of when the release was created.' field :released_at, Types::TimeType, null: true, - description: 'Timestamp of when the release was released' + description: 'Timestamp of when the release was released.' field :upcoming_release, GraphQL::BOOLEAN_TYPE, null: true, method: :upcoming_release?, - description: 'Indicates the release is an upcoming release' + description: 'Indicates the release is an upcoming release.' field :assets, Types::ReleaseAssetsType, null: true, method: :itself, - description: 'Assets of the release' + description: 'Assets of the release.' field :links, Types::ReleaseLinksType, null: true, method: :itself, - description: 'Links of the release' + description: 'Links of the release.' field :milestones, Types::MilestoneType.connection_type, null: true, - description: 'Milestones associated to the release', + description: 'Milestones associated to the release.', resolver: ::Resolvers::ReleaseMilestonesResolver field :evidences, Types::EvidenceType.connection_type, null: true, - description: 'Evidence for the release' + description: 'Evidence for the release.' field :author, Types::UserType, null: true, - description: 'User that created the release' + description: 'User that created the release.' def author Gitlab::Graphql::Loaders::BatchModelLoader.new(User, release.author_id).find @@ -49,7 +49,7 @@ module Types field :commit, Types::CommitType, null: true, complexity: 10, calls_gitaly: true, - description: 'The commit associated with the release' + description: 'The commit associated with the release.' def commit return if release.sha.nil? diff --git a/app/graphql/types/repository_type.rb b/app/graphql/types/repository_type.rb index 5b86871142c..e319a5f3124 100644 --- a/app/graphql/types/repository_type.rb +++ b/app/graphql/types/repository_type.rb @@ -7,12 +7,12 @@ module Types authorize :download_code field :root_ref, GraphQL::STRING_TYPE, null: true, calls_gitaly: true, - description: 'Default branch of the repository' + description: 'Default branch of the repository.' field :empty, GraphQL::BOOLEAN_TYPE, null: false, method: :empty?, calls_gitaly: true, - description: 'Indicates repository has no visible content' + description: 'Indicates repository has no visible content.' field :exists, GraphQL::BOOLEAN_TYPE, null: false, method: :exists?, calls_gitaly: true, - description: 'Indicates a corresponding Git repository exists on disk' + description: 'Indicates a corresponding Git repository exists on disk.' field :tree, Types::Tree::TreeType, null: true, resolver: Resolvers::TreeResolver, calls_gitaly: true, - description: 'Tree of the repository' + description: 'Tree of the repository.' end end diff --git a/app/graphql/types/resolvable_interface.rb b/app/graphql/types/resolvable_interface.rb index a39092c70ca..a9d745c2bc1 100644 --- a/app/graphql/types/resolvable_interface.rb +++ b/app/graphql/types/resolvable_interface.rb @@ -8,7 +8,7 @@ module Types field :resolved_by, Types::UserType, null: true, - description: 'User who resolved the object' + description: 'User who resolved the object.' def resolved_by return unless object.resolved_by_id @@ -17,12 +17,12 @@ module Types end field :resolved, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates if the object is resolved', + description: 'Indicates if the object is resolved.', method: :resolved? field :resolvable, GraphQL::BOOLEAN_TYPE, null: false, - description: 'Indicates if the object can be resolved', + description: 'Indicates if the object can be resolved.', method: :resolvable? field :resolved_at, Types::TimeType, null: true, - description: 'Timestamp of when the object was resolved' + description: 'Timestamp of when the object was resolved.' end end diff --git a/app/graphql/types/root_storage_statistics_type.rb b/app/graphql/types/root_storage_statistics_type.rb index 21448b33bb5..102639f19d9 100644 --- a/app/graphql/types/root_storage_statistics_type.rb +++ b/app/graphql/types/root_storage_statistics_type.rb @@ -6,14 +6,14 @@ module Types authorize :read_statistics - field :storage_size, GraphQL::FLOAT_TYPE, null: false, description: 'The total storage in bytes' - field :repository_size, GraphQL::FLOAT_TYPE, null: false, description: 'The Git repository size in bytes' - field :lfs_objects_size, GraphQL::FLOAT_TYPE, null: false, description: 'The LFS objects size in bytes' - field :build_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'The CI artifacts size in bytes' - field :packages_size, GraphQL::FLOAT_TYPE, null: false, description: 'The packages size in bytes' - field :wiki_size, GraphQL::FLOAT_TYPE, null: false, description: 'The wiki size in bytes' - field :snippets_size, GraphQL::FLOAT_TYPE, null: false, description: 'The snippets size in bytes' - field :pipeline_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'The CI pipeline artifacts size in bytes' - field :uploads_size, GraphQL::FLOAT_TYPE, null: false, description: 'The uploads size in bytes' + field :storage_size, GraphQL::FLOAT_TYPE, null: false, description: 'The total storage in bytes.' + field :repository_size, GraphQL::FLOAT_TYPE, null: false, description: 'The Git repository size in bytes.' + field :lfs_objects_size, GraphQL::FLOAT_TYPE, null: false, description: 'The LFS objects size in bytes.' + field :build_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'The CI artifacts size in bytes.' + field :packages_size, GraphQL::FLOAT_TYPE, null: false, description: 'The packages size in bytes.' + field :wiki_size, GraphQL::FLOAT_TYPE, null: false, description: 'The wiki size in bytes.' + field :snippets_size, GraphQL::FLOAT_TYPE, null: false, description: 'The snippets size in bytes.' + field :pipeline_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'The CI pipeline artifacts size in bytes.' + field :uploads_size, GraphQL::FLOAT_TYPE, null: false, description: 'The uploads size in bytes.' end end diff --git a/app/graphql/types/snippet_type.rb b/app/graphql/types/snippet_type.rb index f587adf207f..2f79ec48c04 100644 --- a/app/graphql/types/snippet_type.rb +++ b/app/graphql/types/snippet_type.rb @@ -14,15 +14,15 @@ module Types expose_permissions Types::PermissionTypes::Snippet field :id, Types::GlobalIDType[::Snippet], - description: 'ID of the snippet', + description: 'ID of the snippet.', null: false field :title, GraphQL::STRING_TYPE, - description: 'Title of the snippet', + description: 'Title of the snippet.', null: false field :project, Types::ProjectType, - description: 'The project the snippet is associated with', + description: 'The project the snippet is associated with.', null: true, authorize: :read_project @@ -30,56 +30,56 @@ module Types # when the admin setting restricted visibility # level is set to public field :author, Types::UserType, - description: 'The owner of the snippet', + description: 'The owner of the snippet.', null: true field :file_name, GraphQL::STRING_TYPE, - description: 'File Name of the snippet', + description: 'File Name of the snippet.', null: true field :description, GraphQL::STRING_TYPE, - description: 'Description of the snippet', + description: 'Description of the snippet.', null: true field :visibility_level, Types::VisibilityLevelsEnum, - description: 'Visibility Level of the snippet', + description: 'Visibility Level of the snippet.', null: false field :created_at, Types::TimeType, - description: 'Timestamp this snippet was created', + description: 'Timestamp this snippet was created.', null: false field :updated_at, Types::TimeType, - description: 'Timestamp this snippet was updated', + description: 'Timestamp this snippet was updated.', null: false field :web_url, type: GraphQL::STRING_TYPE, - description: 'Web URL of the snippet', + description: 'Web URL of the snippet.', null: false field :raw_url, type: GraphQL::STRING_TYPE, - description: 'Raw URL of the snippet', + description: 'Raw URL of the snippet.', null: false field :blob, type: Types::Snippets::BlobType, - description: 'Snippet blob', + description: 'Snippet blob.', calls_gitaly: true, null: false, deprecated: { reason: 'Use `blobs`', milestone: '13.3' } field :blobs, type: Types::Snippets::BlobType.connection_type, - description: 'Snippet blobs', + description: 'Snippet blobs.', calls_gitaly: true, null: true, resolver: Resolvers::Snippets::BlobsResolver field :ssh_url_to_repo, type: GraphQL::STRING_TYPE, - description: 'SSH URL to the snippet repository', + description: 'SSH URL to the snippet repository.', calls_gitaly: true, null: true field :http_url_to_repo, type: GraphQL::STRING_TYPE, - description: 'HTTP URL to the snippet repository', + description: 'HTTP URL to the snippet repository.', calls_gitaly: true, null: true diff --git a/app/graphql/types/snippets/blob_action_input_type.rb b/app/graphql/types/snippets/blob_action_input_type.rb index ccb6ae3f2c1..c4289375f6b 100644 --- a/app/graphql/types/snippets/blob_action_input_type.rb +++ b/app/graphql/types/snippets/blob_action_input_type.rb @@ -7,19 +7,19 @@ module Types description 'Represents an action to perform over a snippet file' argument :action, Types::Snippets::BlobActionEnum, - description: 'Type of input action', + description: 'Type of input action.', required: true argument :previous_path, GraphQL::STRING_TYPE, - description: 'Previous path of the snippet file', + description: 'Previous path of the snippet file.', required: false argument :file_path, GraphQL::STRING_TYPE, - description: 'Path of the snippet file', + description: 'Path of the snippet file.', required: true argument :content, GraphQL::STRING_TYPE, - description: 'Snippet file content', + description: 'Snippet file content.', required: false end end diff --git a/app/graphql/types/snippets/blob_type.rb b/app/graphql/types/snippets/blob_type.rb index dcde1e5a73b..fb0c1d9409b 100644 --- a/app/graphql/types/snippets/blob_type.rb +++ b/app/graphql/types/snippets/blob_type.rb @@ -9,53 +9,53 @@ module Types present_using SnippetBlobPresenter field :rich_data, GraphQL::STRING_TYPE, - description: 'Blob highlighted data', + description: 'Blob highlighted data.', null: true field :plain_data, GraphQL::STRING_TYPE, - description: 'Blob plain highlighted data', + description: 'Blob plain highlighted data.', calls_gitaly: true, null: true field :raw_path, GraphQL::STRING_TYPE, - description: 'Blob raw content endpoint path', + description: 'Blob raw content endpoint path.', null: false field :size, GraphQL::INT_TYPE, - description: 'Blob size', + description: 'Blob size.', null: false field :binary, GraphQL::BOOLEAN_TYPE, - description: 'Shows whether the blob is binary', + description: 'Shows whether the blob is binary.', method: :binary?, null: false field :name, GraphQL::STRING_TYPE, - description: 'Blob name', + description: 'Blob name.', null: true field :path, GraphQL::STRING_TYPE, - description: 'Blob path', + description: 'Blob path.', null: true field :simple_viewer, type: Types::Snippets::BlobViewerType, - description: 'Blob content simple viewer', + description: 'Blob content simple viewer.', null: false field :rich_viewer, type: Types::Snippets::BlobViewerType, - description: 'Blob content rich viewer', + description: 'Blob content rich viewer.', null: true field :mode, type: GraphQL::STRING_TYPE, - description: 'Blob mode', + description: 'Blob mode.', null: true field :external_storage, type: GraphQL::STRING_TYPE, - description: 'Blob external storage', + description: 'Blob external storage.', null: true field :rendered_as_text, type: GraphQL::BOOLEAN_TYPE, - description: 'Shows whether the blob is rendered as text', + description: 'Shows whether the blob is rendered as text.', method: :rendered_as_text?, null: false end diff --git a/app/graphql/types/snippets/blob_viewer_type.rb b/app/graphql/types/snippets/blob_viewer_type.rb index a2ffa144066..9e77457c843 100644 --- a/app/graphql/types/snippets/blob_viewer_type.rb +++ b/app/graphql/types/snippets/blob_viewer_type.rb @@ -7,34 +7,34 @@ module Types description 'Represents how the blob content should be displayed' field :type, Types::BlobViewers::TypeEnum, - description: 'Type of blob viewer', + description: 'Type of blob viewer.', null: false field :load_async, GraphQL::BOOLEAN_TYPE, - description: 'Shows whether the blob content is loaded async', + description: 'Shows whether the blob content is loaded asynchronously.', null: false field :collapsed, GraphQL::BOOLEAN_TYPE, - description: 'Shows whether the blob should be displayed collapsed', + description: 'Shows whether the blob should be displayed collapsed.', method: :collapsed?, null: false field :too_large, GraphQL::BOOLEAN_TYPE, - description: 'Shows whether the blob too large to be displayed', + description: 'Shows whether the blob too large to be displayed.', method: :too_large?, null: false field :render_error, GraphQL::STRING_TYPE, - description: 'Error rendering the blob content', + description: 'Error rendering the blob content.', null: true field :file_type, GraphQL::STRING_TYPE, - description: 'Content file type', + description: 'Content file type.', method: :partial_name, null: false field :loading_partial_name, GraphQL::STRING_TYPE, - description: 'Loading partial name', + description: 'Loading partial name.', null: false def collapsed diff --git a/app/graphql/types/task_completion_status.rb b/app/graphql/types/task_completion_status.rb index 73a8b4f3020..6837256f202 100644 --- a/app/graphql/types/task_completion_status.rb +++ b/app/graphql/types/task_completion_status.rb @@ -9,9 +9,9 @@ module Types description 'Completion status of tasks' field :count, GraphQL::INT_TYPE, null: false, - description: 'Number of total tasks' + description: 'Number of total tasks.' field :completed_count, GraphQL::INT_TYPE, null: false, - description: 'Number of completed tasks' + description: 'Number of completed tasks.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/terraform/state_type.rb b/app/graphql/types/terraform/state_type.rb index d97e673bf31..9e2c47a9ece 100644 --- a/app/graphql/types/terraform/state_type.rb +++ b/app/graphql/types/terraform/state_type.rb @@ -11,32 +11,32 @@ module Types field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the Terraform state' + description: 'ID of the Terraform state.' field :name, GraphQL::STRING_TYPE, null: false, - description: 'Name of the Terraform state' + description: 'Name of the Terraform state.' field :locked_by_user, Types::UserType, null: true, - description: 'The user currently holding a lock on the Terraform state' + description: 'The user currently holding a lock on the Terraform state.' field :locked_at, Types::TimeType, null: true, - description: 'Timestamp the Terraform state was locked' + description: 'Timestamp the Terraform state was locked.' field :latest_version, Types::Terraform::StateVersionType, complexity: 3, null: true, - description: 'The latest version of the Terraform state' + description: 'The latest version of the Terraform state.' field :created_at, Types::TimeType, null: false, - description: 'Timestamp the Terraform state was created' + description: 'Timestamp the Terraform state was created.' field :updated_at, Types::TimeType, null: false, - description: 'Timestamp the Terraform state was updated' + description: 'Timestamp the Terraform state was updated.' def locked_by_user Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.locked_by_user_id).find diff --git a/app/graphql/types/terraform/state_version_type.rb b/app/graphql/types/terraform/state_version_type.rb index a3af5c876ca..2cd2ec8dcda 100644 --- a/app/graphql/types/terraform/state_version_type.rb +++ b/app/graphql/types/terraform/state_version_type.rb @@ -11,32 +11,32 @@ module Types field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the Terraform state version' + description: 'ID of the Terraform state version.' field :created_by_user, Types::UserType, null: true, - description: 'The user that created this version' + description: 'The user that created this version.' field :download_path, GraphQL::STRING_TYPE, null: true, - description: "URL for downloading the version's JSON file" + description: "URL for downloading the version's JSON file." field :job, Types::Ci::JobType, null: true, - description: 'The job that created this version' + description: 'The job that created this version.' field :serial, GraphQL::INT_TYPE, null: true, - description: 'Serial number of the version', + description: 'Serial number of the version.', method: :version field :created_at, Types::TimeType, null: false, - description: 'Timestamp the version was created' + description: 'Timestamp the version was created.' field :updated_at, Types::TimeType, null: false, - description: 'Timestamp the version was updated' + description: 'Timestamp the version was updated.' def created_by_user Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.created_by_user_id).find diff --git a/app/graphql/types/todo_type.rb b/app/graphql/types/todo_type.rb index 3694980ef93..3b983060de2 100644 --- a/app/graphql/types/todo_type.rb +++ b/app/graphql/types/todo_type.rb @@ -3,49 +3,49 @@ module Types class TodoType < BaseObject graphql_name 'Todo' - description 'Representing a todo entry' + description 'Representing a to-do entry' present_using TodoPresenter authorize :read_todo field :id, GraphQL::ID_TYPE, - description: 'ID of the todo', + description: 'ID of the to-do item.', null: false field :project, Types::ProjectType, - description: 'The project this todo is associated with', + description: 'The project this to-do item is associated with.', null: true, authorize: :read_project field :group, Types::GroupType, - description: 'Group this todo is associated with', + description: 'Group this to-do item is associated with.', null: true, authorize: :read_group field :author, Types::UserType, - description: 'The author of this todo', + description: 'The author of this to-do item.', null: false field :action, Types::TodoActionEnum, - description: 'Action of the todo', + description: 'Action of the to-do item.', null: false field :target_type, Types::TodoTargetEnum, - description: 'Target type of the todo', + description: 'Target type of the to-do item.', null: false field :body, GraphQL::STRING_TYPE, - description: 'Body of the todo', + description: 'Body of the to-do item.', null: false, calls_gitaly: true # TODO This is only true when `target_type` is `Commit`. See https://gitlab.com/gitlab-org/gitlab/issues/34757#note_234752665 field :state, Types::TodoStateEnum, - description: 'State of the todo', + description: 'State of the to-do item.', null: false field :created_at, Types::TimeType, - description: 'Timestamp this todo was created', + description: 'Timestamp this to-do item was created.', null: false def project diff --git a/app/graphql/types/tree/blob_type.rb b/app/graphql/types/tree/blob_type.rb index a7b90d2533b..3823bd94083 100644 --- a/app/graphql/types/tree/blob_type.rb +++ b/app/graphql/types/tree/blob_type.rb @@ -11,13 +11,13 @@ module Types graphql_name 'Blob' field :web_url, GraphQL::STRING_TYPE, null: true, - description: 'Web URL of the blob' + description: 'Web URL of the blob.' field :web_path, GraphQL::STRING_TYPE, null: true, - description: 'Web path of the blob' + description: 'Web path of the blob.' field :lfs_oid, GraphQL::STRING_TYPE, null: true, - description: 'LFS ID of the blob' + description: 'LFS ID of the blob.' field :mode, GraphQL::STRING_TYPE, null: true, - description: 'Blob mode in numeric format' + description: 'Blob mode in numeric format.' def lfs_oid Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(object.repository, object.id).find diff --git a/app/graphql/types/tree/entry_type.rb b/app/graphql/types/tree/entry_type.rb index b40e38ec9d1..c0150b77c55 100644 --- a/app/graphql/types/tree/entry_type.rb +++ b/app/graphql/types/tree/entry_type.rb @@ -5,17 +5,17 @@ module Types include Types::BaseInterface field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the entry' + description: 'ID of the entry.' field :sha, GraphQL::STRING_TYPE, null: false, - description: 'Last commit sha for the entry', method: :id + description: 'Last commit SHA for the entry.', method: :id field :name, GraphQL::STRING_TYPE, null: false, - description: 'Name of the entry' + description: 'Name of the entry.' field :type, Tree::TypeEnum, null: false, - description: 'Type of tree entry' + description: 'Type of tree entry.' field :path, GraphQL::STRING_TYPE, null: false, - description: 'Path of the entry' + description: 'Path of the entry.' field :flat_path, GraphQL::STRING_TYPE, null: false, - description: 'Flat path of the entry' + description: 'Flat path of the entry.' end end end diff --git a/app/graphql/types/tree/submodule_type.rb b/app/graphql/types/tree/submodule_type.rb index d41fa4afd4b..519e866ebb0 100644 --- a/app/graphql/types/tree/submodule_type.rb +++ b/app/graphql/types/tree/submodule_type.rb @@ -9,9 +9,9 @@ module Types graphql_name 'Submodule' field :web_url, type: GraphQL::STRING_TYPE, null: true, - description: 'Web URL for the sub-module' + description: 'Web URL for the sub-module.' field :tree_url, type: GraphQL::STRING_TYPE, null: true, - description: 'Tree URL for the sub-module' + description: 'Tree URL for the sub-module.' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/tree/tree_entry_type.rb b/app/graphql/types/tree/tree_entry_type.rb index aff2e025761..daf4b5421fb 100644 --- a/app/graphql/types/tree/tree_entry_type.rb +++ b/app/graphql/types/tree/tree_entry_type.rb @@ -12,9 +12,9 @@ module Types description 'Represents a directory' field :web_url, GraphQL::STRING_TYPE, null: true, - description: 'Web URL for the tree entry (directory)' + description: 'Web URL for the tree entry (directory).' field :web_path, GraphQL::STRING_TYPE, null: true, - description: 'Web path for the tree entry (directory)' + description: 'Web path for the tree entry (directory).' end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/tree/tree_type.rb b/app/graphql/types/tree/tree_type.rb index fecd6c0f309..011cff0c89c 100644 --- a/app/graphql/types/tree/tree_type.rb +++ b/app/graphql/types/tree/tree_type.rb @@ -9,17 +9,17 @@ module Types # Complexity 10 as it triggers a Gitaly call on each render field :last_commit, Types::CommitType, null: true, complexity: 10, calls_gitaly: true, resolver: Resolvers::LastCommitResolver, - description: 'Last commit for the tree' + description: 'Last commit for the tree.' field :trees, Types::Tree::TreeEntryType.connection_type, null: false, - description: 'Trees of the tree' + description: 'Trees of the tree.' field :submodules, Types::Tree::SubmoduleType.connection_type, null: false, - description: 'Sub-modules of the tree', + description: 'Sub-modules of the tree.', calls_gitaly: true field :blobs, Types::Tree::BlobType.connection_type, null: false, - description: 'Blobs of the tree', + description: 'Blobs of the tree.', calls_gitaly: true def trees diff --git a/app/graphql/types/user_status_type.rb b/app/graphql/types/user_status_type.rb index 9cf6c862d3d..c1a736a3722 100644 --- a/app/graphql/types/user_status_type.rb +++ b/app/graphql/types/user_status_type.rb @@ -8,10 +8,10 @@ module Types markdown_field :message_html, null: true, description: 'HTML of the user status message' field :message, GraphQL::STRING_TYPE, null: true, - description: 'User status message' + description: 'User status message.' field :emoji, GraphQL::STRING_TYPE, null: true, - description: 'String representation of emoji' + description: 'String representation of emoji.' field :availability, Types::AvailabilityEnum, null: false, - description: 'User availability status' + description: 'User availability status.' end end diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb index 93503268319..0cefc84633d 100644 --- a/app/graphql/types/user_type.rb +++ b/app/graphql/types/user_type.rb @@ -11,58 +11,61 @@ module Types expose_permissions Types::PermissionTypes::User field :id, GraphQL::ID_TYPE, null: false, - description: 'ID of the user' + description: 'ID of the user.' + field :bot, GraphQL::BOOLEAN_TYPE, null: false, + description: 'Indicates if the user is a bot.', + method: :bot? field :username, GraphQL::STRING_TYPE, null: false, - description: 'Username of the user. Unique within this instance of GitLab' + description: 'Username of the user. Unique within this instance of GitLab.' field :name, GraphQL::STRING_TYPE, null: false, - description: 'Human-readable name of the user' + description: 'Human-readable name of the user.' field :state, Types::UserStateEnum, null: false, - description: 'State of the user' + description: 'State of the user.' field :email, GraphQL::STRING_TYPE, null: true, - description: 'User email', method: :public_email, + description: 'User email.', method: :public_email, deprecated: { reason: 'Use public_email', milestone: '13.7' } field :public_email, GraphQL::STRING_TYPE, null: true, - description: "User's public email" + description: "User's public email." field :avatar_url, GraphQL::STRING_TYPE, null: true, - description: "URL of the user's avatar" + description: "URL of the user's avatar." field :web_url, GraphQL::STRING_TYPE, null: false, - description: 'Web URL of the user' + description: 'Web URL of the user.' field :web_path, GraphQL::STRING_TYPE, null: false, - description: 'Web path of the user' + description: 'Web path of the user.' field :todos, Types::TodoType.connection_type, null: false, resolver: Resolvers::TodoResolver, - description: 'Todos of the user' + description: 'To-do items of the user.' field :group_memberships, Types::GroupMemberType.connection_type, null: true, - description: 'Group memberships of the user' + description: 'Group memberships of the user.' field :group_count, GraphQL::INT_TYPE, null: true, resolver: Resolvers::Users::GroupCountResolver, - description: 'Group count for the user', + description: 'Group count for the user.', feature_flag: :user_group_counts field :status, Types::UserStatusType, null: true, - description: 'User status' + description: 'User status.' field :location, ::GraphQL::STRING_TYPE, null: true, description: 'The location of the user.' field :project_memberships, Types::ProjectMemberType.connection_type, null: true, - description: 'Project memberships of the user' + description: 'Project memberships of the user.' field :starred_projects, Types::ProjectType.connection_type, null: true, - description: 'Projects starred by the user', + description: 'Projects starred by the user.', resolver: Resolvers::UserStarredProjectsResolver # Merge request field: MRs can be authored, assigned, or assigned-for-review: field :authored_merge_requests, resolver: Resolvers::AuthoredMergeRequestsResolver, - description: 'Merge Requests authored by the user' + description: 'Merge Requests authored by the user.' field :assigned_merge_requests, resolver: Resolvers::AssignedMergeRequestsResolver, - description: 'Merge Requests assigned to the user' + description: 'Merge Requests assigned to the user.' field :review_requested_merge_requests, resolver: Resolvers::ReviewRequestedMergeRequestsResolver, - description: 'Merge Requests assigned to the user for review' + description: 'Merge Requests assigned to the user for review.' field :snippets, Types::SnippetType.connection_type, null: true, - description: 'Snippets authored by the user', + description: 'Snippets authored by the user.', resolver: Resolvers::Users::SnippetsResolver end end |