Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-19 18:44:42 +0300
commit4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch)
tree5423a1c7516cffe36384133ade12572cf709398d /app/graphql
parente570267f2f6b326480d284e0164a6464ba4081bc (diff)
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'app/graphql')
-rw-r--r--app/graphql/gitlab_schema.rb4
-rw-r--r--app/graphql/graphql_triggers.rb7
-rw-r--r--app/graphql/mutations/alert_management/http_integration/create.rb2
-rw-r--r--app/graphql/mutations/alert_management/http_integration/http_integration_base.rb2
-rw-r--r--app/graphql/mutations/alert_management/http_integration/update.rb2
-rw-r--r--app/graphql/mutations/boards/create.rb2
-rw-r--r--app/graphql/mutations/boards/issues/issue_move_list.rb2
-rw-r--r--app/graphql/mutations/boards/lists/base_update.rb40
-rw-r--r--app/graphql/mutations/boards/lists/create.rb2
-rw-r--r--app/graphql/mutations/boards/lists/update.rb22
-rw-r--r--app/graphql/mutations/boards/update.rb2
-rw-r--r--app/graphql/mutations/ci/ci_cd_settings_update.rb2
-rw-r--r--app/graphql/mutations/ci/job/base.rb22
-rw-r--r--app/graphql/mutations/ci/job/play.rb29
-rw-r--r--app/graphql/mutations/ci/job/retry.rb29
-rw-r--r--app/graphql/mutations/commits/create.rb11
-rw-r--r--app/graphql/mutations/concerns/mutations/assignable.rb6
-rw-r--r--app/graphql/mutations/concerns/mutations/resolves_issuable.rb2
-rw-r--r--app/graphql/mutations/issues/common_mutation_arguments.rb5
-rw-r--r--app/graphql/mutations/issues/create.rb4
-rw-r--r--app/graphql/mutations/issues/move.rb2
-rw-r--r--app/graphql/mutations/issues/set_confidential.rb2
-rw-r--r--app/graphql/mutations/issues/set_due_date.rb15
-rw-r--r--app/graphql/mutations/issues/set_locked.rb2
-rw-r--r--app/graphql/mutations/issues/set_severity.rb2
-rw-r--r--app/graphql/mutations/issues/update.rb4
-rw-r--r--app/graphql/mutations/labels/create.rb13
-rw-r--r--app/graphql/mutations/merge_requests/accept.rb2
-rw-r--r--app/graphql/mutations/merge_requests/create.rb2
-rw-r--r--app/graphql/mutations/merge_requests/reviewer_rereview.rb2
-rw-r--r--app/graphql/mutations/merge_requests/set_draft.rb35
-rw-r--r--app/graphql/mutations/merge_requests/set_labels.rb6
-rw-r--r--app/graphql/mutations/merge_requests/set_locked.rb4
-rw-r--r--app/graphql/mutations/merge_requests/set_milestone.rb4
-rw-r--r--app/graphql/mutations/merge_requests/set_wip.rb2
-rw-r--r--app/graphql/mutations/merge_requests/update.rb2
-rw-r--r--app/graphql/mutations/namespace/package_settings/update.rb10
-rw-r--r--app/graphql/mutations/security/ci_configuration/configure_sast.rb17
-rw-r--r--app/graphql/mutations/security/ci_configuration/configure_secret_detection.rb48
-rw-r--r--app/graphql/queries/burndown_chart/burnup.query.graphql70
-rw-r--r--app/graphql/queries/epic/epic_children.query.graphql4
-rw-r--r--app/graphql/queries/pipelines/get_pipeline_details.query.graphql1
-rw-r--r--app/graphql/resolvers/ci/runner_resolver.rb36
-rw-r--r--app/graphql/resolvers/ci/runners_resolver.rb43
-rw-r--r--app/graphql/resolvers/ci/template_resolver.rb18
-rw-r--r--app/graphql/resolvers/concerns/board_issue_filterable.rb2
-rw-r--r--app/graphql/resolvers/concerns/issue_resolver_arguments.rb70
-rw-r--r--app/graphql/resolvers/design_management/versions_resolver.rb1
-rw-r--r--app/graphql/resolvers/environments_resolver.rb4
-rw-r--r--app/graphql/resolvers/group_packages_resolver.rb26
-rw-r--r--app/graphql/resolvers/issues_resolver.rb2
-rw-r--r--app/graphql/resolvers/namespace_projects_resolver.rb2
-rw-r--r--app/graphql/resolvers/packages_base_resolver.rb53
-rw-r--r--app/graphql/resolvers/project_packages_resolver.rb16
-rw-r--r--app/graphql/resolvers/projects/services_resolver.rb2
-rw-r--r--app/graphql/resolvers/release_resolver.rb2
-rw-r--r--app/graphql/resolvers/releases_resolver.rb2
-rw-r--r--app/graphql/resolvers/repository_branch_names_resolver.rb12
-rw-r--r--app/graphql/subscriptions/base_subscription.rb31
-rw-r--r--app/graphql/subscriptions/issuable_updated.rb29
-rw-r--r--app/graphql/types/access_level_enum.rb14
-rw-r--r--app/graphql/types/alert_management/http_integration_type.rb2
-rw-r--r--app/graphql/types/alert_management/status_enum.rb2
-rw-r--r--app/graphql/types/base_argument.rb3
-rw-r--r--app/graphql/types/base_enum.rb4
-rw-r--r--app/graphql/types/base_field.rb3
-rw-r--r--app/graphql/types/blob_viewer_type.rb47
-rw-r--r--app/graphql/types/board_list_type.rb2
-rw-r--r--app/graphql/types/board_type.rb2
-rw-r--r--app/graphql/types/boards/board_issue_input_base_type.rb6
-rw-r--r--app/graphql/types/boards/board_issue_input_type.rb7
-rw-r--r--app/graphql/types/boards/negated_board_issue_input_type.rb2
-rw-r--r--app/graphql/types/ci/code_quality_degradation_severity_enum.rb15
-rw-r--r--app/graphql/types/ci/job_type.rb30
-rw-r--r--app/graphql/types/ci/pipeline_status_enum.rb2
-rw-r--r--app/graphql/types/ci/pipeline_type.rb24
-rw-r--r--app/graphql/types/ci/runner_access_level_enum.rb15
-rw-r--r--app/graphql/types/ci/runner_sort_enum.rb13
-rw-r--r--app/graphql/types/ci/runner_status_enum.rb15
-rw-r--r--app/graphql/types/ci/runner_type.rb42
-rw-r--r--app/graphql/types/ci/runner_type_enum.rb15
-rw-r--r--app/graphql/types/ci/stage_type.rb55
-rw-r--r--app/graphql/types/ci/template_type.rb16
-rw-r--r--app/graphql/types/container_expiration_policy_cadence_enum.rb2
-rw-r--r--app/graphql/types/container_expiration_policy_keep_enum.rb2
-rw-r--r--app/graphql/types/container_expiration_policy_older_than_enum.rb2
-rw-r--r--app/graphql/types/design_management/version_type.rb4
-rw-r--r--app/graphql/types/duration_type.rb29
-rw-r--r--app/graphql/types/group_member_relation_enum.rb2
-rw-r--r--app/graphql/types/group_type.rb4
-rw-r--r--app/graphql/types/issuable_type.rb23
-rw-r--r--app/graphql/types/issue_connection_type.rb2
-rw-r--r--app/graphql/types/issue_sort_enum.rb2
-rw-r--r--app/graphql/types/issue_type.rb2
-rw-r--r--app/graphql/types/issues/negated_issue_filter_input_type.rb2
-rw-r--r--app/graphql/types/label_type.rb2
-rw-r--r--app/graphql/types/merge_request_type.rb10
-rw-r--r--app/graphql/types/merge_requests/assignee_type.rb14
-rw-r--r--app/graphql/types/merge_requests/interacts_with_merge_request.rb24
-rw-r--r--app/graphql/types/merge_requests/reviewer_type.rb16
-rw-r--r--app/graphql/types/metadata/kas_type.rb18
-rw-r--r--app/graphql/types/metadata_type.rb2
-rw-r--r--app/graphql/types/milestone_type.rb4
-rw-r--r--app/graphql/types/mutation_type.rb10
-rw-r--r--app/graphql/types/namespace/package_settings_type.rb2
-rw-r--r--app/graphql/types/namespace_type.rb2
-rw-r--r--app/graphql/types/notes/noteable_type.rb2
-rw-r--r--app/graphql/types/notes/position_type_enum.rb4
-rw-r--r--app/graphql/types/packages/maven/metadatum_type.rb22
-rw-r--r--app/graphql/types/packages/metadata_type.rb6
-rw-r--r--app/graphql/types/packages/nuget/metadatum_type.rb19
-rw-r--r--app/graphql/types/packages/package_group_sort_enum.rb15
-rw-r--r--app/graphql/types/packages/package_sort_enum.rb19
-rw-r--r--app/graphql/types/packages/package_status_enum.rb13
-rw-r--r--app/graphql/types/packages/package_type.rb5
-rw-r--r--app/graphql/types/packages/package_type_enum.rb5
-rw-r--r--app/graphql/types/permission_types/ci/job.rb14
-rw-r--r--app/graphql/types/permission_types/project.rb2
-rw-r--r--app/graphql/types/project_type.rb23
-rw-r--r--app/graphql/types/projects/service_type_enum.rb2
-rw-r--r--app/graphql/types/query_type.rb32
-rw-r--r--app/graphql/types/release_assets_type.rb2
-rw-r--r--app/graphql/types/repository/blob_type.rb60
-rw-r--r--app/graphql/types/repository_type.rb4
-rw-r--r--app/graphql/types/snippets/blob_viewer_type.rb44
-rw-r--r--app/graphql/types/snippets/type_enum.rb4
-rw-r--r--app/graphql/types/subscription_type.rb10
-rw-r--r--app/graphql/types/timelog_type.rb9
-rw-r--r--app/graphql/types/todo_target_enum.rb2
-rw-r--r--app/graphql/types/tree/type_enum.rb6
-rw-r--r--app/graphql/types/user_interface.rb111
-rw-r--r--app/graphql/types/user_merge_request_interaction_type.rb2
-rw-r--r--app/graphql/types/user_type.rb97
133 files changed, 1461 insertions, 386 deletions
diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb
index 8369d0e120f..84941fcde02 100644
--- a/app/graphql/gitlab_schema.rb
+++ b/app/graphql/gitlab_schema.rb
@@ -10,6 +10,7 @@ class GitlabSchema < GraphQL::Schema
DEFAULT_MAX_DEPTH = 15
AUTHENTICATED_MAX_DEPTH = 20
+ use GraphQL::Subscriptions::ActionCableSubscriptions
use GraphQL::Pagination::Connections
use BatchLoader::GraphQL
use Gitlab::Graphql::Pagination::Connections
@@ -24,6 +25,7 @@ class GitlabSchema < GraphQL::Schema
query Types::QueryType
mutation Types::MutationType
+ subscription Types::SubscriptionType
default_max_page_size 100
@@ -168,7 +170,7 @@ class GitlabSchema < GraphQL::Schema
end
end
-GitlabSchema.prepend_if_ee('EE::GitlabSchema') # rubocop: disable Cop/InjectEnterpriseEditionModule
+GitlabSchema.prepend_mod_with('GitlabSchema') # rubocop: disable Cop/InjectEnterpriseEditionModule
# Force the schema to load as a workaround for intermittent errors we
# see due to a lack of thread safety.
diff --git a/app/graphql/graphql_triggers.rb b/app/graphql/graphql_triggers.rb
new file mode 100644
index 00000000000..671c7c2cd25
--- /dev/null
+++ b/app/graphql/graphql_triggers.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module GraphqlTriggers
+ def self.issuable_assignees_updated(issuable)
+ GitlabSchema.subscriptions.trigger('issuableAssigneesUpdated', { issuable_id: issuable.to_gid }, issuable)
+ end
+end
diff --git a/app/graphql/mutations/alert_management/http_integration/create.rb b/app/graphql/mutations/alert_management/http_integration/create.rb
index 2d7bffb4333..54803855bcf 100644
--- a/app/graphql/mutations/alert_management/http_integration/create.rb
+++ b/app/graphql/mutations/alert_management/http_integration/create.rb
@@ -34,4 +34,4 @@ module Mutations
end
end
-Mutations::AlertManagement::HttpIntegration::Create.prepend_if_ee('::EE::Mutations::AlertManagement::HttpIntegration::Create')
+Mutations::AlertManagement::HttpIntegration::Create.prepend_mod_with('Mutations::AlertManagement::HttpIntegration::Create')
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 e33b7bb399a..efa92bfe895 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
@@ -33,4 +33,4 @@ module Mutations
end
end
-Mutations::AlertManagement::HttpIntegration::HttpIntegrationBase.prepend_if_ee('::EE::Mutations::AlertManagement::HttpIntegration::HttpIntegrationBase')
+Mutations::AlertManagement::HttpIntegration::HttpIntegrationBase.prepend_mod_with('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 b1e4ce841ee..4e6e7995c10 100644
--- a/app/graphql/mutations/alert_management/http_integration/update.rb
+++ b/app/graphql/mutations/alert_management/http_integration/update.rb
@@ -32,4 +32,4 @@ module Mutations
end
end
-Mutations::AlertManagement::HttpIntegration::Update.prepend_if_ee('::EE::Mutations::AlertManagement::HttpIntegration::Update')
+Mutations::AlertManagement::HttpIntegration::Update.prepend_mod_with('Mutations::AlertManagement::HttpIntegration::Update')
diff --git a/app/graphql/mutations/boards/create.rb b/app/graphql/mutations/boards/create.rb
index 003c4f7761b..44fc22cf883 100644
--- a/app/graphql/mutations/boards/create.rb
+++ b/app/graphql/mutations/boards/create.rb
@@ -30,4 +30,4 @@ module Mutations
end
end
-Mutations::Boards::Create.prepend_if_ee('::EE::Mutations::Boards::Create')
+Mutations::Boards::Create.prepend_mod_with('Mutations::Boards::Create')
diff --git a/app/graphql/mutations/boards/issues/issue_move_list.rb b/app/graphql/mutations/boards/issues/issue_move_list.rb
index f32205643da..4c9752c6343 100644
--- a/app/graphql/mutations/boards/issues/issue_move_list.rb
+++ b/app/graphql/mutations/boards/issues/issue_move_list.rb
@@ -86,4 +86,4 @@ module Mutations
end
end
-Mutations::Boards::Issues::IssueMoveList.prepend_if_ee('EE::Mutations::Boards::Issues::IssueMoveList')
+Mutations::Boards::Issues::IssueMoveList.prepend_mod_with('Mutations::Boards::Issues::IssueMoveList')
diff --git a/app/graphql/mutations/boards/lists/base_update.rb b/app/graphql/mutations/boards/lists/base_update.rb
new file mode 100644
index 00000000000..b06cb3b1e32
--- /dev/null
+++ b/app/graphql/mutations/boards/lists/base_update.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Boards
+ module Lists
+ class BaseUpdate < BaseMutation
+ argument :position, GraphQL::INT_TYPE,
+ required: false,
+ description: 'Position of list within the board.'
+
+ argument :collapsed, GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: 'Indicates if the list is collapsed for this user.'
+
+ def resolve(list: nil, **args)
+ if list.nil? || !can_read_list?(list)
+ raise_resource_not_available_error!
+ end
+
+ update_result = update_list(list, args)
+
+ {
+ list: update_result.payload[:list],
+ errors: update_result.errors
+ }
+ end
+
+ private
+
+ def update_list(list, args)
+ raise NotImplementedError
+ end
+
+ def can_read_list?(list)
+ raise NotImplementedError
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/boards/lists/create.rb b/app/graphql/mutations/boards/lists/create.rb
index 673fa95fc56..590a905ab7b 100644
--- a/app/graphql/mutations/boards/lists/create.rb
+++ b/app/graphql/mutations/boards/lists/create.rb
@@ -34,4 +34,4 @@ module Mutations
end
end
-Mutations::Boards::Lists::Create.prepend_if_ee('::EE::Mutations::Boards::Lists::Create')
+Mutations::Boards::Lists::Create.prepend_mod_with('Mutations::Boards::Lists::Create')
diff --git a/app/graphql/mutations/boards/lists/update.rb b/app/graphql/mutations/boards/lists/update.rb
index 504082ec22c..d17dd5162a0 100644
--- a/app/graphql/mutations/boards/lists/update.rb
+++ b/app/graphql/mutations/boards/lists/update.rb
@@ -3,7 +3,7 @@
module Mutations
module Boards
module Lists
- class Update < BaseMutation
+ class Update < BaseUpdate
graphql_name 'UpdateBoardList'
argument :list_id, Types::GlobalIDType[List],
@@ -11,29 +11,11 @@ module Mutations
loads: Types::BoardListType,
description: 'Global ID of the list.'
- argument :position, GraphQL::INT_TYPE,
- required: false,
- description: 'Position of list within the board.'
-
- argument :collapsed, GraphQL::BOOLEAN_TYPE,
- required: false,
- description: 'Indicates if the list is collapsed for this user.'
-
field :list,
Types::BoardListType,
null: true,
description: 'Mutated list.'
- def resolve(list: nil, **args)
- raise_resource_not_available_error! unless can_read_list?(list)
- update_result = update_list(list, args)
-
- {
- list: update_result[:list],
- errors: list.errors.full_messages
- }
- end
-
private
def update_list(list, args)
@@ -42,8 +24,6 @@ module Mutations
end
def can_read_list?(list)
- return false unless list.present?
-
Ability.allowed?(current_user, :read_issue_board_list, list.board)
end
end
diff --git a/app/graphql/mutations/boards/update.rb b/app/graphql/mutations/boards/update.rb
index 628b3a3fadb..f1a1d57306b 100644
--- a/app/graphql/mutations/boards/update.rb
+++ b/app/graphql/mutations/boards/update.rb
@@ -42,4 +42,4 @@ module Mutations
end
end
-Mutations::Boards::Update.prepend_if_ee('::EE::Mutations::Boards::Update')
+Mutations::Boards::Update.prepend_mod_with('Mutations::Boards::Update')
diff --git a/app/graphql/mutations/ci/ci_cd_settings_update.rb b/app/graphql/mutations/ci/ci_cd_settings_update.rb
index d7451babaea..a484c2438a4 100644
--- a/app/graphql/mutations/ci/ci_cd_settings_update.rb
+++ b/app/graphql/mutations/ci/ci_cd_settings_update.rb
@@ -36,4 +36,4 @@ module Mutations
end
end
-Mutations::Ci::CiCdSettingsUpdate.prepend_if_ee('::EE::Mutations::Ci::CiCdSettingsUpdate')
+Mutations::Ci::CiCdSettingsUpdate.prepend_mod_with('Mutations::Ci::CiCdSettingsUpdate')
diff --git a/app/graphql/mutations/ci/job/base.rb b/app/graphql/mutations/ci/job/base.rb
new file mode 100644
index 00000000000..3359def159a
--- /dev/null
+++ b/app/graphql/mutations/ci/job/base.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Ci
+ module Job
+ class Base < BaseMutation
+ JobID = ::Types::GlobalIDType[::Ci::Build]
+
+ argument :id, JobID,
+ required: true,
+ description: 'The ID of the job to mutate.'
+
+ def find_object(id: )
+ # TODO: remove this line when the compatibility layer is removed
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ id = JobID.coerce_isolated_input(id)
+ GlobalID::Locator.locate(id)
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/ci/job/play.rb b/app/graphql/mutations/ci/job/play.rb
new file mode 100644
index 00000000000..f87904f8b25
--- /dev/null
+++ b/app/graphql/mutations/ci/job/play.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Ci
+ module Job
+ class Play < Base
+ graphql_name 'JobPlay'
+
+ field :job,
+ Types::Ci::JobType,
+ null: true,
+ description: 'The job after the mutation.'
+
+ authorize :update_build
+
+ def resolve(id:)
+ job = authorized_find!(id: id)
+ project = job.project
+
+ ::Ci::PlayBuildService.new(project, current_user).execute(job)
+ {
+ job: job,
+ errors: errors_on_object(job)
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/ci/job/retry.rb b/app/graphql/mutations/ci/job/retry.rb
new file mode 100644
index 00000000000..a61d5dddb40
--- /dev/null
+++ b/app/graphql/mutations/ci/job/retry.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Ci
+ module Job
+ class Retry < Base
+ graphql_name 'JobRetry'
+
+ field :job,
+ Types::Ci::JobType,
+ null: true,
+ description: 'The job after the mutation.'
+
+ authorize :update_build
+
+ def resolve(id:)
+ job = authorized_find!(id: id)
+ project = job.project
+
+ ::Ci::RetryBuildService.new(project, current_user).execute(job)
+ {
+ job: job,
+ errors: errors_on_object(job)
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/commits/create.rb b/app/graphql/mutations/commits/create.rb
index 84933fee5d2..2e06e1ea0c4 100644
--- a/app/graphql/mutations/commits/create.rb
+++ b/app/graphql/mutations/commits/create.rb
@@ -5,6 +5,11 @@ module Mutations
class Create < BaseMutation
include FindsProject
+ class UrlHelpers
+ include GitlabRoutingHelper
+ include Gitlab::Routing
+ end
+
graphql_name 'CommitCreate'
argument :project_path, GraphQL::ID_TYPE,
@@ -29,6 +34,11 @@ module Mutations
required: true,
description: 'Array of action hashes to commit as a batch.'
+ field :commit_pipeline_path,
+ GraphQL::STRING_TYPE,
+ null: true,
+ description: "ETag path for the commit's pipeline."
+
field :commit,
Types::CommitType,
null: true,
@@ -50,6 +60,7 @@ module Mutations
{
commit: (project.repository.commit(result[:result]) if result[:status] == :success),
+ commit_pipeline_path: UrlHelpers.new.graphql_etag_pipeline_sha_path(result[:result]),
errors: Array.wrap(result[:message])
}
end
diff --git a/app/graphql/mutations/concerns/mutations/assignable.rb b/app/graphql/mutations/concerns/mutations/assignable.rb
index d3ab0a1779a..e214a57500c 100644
--- a/app/graphql/mutations/concerns/mutations/assignable.rb
+++ b/app/graphql/mutations/concerns/mutations/assignable.rb
@@ -33,9 +33,9 @@ module Mutations
def assign!(resource, users, operation_mode)
update_service_class.new(
- resource.project,
- current_user,
- assignee_ids: assignee_ids(resource, users, operation_mode)
+ project: resource.project,
+ current_user: current_user,
+ params: { assignee_ids: assignee_ids(resource, users, operation_mode) }
).execute(resource)
end
diff --git a/app/graphql/mutations/concerns/mutations/resolves_issuable.rb b/app/graphql/mutations/concerns/mutations/resolves_issuable.rb
index 0fe2d09de6d..fd9031d3ea7 100644
--- a/app/graphql/mutations/concerns/mutations/resolves_issuable.rb
+++ b/app/graphql/mutations/concerns/mutations/resolves_issuable.rb
@@ -38,4 +38,4 @@ module Mutations
end
end
-Mutations::ResolvesIssuable.prepend_if_ee('::EE::Mutations::ResolvesIssuable')
+Mutations::ResolvesIssuable.prepend_mod_with('Mutations::ResolvesIssuable')
diff --git a/app/graphql/mutations/issues/common_mutation_arguments.rb b/app/graphql/mutations/issues/common_mutation_arguments.rb
index 4b5b246281f..65768b85d14 100644
--- a/app/graphql/mutations/issues/common_mutation_arguments.rb
+++ b/app/graphql/mutations/issues/common_mutation_arguments.rb
@@ -22,6 +22,11 @@ module Mutations
as: :discussion_locked,
required: false,
description: copy_field_description(Types::IssueType, :discussion_locked)
+
+ argument :type, Types::IssueTypeEnum,
+ as: :issue_type,
+ required: false,
+ description: copy_field_description(Types::IssueType, :type)
end
end
end
diff --git a/app/graphql/mutations/issues/create.rb b/app/graphql/mutations/issues/create.rb
index 37fddd92832..3a57e2434a5 100644
--- a/app/graphql/mutations/issues/create.rb
+++ b/app/graphql/mutations/issues/create.rb
@@ -73,7 +73,7 @@ module Mutations
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
+ issue = ::Issues::CreateService.new(project: project, current_user: current_user, params: params).execute
if issue.spam?
issue.errors.add(:base, 'Spam detected.')
@@ -102,4 +102,4 @@ module Mutations
end
end
-Mutations::Issues::Create.prepend_if_ee('::EE::Mutations::Issues::Create')
+Mutations::Issues::Create.prepend_mod_with('Mutations::Issues::Create')
diff --git a/app/graphql/mutations/issues/move.rb b/app/graphql/mutations/issues/move.rb
index 0f2af99bf61..cb4f0f42b38 100644
--- a/app/graphql/mutations/issues/move.rb
+++ b/app/graphql/mutations/issues/move.rb
@@ -18,7 +18,7 @@ module Mutations
target_project = resolve_project(full_path: target_project_path).sync
begin
- moved_issue = ::Issues::MoveService.new(source_project, current_user).execute(issue, target_project)
+ moved_issue = ::Issues::MoveService.new(project: source_project, current_user: current_user).execute(issue, target_project)
rescue ::Issues::MoveService::MoveError => error
errors = error.message
end
diff --git a/app/graphql/mutations/issues/set_confidential.rb b/app/graphql/mutations/issues/set_confidential.rb
index 75befddc261..8e88b31d9ed 100644
--- a/app/graphql/mutations/issues/set_confidential.rb
+++ b/app/graphql/mutations/issues/set_confidential.rb
@@ -14,7 +14,7 @@ module Mutations
issue = authorized_find!(project_path: project_path, iid: iid)
project = issue.project
- ::Issues::UpdateService.new(project, current_user, confidential: confidential)
+ ::Issues::UpdateService.new(project: project, current_user: current_user, params: { confidential: confidential })
.execute(issue)
{
diff --git a/app/graphql/mutations/issues/set_due_date.rb b/app/graphql/mutations/issues/set_due_date.rb
index da7892f4ed4..9cefac96b25 100644
--- a/app/graphql/mutations/issues/set_due_date.rb
+++ b/app/graphql/mutations/issues/set_due_date.rb
@@ -7,14 +7,23 @@ module Mutations
argument :due_date,
Types::TimeType,
- required: true,
- description: 'The desired due date for the issue.'
+ required: false,
+ description: 'The desired due date for the issue, ' \
+ 'due date will be removed if absent or set to null'
+
+ def ready?(**args)
+ unless args.key?(:due_date)
+ raise Gitlab::Graphql::Errors::ArgumentError, 'Argument dueDate must be provided (`null` accepted)'
+ end
+
+ super
+ end
def resolve(project_path:, iid:, due_date:)
issue = authorized_find!(project_path: project_path, iid: iid)
project = issue.project
- ::Issues::UpdateService.new(project, current_user, due_date: due_date)
+ ::Issues::UpdateService.new(project: project, current_user: current_user, params: { due_date: due_date })
.execute(issue)
{
diff --git a/app/graphql/mutations/issues/set_locked.rb b/app/graphql/mutations/issues/set_locked.rb
index 611226e48ad..3a696a64dad 100644
--- a/app/graphql/mutations/issues/set_locked.rb
+++ b/app/graphql/mutations/issues/set_locked.rb
@@ -13,7 +13,7 @@ module Mutations
def resolve(project_path:, iid:, locked:)
issue = authorized_find!(project_path: project_path, iid: iid)
- ::Issues::UpdateService.new(issue.project, current_user, discussion_locked: locked)
+ ::Issues::UpdateService.new(project: issue.project, current_user: current_user, params: { discussion_locked: locked })
.execute(issue)
{
diff --git a/app/graphql/mutations/issues/set_severity.rb b/app/graphql/mutations/issues/set_severity.rb
index bc386e07178..778563ba053 100644
--- a/app/graphql/mutations/issues/set_severity.rb
+++ b/app/graphql/mutations/issues/set_severity.rb
@@ -12,7 +12,7 @@ module Mutations
issue = authorized_find!(project_path: project_path, iid: iid)
project = issue.project
- ::Issues::UpdateService.new(project, current_user, severity: severity)
+ ::Issues::UpdateService.new(project: project, current_user: current_user, params: { severity: severity })
.execute(issue)
{
diff --git a/app/graphql/mutations/issues/update.rb b/app/graphql/mutations/issues/update.rb
index eea2cd49aa0..eb16b7b38d0 100644
--- a/app/graphql/mutations/issues/update.rb
+++ b/app/graphql/mutations/issues/update.rb
@@ -31,7 +31,7 @@ module Mutations
issue = authorized_find!(project_path: project_path, iid: iid)
project = issue.project
- ::Issues::UpdateService.new(project, current_user, args).execute(issue)
+ ::Issues::UpdateService.new(project: project, current_user: current_user, params: args).execute(issue)
{
issue: issue,
@@ -42,4 +42,4 @@ module Mutations
end
end
-Mutations::Issues::Update.prepend_if_ee('::EE::Mutations::Issues::Update')
+Mutations::Issues::Update.prepend_mod_with('Mutations::Issues::Update')
diff --git a/app/graphql/mutations/labels/create.rb b/app/graphql/mutations/labels/create.rb
index ccbd1c37cbf..4da628d53ea 100644
--- a/app/graphql/mutations/labels/create.rb
+++ b/app/graphql/mutations/labels/create.rb
@@ -20,10 +20,21 @@ module Mutations
required: false,
description: 'Description of the label.'
+ argument :remove_on_close, GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: copy_field_description(Types::LabelType, :remove_on_close)
+
argument :color, GraphQL::STRING_TYPE,
required: false,
default_value: Label::DEFAULT_COLOR,
- description: "The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the CSS color names in https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords."
+ see: {
+ 'List of color keywords at mozilla.org' =>
+ 'https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords'
+ },
+ description: <<~DESC
+ The color of the label given in 6-digit hex notation with leading '#' sign
+ (for example, `#FFAABB`) or one of the CSS color names.
+ DESC
authorize :admin_label
diff --git a/app/graphql/mutations/merge_requests/accept.rb b/app/graphql/mutations/merge_requests/accept.rb
index da94dcd8890..9994f793a01 100644
--- a/app/graphql/mutations/merge_requests/accept.rb
+++ b/app/graphql/mutations/merge_requests/accept.rb
@@ -47,7 +47,7 @@ module Mutations
merge_request = authorized_find!(project_path: project_path, iid: iid)
project = merge_request.target_project
merge_params = args.compact.with_indifferent_access
- merge_service = ::MergeRequests::MergeService.new(project, current_user, merge_params)
+ merge_service = ::MergeRequests::MergeService.new(project: project, current_user: current_user, params: merge_params)
if error = validate(merge_request, merge_service, merge_params)
return { merge_request: merge_request, errors: [error] }
diff --git a/app/graphql/mutations/merge_requests/create.rb b/app/graphql/mutations/merge_requests/create.rb
index 9ac8f70be95..4849c198677 100644
--- a/app/graphql/mutations/merge_requests/create.rb
+++ b/app/graphql/mutations/merge_requests/create.rb
@@ -42,7 +42,7 @@ module Mutations
project = authorized_find!(project_path)
params = attributes.merge(author_id: current_user.id)
- merge_request = ::MergeRequests::CreateService.new(project, current_user, params).execute
+ merge_request = ::MergeRequests::CreateService.new(project: project, current_user: current_user, params: params).execute
{
merge_request: merge_request.valid? ? merge_request : nil,
diff --git a/app/graphql/mutations/merge_requests/reviewer_rereview.rb b/app/graphql/mutations/merge_requests/reviewer_rereview.rb
index f6f4881654e..d1d5118e271 100644
--- a/app/graphql/mutations/merge_requests/reviewer_rereview.rb
+++ b/app/graphql/mutations/merge_requests/reviewer_rereview.rb
@@ -15,7 +15,7 @@ module Mutations
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)
+ result = ::MergeRequests::RequestReviewService.new(project: merge_request.project, current_user: current_user).execute(merge_request, user)
{
merge_request: merge_request,
diff --git a/app/graphql/mutations/merge_requests/set_draft.rb b/app/graphql/mutations/merge_requests/set_draft.rb
new file mode 100644
index 00000000000..80006c6f70e
--- /dev/null
+++ b/app/graphql/mutations/merge_requests/set_draft.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Mutations
+ module MergeRequests
+ class SetDraft < Base
+ graphql_name 'MergeRequestSetDraft'
+
+ argument :draft,
+ GraphQL::BOOLEAN_TYPE,
+ required: true,
+ description: <<~DESC
+ Whether or not to set the merge request as a draft.
+ DESC
+
+ def resolve(project_path:, iid:, draft: nil)
+ merge_request = authorized_find!(project_path: project_path, iid: iid)
+ project = merge_request.project
+
+ ::MergeRequests::UpdateService.new(project: project, current_user: current_user, params: { wip_event: wip_event(draft) })
+ .execute(merge_request)
+
+ {
+ merge_request: merge_request,
+ errors: errors_on_object(merge_request)
+ }
+ end
+
+ private
+
+ def wip_event(wip)
+ wip ? 'wip' : 'unwip'
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/merge_requests/set_labels.rb b/app/graphql/mutations/merge_requests/set_labels.rb
index 712c68c9425..a77c2731a05 100644
--- a/app/graphql/mutations/merge_requests/set_labels.rb
+++ b/app/graphql/mutations/merge_requests/set_labels.rb
@@ -9,14 +9,14 @@ module Mutations
[::Types::GlobalIDType[Label]],
required: true,
description: <<~DESC
- The Label IDs to set. Replaces existing labels by default.
+ The Label IDs to set. Replaces existing labels by default.
DESC
argument :operation_mode,
Types::MutationOperationModeEnum,
required: false,
description: <<~DESC
- Changes the operation mode. Defaults to REPLACE.
+ Changes the operation mode. Defaults to REPLACE.
DESC
def resolve(project_path:, iid:, label_ids:, operation_mode: Types::MutationOperationModeEnum.enum[:replace])
@@ -38,7 +38,7 @@ module Mutations
:label_ids
end
- ::MergeRequests::UpdateService.new(project, current_user, attribute_name => label_ids)
+ ::MergeRequests::UpdateService.new(project: project, current_user: current_user, params: { attribute_name => label_ids })
.execute(merge_request)
{
diff --git a/app/graphql/mutations/merge_requests/set_locked.rb b/app/graphql/mutations/merge_requests/set_locked.rb
index c49d5186a03..e9e607551a6 100644
--- a/app/graphql/mutations/merge_requests/set_locked.rb
+++ b/app/graphql/mutations/merge_requests/set_locked.rb
@@ -9,14 +9,14 @@ module Mutations
GraphQL::BOOLEAN_TYPE,
required: true,
description: <<~DESC
- Whether or not to lock the merge request.
+ Whether or not to lock the merge request.
DESC
def resolve(project_path:, iid:, locked:)
merge_request = authorized_find!(project_path: project_path, iid: iid)
project = merge_request.project
- ::MergeRequests::UpdateService.new(project, current_user, discussion_locked: locked)
+ ::MergeRequests::UpdateService.new(project: project, current_user: current_user, params: { discussion_locked: locked })
.execute(merge_request)
{
diff --git a/app/graphql/mutations/merge_requests/set_milestone.rb b/app/graphql/mutations/merge_requests/set_milestone.rb
index abcb1bda1f3..ed5139c4af9 100644
--- a/app/graphql/mutations/merge_requests/set_milestone.rb
+++ b/app/graphql/mutations/merge_requests/set_milestone.rb
@@ -10,14 +10,14 @@ module Mutations
required: false,
loads: Types::MilestoneType,
description: <<~DESC
- The milestone to assign to the merge request.
+ The milestone to assign to the merge request.
DESC
def resolve(project_path:, iid:, milestone: nil)
merge_request = authorized_find!(project_path: project_path, iid: iid)
project = merge_request.project
- ::MergeRequests::UpdateService.new(project, current_user, milestone: milestone)
+ ::MergeRequests::UpdateService.new(project: project, current_user: current_user, params: { milestone: milestone })
.execute(merge_request)
{
diff --git a/app/graphql/mutations/merge_requests/set_wip.rb b/app/graphql/mutations/merge_requests/set_wip.rb
index beb042ce93f..6f52b240840 100644
--- a/app/graphql/mutations/merge_requests/set_wip.rb
+++ b/app/graphql/mutations/merge_requests/set_wip.rb
@@ -16,7 +16,7 @@ module Mutations
merge_request = authorized_find!(project_path: project_path, iid: iid)
project = merge_request.project
- ::MergeRequests::UpdateService.new(project, current_user, wip_event: wip_event(merge_request, wip))
+ ::MergeRequests::UpdateService.new(project: project, current_user: current_user, params: { wip_event: wip_event(merge_request, wip) })
.execute(merge_request)
{
diff --git a/app/graphql/mutations/merge_requests/update.rb b/app/graphql/mutations/merge_requests/update.rb
index 6a94d2f37b2..246e468c34c 100644
--- a/app/graphql/mutations/merge_requests/update.rb
+++ b/app/graphql/mutations/merge_requests/update.rb
@@ -29,7 +29,7 @@ module Mutations
attributes = args.compact
::MergeRequests::UpdateService
- .new(merge_request.project, current_user, attributes)
+ .new(project: merge_request.project, current_user: current_user, params: attributes)
.execute(merge_request)
errors = errors_on_object(merge_request)
diff --git a/app/graphql/mutations/namespace/package_settings/update.rb b/app/graphql/mutations/namespace/package_settings/update.rb
index ca21c3418fc..75c80cfbd3e 100644
--- a/app/graphql/mutations/namespace/package_settings/update.rb
+++ b/app/graphql/mutations/namespace/package_settings/update.rb
@@ -25,6 +25,16 @@ module Mutations
required: false,
description: copy_field_description(Types::Namespace::PackageSettingsType, :maven_duplicate_exception_regex)
+ argument :generic_duplicates_allowed,
+ GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: copy_field_description(Types::Namespace::PackageSettingsType, :generic_duplicates_allowed)
+
+ argument :generic_duplicate_exception_regex,
+ Types::UntrustedRegexp,
+ required: false,
+ description: copy_field_description(Types::Namespace::PackageSettingsType, :generic_duplicate_exception_regex)
+
field :package_settings,
Types::Namespace::PackageSettingsType,
null: true,
diff --git a/app/graphql/mutations/security/ci_configuration/configure_sast.rb b/app/graphql/mutations/security/ci_configuration/configure_sast.rb
index e4a3f815396..237aff1f052 100644
--- a/app/graphql/mutations/security/ci_configuration/configure_sast.rb
+++ b/app/graphql/mutations/security/ci_configuration/configure_sast.rb
@@ -7,6 +7,11 @@ module Mutations
include FindsProject
graphql_name 'ConfigureSast'
+ description <<~DESC
+ Configure SAST for a project by enabling SAST in a new or modified
+ `.gitlab-ci.yml` file in a new branch. The new branch and a URL to
+ create a Merge Request are a part of the response.
+ DESC
argument :project_path, GraphQL::ID_TYPE,
required: true,
@@ -16,12 +21,12 @@ module Mutations
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.'
+ field :branch, GraphQL::STRING_TYPE, null: true,
+ description: 'Branch that has the new/modified `.gitlab-ci.yml` file.'
+
authorize :push_code
def resolve(project_path:, configuration:)
@@ -35,9 +40,9 @@ module Mutations
def prepare_response(result)
{
- status: result[:status],
- success_path: result[:success_path],
- errors: Array(result[:errors])
+ branch: result.payload[:branch],
+ success_path: result.payload[:success_path],
+ errors: result.errors
}
end
end
diff --git a/app/graphql/mutations/security/ci_configuration/configure_secret_detection.rb b/app/graphql/mutations/security/ci_configuration/configure_secret_detection.rb
new file mode 100644
index 00000000000..32ad670edaa
--- /dev/null
+++ b/app/graphql/mutations/security/ci_configuration/configure_secret_detection.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Security
+ module CiConfiguration
+ class ConfigureSecretDetection < BaseMutation
+ include FindsProject
+
+ graphql_name 'ConfigureSecretDetection'
+ description <<~DESC
+ Configure Secret Detection for a project by enabling Secret Detection
+ in a new or modified `.gitlab-ci.yml` file in a new branch. The new
+ branch and a URL to create a Merge Request are a part of the
+ response.
+ DESC
+
+ argument :project_path, GraphQL::ID_TYPE,
+ required: true,
+ description: 'Full path of the project.'
+
+ field :success_path, GraphQL::STRING_TYPE, null: true,
+ description: 'Redirect path to use when the response is successful.'
+
+ field :branch, GraphQL::STRING_TYPE, null: true,
+ description: 'Branch that has the new/modified `.gitlab-ci.yml` file.'
+
+ authorize :push_code
+
+ def resolve(project_path:)
+ project = authorized_find!(project_path)
+
+ result = ::Security::CiConfiguration::SecretDetectionCreateService.new(project, current_user).execute
+ prepare_response(result)
+ end
+
+ private
+
+ def prepare_response(result)
+ {
+ branch: result.payload[:branch],
+ success_path: result.payload[:success_path],
+ errors: result.errors
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/queries/burndown_chart/burnup.query.graphql b/app/graphql/queries/burndown_chart/burnup.query.graphql
new file mode 100644
index 00000000000..7a389a6def5
--- /dev/null
+++ b/app/graphql/queries/burndown_chart/burnup.query.graphql
@@ -0,0 +1,70 @@
+query BurnupTimesSeriesData($id: ID!, $isIteration: Boolean = false, $weight: Boolean = false) {
+ milestone(id: $id) @skip(if: $isIteration) {
+ __typename
+ id
+ title
+ report {
+ __typename
+ burnupTimeSeries {
+ __typename
+ date
+ completedCount @skip(if: $weight)
+ scopeCount @skip(if: $weight)
+ completedWeight @include(if: $weight)
+ scopeWeight @include(if: $weight)
+ }
+ stats {
+ __typename
+ total {
+ __typename
+ count @skip(if: $weight)
+ weight @include(if: $weight)
+ }
+ complete {
+ __typename
+ count @skip(if: $weight)
+ weight @include(if: $weight)
+ }
+ incomplete {
+ __typename
+ count @skip(if: $weight)
+ weight @include(if: $weight)
+ }
+ }
+ }
+ }
+ iteration(id: $id) @include(if: $isIteration) {
+ __typename
+ id
+ title
+ report {
+ __typename
+ burnupTimeSeries {
+ __typename
+ date
+ completedCount @skip(if: $weight)
+ scopeCount @skip(if: $weight)
+ completedWeight @include(if: $weight)
+ scopeWeight @include(if: $weight)
+ }
+ stats {
+ __typename
+ total {
+ __typename
+ count @skip(if: $weight)
+ weight @include(if: $weight)
+ }
+ complete {
+ __typename
+ count @skip(if: $weight)
+ weight @include(if: $weight)
+ }
+ incomplete {
+ __typename
+ count @skip(if: $weight)
+ weight @include(if: $weight)
+ }
+ }
+ }
+ }
+}
diff --git a/app/graphql/queries/epic/epic_children.query.graphql b/app/graphql/queries/epic/epic_children.query.graphql
index c12778109d0..5ee27052f95 100644
--- a/app/graphql/queries/epic/epic_children.query.graphql
+++ b/app/graphql/queries/epic/epic_children.query.graphql
@@ -16,6 +16,10 @@ fragment RelatedTreeBaseEpic on Epic {
adminEpic
createEpic
}
+ descendantWeightSum {
+ closedIssues
+ openedIssues
+ }
descendantCounts {
__typename
openedEpics
diff --git a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
index 959bf7dc91d..873ecc81466 100644
--- a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
+++ b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
@@ -27,6 +27,7 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
__typename
id
iid
+ complete
usesNeeds
downstream {
__typename
diff --git a/app/graphql/resolvers/ci/runner_resolver.rb b/app/graphql/resolvers/ci/runner_resolver.rb
new file mode 100644
index 00000000000..ca94e28b2e9
--- /dev/null
+++ b/app/graphql/resolvers/ci/runner_resolver.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class RunnerResolver < BaseResolver
+ include LooksAhead
+
+ type Types::Ci::RunnerType, null: true
+ extras [:lookahead]
+ description 'Runner information.'
+
+ argument :id,
+ type: ::Types::GlobalIDType[::Ci::Runner],
+ required: true,
+ description: 'Runner ID.'
+
+ def resolve_with_lookahead(id:)
+ find_runner(id: id)
+ end
+
+ private
+
+ def find_runner(id:)
+ runner_id = GitlabSchema.parse_gid(id, expected_type: ::Ci::Runner).model_id.to_i
+ preload_tag_list = lookahead.selects?(:tag_list)
+
+ BatchLoader::GraphQL.for(runner_id).batch(key: { preload_tag_list: preload_tag_list }) do |ids, loader, batch|
+ results = ::Ci::Runner.id_in(ids)
+ results = results.with_tags if batch[:key][:preload_tag_list]
+
+ results.each { |record| loader.call(record.id, record) }
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb
new file mode 100644
index 00000000000..710706325cc
--- /dev/null
+++ b/app/graphql/resolvers/ci/runners_resolver.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class RunnersResolver < BaseResolver
+ type Types::Ci::RunnerType.connection_type, null: true
+
+ argument :status, ::Types::Ci::RunnerStatusEnum,
+ required: false,
+ description: 'Filter runners by status.'
+
+ argument :type, ::Types::Ci::RunnerTypeEnum,
+ required: false,
+ description: 'Filter runners by type.'
+
+ argument :tag_list, [GraphQL::STRING_TYPE],
+ required: false,
+ description: 'Filter by tags associated with the runner (comma-separated or array).'
+
+ argument :sort, ::Types::Ci::RunnerSortEnum,
+ required: false,
+ description: 'Sort order of results.'
+
+ def resolve(**args)
+ ::Ci::RunnersFinder
+ .new(current_user: current_user, params: runners_finder_params(args))
+ .execute
+ end
+
+ private
+
+ def runners_finder_params(params)
+ {
+ status_status: params[:status]&.to_s,
+ type_type: params[:type],
+ tag_name: params[:tag_list],
+ search: params[:search],
+ sort: params[:sort]&.to_s
+ }.compact
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/template_resolver.rb b/app/graphql/resolvers/ci/template_resolver.rb
new file mode 100644
index 00000000000..dd910116544
--- /dev/null
+++ b/app/graphql/resolvers/ci/template_resolver.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class TemplateResolver < BaseResolver
+ type Types::Ci::TemplateType, null: true
+
+ argument :name, GraphQL::STRING_TYPE, required: true,
+ description: 'Name of the CI/CD template to search for.'
+
+ alias_method :project, :object
+
+ def resolve(name: nil)
+ ::TemplateFinder.new(:gitlab_ci_ymls, project, name: name).execute
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/concerns/board_issue_filterable.rb b/app/graphql/resolvers/concerns/board_issue_filterable.rb
index 3484a1cc4ba..88de69a3844 100644
--- a/app/graphql/resolvers/concerns/board_issue_filterable.rb
+++ b/app/graphql/resolvers/concerns/board_issue_filterable.rb
@@ -32,4 +32,4 @@ module BoardIssueFilterable
end
end
-::BoardIssueFilterable.prepend_if_ee('::EE::Resolvers::BoardIssueFilterable')
+::BoardIssueFilterable.prepend_mod_with('Resolvers::BoardIssueFilterable')
diff --git a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
index 0ff3997f3bc..aa08d62c6a5 100644
--- a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
+++ b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
@@ -7,57 +7,57 @@ module IssueResolverArguments
include LooksAhead
argument :iid, GraphQL::STRING_TYPE,
- required: false,
- description: 'IID of the issue. For example, "1".'
+ required: false,
+ description: 'IID of the issue. For example, "1".'
argument :iids, [GraphQL::STRING_TYPE],
- required: false,
- description: 'List of IIDs of issues. For example, [1, 2].'
+ required: false,
+ description: 'List of IIDs of issues. For example, ["1", "2"].'
argument :label_name, [GraphQL::STRING_TYPE, null: true],
- required: false,
- description: 'Labels applied to this issue.'
+ required: false,
+ description: 'Labels applied to this issue.'
argument :milestone_title, [GraphQL::STRING_TYPE, null: true],
- required: false,
- description: 'Milestone applied to this issue.'
+ required: false,
+ description: 'Milestone applied to this issue.'
argument :author_username, GraphQL::STRING_TYPE,
- required: false,
- description: 'Username of the author of the issue.'
+ required: false,
+ description: 'Username of the author of the issue.'
argument :assignee_username, GraphQL::STRING_TYPE,
- required: false,
- description: 'Username of a user assigned to the issue.',
- deprecated: { reason: 'Use `assigneeUsernames`', milestone: '13.11' }
+ required: false,
+ description: 'Username of a user assigned to the issue.',
+ deprecated: { reason: 'Use `assigneeUsernames`', milestone: '13.11' }
argument :assignee_usernames, [GraphQL::STRING_TYPE],
- required: false,
- description: 'Usernames of users assigned to the issue.'
+ required: false,
+ description: 'Usernames of users assigned to the issue.'
argument :assignee_id, GraphQL::STRING_TYPE,
- required: false,
- description: 'ID of a user assigned to the issues, "none" and "any" values are supported.'
+ required: false,
+ description: 'ID of a user assigned to the issues, "none" and "any" values are supported.'
argument :created_before, Types::TimeType,
- required: false,
- description: 'Issues created before this date.'
+ required: false,
+ description: 'Issues created before this date.'
argument :created_after, Types::TimeType,
- required: false,
- description: 'Issues created after this date.'
+ required: false,
+ description: 'Issues created after this date.'
argument :updated_before, Types::TimeType,
- required: false,
- description: 'Issues updated before this date.'
+ required: false,
+ description: 'Issues updated before this date.'
argument :updated_after, Types::TimeType,
- required: false,
- description: 'Issues updated after this date.'
+ required: false,
+ description: 'Issues updated after this date.'
argument :closed_before, Types::TimeType,
- required: false,
- description: 'Issues closed before this date.'
+ required: false,
+ description: 'Issues closed before this date.'
argument :closed_after, Types::TimeType,
- required: false,
- description: 'Issues closed after this date.'
+ required: false,
+ description: 'Issues closed after this date.'
argument :search, GraphQL::STRING_TYPE,
- required: false,
- description: 'Search query for issue title or description.'
+ required: false,
+ description: 'Search query for issue title or description.'
argument :types, [Types::IssueTypeEnum],
- as: :issue_types,
- description: 'Filter issues by the given issue types.',
- required: false
+ as: :issue_types,
+ description: 'Filter issues by the given issue types.',
+ required: false
argument :not, Types::Issues::NegatedIssueFilterInputType,
- description: 'List of negated params.',
+ description: 'Negated arguments.',
prepare: ->(negated_args, ctx) { negated_args.to_h },
required: false
end
diff --git a/app/graphql/resolvers/design_management/versions_resolver.rb b/app/graphql/resolvers/design_management/versions_resolver.rb
index 619448cbc18..08b29d884b0 100644
--- a/app/graphql/resolvers/design_management/versions_resolver.rb
+++ b/app/graphql/resolvers/design_management/versions_resolver.rb
@@ -62,6 +62,7 @@ module Resolvers
::DesignManagement::VersionsFinder
.new(design_or_collection, current_user, params)
.execute
+ .with_author
end
def by_id(gid)
diff --git a/app/graphql/resolvers/environments_resolver.rb b/app/graphql/resolvers/environments_resolver.rb
index df04e70e250..ee604e7b307 100644
--- a/app/graphql/resolvers/environments_resolver.rb
+++ b/app/graphql/resolvers/environments_resolver.rb
@@ -21,8 +21,8 @@ module Resolvers
def resolve(**args)
return unless project.present?
- EnvironmentsFinder.new(project, context[:current_user], args).execute
- rescue EnvironmentsFinder::InvalidStatesError => exception
+ Environments::EnvironmentsFinder.new(project, context[:current_user], args).execute
+ rescue Environments::EnvironmentsFinder::InvalidStatesError => exception
raise Gitlab::Graphql::Errors::ArgumentError, exception.message
end
end
diff --git a/app/graphql/resolvers/group_packages_resolver.rb b/app/graphql/resolvers/group_packages_resolver.rb
index d441cd80249..d91fe84317d 100644
--- a/app/graphql/resolvers/group_packages_resolver.rb
+++ b/app/graphql/resolvers/group_packages_resolver.rb
@@ -1,8 +1,19 @@
# frozen_string_literal: true
+# rubocop: disable Graphql/ResolverType
module Resolvers
- class GroupPackagesResolver < BaseResolver
- type Types::Packages::PackageType.connection_type, null: true
+ class GroupPackagesResolver < PackagesBaseResolver
+ # The GraphQL type is defined in the extended class
+
+ argument :sort, Types::Packages::PackageGroupSortEnum,
+ description: 'Sort packages by this criteria.',
+ required: false,
+ default_value: :created_desc
+
+ GROUP_SORT_TO_PARAMS_MAP = SORT_TO_PARAMS_MAP.merge({
+ project_path_desc: { order_by: 'project_path', sort: 'desc' },
+ project_path_asc: { order_by: 'project_path', sort: 'asc' }
+ }).freeze
def ready?(**args)
context[self.class] ||= { executions: 0 }
@@ -12,16 +23,11 @@ module Resolvers
super
end
- def resolve(**args)
+ def resolve(sort:, **filters)
return unless packages_available?
- ::Packages::GroupPackagesFinder.new(current_user, object).execute
- end
-
- private
-
- def packages_available?
- ::Gitlab.config.packages.enabled
+ ::Packages::GroupPackagesFinder.new(current_user, object, filters.merge(GROUP_SORT_TO_PARAMS_MAP.fetch(sort))).execute
end
end
end
+# rubocop: enable Graphql/ResolverType
diff --git a/app/graphql/resolvers/issues_resolver.rb b/app/graphql/resolvers/issues_resolver.rb
index 7a67f115abf..93e679b2d0c 100644
--- a/app/graphql/resolvers/issues_resolver.rb
+++ b/app/graphql/resolvers/issues_resolver.rb
@@ -55,4 +55,4 @@ module Resolvers
end
end
-Resolvers::IssuesResolver.prepend_if_ee('::EE::Resolvers::IssuesResolver')
+Resolvers::IssuesResolver.prepend_mod_with('Resolvers::IssuesResolver')
diff --git a/app/graphql/resolvers/namespace_projects_resolver.rb b/app/graphql/resolvers/namespace_projects_resolver.rb
index 7320c3ce141..86286a744bd 100644
--- a/app/graphql/resolvers/namespace_projects_resolver.rb
+++ b/app/graphql/resolvers/namespace_projects_resolver.rb
@@ -64,4 +64,4 @@ module Resolvers
end
end
-Resolvers::NamespaceProjectsResolver.prepend_if_ee('::EE::Resolvers::NamespaceProjectsResolver')
+Resolvers::NamespaceProjectsResolver.prepend_mod_with('Resolvers::NamespaceProjectsResolver')
diff --git a/app/graphql/resolvers/packages_base_resolver.rb b/app/graphql/resolvers/packages_base_resolver.rb
new file mode 100644
index 00000000000..3378cc32c9f
--- /dev/null
+++ b/app/graphql/resolvers/packages_base_resolver.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class PackagesBaseResolver < BaseResolver
+ type Types::Packages::PackageType.connection_type, null: true
+
+ argument :sort, Types::Packages::PackageSortEnum,
+ description: 'Sort packages by this criteria.',
+ required: false,
+ default_value: :created_desc
+
+ argument :package_name, GraphQL::STRING_TYPE,
+ description: 'Search a package by name.',
+ required: false,
+ default_value: nil
+
+ argument :package_type, Types::Packages::PackageTypeEnum,
+ description: 'Filter a package by type.',
+ required: false,
+ default_value: nil
+
+ argument :status, Types::Packages::PackageStatusEnum,
+ description: 'Filter a package by status.',
+ required: false,
+ default_value: nil
+
+ argument :include_versionless, GraphQL::BOOLEAN_TYPE,
+ description: 'Include versionless packages.',
+ required: false,
+ default_value: false
+
+ SORT_TO_PARAMS_MAP = {
+ created_desc: { order_by: 'created', sort: 'desc' },
+ created_asc: { order_by: 'created', sort: 'asc' },
+ name_desc: { order_by: 'name', sort: 'desc' },
+ name_asc: { order_by: 'name', sort: 'asc' },
+ version_desc: { order_by: 'version', sort: 'desc' },
+ version_asc: { order_by: 'version', sort: 'asc' },
+ type_desc: { order_by: 'type', sort: 'desc' },
+ type_asc: { order_by: 'type', sort: 'asc' }
+ }.freeze
+
+ def resolve
+ raise NotImplementedError
+ end
+
+ private
+
+ def packages_available?
+ ::Gitlab.config.packages.enabled
+ end
+ end
+end
diff --git a/app/graphql/resolvers/project_packages_resolver.rb b/app/graphql/resolvers/project_packages_resolver.rb
index 288e14b41d0..6d66c2fe460 100644
--- a/app/graphql/resolvers/project_packages_resolver.rb
+++ b/app/graphql/resolvers/project_packages_resolver.rb
@@ -1,19 +1,15 @@
# frozen_string_literal: true
+# rubocop: disable Graphql/ResolverType
module Resolvers
- class ProjectPackagesResolver < BaseResolver
- type Types::Packages::PackageType.connection_type, null: true
+ class ProjectPackagesResolver < PackagesBaseResolver
+ # The GraphQL type is defined in the extended class
- def resolve(**args)
+ def resolve(sort:, **filters)
return unless packages_available?
- ::Packages::PackagesFinder.new(object).execute
- end
-
- private
-
- def packages_available?
- ::Gitlab.config.packages.enabled
+ ::Packages::PackagesFinder.new(object, filters.merge(SORT_TO_PARAMS_MAP.fetch(sort))).execute
end
end
end
+# rubocop: enable Graphql/ResolverType
diff --git a/app/graphql/resolvers/projects/services_resolver.rb b/app/graphql/resolvers/projects/services_resolver.rb
index ec31a7dbe6d..db3037ec591 100644
--- a/app/graphql/resolvers/projects/services_resolver.rb
+++ b/app/graphql/resolvers/projects/services_resolver.rb
@@ -21,7 +21,7 @@ module Resolvers
alias_method :project, :object
def resolve(active: nil, type: nil)
- servs = project.services
+ servs = project.integrations
servs = servs.by_active_flag(active) unless active.nil?
servs = servs.by_type(type) unless type.blank?
servs
diff --git a/app/graphql/resolvers/release_resolver.rb b/app/graphql/resolvers/release_resolver.rb
index 20ef01f8593..67ff5fed0bb 100644
--- a/app/graphql/resolvers/release_resolver.rb
+++ b/app/graphql/resolvers/release_resolver.rb
@@ -15,8 +15,6 @@ module Resolvers
end
def resolve(tag_name:)
- return unless Feature.enabled?(:graphql_release_data, project, default_enabled: true)
-
ReleasesFinder.new(
project,
current_user,
diff --git a/app/graphql/resolvers/releases_resolver.rb b/app/graphql/resolvers/releases_resolver.rb
index 01c1e9b11e7..358f3c33836 100644
--- a/app/graphql/resolvers/releases_resolver.rb
+++ b/app/graphql/resolvers/releases_resolver.rb
@@ -23,8 +23,6 @@ module Resolvers
}.freeze
def resolve(sort:)
- return unless Feature.enabled?(:graphql_release_data, project, default_enabled: true)
-
ReleasesFinder.new(
project,
current_user,
diff --git a/app/graphql/resolvers/repository_branch_names_resolver.rb b/app/graphql/resolvers/repository_branch_names_resolver.rb
index 45cfe229b2f..c0a5ea0366f 100644
--- a/app/graphql/resolvers/repository_branch_names_resolver.rb
+++ b/app/graphql/resolvers/repository_branch_names_resolver.rb
@@ -10,8 +10,16 @@ module Resolvers
required: true,
description: 'The pattern to search for branch names by.'
- def resolve(search_pattern:)
- Repositories::BranchNamesFinder.new(object, search: search_pattern).execute
+ argument :offset, GraphQL::INT_TYPE,
+ required: true,
+ description: 'The number of branch names to skip.'
+
+ argument :limit, GraphQL::INT_TYPE,
+ required: true,
+ description: 'The number of branch names to return.'
+
+ def resolve(search_pattern:, offset:, limit:)
+ Repositories::BranchNamesFinder.new(object, offset: offset, limit: limit, search: search_pattern).execute
end
end
end
diff --git a/app/graphql/subscriptions/base_subscription.rb b/app/graphql/subscriptions/base_subscription.rb
new file mode 100644
index 00000000000..5f7931787df
--- /dev/null
+++ b/app/graphql/subscriptions/base_subscription.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Subscriptions
+ class BaseSubscription < GraphQL::Schema::Subscription
+ object_class Types::BaseObject
+ field_class Types::BaseField
+
+ def initialize(object:, context:, field:)
+ super
+
+ # Reset user so that we don't use a stale user for authorization
+ current_user.reset if current_user
+ end
+
+ def authorized?(*)
+ raise NotImplementedError
+ end
+
+ private
+
+ def unauthorized!
+ unsubscribe if context.query.subscription_update?
+
+ raise GraphQL::ExecutionError, 'Unauthorized subscription'
+ end
+
+ def current_user
+ context[:current_user]
+ end
+ end
+end
diff --git a/app/graphql/subscriptions/issuable_updated.rb b/app/graphql/subscriptions/issuable_updated.rb
new file mode 100644
index 00000000000..c1d82bfcf9c
--- /dev/null
+++ b/app/graphql/subscriptions/issuable_updated.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Subscriptions
+ class IssuableUpdated < BaseSubscription
+ include Gitlab::Graphql::Laziness
+
+ payload_type Types::IssuableType
+
+ argument :issuable_id, Types::GlobalIDType[Issuable],
+ required: true,
+ description: 'ID of the issuable.'
+
+ def subscribe(issuable_id:)
+ nil
+ end
+
+ def authorized?(issuable_id:)
+ # TODO: remove this check when the compatibility layer is removed
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ raise Gitlab::Graphql::Errors::ArgumentError, 'Invalid IssuableID' unless issuable_id.is_a?(GlobalID)
+
+ issuable = force(GitlabSchema.find_by_gid(issuable_id))
+
+ unauthorized! unless issuable && Ability.allowed?(current_user, :"read_#{issuable.to_ability_name}", issuable)
+
+ true
+ end
+ end
+end
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