diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 15:44:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 15:44:42 +0000 |
commit | 4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch) | |
tree | 5423a1c7516cffe36384133ade12572cf709398d /app/graphql/types | |
parent | e570267f2f6b326480d284e0164a6464ba4081bc (diff) | |
download | gitlab-ce-4555e1b21c365ed8303ffb7a3325d773c9b8bf31.tar.gz |
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'app/graphql/types')
73 files changed, 795 insertions, 255 deletions
diff --git a/app/graphql/types/access_level_enum.rb b/app/graphql/types/access_level_enum.rb index b7eb35ddfc9..299952e4685 100644 --- a/app/graphql/types/access_level_enum.rb +++ b/app/graphql/types/access_level_enum.rb @@ -5,12 +5,12 @@ module Types graphql_name 'AccessLevelEnum' description 'Access level to a resource' - value 'NO_ACCESS', value: Gitlab::Access::NO_ACCESS, description: 'No access' - value 'MINIMAL_ACCESS', value: Gitlab::Access::MINIMAL_ACCESS, description: 'Minimal access' - value 'GUEST', value: Gitlab::Access::GUEST, description: 'Guest access' - value 'REPORTER', value: Gitlab::Access::REPORTER, description: 'Reporter access' - value 'DEVELOPER', value: Gitlab::Access::DEVELOPER, description: 'Developer access' - value 'MAINTAINER', value: Gitlab::Access::MAINTAINER, description: 'Maintainer access' - value 'OWNER', value: Gitlab::Access::OWNER, description: 'Owner access' + value 'NO_ACCESS', value: Gitlab::Access::NO_ACCESS, description: 'No access.' + value 'MINIMAL_ACCESS', value: Gitlab::Access::MINIMAL_ACCESS, description: 'Minimal access.' + value 'GUEST', value: Gitlab::Access::GUEST, description: 'Guest access.' + value 'REPORTER', value: Gitlab::Access::REPORTER, description: 'Reporter access.' + value 'DEVELOPER', value: Gitlab::Access::DEVELOPER, description: 'Developer access.' + value 'MAINTAINER', value: Gitlab::Access::MAINTAINER, description: 'Maintainer access.' + value 'OWNER', value: Gitlab::Access::OWNER, description: 'Owner access.' end end diff --git a/app/graphql/types/alert_management/http_integration_type.rb b/app/graphql/types/alert_management/http_integration_type.rb index 0d5bb50a77c..bba9cb1bbfc 100644 --- a/app/graphql/types/alert_management/http_integration_type.rb +++ b/app/graphql/types/alert_management/http_integration_type.rb @@ -21,4 +21,4 @@ module Types end end -Types::AlertManagement::HttpIntegrationType.prepend_ee_mod +Types::AlertManagement::HttpIntegrationType.prepend_mod diff --git a/app/graphql/types/alert_management/status_enum.rb b/app/graphql/types/alert_management/status_enum.rb index 9d2c7316254..32a578cb155 100644 --- a/app/graphql/types/alert_management/status_enum.rb +++ b/app/graphql/types/alert_management/status_enum.rb @@ -7,7 +7,7 @@ module Types description 'Alert status values' ::AlertManagement::Alert.status_names.each do |status| - value status.to_s.upcase, value: status, description: "#{status.to_s.titleize} status" + value status.to_s.upcase, value: status, description: "#{::AlertManagement::Alert::STATUS_DESCRIPTIONS[status]}." end end end diff --git a/app/graphql/types/base_argument.rb b/app/graphql/types/base_argument.rb index ff9a5a0611d..536a32f2bdd 100644 --- a/app/graphql/types/base_argument.rb +++ b/app/graphql/types/base_argument.rb @@ -4,10 +4,11 @@ module Types class BaseArgument < GraphQL::Schema::Argument include GitlabStyleDeprecations - attr_reader :deprecation + attr_reader :deprecation, :doc_reference def initialize(*args, **kwargs, &block) @deprecation = gitlab_deprecation(kwargs) + @doc_reference = kwargs.delete(:see) super(*args, **kwargs, &block) end diff --git a/app/graphql/types/base_enum.rb b/app/graphql/types/base_enum.rb index 518a902a5d7..7ef1cbddbd9 100644 --- a/app/graphql/types/base_enum.rb +++ b/app/graphql/types/base_enum.rb @@ -17,6 +17,9 @@ module Types # declarative_enum MyDeclarativeEnum # end # + # Disabling descriptions rubocop for a false positive here + # rubocop: disable Graphql/Descriptions + # def declarative_enum(enum_mod, use_name: true, use_description: true) graphql_name(enum_mod.name) if use_name description(enum_mod.description) if use_description @@ -25,6 +28,7 @@ module Types value(key.to_s.upcase, **content) end end + # rubocop: enable Graphql/Descriptions # Helper to define an enum member for each element of a Rails AR enum def from_rails_enum(enum, description:) diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb index 7c939f94dde..47caf83eb1c 100644 --- a/app/graphql/types/base_field.rb +++ b/app/graphql/types/base_field.rb @@ -8,10 +8,11 @@ module Types DEFAULT_COMPLEXITY = 1 - attr_reader :deprecation + attr_reader :deprecation, :doc_reference def initialize(**kwargs, &block) @calls_gitaly = !!kwargs.delete(:calls_gitaly) + @doc_reference = kwargs.delete(:see) @constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0 @requires_argument = !!kwargs.delete(:requires_argument) @authorize = Array.wrap(kwargs.delete(:authorize)) diff --git a/app/graphql/types/blob_viewer_type.rb b/app/graphql/types/blob_viewer_type.rb new file mode 100644 index 00000000000..8d863c32bc7 --- /dev/null +++ b/app/graphql/types/blob_viewer_type.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Types + class BlobViewerType < BaseObject # rubocop:disable Graphql/AuthorizeTypes + graphql_name 'BlobViewer' + description 'Represents how the blob content should be displayed' + + field :type, Types::BlobViewers::TypeEnum, + description: 'Type of blob viewer.', + null: false + + field :load_async, GraphQL::BOOLEAN_TYPE, + 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.', + method: :collapsed?, + null: false + + field :too_large, GraphQL::BOOLEAN_TYPE, + description: 'Shows whether the blob is too large to be displayed.', + method: :too_large?, + null: false + + field :render_error, GraphQL::STRING_TYPE, + description: 'Error rendering the blob content.', + null: true + + field :file_type, GraphQL::STRING_TYPE, + description: 'Content file type.', + method: :partial_name, + null: false + + field :loading_partial_name, GraphQL::STRING_TYPE, + description: 'Loading partial name.', + null: false + + def collapsed + !!object&.collapsed? + end + + def too_large + !!object&.too_large? + end + end +end diff --git a/app/graphql/types/board_list_type.rb b/app/graphql/types/board_list_type.rb index f215aa255de..dc10716dcb0 100644 --- a/app/graphql/types/board_list_type.rb +++ b/app/graphql/types/board_list_type.rb @@ -50,4 +50,4 @@ module Types # rubocop: enable Graphql/AuthorizeTypes end -Types::BoardListType.prepend_if_ee('::EE::Types::BoardListType') +Types::BoardListType.prepend_mod_with('Types::BoardListType') diff --git a/app/graphql/types/board_type.rb b/app/graphql/types/board_type.rb index 42d8eecc366..292809b0d64 100644 --- a/app/graphql/types/board_type.rb +++ b/app/graphql/types/board_type.rb @@ -41,4 +41,4 @@ module Types end end -Types::BoardType.prepend_if_ee('::EE::Types::BoardType') +Types::BoardType.prepend_mod_with('Types::BoardType') 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 7cf2dcb9c82..633221e61d1 100644 --- a/app/graphql/types/boards/board_issue_input_base_type.rb +++ b/app/graphql/types/boards/board_issue_input_base_type.rb @@ -4,6 +4,10 @@ module Types module Boards # rubocop: disable Graphql/AuthorizeTypes class BoardIssueInputBaseType < BoardIssuableInputBaseType + argument :iids, [GraphQL::STRING_TYPE], + required: false, + description: 'List of IIDs of issues. For example ["1", "2"].' + argument :milestone_title, GraphQL::STRING_TYPE, required: false, description: 'Filter by milestone title.' @@ -19,4 +23,4 @@ module Types end end -Types::Boards::BoardIssueInputBaseType.prepend_if_ee('::EE::Types::Boards::BoardIssueInputBaseType') +Types::Boards::BoardIssueInputBaseType.prepend_mod_with('Types::Boards::BoardIssueInputBaseType') diff --git a/app/graphql/types/boards/board_issue_input_type.rb b/app/graphql/types/boards/board_issue_input_type.rb index 8c0e37e5cb7..7580b0378fe 100644 --- a/app/graphql/types/boards/board_issue_input_type.rb +++ b/app/graphql/types/boards/board_issue_input_type.rb @@ -8,10 +8,7 @@ module Types argument :not, NegatedBoardIssueInputType, required: false, prepare: ->(negated_args, ctx) { negated_args.to_h }, - description: <<~MD - List of negated arguments. - Warning: this argument is experimental and a subject to change in future. - MD + description: 'List of negated arguments.' argument :search, GraphQL::STRING_TYPE, required: false, @@ -24,4 +21,4 @@ module Types end end -Types::Boards::BoardIssueInputType.prepend_if_ee('::EE::Types::Boards::BoardIssueInputType') +Types::Boards::BoardIssueInputType.prepend_mod_with('Types::Boards::BoardIssueInputType') diff --git a/app/graphql/types/boards/negated_board_issue_input_type.rb b/app/graphql/types/boards/negated_board_issue_input_type.rb index a0fab2ae969..834d94d4de6 100644 --- a/app/graphql/types/boards/negated_board_issue_input_type.rb +++ b/app/graphql/types/boards/negated_board_issue_input_type.rb @@ -7,4 +7,4 @@ module Types end end -Types::Boards::NegatedBoardIssueInputType.prepend_if_ee('::EE::Types::Boards::NegatedBoardIssueInputType') +Types::Boards::NegatedBoardIssueInputType.prepend_mod_with('Types::Boards::NegatedBoardIssueInputType') diff --git a/app/graphql/types/ci/code_quality_degradation_severity_enum.rb b/app/graphql/types/ci/code_quality_degradation_severity_enum.rb new file mode 100644 index 00000000000..742ac922198 --- /dev/null +++ b/app/graphql/types/ci/code_quality_degradation_severity_enum.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Ci + class CodeQualityDegradationSeverityEnum < BaseEnum + graphql_name 'CodeQualityDegradationSeverity' + + ::Gitlab::Ci::Reports::CodequalityReports::SEVERITY_PRIORITIES.keys.each do |status| + value status.upcase, + description: "Code Quality degradation has a status of #{status}.", + value: status + end + end + end +end diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb index 94a256fed3d..5ed4d823aee 100644 --- a/app/graphql/types/ci/job_type.rb +++ b/app/graphql/types/ci/job_type.rb @@ -8,6 +8,8 @@ module Types connection_type_class(Types::CountableConnectionType) + expose_permissions Types::PermissionTypes::Ci::Job + field :id, ::Types::GlobalIDType[::CommitStatus].as('JobID'), null: true, description: 'ID of the job.' field :pipeline, Types::Ci::PipelineType, null: true, @@ -23,7 +25,7 @@ module Types field :stage, Types::Ci::StageType, null: true, description: 'Stage of the job.' field :allow_failure, ::GraphQL::BOOLEAN_TYPE, null: false, - description: 'Whether this job is allowed to fail.' + description: 'Whether the job is allowed to fail.' field :duration, GraphQL::INT_TYPE, null: true, description: 'Duration of the job in seconds.' field :tags, [GraphQL::STRING_TYPE], null: true, @@ -41,6 +43,12 @@ module Types field :scheduled_at, Types::TimeType, null: true, description: 'Schedule for the build.' + # Life-cycle durations: + field :queued_duration, + type: Types::DurationType, + null: true, + description: 'How long the job was enqueued before starting.' + field :detailed_status, Types::Ci::DetailedStatusType, null: true, description: 'Detailed status of the job.' field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true, @@ -63,8 +71,16 @@ module Types description: 'Indicates the job can be canceled.' field :active, GraphQL::BOOLEAN_TYPE, null: false, method: :active?, description: 'Indicates the job is active.' + field :stuck, GraphQL::BOOLEAN_TYPE, null: false, method: :stuck?, + description: 'Indicates the job is stuck.' field :coverage, GraphQL::FLOAT_TYPE, null: true, description: 'Coverage level of the job.' + field :created_by_tag, GraphQL::BOOLEAN_TYPE, null: false, + description: 'Whether the job was created by a tag.' + field :manual_job, GraphQL::BOOLEAN_TYPE, null: true, + description: 'Whether the job has a manual action.' + field :triggered, GraphQL::BOOLEAN_TYPE, null: true, + description: 'Whether the job was triggered.' def pipeline Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, object.pipeline_id).find @@ -123,6 +139,18 @@ module Types def coverage object&.coverage end + + def created_by_tag + object.tag? + end + + def manual_job + object.try(:action?) + end + + def triggered + object.try(:trigger_request) + end end end end diff --git a/app/graphql/types/ci/pipeline_status_enum.rb b/app/graphql/types/ci/pipeline_status_enum.rb index e0b2020dcc1..2800454a999 100644 --- a/app/graphql/types/ci/pipeline_status_enum.rb +++ b/app/graphql/types/ci/pipeline_status_enum.rb @@ -5,7 +5,7 @@ module Types class PipelineStatusEnum < BaseEnum ::Ci::Pipeline.all_state_names.each do |state_symbol| value state_symbol.to_s.upcase, - description: ::Ci::Pipeline::STATUSES_DESCRIPTION[state_symbol], + description: "#{::Ci::Pipeline::STATUSES_DESCRIPTION[state_symbol]}.", value: state_symbol.to_s end end diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb index 2e83f6c1f5a..2eeddaca6ba 100644 --- a/app/graphql/types/ci/pipeline_type.rb +++ b/app/graphql/types/ci/pipeline_type.rb @@ -24,6 +24,9 @@ module Types field :before_sha, GraphQL::STRING_TYPE, null: true, description: 'Base SHA of the source branch.' + field :complete, GraphQL::BOOLEAN_TYPE, null: false, method: :complete?, + description: 'Indicates if a pipeline is complete.' + field :status, PipelineStatusEnum, null: false, description: "Status of the pipeline (#{::Ci::Pipeline.all_state_names.compact.join(', ').upcase})" @@ -39,6 +42,9 @@ module Types field :duration, GraphQL::INT_TYPE, null: true, description: 'Duration of the pipeline in seconds.' + field :queued_duration, Types::DurationType, null: true, + description: 'How long the pipeline was queued before starting.' + field :coverage, GraphQL::FLOAT_TYPE, null: true, description: 'Coverage percentage.' @@ -57,12 +63,17 @@ module Types field :committed_at, Types::TimeType, null: true, description: "Timestamp of the pipeline's commit." - field :stages, Types::Ci::StageType.connection_type, null: true, + field :stages, + type: Types::Ci::StageType.connection_type, + null: true, + authorize: :read_commit_status, description: 'Stages of the pipeline.', extras: [:lookahead], resolver: Resolvers::Ci::PipelineStagesResolver - field :user, Types::UserType, null: true, + field :user, + type: Types::UserType, + null: true, description: 'Pipeline user.' field :retryable, GraphQL::BOOLEAN_TYPE, @@ -78,12 +89,14 @@ module Types field :jobs, ::Types::Ci::JobType.connection_type, null: true, + authorize: :read_commit_status, description: 'Jobs belonging to the pipeline.', resolver: ::Resolvers::Ci::JobsResolver field :job, type: ::Types::Ci::JobType, null: true, + authorize: :read_commit_status, description: 'A specific job in this pipeline, either by name or ID.' do argument :id, type: ::Types::GlobalIDType[::CommitStatus], @@ -95,7 +108,10 @@ module Types description: 'Name of the job.' end - field :source_job, Types::Ci::JobType, null: true, + field :source_job, + type: Types::Ci::JobType, + null: true, + authorize: :read_commit_status, description: 'Job where pipeline was triggered from.' field :downstream, Types::Ci::PipelineType.connection_type, null: true, @@ -166,4 +182,4 @@ module Types end end -Types::Ci::PipelineType.prepend_if_ee('::EE::Types::Ci::PipelineType') +Types::Ci::PipelineType.prepend_mod_with('Types::Ci::PipelineType') diff --git a/app/graphql/types/ci/runner_access_level_enum.rb b/app/graphql/types/ci/runner_access_level_enum.rb new file mode 100644 index 00000000000..e98f80336f1 --- /dev/null +++ b/app/graphql/types/ci/runner_access_level_enum.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Ci + class RunnerAccessLevelEnum < BaseEnum + graphql_name 'CiRunnerAccessLevel' + + ::Ci::Runner.access_levels.keys.each do |type| + value type.upcase, + description: "A runner that is #{type.tr('_', ' ')}.", + value: type + end + end + end +end diff --git a/app/graphql/types/ci/runner_sort_enum.rb b/app/graphql/types/ci/runner_sort_enum.rb new file mode 100644 index 00000000000..550e870316a --- /dev/null +++ b/app/graphql/types/ci/runner_sort_enum.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Types + module Ci + class RunnerSortEnum < BaseEnum + graphql_name 'CiRunnerSort' + description 'Values for sorting runners' + + value 'CONTACTED_ASC', 'Ordered by contacted_at in ascending order.', value: :contacted_asc + value 'CREATED_DESC', 'Ordered by created_date in descending order.', value: :created_date + end + end +end diff --git a/app/graphql/types/ci/runner_status_enum.rb b/app/graphql/types/ci/runner_status_enum.rb new file mode 100644 index 00000000000..ad69175e44a --- /dev/null +++ b/app/graphql/types/ci/runner_status_enum.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Ci + class RunnerStatusEnum < BaseEnum + graphql_name 'CiRunnerStatus' + + ::Ci::Runner::AVAILABLE_STATUSES.each do |status| + value status.to_s.upcase, + description: "A runner that is #{status.to_s.tr('_', ' ')}.", + value: status.to_sym + end + end + end +end diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb new file mode 100644 index 00000000000..3abed7289d5 --- /dev/null +++ b/app/graphql/types/ci/runner_type.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Types + module Ci + class RunnerType < BaseObject + graphql_name 'CiRunner' + authorize :read_runner + + field :id, ::Types::GlobalIDType[::Ci::Runner], null: false, + description: 'ID of the runner.' + field :description, GraphQL::STRING_TYPE, null: true, + description: 'Description of the runner.' + field :contacted_at, Types::TimeType, null: true, + description: 'Last contact from the runner.', + method: :contacted_at + field :maximum_timeout, GraphQL::INT_TYPE, null: true, + description: 'Maximum timeout (in seconds) for jobs processed by the runner.' + field :access_level, ::Types::Ci::RunnerAccessLevelEnum, null: false, + description: 'Access level of the runner.' + field :active, GraphQL::BOOLEAN_TYPE, null: false, + description: 'Indicates the runner is allowed to receive jobs.' + field :status, ::Types::Ci::RunnerStatusEnum, null: false, + description: 'Status of the runner.' + field :version, GraphQL::STRING_TYPE, null: false, + description: 'Version of the runner.' + field :short_sha, GraphQL::STRING_TYPE, null: true, + description: %q(First eight characters of the runner's token used to authenticate new job requests. Used as the runner's unique ID.) + field :revision, GraphQL::STRING_TYPE, null: false, + description: 'Revision of the runner.' + field :locked, GraphQL::BOOLEAN_TYPE, null: true, + description: 'Indicates the runner is locked.' + field :run_untagged, GraphQL::BOOLEAN_TYPE, null: false, + description: 'Indicates the runner is able to run untagged jobs.' + field :ip_address, GraphQL::STRING_TYPE, null: false, + description: 'IP address of the runner.' + field :runner_type, ::Types::Ci::RunnerTypeEnum, null: false, + description: 'Type of the runner.' + field :tag_list, [GraphQL::STRING_TYPE], null: true, + description: 'Tags associated with the runner.' + end + end +end diff --git a/app/graphql/types/ci/runner_type_enum.rb b/app/graphql/types/ci/runner_type_enum.rb new file mode 100644 index 00000000000..f771635f4ed --- /dev/null +++ b/app/graphql/types/ci/runner_type_enum.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Ci + class RunnerTypeEnum < BaseEnum + graphql_name 'CiRunnerType' + + ::Ci::Runner.runner_types.keys.each do |type| + value type.upcase, + description: "A runner that is #{type.tr('_', ' ')}.", + value: type + end + end + end +end diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb index 56b4f248697..1be9e3192a9 100644 --- a/app/graphql/types/ci/stage_type.rb +++ b/app/graphql/types/ci/stage_type.rb @@ -2,20 +2,26 @@ module Types module Ci - # rubocop: disable Graphql/AuthorizeTypes class StageType < BaseObject graphql_name 'CiStage' + authorize :read_commit_status - field :name, GraphQL::STRING_TYPE, null: true, - description: 'Name of the stage.' - field :groups, Ci::GroupType.connection_type, null: true, - extras: [:lookahead], - description: 'Group of jobs for the stage.' - field :detailed_status, Types::Ci::DetailedStatusType, null: true, - description: 'Detailed status of the stage.' - field :jobs, Ci::JobType.connection_type, null: true, - description: 'Jobs for the stage.', - method: 'latest_statuses' + field :name, + type: GraphQL::STRING_TYPE, + null: true, + description: 'Name of the stage.' + field :groups, + type: Ci::GroupType.connection_type, + null: true, + extras: [:lookahead], + description: 'Group of jobs for the stage.' + field :detailed_status, Types::Ci::DetailedStatusType, + null: true, + description: 'Detailed status of the stage.' + field :jobs, Ci::JobType.connection_type, + null: true, + description: 'Jobs for the stage.', + method: 'latest_statuses' def detailed_status object.detailed_status(current_user) @@ -37,33 +43,6 @@ module Types key = indexed[stage_id] groups = ::Ci::Group.fabricate(project, key.stage, statuses) - if Feature.enabled?(:ci_no_empty_groups, project) - groups.each do |group| - rejected = group.jobs.reject { |job| Ability.allowed?(current_user, :read_commit_status, job) } - group.jobs.select! { |job| Ability.allowed?(current_user, :read_commit_status, job) } - next unless group.jobs.empty? - - exc = StandardError.new('Empty Ci::Group') - traces = rejected.map do |job| - trace = [] - policy = Ability.policy_for(current_user, job) - policy.debug(:read_commit_status, trace) - trace - end - extra = { - current_user_id: current_user&.id, - project_id: project.id, - pipeline_id: pl.id, - stage_id: stage_id, - group_name: group.name, - rejected_job_ids: rejected.map(&:id), - rejected_traces: traces - } - Gitlab::ErrorTracking.track_exception(exc, extra) - end - groups.reject! { |group| group.jobs.empty? } - end - loader.call(key, groups) end end diff --git a/app/graphql/types/ci/template_type.rb b/app/graphql/types/ci/template_type.rb new file mode 100644 index 00000000000..5f07fa16928 --- /dev/null +++ b/app/graphql/types/ci/template_type.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + module Ci + # rubocop: disable Graphql/AuthorizeTypes + class TemplateType < BaseObject + graphql_name 'CiTemplate' + description 'GitLab CI/CD configuration template.' + + field :name, GraphQL::STRING_TYPE, null: false, + description: 'Name of the CI template.' + field :content, GraphQL::STRING_TYPE, null: false, + description: 'Contents of the CI template.' + end + end +end diff --git a/app/graphql/types/container_expiration_policy_cadence_enum.rb b/app/graphql/types/container_expiration_policy_cadence_enum.rb index bb8bdf2197b..ac923f64b52 100644 --- a/app/graphql/types/container_expiration_policy_cadence_enum.rb +++ b/app/graphql/types/container_expiration_policy_cadence_enum.rb @@ -11,7 +11,7 @@ module Types }.freeze ::ContainerExpirationPolicy.cadence_options.each do |option, description| - value OPTIONS_MAPPING[option], description, value: option.to_s + value OPTIONS_MAPPING[option], description: description, value: option.to_s end end end diff --git a/app/graphql/types/container_expiration_policy_keep_enum.rb b/app/graphql/types/container_expiration_policy_keep_enum.rb index 7632df61092..ca6fbbcf5ae 100644 --- a/app/graphql/types/container_expiration_policy_keep_enum.rb +++ b/app/graphql/types/container_expiration_policy_keep_enum.rb @@ -12,7 +12,7 @@ module Types }.freeze ::ContainerExpirationPolicy.keep_n_options.each do |option, description| - value OPTIONS_MAPPING[option], description, value: option + value OPTIONS_MAPPING[option], description: description, value: option end end end diff --git a/app/graphql/types/container_expiration_policy_older_than_enum.rb b/app/graphql/types/container_expiration_policy_older_than_enum.rb index da70534b0d7..7364910f8cd 100644 --- a/app/graphql/types/container_expiration_policy_older_than_enum.rb +++ b/app/graphql/types/container_expiration_policy_older_than_enum.rb @@ -10,7 +10,7 @@ module Types }.freeze ::ContainerExpirationPolicy.older_than_options.each do |option, description| - value OPTIONS_MAPPING[option], description, value: option.to_s + value OPTIONS_MAPPING[option], description: description, value: option.to_s end end end diff --git a/app/graphql/types/design_management/version_type.rb b/app/graphql/types/design_management/version_type.rb index 4bc71aef0f4..265d6185110 100644 --- a/app/graphql/types/design_management/version_type.rb +++ b/app/graphql/types/design_management/version_type.rb @@ -32,6 +32,10 @@ module Types null: false, description: 'A particular design as of this version, provided it is visible at this version.', resolver: ::Resolvers::DesignManagement::Version::DesignsAtVersionResolver.single + + field :author, Types::UserType, null: false, description: 'Author of the version.' + field :created_at, Types::TimeType, null: false, + description: 'Timestamp of when the version was created.' end end end diff --git a/app/graphql/types/duration_type.rb b/app/graphql/types/duration_type.rb new file mode 100644 index 00000000000..260a2975ec1 --- /dev/null +++ b/app/graphql/types/duration_type.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Types + class DurationType < BaseScalar + graphql_name 'Duration' + description <<~DESC + Duration between two instants, represented as a fractional number of seconds. + + For example: 12.3334 + DESC + + def self.coerce_input(value, ctx) + case value + when Float + value + when Integer + value.to_f + when NilClass + raise GraphQL::CoercionError, 'Cannot be nil' + else + raise GraphQL::CoercionError, "Expected number: got #{value.class}" + end + end + + def self.coerce_result(value, ctx) + value.to_f + end + end +end diff --git a/app/graphql/types/group_member_relation_enum.rb b/app/graphql/types/group_member_relation_enum.rb index aa2e73d4944..54e2a175f33 100644 --- a/app/graphql/types/group_member_relation_enum.rb +++ b/app/graphql/types/group_member_relation_enum.rb @@ -6,7 +6,7 @@ module Types description 'Group member relation' ::GroupMembersFinder::RELATIONS.each do |member_relation| - value member_relation.to_s.upcase, value: member_relation, description: "#{member_relation.to_s.titleize} members" + value member_relation.to_s.upcase, value: member_relation, description: "#{::GroupMembersFinder::RELATIONS_DESCRIPTIONS[member_relation]}." end end end diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb index a44281b2bdf..27f4ae47c41 100644 --- a/app/graphql/types/group_type.rb +++ b/app/graphql/types/group_type.rb @@ -144,7 +144,7 @@ module Types resolver: Resolvers::GroupLabelsResolver field :timelogs, ::Types::TimelogType.connection_type, null: false, - description: 'Time logged on issues in the group and its subgroups.', + description: 'Time logged on issues and merge requests in the group and its subgroups.', extras: [:lookahead], complexity: 5, resolver: ::Resolvers::TimelogResolver @@ -169,4 +169,4 @@ module Types end end -Types::GroupType.prepend_if_ee('EE::Types::GroupType') +Types::GroupType.prepend_mod_with('Types::GroupType') diff --git a/app/graphql/types/issuable_type.rb b/app/graphql/types/issuable_type.rb new file mode 100644 index 00000000000..6ca74087f8a --- /dev/null +++ b/app/graphql/types/issuable_type.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Types + class IssuableType < BaseUnion + graphql_name 'Issuable' + description 'Represents an issuable.' + + possible_types Types::IssueType, Types::MergeRequestType + + def self.resolve_type(object, context) + case object + when Issue + Types::IssueType + when MergeRequest + Types::MergeRequestType + else + raise 'Unsupported issuable type' + end + end + end +end + +Types::IssuableType.prepend_mod_with('Types::IssuableType') diff --git a/app/graphql/types/issue_connection_type.rb b/app/graphql/types/issue_connection_type.rb index 2e0f05f741e..7abb2253fac 100644 --- a/app/graphql/types/issue_connection_type.rb +++ b/app/graphql/types/issue_connection_type.rb @@ -6,4 +6,4 @@ module Types end end -Types::IssueConnectionType.prepend_if_ee('::EE::Types::IssueConnectionType') +Types::IssueConnectionType.prepend_mod_with('Types::IssueConnectionType') diff --git a/app/graphql/types/issue_sort_enum.rb b/app/graphql/types/issue_sort_enum.rb index bf900fe3525..e730a51b60e 100644 --- a/app/graphql/types/issue_sort_enum.rb +++ b/app/graphql/types/issue_sort_enum.rb @@ -13,4 +13,4 @@ module Types end end -Types::IssueSortEnum.prepend_if_ee('::EE::Types::IssueSortEnum') +Types::IssueSortEnum.prepend_mod_with('Types::IssueSortEnum') diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb index 34c824fe9fb..0ccd1e2cebd 100644 --- a/app/graphql/types/issue_type.rb +++ b/app/graphql/types/issue_type.rb @@ -153,4 +153,4 @@ module Types end end -Types::IssueType.prepend_if_ee('::EE::Types::IssueType') +Types::IssueType.prepend_mod_with('Types::IssueType') diff --git a/app/graphql/types/issues/negated_issue_filter_input_type.rb b/app/graphql/types/issues/negated_issue_filter_input_type.rb index 10bf6f21792..8a2e75ed9ba 100644 --- a/app/graphql/types/issues/negated_issue_filter_input_type.rb +++ b/app/graphql/types/issues/negated_issue_filter_input_type.rb @@ -24,4 +24,4 @@ module Types end end -Types::Issues::NegatedIssueFilterInputType.prepend_if_ee('::EE::Types::Issues::NegatedIssueFilterInputType') +Types::Issues::NegatedIssueFilterInputType.prepend_mod_with('Types::Issues::NegatedIssueFilterInputType') diff --git a/app/graphql/types/label_type.rb b/app/graphql/types/label_type.rb index 4e8718a80da..cb6b0312aa3 100644 --- a/app/graphql/types/label_type.rb +++ b/app/graphql/types/label_type.rb @@ -23,5 +23,7 @@ module Types description: 'When this label was created.' field :updated_at, Types::TimeType, null: false, description: 'When this label was last updated.' + field :remove_on_close, GraphQL::BOOLEAN_TYPE, null: false, + description: 'Whether the label should be removed from an issue when the issue is closed.' end end diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb index c8ccf9d8aff..4eeeaa4f5d0 100644 --- a/app/graphql/types/merge_request_type.rb +++ b/app/graphql/types/merge_request_type.rb @@ -54,6 +54,9 @@ module Types field :target_branch, GraphQL::STRING_TYPE, null: false, description: 'Target branch of the merge request.' field :work_in_progress, GraphQL::BOOLEAN_TYPE, method: :work_in_progress?, null: false, + deprecated: { reason: 'Use `draft`', milestone: '13.12' }, + description: 'Indicates if the merge request is a draft.' + field :draft, GraphQL::BOOLEAN_TYPE, method: :draft?, null: false, description: 'Indicates if the merge request is a draft.' field :merge_when_pipeline_succeeds, GraphQL::BOOLEAN_TYPE, null: true, description: 'Indicates if the merge has been set to be merged when its pipeline succeeds (MWPS).' @@ -130,7 +133,10 @@ module Types field :milestone, Types::MilestoneType, null: true, description: 'The milestone of the merge request.' - field :assignees, Types::UserType.connection_type, null: true, complexity: 5, + field :assignees, + type: Types::MergeRequests::AssigneeType.connection_type, + null: true, + complexity: 5, description: 'Assignees of the merge request.' field :reviewers, type: Types::MergeRequests::ReviewerType.connection_type, @@ -257,4 +263,4 @@ module Types end end -Types::MergeRequestType.prepend_if_ee('::EE::Types::MergeRequestType') +Types::MergeRequestType.prepend_mod_with('Types::MergeRequestType') diff --git a/app/graphql/types/merge_requests/assignee_type.rb b/app/graphql/types/merge_requests/assignee_type.rb new file mode 100644 index 00000000000..8448477370e --- /dev/null +++ b/app/graphql/types/merge_requests/assignee_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module MergeRequests + class AssigneeType < ::Types::UserType + include FindClosest + include ::Types::MergeRequests::InteractsWithMergeRequest + + graphql_name 'MergeRequestAssignee' + description 'A user assigned to a merge request.' + authorize :read_user + end + end +end diff --git a/app/graphql/types/merge_requests/interacts_with_merge_request.rb b/app/graphql/types/merge_requests/interacts_with_merge_request.rb new file mode 100644 index 00000000000..d685ac4d3c9 --- /dev/null +++ b/app/graphql/types/merge_requests/interacts_with_merge_request.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Types + module MergeRequests + module InteractsWithMergeRequest + extend ActiveSupport::Concern + + included do + field :merge_request_interaction, + type: ::Types::UserMergeRequestInteractionType, + null: true, + extras: [:parent], + description: "Details of this user's interactions with the merge request." + end + + def merge_request_interaction(parent:) + merge_request = closest_parent(::Types::MergeRequestType, parent) + return unless merge_request + + Users::MergeRequestInteraction.new(user: object, merge_request: merge_request) + end + end + end +end diff --git a/app/graphql/types/merge_requests/reviewer_type.rb b/app/graphql/types/merge_requests/reviewer_type.rb index 09ced39844a..1ced821c839 100644 --- a/app/graphql/types/merge_requests/reviewer_type.rb +++ b/app/graphql/types/merge_requests/reviewer_type.rb @@ -4,23 +4,11 @@ module Types module MergeRequests class ReviewerType < ::Types::UserType include FindClosest + include ::Types::MergeRequests::InteractsWithMergeRequest graphql_name 'MergeRequestReviewer' - description 'A user from whom a merge request review has been requested.' + description 'A user assigned to a merge request as a reviewer.' authorize :read_user - - field :merge_request_interaction, - type: ::Types::UserMergeRequestInteractionType, - null: true, - extras: [:parent], - description: "Details of this user's interactions with the merge request." - - def merge_request_interaction(parent:) - merge_request = closest_parent(::Types::MergeRequestType, parent) - return unless merge_request - - Users::MergeRequestInteraction.new(user: object, merge_request: merge_request) - end end end end diff --git a/app/graphql/types/metadata/kas_type.rb b/app/graphql/types/metadata/kas_type.rb new file mode 100644 index 00000000000..8af4c23270b --- /dev/null +++ b/app/graphql/types/metadata/kas_type.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Types + module Metadata + class KasType < ::Types::BaseObject + graphql_name 'Kas' + + authorize :read_instance_metadata + + field :enabled, GraphQL::BOOLEAN_TYPE, null: false, + description: 'Indicates whether the Kubernetes Agent Server is enabled.' + field :version, GraphQL::STRING_TYPE, null: true, + description: 'KAS version.' + field :external_url, GraphQL::STRING_TYPE, null: true, + description: 'The URL used by the Agents to communicate with KAS.' + end + end +end diff --git a/app/graphql/types/metadata_type.rb b/app/graphql/types/metadata_type.rb index 0c360d4f292..851c2a3f1e3 100644 --- a/app/graphql/types/metadata_type.rb +++ b/app/graphql/types/metadata_type.rb @@ -10,5 +10,7 @@ module Types description: 'Version.' field :revision, GraphQL::STRING_TYPE, null: false, description: 'Revision.' + field :kas, ::Types::Metadata::KasType, null: false, + description: 'Metadata about KAS.' end end diff --git a/app/graphql/types/milestone_type.rb b/app/graphql/types/milestone_type.rb index 91a5109c748..eafede26c9e 100644 --- a/app/graphql/types/milestone_type.rb +++ b/app/graphql/types/milestone_type.rb @@ -57,11 +57,9 @@ module Types description: 'Milestone statistics.' def stats - return unless Feature.enabled?(:graphql_milestone_stats, milestone.project || milestone.group, default_enabled: true) - milestone end end end -Types::MilestoneType.prepend_if_ee('::EE::Types::MilestoneType') +Types::MilestoneType.prepend_mod_with('Types::MilestoneType') diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index 5a9c7b32deb..54a06ed5342 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -16,6 +16,7 @@ module Types mount_mutation Mutations::AlertManagement::HttpIntegration::ResetToken mount_mutation Mutations::AlertManagement::HttpIntegration::Destroy mount_mutation Mutations::Security::CiConfiguration::ConfigureSast + mount_mutation Mutations::Security::CiConfiguration::ConfigureSecretDetection mount_mutation Mutations::AlertManagement::PrometheusIntegration::Create mount_mutation Mutations::AlertManagement::PrometheusIntegration::Update mount_mutation Mutations::AlertManagement::PrometheusIntegration::ResetToken @@ -51,7 +52,10 @@ module Types mount_mutation Mutations::MergeRequests::SetLocked mount_mutation Mutations::MergeRequests::SetMilestone mount_mutation Mutations::MergeRequests::SetSubscription - mount_mutation Mutations::MergeRequests::SetWip, calls_gitaly: true + mount_mutation Mutations::MergeRequests::SetWip, + calls_gitaly: true, + deprecated: { reason: 'Use mergeRequestSetDraft', milestone: '13.12' } + mount_mutation Mutations::MergeRequests::SetDraft, calls_gitaly: true mount_mutation Mutations::MergeRequests::SetAssignees mount_mutation Mutations::MergeRequests::ReviewerRereview mount_mutation Mutations::Metrics::Dashboard::Annotations::Create @@ -93,10 +97,12 @@ module Types mount_mutation Mutations::Ci::Pipeline::Destroy mount_mutation Mutations::Ci::Pipeline::Retry mount_mutation Mutations::Ci::CiCdSettingsUpdate + mount_mutation Mutations::Ci::Job::Play + mount_mutation Mutations::Ci::Job::Retry mount_mutation Mutations::Namespace::PackageSettings::Update mount_mutation Mutations::UserCallouts::Create end end ::Types::MutationType.prepend(::Types::DeprecatedMutations) -::Types::MutationType.prepend_if_ee('::EE::Types::MutationType') +::Types::MutationType.prepend_mod_with('Types::MutationType') diff --git a/app/graphql/types/namespace/package_settings_type.rb b/app/graphql/types/namespace/package_settings_type.rb index 0720a1cfb4b..af091515979 100644 --- a/app/graphql/types/namespace/package_settings_type.rb +++ b/app/graphql/types/namespace/package_settings_type.rb @@ -10,5 +10,7 @@ module Types field :maven_duplicates_allowed, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether duplicate Maven packages are allowed for this namespace.' field :maven_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.' + field :generic_duplicates_allowed, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether duplicate generic packages are allowed for this namespace.' + field :generic_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.' end end diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb index da983399a11..96eff8a46b0 100644 --- a/app/graphql/types/namespace_type.rb +++ b/app/graphql/types/namespace_type.rb @@ -48,4 +48,4 @@ module Types end end -Types::NamespaceType.prepend_if_ee('EE::Types::NamespaceType') +Types::NamespaceType.prepend_mod_with('Types::NamespaceType') diff --git a/app/graphql/types/notes/noteable_type.rb b/app/graphql/types/notes/noteable_type.rb index f8626d249a1..a82a76f9c87 100644 --- a/app/graphql/types/notes/noteable_type.rb +++ b/app/graphql/types/notes/noteable_type.rb @@ -28,4 +28,4 @@ module Types end end -Types::Notes::NoteableType.prepend_if_ee('::EE::Types::Notes::NoteableType') +Types::Notes::NoteableType.prepend_mod_with('Types::Notes::NoteableType') diff --git a/app/graphql/types/notes/position_type_enum.rb b/app/graphql/types/notes/position_type_enum.rb index 9939f6511ce..18934636670 100644 --- a/app/graphql/types/notes/position_type_enum.rb +++ b/app/graphql/types/notes/position_type_enum.rb @@ -6,8 +6,8 @@ module Types graphql_name 'DiffPositionType' description 'Type of file the position refers to' - value 'text', description: "A text file" - value 'image', description: "An image" + value 'text', description: "A text file." + value 'image', description: "An image." end end end diff --git a/app/graphql/types/packages/maven/metadatum_type.rb b/app/graphql/types/packages/maven/metadatum_type.rb new file mode 100644 index 00000000000..bdb250ef96b --- /dev/null +++ b/app/graphql/types/packages/maven/metadatum_type.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Types + module Packages + module Maven + class MetadatumType < BaseObject + graphql_name 'MavenMetadata' + description 'Maven metadata' + + authorize :read_package + + field :id, ::Types::GlobalIDType[::Packages::Maven::Metadatum], null: false, description: 'ID of the metadatum.' + 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 :path, GraphQL::STRING_TYPE, null: false, description: 'Path of the Maven package.' + field :app_group, GraphQL::STRING_TYPE, null: false, description: 'App group of the Maven package.' + field :app_version, GraphQL::STRING_TYPE, null: true, description: 'App version of the Maven package.' + field :app_name, GraphQL::STRING_TYPE, null: false, description: 'App name of the Maven package.' + end + end + end +end diff --git a/app/graphql/types/packages/metadata_type.rb b/app/graphql/types/packages/metadata_type.rb index 4ab6707df88..94880cb9b22 100644 --- a/app/graphql/types/packages/metadata_type.rb +++ b/app/graphql/types/packages/metadata_type.rb @@ -6,7 +6,7 @@ module Types graphql_name 'PackageMetadata' description 'Represents metadata associated with a Package' - possible_types ::Types::Packages::Composer::MetadatumType, ::Types::Packages::Conan::MetadatumType + possible_types ::Types::Packages::Composer::MetadatumType, ::Types::Packages::Conan::MetadatumType, ::Types::Packages::Maven::MetadatumType, ::Types::Packages::Nuget::MetadatumType def self.resolve_type(object, context) case object @@ -14,6 +14,10 @@ module Types ::Types::Packages::Composer::MetadatumType when ::Packages::Conan::Metadatum ::Types::Packages::Conan::MetadatumType + when ::Packages::Maven::Metadatum + ::Types::Packages::Maven::MetadatumType + when ::Packages::Nuget::Metadatum + ::Types::Packages::Nuget::MetadatumType else # NOTE: This method must be kept in sync with `PackageWithoutVersionsType#metadata`, # which must never produce data that this discriminator cannot handle. diff --git a/app/graphql/types/packages/nuget/metadatum_type.rb b/app/graphql/types/packages/nuget/metadatum_type.rb new file mode 100644 index 00000000000..63fae2fb197 --- /dev/null +++ b/app/graphql/types/packages/nuget/metadatum_type.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Types + module Packages + module Nuget + class MetadatumType < BaseObject + graphql_name 'NugetMetadata' + description 'Nuget metadata' + + authorize :read_package + + field :id, ::Types::GlobalIDType[::Packages::Nuget::Metadatum], null: false, description: 'ID of the metadatum.' + field :license_url, GraphQL::STRING_TYPE, null: false, description: 'License URL of the Nuget package.' + field :project_url, GraphQL::STRING_TYPE, null: false, description: 'Project URL of the Nuget package.' + field :icon_url, GraphQL::STRING_TYPE, null: false, description: 'Icon URL of the Nuget package.' + end + end + end +end diff --git a/app/graphql/types/packages/package_group_sort_enum.rb b/app/graphql/types/packages/package_group_sort_enum.rb new file mode 100644 index 00000000000..70fb27ec0db --- /dev/null +++ b/app/graphql/types/packages/package_group_sort_enum.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Packages + class PackageGroupSortEnum < PackageSortEnum + graphql_name 'PackageGroupSort' + description 'Values for sorting group packages' + + # The following enums are not available till we enable the new Arel node: + # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58657#note_552632305 + # value 'PROJECT_PATH_DESC', 'Project by descending order.', value: :project_path_desc + # value 'PROJECT_PATH_ASC', 'Project by ascending order.', value: :project_path_asc + end + end +end diff --git a/app/graphql/types/packages/package_sort_enum.rb b/app/graphql/types/packages/package_sort_enum.rb new file mode 100644 index 00000000000..ee14cf7a9e6 --- /dev/null +++ b/app/graphql/types/packages/package_sort_enum.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Types + module Packages + class PackageSortEnum < BaseEnum + graphql_name 'PackageSort' + description 'Values for sorting package' + + value 'CREATED_DESC', 'Ordered by created_at in descending order.', value: :created_desc + value 'CREATED_ASC', 'Ordered by created_at in ascending order.', value: :created_asc + value 'NAME_DESC', 'Ordered by name in descending order.', value: :name_desc + value 'NAME_ASC', 'Ordered by name in ascending order.', value: :name_asc + value 'VERSION_DESC', 'Ordered by version in descending order.', value: :version_desc + value 'VERSION_ASC', 'Ordered by version in ascending order.', value: :version_asc + value 'TYPE_DESC', 'Ordered by type in descending order.', value: :type_desc + value 'TYPE_ASC', 'Ordered by type in ascending order.', value: :type_asc + end + end +end diff --git a/app/graphql/types/packages/package_status_enum.rb b/app/graphql/types/packages/package_status_enum.rb new file mode 100644 index 00000000000..2e6ea5d0a50 --- /dev/null +++ b/app/graphql/types/packages/package_status_enum.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Types + module Packages + class PackageStatusEnum < BaseEnum + graphql_name 'PackageStatus' + + ::Packages::Package.statuses.keys.each do |status| + value status.to_s.upcase, description: "Packages with a #{status} status", value: status.to_s + end + end + end +end diff --git a/app/graphql/types/packages/package_type.rb b/app/graphql/types/packages/package_type.rb index a263ca1577a..b349b655fa5 100644 --- a/app/graphql/types/packages/package_type.rb +++ b/app/graphql/types/packages/package_type.rb @@ -25,6 +25,7 @@ module Types field :versions, ::Types::Packages::PackageType.connection_type, null: true, description: 'The other versions of the package.', deprecated: { reason: 'This field is now only returned in the PackageDetailsType', milestone: '13.11' } + field :status, Types::Packages::PackageStatusEnum, null: false, description: 'Package status.' def project Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find @@ -44,6 +45,10 @@ module Types object.composer_metadatum when 'conan' object.conan_metadatum + when 'maven' + object.maven_metadatum + when 'nuget' + object.nuget_metadatum else nil end diff --git a/app/graphql/types/packages/package_type_enum.rb b/app/graphql/types/packages/package_type_enum.rb index e2b5cf3163e..17145d8e000 100644 --- a/app/graphql/types/packages/package_type_enum.rb +++ b/app/graphql/types/packages/package_type_enum.rb @@ -5,12 +5,13 @@ module Types class PackageTypeEnum < BaseEnum PACKAGE_TYPE_NAMES = { pypi: 'PyPI', - npm: 'npm' + npm: 'npm', + terraform_module: 'Terraform Module' }.freeze ::Packages::Package.package_types.keys.each do |package_type| type_name = PACKAGE_TYPE_NAMES.fetch(package_type.to_sym, package_type.capitalize) - value package_type.to_s.upcase, "Packages from the #{type_name} package manager", value: package_type.to_s + value package_type.to_s.upcase, description: "Packages from the #{type_name} package manager", value: package_type.to_s end end end diff --git a/app/graphql/types/permission_types/ci/job.rb b/app/graphql/types/permission_types/ci/job.rb new file mode 100644 index 00000000000..c9a85317e67 --- /dev/null +++ b/app/graphql/types/permission_types/ci/job.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Types + module PermissionTypes + module Ci + class Job < BasePermissionType + graphql_name 'JobPermissions' + + abilities :read_job_artifacts, :read_build + ability_field :update_build, calls_gitaly: true + end + end + end +end diff --git a/app/graphql/types/permission_types/project.rb b/app/graphql/types/permission_types/project.rb index 5747e63d195..f6a5563d367 100644 --- a/app/graphql/types/permission_types/project.rb +++ b/app/graphql/types/permission_types/project.rb @@ -27,3 +27,5 @@ module Types end end end + +::Types::PermissionTypes::Project.prepend_mod_with('Types::PermissionTypes::Project') diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index 21534f40499..a2852588e89 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -30,8 +30,12 @@ module Types markdown_field :description_html, null: true field :tag_list, GraphQL::STRING_TYPE, null: true, + deprecated: { reason: 'Use `topics`', milestone: '13.12' }, description: 'List of project topics (not Git tags).' + field :topics, [GraphQL::STRING_TYPE], null: true, + description: 'List of project topics.' + field :ssh_url_to_repo, GraphQL::STRING_TYPE, null: true, description: 'URL to connect to the project via SSH.' field :http_url_to_repo, GraphQL::STRING_TYPE, null: true, @@ -180,14 +184,15 @@ module Types resolver: Resolvers::IssuesResolver.single field :packages, - description: 'Packages of the project.', - resolver: Resolvers::ProjectPackagesResolver + description: 'Packages of the project.', + resolver: Resolvers::ProjectPackagesResolver field :jobs, - Types::Ci::JobType.connection_type, - null: true, - description: 'Jobs of a project. This field can only be resolved for one project in any single request.', - resolver: Resolvers::ProjectJobsResolver + type: Types::Ci::JobType.connection_type, + null: true, + authorize: :read_commit_status, + description: 'Jobs of a project. This field can only be resolved for one project in any single request.', + resolver: Resolvers::ProjectJobsResolver field :pipelines, null: true, @@ -337,6 +342,10 @@ module Types description: 'Pipeline analytics.', resolver: Resolvers::ProjectPipelineStatisticsResolver + field :ci_template, Types::Ci::TemplateType, null: true, + description: 'Find a single CI/CD template by name.', + resolver: Resolvers::Ci::TemplateResolver + def label(title:) BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args| LabelsFinder @@ -386,4 +395,4 @@ module Types end end -Types::ProjectType.prepend_if_ee('::EE::Types::ProjectType') +Types::ProjectType.prepend_mod_with('Types::ProjectType') diff --git a/app/graphql/types/projects/service_type_enum.rb b/app/graphql/types/projects/service_type_enum.rb index fcb36fc233d..0a57cd48df4 100644 --- a/app/graphql/types/projects/service_type_enum.rb +++ b/app/graphql/types/projects/service_type_enum.rb @@ -5,7 +5,7 @@ module Types class ServiceTypeEnum < BaseEnum graphql_name 'ServiceType' - ::Service.available_services_types(include_dev: false).each do |service_type| + ::Integration.available_services_types(include_dev: false).each do |service_type| value service_type.underscore.upcase, value: service_type, description: "#{service_type} type" end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 8af0db644dd..8b7b9f0107b 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -79,8 +79,14 @@ module Types 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 :merge_request, Types::MergeRequestType, + null: true, + description: 'Find a merge request.' do + argument :id, ::Types::GlobalIDType[::MergeRequest], required: true, description: 'The global ID of the merge request.' end field :instance_statistics_measurements, @@ -106,6 +112,19 @@ module Types field :runner_platforms, resolver: Resolvers::Ci::RunnerPlatformsResolver field :runner_setup, resolver: Resolvers::Ci::RunnerSetupResolver + field :runner, Types::Ci::RunnerType, + null: true, + resolver: Resolvers::Ci::RunnerResolver, + extras: [:lookahead], + description: "Find a runner.", + feature_flag: :runner_graphql_query + + field :runners, Types::Ci::RunnerType.connection_type, + null: true, + resolver: Resolvers::Ci::RunnersResolver, + description: "Find runners visible to the current user.", + feature_flag: :runner_graphql_query + field :ci_config, resolver: Resolvers::Ci::ConfigResolver, complexity: 126 # AUTHENTICATED_COMPLEXITY / 2 + 1 def design_management @@ -119,6 +138,13 @@ module Types GitlabSchema.find_by_gid(id) end + def merge_request(id:) + # TODO: remove this line when the compatibility layer is removed + # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883 + id = ::Types::GlobalIDType[::MergeRequest].coerce_isolated_input(id) + GitlabSchema.find_by_gid(id) + end + def milestone(id:) # TODO: remove this line when the compatibility layer is removed # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883 @@ -147,4 +173,4 @@ module Types end end -Types::QueryType.prepend_if_ee('EE::Types::QueryType') +Types::QueryType.prepend_mod_with('Types::QueryType') diff --git a/app/graphql/types/release_assets_type.rb b/app/graphql/types/release_assets_type.rb index 79c132358e0..d847d9842d5 100644 --- a/app/graphql/types/release_assets_type.rb +++ b/app/graphql/types/release_assets_type.rb @@ -13,7 +13,7 @@ module Types field :count, GraphQL::INT_TYPE, null: true, method: :assets_count, description: 'Number of assets of the release.' - field :links, Types::ReleaseAssetLinkType.connection_type, null: true, + field :links, Types::ReleaseAssetLinkType.connection_type, null: true, method: :sorted_links, description: 'Asset links of the release.' field :sources, Types::ReleaseSourceType.connection_type, null: true, description: 'Sources of the release.' diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb index 912fc5f643a..8ed97d7e663 100644 --- a/app/graphql/types/repository/blob_type.rb +++ b/app/graphql/types/repository/blob_type.rb @@ -32,6 +32,66 @@ module Types field :web_path, GraphQL::STRING_TYPE, null: true, description: 'Web path of the blob.' + field :ide_edit_path, GraphQL::STRING_TYPE, null: true, + description: 'Web path to edit this blob in the Web IDE.' + + field :fork_and_edit_path, GraphQL::STRING_TYPE, null: true, + description: 'Web path to edit this blob using a forked project.' + + field :ide_fork_and_edit_path, GraphQL::STRING_TYPE, null: true, + description: 'Web path to edit this blob in the Web IDE using a forked project.' + + field :size, GraphQL::INT_TYPE, null: true, + description: 'Size (in bytes) of the blob.' + + field :raw_size, GraphQL::INT_TYPE, null: true, + description: 'Size (in bytes) of the blob, or the blob target if stored externally.' + + field :raw_blob, GraphQL::STRING_TYPE, null: true, method: :data, + description: 'The raw content of the blob.' + + field :raw_text_blob, GraphQL::STRING_TYPE, null: true, method: :text_only_data, + description: 'The raw content of the blob, if the blob is text data.' + + field :stored_externally, GraphQL::BOOLEAN_TYPE, null: true, method: :stored_externally?, + description: "Whether the blob's content is stored externally (for instance, in LFS)." + + field :edit_blob_path, GraphQL::STRING_TYPE, null: true, + description: 'Web path to edit the blob in the old-style editor.' + + field :raw_path, GraphQL::STRING_TYPE, null: true, + description: 'Web path to download the raw blob.' + + field :external_storage_url, GraphQL::STRING_TYPE, null: true, + description: 'Web path to download the raw blob via external storage, if enabled.' + + field :replace_path, GraphQL::STRING_TYPE, null: true, + description: 'Web path to replace the blob content.' + + field :file_type, GraphQL::STRING_TYPE, null: true, + description: 'The expected format of the blob based on the extension.' + + field :simple_viewer, type: Types::BlobViewerType, + description: 'Blob content simple viewer.', + null: false + + field :rich_viewer, type: Types::BlobViewerType, + description: 'Blob content rich viewer.', + null: true + + field :plain_data, GraphQL::STRING_TYPE, + description: 'Blob plain highlighted data.', + null: true, + calls_gitaly: true + + field :can_modify_blob, GraphQL::BOOLEAN_TYPE, null: true, method: :can_modify_blob?, + calls_gitaly: true, + description: 'Whether the current user can modify the blob.' + + def raw_text_blob + object.data unless object.binary? + end + def lfs_oid Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(object.repository, object.id).find end diff --git a/app/graphql/types/repository_type.rb b/app/graphql/types/repository_type.rb index 963a4296c4f..9d896888fa7 100644 --- a/app/graphql/types/repository_type.rb +++ b/app/graphql/types/repository_type.rb @@ -19,5 +19,9 @@ module Types field :branch_names, [GraphQL::STRING_TYPE], null: true, calls_gitaly: true, complexity: 170, description: 'Names of branches available in this repository that match the search pattern.', resolver: Resolvers::RepositoryBranchNamesResolver + field :disk_path, GraphQL::STRING_TYPE, + description: 'Shows a disk path of the repository.', + null: true, + authorize: :read_storage_disk_path end end diff --git a/app/graphql/types/snippets/blob_viewer_type.rb b/app/graphql/types/snippets/blob_viewer_type.rb index 9e77457c843..8b73234bbd9 100644 --- a/app/graphql/types/snippets/blob_viewer_type.rb +++ b/app/graphql/types/snippets/blob_viewer_type.rb @@ -2,48 +2,10 @@ module Types module Snippets - class BlobViewerType < BaseObject # rubocop:disable Graphql/AuthorizeTypes + # Kept to avoid changing the type of existing fields. New fields should use + # ::Types::BlobViewerType directly + class BlobViewerType < ::Types::BlobViewerType # rubocop:disable Graphql/AuthorizeTypes graphql_name 'SnippetBlobViewer' - description 'Represents how the blob content should be displayed' - - field :type, Types::BlobViewers::TypeEnum, - description: 'Type of blob viewer.', - null: false - - field :load_async, GraphQL::BOOLEAN_TYPE, - 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.', - method: :collapsed?, - null: false - - field :too_large, GraphQL::BOOLEAN_TYPE, - 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.', - null: true - - field :file_type, GraphQL::STRING_TYPE, - description: 'Content file type.', - method: :partial_name, - null: false - - field :loading_partial_name, GraphQL::STRING_TYPE, - description: 'Loading partial name.', - null: false - - def collapsed - !!object&.collapsed? - end - - def too_large - !!object&.too_large? - end end end end diff --git a/app/graphql/types/snippets/type_enum.rb b/app/graphql/types/snippets/type_enum.rb index 243f05359db..0ddd73d278d 100644 --- a/app/graphql/types/snippets/type_enum.rb +++ b/app/graphql/types/snippets/type_enum.rb @@ -3,8 +3,8 @@ module Types module Snippets class TypeEnum < BaseEnum - value 'personal', value: 'personal' - value 'project', value: 'project' + value 'personal', description: 'Snippet created independent of any project.', value: 'personal' + value 'project', description: 'Snippet related to a specific project.', value: 'project' end end end diff --git a/app/graphql/types/subscription_type.rb b/app/graphql/types/subscription_type.rb new file mode 100644 index 00000000000..5356a998f0d --- /dev/null +++ b/app/graphql/types/subscription_type.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Types + class SubscriptionType < ::Types::BaseObject + graphql_name 'Subscription' + + field :issuable_assignees_updated, subscription: Subscriptions::IssuableUpdated, null: true, + description: 'Triggered when the assignees of an issuable are updated.' + end +end diff --git a/app/graphql/types/timelog_type.rb b/app/graphql/types/timelog_type.rb index 465e3c492bc..99a619f1b1d 100644 --- a/app/graphql/types/timelog_type.rb +++ b/app/graphql/types/timelog_type.rb @@ -26,6 +26,11 @@ module Types null: true, description: 'The issue that logged time was added to.' + field :merge_request, + Types::MergeRequestType, + null: true, + description: 'The merge request that logged time was added to.' + field :note, Types::Notes::NoteType, null: true, @@ -38,5 +43,9 @@ module Types def issue Gitlab::Graphql::Loaders::BatchModelLoader.new(Issue, object.issue_id).find end + + def spent_at + object.spent_at || object.created_at + end end end diff --git a/app/graphql/types/todo_target_enum.rb b/app/graphql/types/todo_target_enum.rb index ebf65e99936..ce61bc8a926 100644 --- a/app/graphql/types/todo_target_enum.rb +++ b/app/graphql/types/todo_target_enum.rb @@ -10,4 +10,4 @@ module Types end end -Types::TodoTargetEnum.prepend_if_ee('::EE::Types::TodoTargetEnum') +Types::TodoTargetEnum.prepend_mod_with('Types::TodoTargetEnum') diff --git a/app/graphql/types/tree/type_enum.rb b/app/graphql/types/tree/type_enum.rb index 6560d91e9e5..7acb83a2a8a 100644 --- a/app/graphql/types/tree/type_enum.rb +++ b/app/graphql/types/tree/type_enum.rb @@ -6,9 +6,9 @@ module Types graphql_name 'EntryType' description 'Type of a tree entry' - value 'tree', value: :tree - value 'blob', value: :blob - value 'commit', value: :commit + value 'tree', description: 'Directory tree type.', value: :tree + value 'blob', description: 'File tree type.', value: :blob + value 'commit', description: 'Commit tree type.', value: :commit end end end diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb new file mode 100644 index 00000000000..e5abc033155 --- /dev/null +++ b/app/graphql/types/user_interface.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +module Types + module UserInterface + include Types::BaseInterface + + graphql_name 'User' + description 'Representation of a GitLab user.' + + field :user_permissions, + type: Types::PermissionTypes::User, + description: 'Permissions for the current user on the resource.', + null: false, + method: :itself + + field :id, + type: GraphQL::ID_TYPE, + null: false, + description: 'ID of the user.' + field :bot, + type: GraphQL::BOOLEAN_TYPE, + null: false, + description: 'Indicates if the user is a bot.', + method: :bot? + field :username, + type: GraphQL::STRING_TYPE, + null: false, + description: 'Username of the user. Unique within this instance of GitLab.' + field :name, + type: GraphQL::STRING_TYPE, + null: false, + description: 'Human-readable name of the user.' + field :state, + type: Types::UserStateEnum, + null: false, + description: 'State of the user.' + field :email, + type: GraphQL::STRING_TYPE, + null: true, + description: 'User email.', method: :public_email, + deprecated: { reason: :renamed, replacement: 'User.publicEmail', milestone: '13.7' } + field :public_email, + type: GraphQL::STRING_TYPE, + null: true, + description: "User's public email." + field :avatar_url, + type: GraphQL::STRING_TYPE, + null: true, + description: "URL of the user's avatar." + field :web_url, + type: GraphQL::STRING_TYPE, + null: false, + description: 'Web URL of the user.' + field :web_path, + type: GraphQL::STRING_TYPE, + null: false, + description: 'Web path of the user.' + field :todos, + resolver: Resolvers::TodoResolver, + description: 'To-do items of the user.' + field :group_memberships, + type: Types::GroupMemberType.connection_type, + null: true, + description: 'Group memberships of the user.' + field :group_count, + resolver: Resolvers::Users::GroupCountResolver, + description: 'Group count for the user.' + field :status, + type: Types::UserStatusType, + null: true, + description: 'User status.' + field :location, + type: ::GraphQL::STRING_TYPE, + null: true, + description: 'The location of the user.' + field :project_memberships, + type: Types::ProjectMemberType.connection_type, + null: true, + description: 'Project memberships of the user.' + field :starred_projects, + 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.' + field :assigned_merge_requests, + resolver: Resolvers::AssignedMergeRequestsResolver, + description: 'Merge requests assigned to the user.' + field :review_requested_merge_requests, + resolver: Resolvers::ReviewRequestedMergeRequestsResolver, + description: 'Merge requests assigned to the user for review.' + + field :snippets, + description: 'Snippets authored by the user.', + resolver: Resolvers::Users::SnippetsResolver + field :callouts, + Types::UserCalloutType.connection_type, + null: true, + description: 'User callouts that belong to the user.' + + definition_methods do + def resolve_type(object, context) + # in the absense of other information, we cannot tell - just default to + # the core user type. + ::Types::UserType + end + end + end +end diff --git a/app/graphql/types/user_merge_request_interaction_type.rb b/app/graphql/types/user_merge_request_interaction_type.rb index 5ff0d79f13e..b9ff489e0d6 100644 --- a/app/graphql/types/user_merge_request_interaction_type.rb +++ b/app/graphql/types/user_merge_request_interaction_type.rb @@ -44,4 +44,4 @@ module Types end end -::Types::UserMergeRequestInteractionType.prepend_if_ee('EE::Types::UserMergeRequestInteractionType') +::Types::UserMergeRequestInteractionType.prepend_mod_with('Types::UserMergeRequestInteractionType') diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb index 3d7db80ae11..a6f5b7e7456 100644 --- a/app/graphql/types/user_type.rb +++ b/app/graphql/types/user_type.rb @@ -1,102 +1,13 @@ # frozen_string_literal: true module Types - class UserType < BaseObject - graphql_name 'User' - description 'Representation of a GitLab user.' + class UserType < ::Types::BaseObject + graphql_name 'UserCore' + description 'Core represention of a GitLab user.' + implements ::Types::UserInterface authorize :read_user present_using UserPresenter - - expose_permissions Types::PermissionTypes::User - - field :id, - type: GraphQL::ID_TYPE, - null: false, - description: 'ID of the user.' - field :bot, - type: GraphQL::BOOLEAN_TYPE, - null: false, - description: 'Indicates if the user is a bot.', - method: :bot? - field :username, - type: GraphQL::STRING_TYPE, - null: false, - description: 'Username of the user. Unique within this instance of GitLab.' - field :name, - type: GraphQL::STRING_TYPE, - null: false, - description: 'Human-readable name of the user.' - field :state, - type: Types::UserStateEnum, - null: false, - description: 'State of the user.' - field :email, - type: GraphQL::STRING_TYPE, - null: true, - description: 'User email.', method: :public_email, - deprecated: { reason: :renamed, replacement: 'User.publicEmail', milestone: '13.7' } - field :public_email, - type: GraphQL::STRING_TYPE, - null: true, - description: "User's public email." - field :avatar_url, - type: GraphQL::STRING_TYPE, - null: true, - description: "URL of the user's avatar." - field :web_url, - type: GraphQL::STRING_TYPE, - null: false, - description: 'Web URL of the user.' - field :web_path, - type: GraphQL::STRING_TYPE, - null: false, - description: 'Web path of the user.' - field :todos, - resolver: Resolvers::TodoResolver, - description: 'To-do items of the user.' - field :group_memberships, - type: Types::GroupMemberType.connection_type, - null: true, - description: 'Group memberships of the user.' - field :group_count, - resolver: Resolvers::Users::GroupCountResolver, - description: 'Group count for the user.', - feature_flag: :user_group_counts - field :status, - type: Types::UserStatusType, - null: true, - description: 'User status.' - field :location, - type: ::GraphQL::STRING_TYPE, - null: true, - description: 'The location of the user.' - field :project_memberships, - type: Types::ProjectMemberType.connection_type, - null: true, - description: 'Project memberships of the user.' - field :starred_projects, - 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.' - field :assigned_merge_requests, - resolver: Resolvers::AssignedMergeRequestsResolver, - description: 'Merge requests assigned to the user.' - field :review_requested_merge_requests, - resolver: Resolvers::ReviewRequestedMergeRequestsResolver, - description: 'Merge requests assigned to the user for review.' - - field :snippets, - description: 'Snippets authored by the user.', - resolver: Resolvers::Users::SnippetsResolver - field :callouts, - Types::UserCalloutType.connection_type, - null: true, - description: 'User callouts that belong to the user.' end end |