summaryrefslogtreecommitdiff
path: root/app/graphql
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-18 09:45:46 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-18 09:45:46 +0000
commita7b3560714b4d9cc4ab32dffcd1f74a284b93580 (patch)
tree7452bd5c3545c2fa67a28aa013835fb4fa071baf /app/graphql
parentee9173579ae56a3dbfe5afe9f9410c65bb327ca7 (diff)
downloadgitlab-ce-a7b3560714b4d9cc4ab32dffcd1f74a284b93580.tar.gz
Add latest changes from gitlab-org/gitlab@14-8-stable-eev14.8.0-rc42
Diffstat (limited to 'app/graphql')
-rw-r--r--app/graphql/graphql_triggers.rb4
-rw-r--r--app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb2
-rw-r--r--app/graphql/mutations/alert_management/http_integration/create.rb4
-rw-r--r--app/graphql/mutations/alert_management/prometheus_integration/create.rb4
-rw-r--r--app/graphql/mutations/boards/create.rb3
-rw-r--r--app/graphql/mutations/branches/create.rb4
-rw-r--r--app/graphql/mutations/ci/ci_cd_settings_update.rb4
-rw-r--r--app/graphql/mutations/ci/job_token_scope/add_project.rb4
-rw-r--r--app/graphql/mutations/ci/job_token_scope/remove_project.rb4
-rw-r--r--app/graphql/mutations/ci/runner/delete.rb2
-rw-r--r--app/graphql/mutations/ci/runner/update.rb7
-rw-r--r--app/graphql/mutations/clusters/agents/create.rb4
-rw-r--r--app/graphql/mutations/commits/create.rb4
-rw-r--r--app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb51
-rw-r--r--app/graphql/mutations/container_expiration_policies/update.rb4
-rw-r--r--app/graphql/mutations/container_repositories/destroy_tags.rb5
-rw-r--r--app/graphql/mutations/custom_emoji/create.rb4
-rw-r--r--app/graphql/mutations/customer_relations/contacts/create.rb4
-rw-r--r--app/graphql/mutations/customer_relations/contacts/update.rb4
-rw-r--r--app/graphql/mutations/customer_relations/organizations/create.rb4
-rw-r--r--app/graphql/mutations/customer_relations/organizations/update.rb4
-rw-r--r--app/graphql/mutations/dependency_proxy/group_settings/update.rb4
-rw-r--r--app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb4
-rw-r--r--app/graphql/mutations/design_management/delete.rb4
-rw-r--r--app/graphql/mutations/groups/update.rb4
-rw-r--r--app/graphql/mutations/issues/create.rb19
-rw-r--r--app/graphql/mutations/issues/set_confidential.rb4
-rw-r--r--app/graphql/mutations/issues/set_escalation_status.rb6
-rw-r--r--app/graphql/mutations/jira_import/import_users.rb4
-rw-r--r--app/graphql/mutations/jira_import/start.rb4
-rw-r--r--app/graphql/mutations/labels/create.rb4
-rw-r--r--app/graphql/mutations/merge_requests/accept.rb12
-rw-r--r--app/graphql/mutations/merge_requests/create.rb4
-rw-r--r--app/graphql/mutations/namespace/package_settings/update.rb4
-rw-r--r--app/graphql/mutations/release_asset_links/create.rb7
-rw-r--r--app/graphql/mutations/snippets/create.rb5
-rw-r--r--app/graphql/mutations/snippets/update.rb5
-rw-r--r--app/graphql/mutations/user_preferences/update.rb28
-rw-r--r--app/graphql/mutations/work_items/create.rb18
-rw-r--r--app/graphql/mutations/work_items/delete.rb47
-rw-r--r--app/graphql/mutations/work_items/update.rb61
-rw-r--r--app/graphql/queries/pipelines/get_pipeline_details.query.graphql1
-rw-r--r--app/graphql/resolvers/ci/project_pipeline_counts_resolver.rb28
-rw-r--r--app/graphql/resolvers/ci/runner_jobs_resolver.rb45
-rw-r--r--app/graphql/resolvers/ci/runners_resolver.rb12
-rw-r--r--app/graphql/resolvers/clusters/agent_tokens_resolver.rb2
-rw-r--r--app/graphql/resolvers/kas/agent_configurations_resolver.rb2
-rw-r--r--app/graphql/resolvers/kas/agent_connections_resolver.rb2
-rw-r--r--app/graphql/resolvers/merge_requests_resolver.rb19
-rw-r--r--app/graphql/resolvers/paginated_tree_resolver.rb8
-rw-r--r--app/graphql/resolvers/project_jobs_resolver.rb3
-rw-r--r--app/graphql/resolvers/recent_boards_resolver.rb17
-rw-r--r--app/graphql/resolvers/tree_resolver.rb8
-rw-r--r--app/graphql/resolvers/users/groups_resolver.rb6
-rw-r--r--app/graphql/types/admin/analytics/usage_trends/measurement_type.rb3
-rw-r--r--app/graphql/types/alert_management/prometheus_integration_type.rb4
-rw-r--r--app/graphql/types/board_list_type.rb4
-rw-r--r--app/graphql/types/ci/pipeline_counts_type.rb24
-rw-r--r--app/graphql/types/ci/runner_sort_enum.rb2
-rw-r--r--app/graphql/types/ci/runner_status_enum.rb12
-rw-r--r--app/graphql/types/ci/runner_type.rb50
-rw-r--r--app/graphql/types/clusters/agent_activity_event_type.rb2
-rw-r--r--app/graphql/types/clusters/agent_token_type.rb2
-rw-r--r--app/graphql/types/clusters/agent_type.rb2
-rw-r--r--app/graphql/types/commit_type.rb14
-rw-r--r--app/graphql/types/group_invitation_type.rb6
-rw-r--r--app/graphql/types/group_member_type.rb6
-rw-r--r--app/graphql/types/group_type.rb24
-rw-r--r--app/graphql/types/issuable_type.rb4
-rw-r--r--app/graphql/types/issue_type.rb11
-rw-r--r--app/graphql/types/label_type.rb3
-rw-r--r--app/graphql/types/member_interface.rb12
-rw-r--r--app/graphql/types/merge_request_sort_enum.rb2
-rw-r--r--app/graphql/types/merge_requests/assignee_type.rb5
-rw-r--r--app/graphql/types/merge_requests/interacts_with_merge_request.rb5
-rw-r--r--app/graphql/types/merge_requests/reviewer_type.rb5
-rw-r--r--app/graphql/types/metrics/dashboards/annotation_type.rb2
-rw-r--r--app/graphql/types/mutation_type.rb9
-rw-r--r--app/graphql/types/notes/discussion_type.rb4
-rw-r--r--app/graphql/types/packages/package_details_type.rb15
-rw-r--r--app/graphql/types/permission_types/issue.rb2
-rw-r--r--app/graphql/types/permission_types/merge_request.rb9
-rw-r--r--app/graphql/types/project_type.rb14
-rw-r--r--app/graphql/types/query_complexity_type.rb4
-rw-r--r--app/graphql/types/repository/blob_type.rb18
-rw-r--r--app/graphql/types/root_storage_statistics_type.rb1
-rw-r--r--app/graphql/types/subscription_type.rb3
-rw-r--r--app/graphql/types/terraform/state_version_type.rb4
-rw-r--r--app/graphql/types/tree/blob_type.rb5
-rw-r--r--app/graphql/types/tree/submodule_type.rb4
-rw-r--r--app/graphql/types/tree/tree_entry_type.rb7
-rw-r--r--app/graphql/types/user_interface.rb4
-rw-r--r--app/graphql/types/user_preferences_type.rb17
-rw-r--r--app/graphql/types/work_item_state_enum.rb11
-rw-r--r--app/graphql/types/work_item_type.rb2
-rw-r--r--app/graphql/types/work_items/state_event_enum.rb13
96 files changed, 642 insertions, 239 deletions
diff --git a/app/graphql/graphql_triggers.rb b/app/graphql/graphql_triggers.rb
index 290cd4d7146..ac1a4a6b9ef 100644
--- a/app/graphql/graphql_triggers.rb
+++ b/app/graphql/graphql_triggers.rb
@@ -8,4 +8,8 @@ module GraphqlTriggers
def self.issue_crm_contacts_updated(issue)
GitlabSchema.subscriptions.trigger('issueCrmContactsUpdated', { issuable_id: issue.to_gid }, issue)
end
+
+ def self.issuable_title_updated(issuable)
+ GitlabSchema.subscriptions.trigger('issuableTitleUpdated', { issuable_id: issuable.to_gid }, issuable)
+ end
end
diff --git a/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb b/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb
index c4f91d0c15c..b1db355aa40 100644
--- a/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb
+++ b/app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb
@@ -8,7 +8,7 @@ module Mutations
ADMIN_MESSAGE = 'You must be an admin to use this mutation'
- ::Gitlab::ApplicationContext::KNOWN_KEYS.each do |key|
+ ::Gitlab::ApplicationContext.known_keys.each do |key|
argument key,
GraphQL::Types::String,
required: false,
diff --git a/app/graphql/mutations/alert_management/http_integration/create.rb b/app/graphql/mutations/alert_management/http_integration/create.rb
index 04840ac43bd..f8d1a383706 100644
--- a/app/graphql/mutations/alert_management/http_integration/create.rb
+++ b/app/graphql/mutations/alert_management/http_integration/create.rb
@@ -4,10 +4,10 @@ module Mutations
module AlertManagement
module HttpIntegration
class Create < HttpIntegrationBase
- include FindsProject
-
graphql_name 'HttpIntegrationCreate'
+ include FindsProject
+
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project to create the integration in.'
diff --git a/app/graphql/mutations/alert_management/prometheus_integration/create.rb b/app/graphql/mutations/alert_management/prometheus_integration/create.rb
index 0153bd0e42a..9c3aefce033 100644
--- a/app/graphql/mutations/alert_management/prometheus_integration/create.rb
+++ b/app/graphql/mutations/alert_management/prometheus_integration/create.rb
@@ -4,10 +4,10 @@ module Mutations
module AlertManagement
module PrometheusIntegration
class Create < PrometheusIntegrationBase
- include FindsProject
-
graphql_name 'PrometheusIntegrationCreate'
+ include FindsProject
+
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project to create the integration in.'
diff --git a/app/graphql/mutations/boards/create.rb b/app/graphql/mutations/boards/create.rb
index 080bf7c6e79..773ba08a291 100644
--- a/app/graphql/mutations/boards/create.rb
+++ b/app/graphql/mutations/boards/create.rb
@@ -3,10 +3,9 @@
module Mutations
module Boards
class Create < ::Mutations::BaseMutation
- include Mutations::ResolvesResourceParent
-
graphql_name 'CreateBoard'
+ include Mutations::ResolvesResourceParent
include Mutations::Boards::CommonMutationArguments
field :board,
diff --git a/app/graphql/mutations/branches/create.rb b/app/graphql/mutations/branches/create.rb
index 078c84bcdc0..b851622bfde 100644
--- a/app/graphql/mutations/branches/create.rb
+++ b/app/graphql/mutations/branches/create.rb
@@ -3,10 +3,10 @@
module Mutations
module Branches
class Create < BaseMutation
- include FindsProject
-
graphql_name 'CreateBranch'
+ include FindsProject
+
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project full path the branch is associated with.'
diff --git a/app/graphql/mutations/ci/ci_cd_settings_update.rb b/app/graphql/mutations/ci/ci_cd_settings_update.rb
index 7bd38bc2998..dec90ced962 100644
--- a/app/graphql/mutations/ci/ci_cd_settings_update.rb
+++ b/app/graphql/mutations/ci/ci_cd_settings_update.rb
@@ -3,10 +3,10 @@
module Mutations
module Ci
class CiCdSettingsUpdate < BaseMutation
- include FindsProject
-
graphql_name 'CiCdSettingsUpdate'
+ include FindsProject
+
authorize :admin_project
argument :full_path, GraphQL::Types::ID,
diff --git a/app/graphql/mutations/ci/job_token_scope/add_project.rb b/app/graphql/mutations/ci/job_token_scope/add_project.rb
index 41adcae2c82..e16c08cb116 100644
--- a/app/graphql/mutations/ci/job_token_scope/add_project.rb
+++ b/app/graphql/mutations/ci/job_token_scope/add_project.rb
@@ -4,10 +4,10 @@ module Mutations
module Ci
module JobTokenScope
class AddProject < BaseMutation
- include FindsProject
-
graphql_name 'CiJobTokenScopeAddProject'
+ include FindsProject
+
authorize :admin_project
argument :project_path, GraphQL::Types::ID,
diff --git a/app/graphql/mutations/ci/job_token_scope/remove_project.rb b/app/graphql/mutations/ci/job_token_scope/remove_project.rb
index dd6b2358dd5..f503b4f2f7a 100644
--- a/app/graphql/mutations/ci/job_token_scope/remove_project.rb
+++ b/app/graphql/mutations/ci/job_token_scope/remove_project.rb
@@ -4,10 +4,10 @@ module Mutations
module Ci
module JobTokenScope
class RemoveProject < BaseMutation
- include FindsProject
-
graphql_name 'CiJobTokenScopeRemoveProject'
+ include FindsProject
+
authorize :admin_project
argument :project_path, GraphQL::Types::ID,
diff --git a/app/graphql/mutations/ci/runner/delete.rb b/app/graphql/mutations/ci/runner/delete.rb
index 88dc426398b..21c3d55881c 100644
--- a/app/graphql/mutations/ci/runner/delete.rb
+++ b/app/graphql/mutations/ci/runner/delete.rb
@@ -20,7 +20,7 @@ module Mutations
error = authenticate_delete_runner!(runner)
return { errors: [error] } if error
- runner.destroy!
+ ::Ci::UnregisterRunnerService.new(runner).execute
{ errors: runner.errors.full_messages }
end
diff --git a/app/graphql/mutations/ci/runner/update.rb b/app/graphql/mutations/ci/runner/update.rb
index e37ab1081f9..e6123b4283a 100644
--- a/app/graphql/mutations/ci/runner/update.rb
+++ b/app/graphql/mutations/ci/runner/update.rb
@@ -28,7 +28,12 @@ module Mutations
argument :active, GraphQL::Types::Boolean,
required: false,
- description: 'Indicates the runner is allowed to receive jobs.'
+ description: 'Indicates the runner is allowed to receive jobs.',
+ deprecated: { reason: :renamed, replacement: 'paused', milestone: '14.8' }
+
+ argument :paused, GraphQL::Types::Boolean,
+ required: false,
+ description: 'Indicates the runner is not allowed to receive jobs.'
argument :locked, GraphQL::Types::Boolean, required: false,
description: 'Indicates the runner is locked.'
diff --git a/app/graphql/mutations/clusters/agents/create.rb b/app/graphql/mutations/clusters/agents/create.rb
index 0896cc7b203..deaa9c2d656 100644
--- a/app/graphql/mutations/clusters/agents/create.rb
+++ b/app/graphql/mutations/clusters/agents/create.rb
@@ -4,12 +4,12 @@ module Mutations
module Clusters
module Agents
class Create < BaseMutation
+ graphql_name 'CreateClusterAgent'
+
include FindsProject
authorize :create_cluster
- graphql_name 'CreateClusterAgent'
-
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Full path of the associated project for this cluster agent.'
diff --git a/app/graphql/mutations/commits/create.rb b/app/graphql/mutations/commits/create.rb
index 3eb1912dbc4..00ec64becc8 100644
--- a/app/graphql/mutations/commits/create.rb
+++ b/app/graphql/mutations/commits/create.rb
@@ -3,6 +3,8 @@
module Mutations
module Commits
class Create < BaseMutation
+ graphql_name 'CommitCreate'
+
include FindsProject
class UrlHelpers
@@ -10,8 +12,6 @@ module Mutations
include Gitlab::Routing
end
- graphql_name 'CommitCreate'
-
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project full path the branch is associated with.'
diff --git a/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb b/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb
deleted file mode 100644
index f1ae54aa014..00000000000
--- a/app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module Mutations
- # This concern is deprecated and will be deleted in 14.6
- #
- # Use the SpamProtection concern instead.
- module CanMutateSpammable
- extend ActiveSupport::Concern
-
- DEPRECATION_NOTICE = {
- reason: 'Use spam protection with HTTP headers instead',
- milestone: '13.11'
- }.freeze
-
- included do
- argument :captcha_response, GraphQL::Types::String,
- required: false,
- deprecated: DEPRECATION_NOTICE,
- description: 'Valid CAPTCHA response value obtained by using the provided captchaSiteKey with a CAPTCHA API to present a challenge to be solved on the client. Required to resubmit if the previous operation returned "NeedsCaptchaResponse: true".'
-
- argument :spam_log_id, GraphQL::Types::Int,
- required: false,
- deprecated: DEPRECATION_NOTICE,
- description: 'Spam log ID which must be passed along with a valid CAPTCHA response for the operation to be completed. Required to resubmit if the previous operation returned "NeedsCaptchaResponse: true".'
-
- field :spam,
- GraphQL::Types::Boolean,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'Indicates whether the operation was detected as definite spam. There is no option to resubmit the request with a CAPTCHA response.'
-
- field :needs_captcha_response,
- GraphQL::Types::Boolean,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'Indicates whether the operation was detected as possible spam and not completed. If CAPTCHA is enabled, the request must be resubmitted with a valid CAPTCHA response and spam_log_id included for the operation to be completed. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.'
-
- field :spam_log_id,
- GraphQL::Types::Int,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'Spam log ID which must be passed along with a valid CAPTCHA response for an operation to be completed. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.'
-
- field :captcha_site_key,
- GraphQL::Types::String,
- null: true,
- deprecated: DEPRECATION_NOTICE,
- description: 'CAPTCHA site key which must be used to render a challenge for the user to solve to obtain a valid captchaResponse value. Included only when an operation was not completed because "NeedsCaptchaResponse" is true.'
- end
- end
-end
diff --git a/app/graphql/mutations/container_expiration_policies/update.rb b/app/graphql/mutations/container_expiration_policies/update.rb
index db4acadfc38..762058acf3d 100644
--- a/app/graphql/mutations/container_expiration_policies/update.rb
+++ b/app/graphql/mutations/container_expiration_policies/update.rb
@@ -3,10 +3,10 @@
module Mutations
module ContainerExpirationPolicies
class Update < Mutations::BaseMutation
- include FindsProject
-
graphql_name 'UpdateContainerExpirationPolicy'
+ include FindsProject
+
authorize :destroy_container_image
argument :project_path,
diff --git a/app/graphql/mutations/container_repositories/destroy_tags.rb b/app/graphql/mutations/container_repositories/destroy_tags.rb
index c2737820d22..7777f903516 100644
--- a/app/graphql/mutations/container_repositories/destroy_tags.rb
+++ b/app/graphql/mutations/container_repositories/destroy_tags.rb
@@ -3,12 +3,11 @@
module Mutations
module ContainerRepositories
class DestroyTags < ::Mutations::ContainerRepositories::DestroyBase
- LIMIT = 20
+ graphql_name 'DestroyContainerRepositoryTags'
+ LIMIT = 20
TOO_MANY_TAGS_ERROR_MESSAGE = "Number of tags is greater than #{LIMIT}"
- graphql_name 'DestroyContainerRepositoryTags'
-
authorize :destroy_container_image
argument :id,
diff --git a/app/graphql/mutations/custom_emoji/create.rb b/app/graphql/mutations/custom_emoji/create.rb
index ad392d6c814..269ea6c9999 100644
--- a/app/graphql/mutations/custom_emoji/create.rb
+++ b/app/graphql/mutations/custom_emoji/create.rb
@@ -3,10 +3,10 @@
module Mutations
module CustomEmoji
class Create < BaseMutation
- include Mutations::ResolvesGroup
-
graphql_name 'CreateCustomEmoji'
+ include Mutations::ResolvesGroup
+
authorize :create_custom_emoji
field :custom_emoji,
diff --git a/app/graphql/mutations/customer_relations/contacts/create.rb b/app/graphql/mutations/customer_relations/contacts/create.rb
index 3495f30f227..96dc047c3db 100644
--- a/app/graphql/mutations/customer_relations/contacts/create.rb
+++ b/app/graphql/mutations/customer_relations/contacts/create.rb
@@ -4,11 +4,11 @@ module Mutations
module CustomerRelations
module Contacts
class Create < BaseMutation
+ graphql_name 'CustomerRelationsContactCreate'
+
include ResolvesIds
include Gitlab::Graphql::Authorize::AuthorizeResource
- graphql_name 'CustomerRelationsContactCreate'
-
field :contact,
Types::CustomerRelations::ContactType,
null: true,
diff --git a/app/graphql/mutations/customer_relations/contacts/update.rb b/app/graphql/mutations/customer_relations/contacts/update.rb
index e2f671058f0..a3abf37f21f 100644
--- a/app/graphql/mutations/customer_relations/contacts/update.rb
+++ b/app/graphql/mutations/customer_relations/contacts/update.rb
@@ -4,10 +4,10 @@ module Mutations
module CustomerRelations
module Contacts
class Update < Mutations::BaseMutation
- include ResolvesIds
-
graphql_name 'CustomerRelationsContactUpdate'
+ include ResolvesIds
+
authorize :admin_crm_contact
field :contact,
diff --git a/app/graphql/mutations/customer_relations/organizations/create.rb b/app/graphql/mutations/customer_relations/organizations/create.rb
index 17e0e9ad459..43c50a9fb30 100644
--- a/app/graphql/mutations/customer_relations/organizations/create.rb
+++ b/app/graphql/mutations/customer_relations/organizations/create.rb
@@ -4,11 +4,11 @@ module Mutations
module CustomerRelations
module Organizations
class Create < BaseMutation
+ graphql_name 'CustomerRelationsOrganizationCreate'
+
include ResolvesIds
include Gitlab::Graphql::Authorize::AuthorizeResource
- graphql_name 'CustomerRelationsOrganizationCreate'
-
field :organization,
Types::CustomerRelations::OrganizationType,
null: true,
diff --git a/app/graphql/mutations/customer_relations/organizations/update.rb b/app/graphql/mutations/customer_relations/organizations/update.rb
index 21fcf565239..0c05541dbd7 100644
--- a/app/graphql/mutations/customer_relations/organizations/update.rb
+++ b/app/graphql/mutations/customer_relations/organizations/update.rb
@@ -4,10 +4,10 @@ module Mutations
module CustomerRelations
module Organizations
class Update < Mutations::BaseMutation
- include ResolvesIds
-
graphql_name 'CustomerRelationsOrganizationUpdate'
+ include ResolvesIds
+
authorize :admin_crm_organization
field :organization,
diff --git a/app/graphql/mutations/dependency_proxy/group_settings/update.rb b/app/graphql/mutations/dependency_proxy/group_settings/update.rb
index d10e43cde29..65c919db3c3 100644
--- a/app/graphql/mutations/dependency_proxy/group_settings/update.rb
+++ b/app/graphql/mutations/dependency_proxy/group_settings/update.rb
@@ -4,10 +4,10 @@ module Mutations
module DependencyProxy
module GroupSettings
class Update < Mutations::BaseMutation
- include Mutations::ResolvesGroup
-
graphql_name 'UpdateDependencyProxySettings'
+ include Mutations::ResolvesGroup
+
authorize :admin_dependency_proxy
argument :group_path,
diff --git a/app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb b/app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb
index a5eb114b2da..79d7a93c4e2 100644
--- a/app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb
+++ b/app/graphql/mutations/dependency_proxy/image_ttl_group_policy/update.rb
@@ -4,10 +4,10 @@ module Mutations
module DependencyProxy
module ImageTtlGroupPolicy
class Update < Mutations::BaseMutation
- include Mutations::ResolvesGroup
-
graphql_name 'UpdateDependencyProxyImageTtlGroupPolicy'
+ include Mutations::ResolvesGroup
+
authorize :admin_dependency_proxy
argument :group_path,
diff --git a/app/graphql/mutations/design_management/delete.rb b/app/graphql/mutations/design_management/delete.rb
index 4e9f0aad934..9e643110628 100644
--- a/app/graphql/mutations/design_management/delete.rb
+++ b/app/graphql/mutations/design_management/delete.rb
@@ -3,10 +3,10 @@
module Mutations
module DesignManagement
class Delete < Base
- Errors = ::Gitlab::Graphql::Errors
-
graphql_name "DesignManagementDelete"
+ Errors = ::Gitlab::Graphql::Errors
+
argument :filenames, [GraphQL::Types::String],
required: true,
description: "Filenames of the designs to delete.",
diff --git a/app/graphql/mutations/groups/update.rb b/app/graphql/mutations/groups/update.rb
index 9c5628a57cd..be7a14d0b43 100644
--- a/app/graphql/mutations/groups/update.rb
+++ b/app/graphql/mutations/groups/update.rb
@@ -3,10 +3,10 @@
module Mutations
module Groups
class Update < Mutations::BaseMutation
- include Mutations::ResolvesGroup
-
graphql_name 'GroupUpdate'
+ include Mutations::ResolvesGroup
+
authorize :admin_group
field :group, Types::GroupType,
diff --git a/app/graphql/mutations/issues/create.rb b/app/graphql/mutations/issues/create.rb
index 72b03cc27c2..6bf8caf82d7 100644
--- a/app/graphql/mutations/issues/create.rb
+++ b/app/graphql/mutations/issues/create.rb
@@ -3,12 +3,12 @@
module Mutations
module Issues
class Create < BaseMutation
+ graphql_name 'CreateIssue'
+
include Mutations::SpamProtection
include FindsProject
include CommonMutationArguments
- graphql_name 'CreateIssue'
-
authorize :create_issue
argument :project_path, GraphQL::Types::ID,
@@ -51,6 +51,14 @@ module Mutations
required: false,
description: 'Array of user IDs to assign to the issue.'
+ argument :move_before_id, ::Types::GlobalIDType[::Issue],
+ required: false,
+ description: 'Global ID of issue that should be placed before the current issue.'
+
+ argument :move_after_id, ::Types::GlobalIDType[::Issue],
+ required: false,
+ description: 'Global ID of issue that should be placed after the current issue.'
+
field :issue,
Types::IssueType,
null: true,
@@ -93,6 +101,13 @@ module Mutations
params[:assignee_ids] &&= params[:assignee_ids].map { |assignee_id| assignee_id&.model_id }
params[:label_ids] &&= params[:label_ids].map { |label_id| label_id&.model_id }
+ if params[:move_before_id].present? || params[:move_after_id].present?
+ params[:move_between_ids] = [
+ params.delete(:move_before_id)&.model_id,
+ params.delete(:move_after_id)&.model_id
+ ]
+ end
+
params
end
diff --git a/app/graphql/mutations/issues/set_confidential.rb b/app/graphql/mutations/issues/set_confidential.rb
index 35e629ddc90..abfd6fec0bd 100644
--- a/app/graphql/mutations/issues/set_confidential.rb
+++ b/app/graphql/mutations/issues/set_confidential.rb
@@ -3,10 +3,10 @@
module Mutations
module Issues
class SetConfidential < Base
- include Mutations::SpamProtection
-
graphql_name 'IssueSetConfidential'
+ include Mutations::SpamProtection
+
argument :confidential,
GraphQL::Types::Boolean,
required: true,
diff --git a/app/graphql/mutations/issues/set_escalation_status.rb b/app/graphql/mutations/issues/set_escalation_status.rb
index 6073b73277b..4f3fcb4886d 100644
--- a/app/graphql/mutations/issues/set_escalation_status.rb
+++ b/app/graphql/mutations/issues/set_escalation_status.rb
@@ -14,7 +14,7 @@ module Mutations
project = issue.project
authorize_escalation_status!(project)
- check_feature_availability!(project, issue)
+ check_feature_availability!(issue)
::Issues::UpdateService.new(
project: project,
@@ -36,8 +36,8 @@ module Mutations
raise_resource_not_available_error!
end
- def check_feature_availability!(project, issue)
- return if Feature.enabled?(:incident_escalations, project) && issue.supports_escalation?
+ def check_feature_availability!(issue)
+ return if issue.supports_escalation?
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature unavailable for provided issue'
end
diff --git a/app/graphql/mutations/jira_import/import_users.rb b/app/graphql/mutations/jira_import/import_users.rb
index 8d82a058dd0..b3874caee61 100644
--- a/app/graphql/mutations/jira_import/import_users.rb
+++ b/app/graphql/mutations/jira_import/import_users.rb
@@ -3,10 +3,10 @@
module Mutations
module JiraImport
class ImportUsers < BaseMutation
- include FindsProject
-
graphql_name 'JiraImportUsers'
+ include FindsProject
+
authorize :admin_project
field :jira_users,
diff --git a/app/graphql/mutations/jira_import/start.rb b/app/graphql/mutations/jira_import/start.rb
index 4929d6f394a..ea071c45bcf 100644
--- a/app/graphql/mutations/jira_import/start.rb
+++ b/app/graphql/mutations/jira_import/start.rb
@@ -3,10 +3,10 @@
module Mutations
module JiraImport
class Start < BaseMutation
- include FindsProject
-
graphql_name 'JiraImportStart'
+ include FindsProject
+
authorize :admin_project
field :jira_import,
diff --git a/app/graphql/mutations/labels/create.rb b/app/graphql/mutations/labels/create.rb
index cb3ba7939ae..3cd41dc01de 100644
--- a/app/graphql/mutations/labels/create.rb
+++ b/app/graphql/mutations/labels/create.rb
@@ -3,10 +3,10 @@
module Mutations
module Labels
class Create < BaseMutation
- include Mutations::ResolvesResourceParent
-
graphql_name 'LabelCreate'
+ include Mutations::ResolvesResourceParent
+
field :label,
Types::LabelType,
null: true,
diff --git a/app/graphql/mutations/merge_requests/accept.rb b/app/graphql/mutations/merge_requests/accept.rb
index 7ce850901af..ebd9e2b8fdd 100644
--- a/app/graphql/mutations/merge_requests/accept.rb
+++ b/app/graphql/mutations/merge_requests/accept.rb
@@ -3,12 +3,6 @@
module Mutations
module MergeRequests
class Accept < Base
- NOT_MERGEABLE = 'This branch cannot be merged'
- HOOKS_VALIDATION_ERROR = 'Pre-merge hooks failed'
- SHA_MISMATCH = 'The merge-head is not at the anticipated SHA'
- MERGE_FAILED = 'The merge failed'
- ALREADY_SCHEDULED = 'The merge request is already scheduled to be merged'
-
graphql_name 'MergeRequestAccept'
authorize :accept_merge_request
description <<~DESC
@@ -17,6 +11,12 @@ module Mutations
immediately if possible, or using one of the automatic merge strategies.
DESC
+ NOT_MERGEABLE = 'This branch cannot be merged'
+ HOOKS_VALIDATION_ERROR = 'Pre-merge hooks failed'
+ SHA_MISMATCH = 'The merge-head is not at the anticipated SHA'
+ MERGE_FAILED = 'The merge failed'
+ ALREADY_SCHEDULED = 'The merge request is already scheduled to be merged'
+
argument :strategy,
::Types::MergeStrategyEnum,
required: false,
diff --git a/app/graphql/mutations/merge_requests/create.rb b/app/graphql/mutations/merge_requests/create.rb
index dc1d5a22bc9..2883c02a671 100644
--- a/app/graphql/mutations/merge_requests/create.rb
+++ b/app/graphql/mutations/merge_requests/create.rb
@@ -3,10 +3,10 @@
module Mutations
module MergeRequests
class Create < BaseMutation
- include FindsProject
-
graphql_name 'MergeRequestCreate'
+ include FindsProject
+
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project full path the merge request is associated with.'
diff --git a/app/graphql/mutations/namespace/package_settings/update.rb b/app/graphql/mutations/namespace/package_settings/update.rb
index 400169d6b64..934b75193d7 100644
--- a/app/graphql/mutations/namespace/package_settings/update.rb
+++ b/app/graphql/mutations/namespace/package_settings/update.rb
@@ -4,10 +4,10 @@ module Mutations
module Namespace
module PackageSettings
class Update < Mutations::BaseMutation
- include Mutations::ResolvesNamespace
-
graphql_name 'UpdateNamespacePackageSettings'
+ include Mutations::ResolvesNamespace
+
authorize :create_package_settings
argument :namespace_path,
diff --git a/app/graphql/mutations/release_asset_links/create.rb b/app/graphql/mutations/release_asset_links/create.rb
index db486640507..f6445514ce9 100644
--- a/app/graphql/mutations/release_asset_links/create.rb
+++ b/app/graphql/mutations/release_asset_links/create.rb
@@ -3,14 +3,13 @@
module Mutations
module ReleaseAssetLinks
class Create < BaseMutation
- include FindsProject
-
graphql_name 'ReleaseAssetLinkCreate'
- authorize :create_release
-
+ include FindsProject
include Types::ReleaseAssetLinkSharedInputArguments
+ authorize :create_release
+
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Full path of the project the asset link is associated with.'
diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb
index c01b0e4a01b..2921a77b86d 100644
--- a/app/graphql/mutations/snippets/create.rb
+++ b/app/graphql/mutations/snippets/create.rb
@@ -3,14 +3,13 @@
module Mutations
module Snippets
class Create < BaseMutation
+ graphql_name 'CreateSnippet'
+
include ServiceCompatibility
- include CanMutateSpammable
include Mutations::SpamProtection
authorize :create_snippet
- graphql_name 'CreateSnippet'
-
field :snippet,
Types::SnippetType,
null: true,
diff --git a/app/graphql/mutations/snippets/update.rb b/app/graphql/mutations/snippets/update.rb
index 9ecaa8d4bf2..2a2941c5328 100644
--- a/app/graphql/mutations/snippets/update.rb
+++ b/app/graphql/mutations/snippets/update.rb
@@ -3,12 +3,11 @@
module Mutations
module Snippets
class Update < Base
+ graphql_name 'UpdateSnippet'
+
include ServiceCompatibility
- include CanMutateSpammable
include Mutations::SpamProtection
- graphql_name 'UpdateSnippet'
-
argument :id, ::Types::GlobalIDType[::Snippet],
required: true,
description: 'Global ID of the snippet to update.'
diff --git a/app/graphql/mutations/user_preferences/update.rb b/app/graphql/mutations/user_preferences/update.rb
new file mode 100644
index 00000000000..c92c6d725b7
--- /dev/null
+++ b/app/graphql/mutations/user_preferences/update.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Mutations
+ module UserPreferences
+ class Update < BaseMutation
+ graphql_name 'UserPreferencesUpdate'
+
+ argument :issues_sort, Types::IssueSortEnum,
+ required: false,
+ description: 'Sort order for issue lists.'
+
+ field :user_preferences,
+ Types::UserPreferencesType,
+ null: true,
+ description: 'User preferences after mutation.'
+
+ def resolve(**attributes)
+ user_preferences = current_user.user_preference
+ user_preferences.update(attributes)
+
+ {
+ user_preferences: user_preferences.valid? ? user_preferences : nil,
+ errors: errors_on_object(user_preferences)
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index 88b8cefd8d2..81454db62b1 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -3,10 +3,13 @@
module Mutations
module WorkItems
class Create < BaseMutation
+ graphql_name 'WorkItemCreate'
+
include Mutations::SpamProtection
include FindsProject
- graphql_name 'WorkItemCreate'
+ description "Creates a work item." \
+ " Available only when feature flag `work_items` is enabled. The feature is experimental and is subject to change without notice."
authorize :create_work_item
@@ -29,16 +32,21 @@ module Mutations
def resolve(project_path:, **attributes)
project = authorized_find!(project_path)
+
+ unless Feature.enabled?(:work_items, project)
+ return { errors: ['`work_items` feature flag disabled for this project'] }
+ end
+
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
- work_item = ::WorkItems::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute
+ create_result = ::WorkItems::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute
- check_spam_action_response!(work_item)
+ check_spam_action_response!(create_result[:work_item]) if create_result[:work_item]
{
- work_item: work_item.valid? ? work_item : nil,
- errors: errors_on_object(work_item)
+ work_item: create_result.success? ? create_result[:work_item] : nil,
+ errors: create_result.errors
}
end
diff --git a/app/graphql/mutations/work_items/delete.rb b/app/graphql/mutations/work_items/delete.rb
new file mode 100644
index 00000000000..71792a802c0
--- /dev/null
+++ b/app/graphql/mutations/work_items/delete.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ class Delete < BaseMutation
+ graphql_name 'WorkItemDelete'
+ description "Deletes a work item." \
+ " Available only when feature flag `work_items` is enabled. The feature is experimental and is subject to change without notice."
+
+ authorize :delete_work_item
+
+ argument :id, ::Types::GlobalIDType[::WorkItem],
+ required: true,
+ description: 'Global ID of the work item.'
+
+ field :project, Types::ProjectType,
+ null: true,
+ description: 'Project the deleted work item belonged to.'
+
+ def resolve(id:)
+ work_item = authorized_find!(id: id)
+
+ unless Feature.enabled?(:work_items, work_item.project)
+ return { errors: ['`work_items` feature flag disabled for this project'] }
+ end
+
+ result = ::WorkItems::DeleteService.new(
+ project: work_item.project,
+ current_user: current_user
+ ).execute(work_item)
+
+ {
+ project: result.success? ? work_item.project : nil,
+ errors: result.errors
+ }
+ end
+
+ private
+
+ def find_object(id:)
+ # TODO: Remove coercion when working on https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ id = ::Types::GlobalIDType[::WorkItem].coerce_isolated_input(id)
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/update.rb b/app/graphql/mutations/work_items/update.rb
new file mode 100644
index 00000000000..3ab9ba2d502
--- /dev/null
+++ b/app/graphql/mutations/work_items/update.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ class Update < BaseMutation
+ graphql_name 'WorkItemUpdate'
+ description "Updates a work item by Global ID." \
+ " Available only when feature flag `work_items` is enabled. The feature is experimental and is subject to change without notice."
+
+ include Mutations::SpamProtection
+
+ authorize :update_work_item
+
+ argument :id, ::Types::GlobalIDType[::WorkItem],
+ required: true,
+ description: 'Global ID of the work item.'
+ argument :state_event, Types::WorkItems::StateEventEnum,
+ description: 'Close or reopen a work item.',
+ required: false
+ argument :title, GraphQL::Types::String,
+ required: false,
+ description: copy_field_description(Types::WorkItemType, :title)
+
+ field :work_item, Types::WorkItemType,
+ null: true,
+ description: 'Updated work item.'
+
+ def resolve(id:, **attributes)
+ work_item = authorized_find!(id: id)
+
+ unless Feature.enabled?(:work_items, work_item.project)
+ return { errors: ['`work_items` feature flag disabled for this project'] }
+ end
+
+ spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
+
+ ::WorkItems::UpdateService.new(
+ project: work_item.project,
+ current_user: current_user,
+ params: attributes,
+ spam_params: spam_params
+ ).execute(work_item)
+
+ check_spam_action_response!(work_item)
+
+ {
+ work_item: work_item.valid? ? work_item : nil,
+ errors: errors_on_object(work_item)
+ }
+ end
+
+ private
+
+ def find_object(id:)
+ # TODO: Remove coercion when working on https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ id = ::Types::GlobalIDType[::WorkItem].coerce_isolated_input(id)
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+end
diff --git a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
index 5dece2f81cc..f4921706f7e 100644
--- a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
+++ b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
@@ -120,6 +120,7 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
hasDetails
detailsPath
group
+ label
action {
__typename
id
diff --git a/app/graphql/resolvers/ci/project_pipeline_counts_resolver.rb b/app/graphql/resolvers/ci/project_pipeline_counts_resolver.rb
new file mode 100644
index 00000000000..728bc9627c5
--- /dev/null
+++ b/app/graphql/resolvers/ci/project_pipeline_counts_resolver.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class ProjectPipelineCountsResolver < BaseResolver
+ type Types::Ci::PipelineCountsType, null: true
+
+ argument :ref,
+ GraphQL::Types::String,
+ required: false,
+ description: "Filter pipelines by the ref they are run for."
+
+ argument :sha,
+ GraphQL::Types::String,
+ required: false,
+ description: "Filter pipelines by the SHA of the commit they are run for."
+
+ argument :source,
+ GraphQL::Types::String,
+ required: false,
+ description: "Filter pipelines by their source."
+
+ def resolve(**args)
+ ::Gitlab::PipelineScopeCounts.new(context[:current_user], object, args)
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/runner_jobs_resolver.rb b/app/graphql/resolvers/ci/runner_jobs_resolver.rb
new file mode 100644
index 00000000000..2f6ca09d031
--- /dev/null
+++ b/app/graphql/resolvers/ci/runner_jobs_resolver.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class RunnerJobsResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+ include LooksAhead
+
+ type ::Types::Ci::JobType.connection_type, null: true
+ authorize :read_builds
+ authorizes_object!
+
+ argument :statuses, [::Types::Ci::JobStatusEnum],
+ required: false,
+ description: 'Filter jobs by status.'
+
+ alias_method :runner, :object
+
+ def ready?(**args)
+ context[self.class] ||= { executions: 0 }
+ context[self.class][:executions] += 1
+
+ raise GraphQL::ExecutionError, "Jobs can be requested for only one runner at a time" if context[self.class][:executions] > 1
+
+ super
+ end
+
+ def resolve_with_lookahead(statuses: nil)
+ jobs = ::Ci::JobsFinder.new(current_user: current_user, runner: runner, params: { scope: statuses }).execute
+
+ apply_lookahead(jobs)
+ end
+
+ private
+
+ def preloads
+ {
+ previous_stage_jobs_and_needs: [:needs, :pipeline],
+ artifacts: [:job_artifacts],
+ pipeline: [:user]
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb
index 9848b5a503f..e221dfea4d0 100644
--- a/app/graphql/resolvers/ci/runners_resolver.rb
+++ b/app/graphql/resolvers/ci/runners_resolver.rb
@@ -9,7 +9,12 @@ module Resolvers
argument :active, ::GraphQL::Types::Boolean,
required: false,
- description: 'Filter runners by active (true) or paused (false) status.'
+ description: 'Filter runners by `active` (true) or `paused` (false) status.',
+ deprecated: { reason: :renamed, replacement: 'paused', milestone: '14.8' }
+
+ argument :paused, ::GraphQL::Types::Boolean,
+ required: false,
+ description: 'Filter runners by `paused` (true) or `active` (false) status.'
argument :status, ::Types::Ci::RunnerStatusEnum,
required: false,
@@ -41,8 +46,11 @@ module Resolvers
protected
def runners_finder_params(params)
+ # Give preference to paused argument over the deprecated 'active' argument
+ paused = params.fetch(:paused, params[:active] ? !params[:active] : nil)
+
{
- active: params[:active],
+ active: paused.nil? ? nil : !paused,
status_status: params[:status]&.to_s,
type_type: params[:type],
tag_name: params[:tag_list],
diff --git a/app/graphql/resolvers/clusters/agent_tokens_resolver.rb b/app/graphql/resolvers/clusters/agent_tokens_resolver.rb
index 8208fa56485..722fbab3bb7 100644
--- a/app/graphql/resolvers/clusters/agent_tokens_resolver.rb
+++ b/app/graphql/resolvers/clusters/agent_tokens_resolver.rb
@@ -25,7 +25,7 @@ module Resolvers
private
def can_read_agent_tokens?
- current_user.can?(:admin_cluster, project)
+ current_user.can?(:read_cluster, project)
end
end
end
diff --git a/app/graphql/resolvers/kas/agent_configurations_resolver.rb b/app/graphql/resolvers/kas/agent_configurations_resolver.rb
index a1b1d3bfe4c..9db104287a6 100644
--- a/app/graphql/resolvers/kas/agent_configurations_resolver.rb
+++ b/app/graphql/resolvers/kas/agent_configurations_resolver.rb
@@ -21,7 +21,7 @@ module Resolvers
private
def can_read_agent_configuration?
- current_user.can?(:admin_cluster, project)
+ current_user.can?(:read_cluster, project)
end
def kas_client
diff --git a/app/graphql/resolvers/kas/agent_connections_resolver.rb b/app/graphql/resolvers/kas/agent_connections_resolver.rb
index 8b7c4003598..cf1a47aac75 100644
--- a/app/graphql/resolvers/kas/agent_connections_resolver.rb
+++ b/app/graphql/resolvers/kas/agent_connections_resolver.rb
@@ -29,7 +29,7 @@ module Resolvers
def get_connected_agents
kas_client.get_connected_agents(project: project)
- rescue GRPC::BadStatus => e
+ rescue GRPC::BadStatus, Gitlab::Kas::Client::ConfigurationError => e
raise Gitlab::Graphql::Errors::ResourceNotAvailable, e.class.name
end
diff --git a/app/graphql/resolvers/merge_requests_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb
index 6dbcbe0e04d..72372ae6b42 100644
--- a/app/graphql/resolvers/merge_requests_resolver.rb
+++ b/app/graphql/resolvers/merge_requests_resolver.rb
@@ -55,6 +55,19 @@ module Resolvers
required: false,
description: 'Limit result to draft merge requests.'
+ argument :created_after, Types::TimeType,
+ required: false,
+ description: 'Merge requests created after this timestamp.'
+ argument :created_before, Types::TimeType,
+ required: false,
+ description: 'Merge requests created before this timestamp.'
+ argument :updated_after, Types::TimeType,
+ required: false,
+ description: 'Merge requests updated after this timestamp.'
+ argument :updated_before, Types::TimeType,
+ required: false,
+ description: 'Merge requests updated before this timestamp.'
+
argument :labels, [GraphQL::Types::String],
required: false,
as: :label_name,
@@ -72,12 +85,6 @@ module Resolvers
description: 'Sort merge requests by this criteria.',
required: false,
default_value: :created_desc
- argument :created_after, Types::TimeType,
- required: false,
- description: 'Merge requests created after this timestamp.'
- argument :created_before, Types::TimeType,
- required: false,
- description: 'Merge requests created before this timestamp.'
negated do
argument :labels, [GraphQL::Types::String],
diff --git a/app/graphql/resolvers/paginated_tree_resolver.rb b/app/graphql/resolvers/paginated_tree_resolver.rb
index 6c0545d26de..d29d87ca204 100644
--- a/app/graphql/resolvers/paginated_tree_resolver.rb
+++ b/app/graphql/resolvers/paginated_tree_resolver.rb
@@ -11,14 +11,14 @@ module Resolvers
required: false,
default_value: '', # root of the repository
description: 'Path to get the tree for. Default value is the root of the repository.'
- argument :ref, GraphQL::Types::String,
- required: false,
- default_value: :head,
- description: 'Commit ref to get the tree for. Default value is HEAD.'
argument :recursive, GraphQL::Types::Boolean,
required: false,
default_value: false,
description: 'Used to get a recursive tree. Default is false.'
+ argument :ref, GraphQL::Types::String,
+ required: false,
+ default_value: :head,
+ description: 'Commit ref to get the tree for. Default value is HEAD.'
alias_method :repository, :object
diff --git a/app/graphql/resolvers/project_jobs_resolver.rb b/app/graphql/resolvers/project_jobs_resolver.rb
index 8a2693ee46b..b09158d475d 100644
--- a/app/graphql/resolvers/project_jobs_resolver.rb
+++ b/app/graphql/resolvers/project_jobs_resolver.rb
@@ -18,7 +18,8 @@ module Resolvers
def ready?(**args)
context[self.class] ||= { executions: 0 }
context[self.class][:executions] += 1
- raise GraphQL::ExecutionError, "Jobs can only be requested for one project at a time" if context[self.class][:executions] > 1
+
+ raise GraphQL::ExecutionError, "Jobs can be requested for only one project at a time" if context[self.class][:executions] > 1
super
end
diff --git a/app/graphql/resolvers/recent_boards_resolver.rb b/app/graphql/resolvers/recent_boards_resolver.rb
new file mode 100644
index 00000000000..4de5b8f072b
--- /dev/null
+++ b/app/graphql/resolvers/recent_boards_resolver.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class RecentBoardsResolver < BaseResolver
+ type Types::BoardType, null: true
+
+ def resolve
+ parent = object.respond_to?(:sync) ? object.sync : object
+ return Board.none unless parent
+
+ recent_visits =
+ ::Boards::VisitsFinder.new(parent, current_user).latest(Board::RECENT_BOARDS_SIZE)
+
+ recent_visits&.map(&:board) || []
+ end
+ end
+end
diff --git a/app/graphql/resolvers/tree_resolver.rb b/app/graphql/resolvers/tree_resolver.rb
index 8d6ece0956e..f02eb226810 100644
--- a/app/graphql/resolvers/tree_resolver.rb
+++ b/app/graphql/resolvers/tree_resolver.rb
@@ -10,14 +10,14 @@ module Resolvers
required: false,
default_value: '',
description: 'Path to get the tree for. Default value is the root of the repository.'
- argument :ref, GraphQL::Types::String,
- required: false,
- default_value: :head,
- description: 'Commit ref to get the tree for. Default value is HEAD.'
argument :recursive, GraphQL::Types::Boolean,
required: false,
default_value: false,
description: 'Used to get a recursive tree. Default is false.'
+ argument :ref, GraphQL::Types::String,
+ required: false,
+ default_value: :head,
+ description: 'Commit ref to get the tree for. Default value is HEAD.'
alias_method :repository, :object
diff --git a/app/graphql/resolvers/users/groups_resolver.rb b/app/graphql/resolvers/users/groups_resolver.rb
index d8492a8fcf9..09c6b51cc3d 100644
--- a/app/graphql/resolvers/users/groups_resolver.rb
+++ b/app/graphql/resolvers/users/groups_resolver.rb
@@ -11,13 +11,13 @@ module Resolvers
authorize :read_user_groups
authorizes_object!
- argument :search, GraphQL::Types::String,
- required: false,
- description: 'Search by group name or path.'
argument :permission_scope,
::Types::PermissionTypes::GroupEnum,
required: false,
description: 'Filter by permissions the user has on groups.'
+ argument :search, GraphQL::Types::String,
+ required: false,
+ description: 'Search by group name or path.'
before_connection_authorization do |nodes, current_user|
Preloaders::GroupPolicyPreloader.new(nodes, current_user).execute
diff --git a/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
index 8276549ddcc..1fc47303d67 100644
--- a/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
+++ b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
@@ -5,10 +5,11 @@ module Types
module Analytics
module UsageTrends
class MeasurementType < BaseObject
- include Gitlab::Graphql::Authorize::AuthorizeResource
graphql_name 'UsageTrendsMeasurement'
description 'Represents a recorded measurement (object count) for the Admins'
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
authorize :read_usage_trends_measurement
field :recorded_at, Types::TimeType, null: true,
diff --git a/app/graphql/types/alert_management/prometheus_integration_type.rb b/app/graphql/types/alert_management/prometheus_integration_type.rb
index 27e4832d8f6..9a2ef78eca7 100644
--- a/app/graphql/types/alert_management/prometheus_integration_type.rb
+++ b/app/graphql/types/alert_management/prometheus_integration_type.rb
@@ -3,11 +3,11 @@
module Types
module AlertManagement
class PrometheusIntegrationType < ::Types::BaseObject
- include ::Gitlab::Routing
-
graphql_name 'AlertManagementPrometheusIntegration'
description 'An endpoint and credentials used to accept Prometheus alerts for a project'
+ include ::Gitlab::Routing
+
implements(Types::AlertManagement::IntegrationType)
authorize :admin_project
diff --git a/app/graphql/types/board_list_type.rb b/app/graphql/types/board_list_type.rb
index 8c67803e39e..733006369ea 100644
--- a/app/graphql/types/board_list_type.rb
+++ b/app/graphql/types/board_list_type.rb
@@ -3,11 +3,11 @@
module Types
# rubocop: disable Graphql/AuthorizeTypes
class BoardListType < BaseObject
- include Gitlab::Utils::StrongMemoize
-
graphql_name 'BoardList'
description 'Represents a list for an issue board'
+ include Gitlab::Utils::StrongMemoize
+
alias_method :list, :object
field :id, GraphQL::Types::ID,
diff --git a/app/graphql/types/ci/pipeline_counts_type.rb b/app/graphql/types/ci/pipeline_counts_type.rb
new file mode 100644
index 00000000000..9c2b822091e
--- /dev/null
+++ b/app/graphql/types/ci/pipeline_counts_type.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ class PipelineCountsType < BaseObject
+ graphql_name 'PipelineCounts'
+ description "Represents pipeline counts for the project"
+
+ authorize :read_pipeline
+
+ (::Types::Ci::PipelineScopeEnum.values.keys - %w[BRANCHES TAGS]).each do |scope|
+ field scope.downcase,
+ GraphQL::Types::Int,
+ null: true,
+ description: "Number of pipelines with scope #{scope} for the project"
+ end
+
+ field :all,
+ GraphQL::Types::Int,
+ null: true,
+ description: 'Total number of pipelines for the project.'
+ end
+ end
+end
diff --git a/app/graphql/types/ci/runner_sort_enum.rb b/app/graphql/types/ci/runner_sort_enum.rb
index 95ec1867fea..8f2a13bd699 100644
--- a/app/graphql/types/ci/runner_sort_enum.rb
+++ b/app/graphql/types/ci/runner_sort_enum.rb
@@ -10,6 +10,8 @@ module Types
value 'CONTACTED_DESC', 'Ordered by contacted_at in descending order.', value: :contacted_desc
value 'CREATED_ASC', 'Ordered by created_at in ascending order.', value: :created_at_asc
value 'CREATED_DESC', 'Ordered by created_at in descending order.', value: :created_at_desc
+ value 'TOKEN_EXPIRES_AT_ASC', 'Ordered by token_expires_at in ascending order.', value: :token_expires_at_asc
+ value 'TOKEN_EXPIRES_AT_DESC', 'Ordered by token_expires_at in descending order.', value: :token_expires_at_desc
end
end
end
diff --git a/app/graphql/types/ci/runner_status_enum.rb b/app/graphql/types/ci/runner_status_enum.rb
index dd056191ceb..2e65e2d4e1e 100644
--- a/app/graphql/types/ci/runner_status_enum.rb
+++ b/app/graphql/types/ci/runner_status_enum.rb
@@ -7,12 +7,20 @@ module Types
value 'ACTIVE',
description: 'Runner that is not paused.',
- deprecated: { reason: 'Use CiRunnerType.active instead', milestone: '14.6' },
+ deprecated: {
+ reason: :renamed,
+ replacement: 'CiRunner.paused',
+ milestone: '14.6'
+ },
value: :active
value 'PAUSED',
description: 'Runner that is paused.',
- deprecated: { reason: 'Use CiRunnerType.active instead', milestone: '14.6' },
+ deprecated: {
+ reason: :renamed,
+ replacement: 'CiRunner.paused',
+ milestone: '14.6'
+ },
value: :paused
value 'ONLINE',
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 4fe65734911..9094c6b96e4 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -3,12 +3,13 @@
module Types
module Ci
class RunnerType < BaseObject
+ graphql_name 'CiRunner'
+
edge_type_class(RunnerWebUrlEdge)
connection_type_class(Types::CountableConnectionType)
- graphql_name 'CiRunner'
+
authorize :read_runner
present_using ::Ci::RunnerPresenter
-
expose_permissions Types::PermissionTypes::Ci::Runner
JOB_COUNT_LIMIT = 1000
@@ -24,12 +25,18 @@ module Types
field :contacted_at, Types::TimeType, null: true,
description: 'Timestamp of last contact from this runner.',
method: :contacted_at
+ field :token_expires_at, Types::TimeType, null: true,
+ description: 'Runner token expiration time.',
+ method: :token_expires_at
field :maximum_timeout, GraphQL::Types::Int, 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::Types::Boolean, null: false,
- description: 'Indicates the runner is allowed to receive jobs.'
+ description: 'Indicates the runner is allowed to receive jobs.',
+ deprecated: { reason: 'Use paused', milestone: '14.8' }
+ field :paused, GraphQL::Types::Boolean, null: false,
+ description: 'Indicates the runner is paused and not available to run jobs.'
field :status,
Types::Ci::RunnerStatusEnum,
null: false,
@@ -63,6 +70,14 @@ module Types
description: 'Executor last advertised by the runner.',
method: :executor_name,
feature_flag: :graphql_ci_runner_executor
+ field :groups, ::Types::GroupType.connection_type, null: true,
+ description: 'Groups the runner is associated with. For group runners only.'
+ field :projects, ::Types::ProjectType.connection_type, null: true,
+ description: 'Projects the runner is associated with. For project runners only.'
+ field :jobs, ::Types::Ci::JobType.connection_type, null: true,
+ description: 'Jobs assigned to the runner.',
+ authorize: :read_builds,
+ resolver: ::Resolvers::Ci::RunnerJobsResolver
def job_count
# We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
@@ -94,11 +109,40 @@ module Types
end
# rubocop: enable CodeReuse/ActiveRecord
+ def groups
+ return unless runner.group_type?
+
+ batched_owners(::Ci::RunnerNamespace, Group, :runner_groups, :namespace_id)
+ end
+
+ def projects
+ return unless runner.project_type?
+
+ batched_owners(::Ci::RunnerProject, Project, :runner_projects, :project_id)
+ end
+
private
def can_admin_runners?
context[:current_user]&.can_admin_all_resources?
end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def batched_owners(runner_assoc_type, assoc_type, key, column_name)
+ BatchLoader::GraphQL.for(runner.id).batch(key: key) do |runner_ids, loader, args|
+ runner_and_owner_ids = runner_assoc_type.where(runner_id: runner_ids).pluck(:runner_id, column_name)
+
+ owner_ids_by_runner_id = runner_and_owner_ids.group_by(&:first).transform_values { |v| v.pluck(1) }
+ owner_ids = runner_and_owner_ids.pluck(1).uniq
+
+ owners = assoc_type.where(id: owner_ids).index_by(&:id)
+
+ runner_ids.each do |runner_id|
+ loader.call(runner_id, owner_ids_by_runner_id[runner_id]&.map { |owner_id| owners[owner_id] } || [])
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
end
end
diff --git a/app/graphql/types/clusters/agent_activity_event_type.rb b/app/graphql/types/clusters/agent_activity_event_type.rb
index 79a9fd70505..3484acfe25e 100644
--- a/app/graphql/types/clusters/agent_activity_event_type.rb
+++ b/app/graphql/types/clusters/agent_activity_event_type.rb
@@ -5,7 +5,7 @@ module Types
class AgentActivityEventType < BaseObject
graphql_name 'ClusterAgentActivityEvent'
- authorize :admin_cluster
+ authorize :read_cluster
connection_type_class(Types::CountableConnectionType)
diff --git a/app/graphql/types/clusters/agent_token_type.rb b/app/graphql/types/clusters/agent_token_type.rb
index 96fdb5f05c8..24489707698 100644
--- a/app/graphql/types/clusters/agent_token_type.rb
+++ b/app/graphql/types/clusters/agent_token_type.rb
@@ -5,7 +5,7 @@ module Types
class AgentTokenType < BaseObject
graphql_name 'ClusterAgentToken'
- authorize :admin_cluster
+ authorize :read_cluster
connection_type_class(Types::CountableConnectionType)
diff --git a/app/graphql/types/clusters/agent_type.rb b/app/graphql/types/clusters/agent_type.rb
index 89316ed4728..546252b2285 100644
--- a/app/graphql/types/clusters/agent_type.rb
+++ b/app/graphql/types/clusters/agent_type.rb
@@ -5,7 +5,7 @@ module Types
class AgentType < BaseObject
graphql_name 'ClusterAgent'
- authorize :admin_cluster
+ authorize :read_cluster
connection_type_class(Types::CountableConnectionType)
diff --git a/app/graphql/types/commit_type.rb b/app/graphql/types/commit_type.rb
index 2584e15ff0b..8bc00359ccb 100644
--- a/app/graphql/types/commit_type.rb
+++ b/app/graphql/types/commit_type.rb
@@ -10,33 +10,37 @@ module Types
field :id, type: GraphQL::Types::ID, null: false,
description: 'ID (global ID) of the commit.'
+
field :sha, type: GraphQL::Types::String, null: false,
description: 'SHA1 ID of the commit.'
+
field :short_id, type: GraphQL::Types::String, null: false,
description: 'Short SHA1 ID of the commit.'
field :title, type: GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'Title of the commit message.'
- markdown_field :title_html, null: true
field :full_title, type: GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'Full title of the commit message.'
- markdown_field :full_title_html, null: true
field :description, type: GraphQL::Types::String, null: true,
description: 'Description of the commit message.'
- markdown_field :description_html, null: true
field :message, type: GraphQL::Types::String, null: true,
description: 'Raw commit message.'
+
field :authored_date, type: Types::TimeType, null: true,
description: 'Timestamp of when the commit was authored.'
+
field :web_url, type: GraphQL::Types::String, null: false,
description: 'Web URL of the commit.'
+
field :web_path, type: GraphQL::Types::String, null: false,
description: 'Web path of the commit.'
+
field :signature_html, type: GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'Rendered HTML of the commit signature.'
+
field :author_name, type: GraphQL::Types::String, null: true,
description: 'Commit authors name.'
field :author_email, type: GraphQL::Types::String, null: true,
@@ -53,6 +57,10 @@ module Types
description: 'Pipelines of the commit ordered latest first.',
resolver: Resolvers::CommitPipelinesResolver
+ markdown_field :title_html, null: true
+ markdown_field :full_title_html, null: true
+ markdown_field :description_html, null: true
+
def author_gravatar
GravatarService.new.execute(object.author_email, 40)
end
diff --git a/app/graphql/types/group_invitation_type.rb b/app/graphql/types/group_invitation_type.rb
index 9410253553c..48281dcfd9f 100644
--- a/app/graphql/types/group_invitation_type.rb
+++ b/app/graphql/types/group_invitation_type.rb
@@ -2,14 +2,14 @@
module Types
class GroupInvitationType < BaseObject
+ graphql_name 'GroupInvitation'
+ description 'Represents a Group Invitation'
+
expose_permissions Types::PermissionTypes::Group
authorize :admin_group
implements InvitationInterface
- graphql_name 'GroupInvitation'
- description 'Represents a Group Invitation'
-
field :group, Types::GroupType, null: true,
description: 'Group that a User is invited to.'
diff --git a/app/graphql/types/group_member_type.rb b/app/graphql/types/group_member_type.rb
index 8b8e69d795d..d68abc11bba 100644
--- a/app/graphql/types/group_member_type.rb
+++ b/app/graphql/types/group_member_type.rb
@@ -2,14 +2,14 @@
module Types
class GroupMemberType < BaseObject
+ graphql_name 'GroupMember'
+ description 'Represents a Group Membership'
+
expose_permissions Types::PermissionTypes::Group
authorize :read_group
implements MemberInterface
- graphql_name 'GroupMember'
- description 'Represents a Group Membership'
-
field :group, Types::GroupType, null: true,
description: 'Group that a User is a member of.'
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index e02650fd285..5f63aa20953 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -94,6 +94,12 @@ module Types
max_page_size: 2000,
resolver: Resolvers::BoardsResolver
+ field :recent_issue_boards,
+ Types::BoardType.connection_type,
+ null: true,
+ description: 'List of recently visited boards of the group. Maximum size is 4.',
+ resolver: Resolvers::RecentBoardsResolver
+
field :board,
Types::BoardType,
null: true,
@@ -170,15 +176,6 @@ module Types
null: true,
description: 'Dependency proxy TTL policy for the group.'
- def label(title:)
- BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
- LabelsFinder
- .new(current_user, group: args[:key], title: titles)
- .execute
- .each { |label| loader.call(label.title, label) }
- end
- end
-
field :labels,
Types::LabelType.connection_type,
null: true,
@@ -215,6 +212,15 @@ module Types
description: 'Work item types available to the group.',
feature_flag: :work_items
+ def label(title:)
+ BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
+ LabelsFinder
+ .new(current_user, group: args[:key], title: titles)
+ .execute
+ .each { |label| loader.call(label.title, label) }
+ end
+ end
+
def avatar_url
object.avatar_url(only_path: false)
end
diff --git a/app/graphql/types/issuable_type.rb b/app/graphql/types/issuable_type.rb
index 6ca74087f8a..4a39b5ed6ec 100644
--- a/app/graphql/types/issuable_type.rb
+++ b/app/graphql/types/issuable_type.rb
@@ -5,10 +5,12 @@ module Types
graphql_name 'Issuable'
description 'Represents an issuable.'
- possible_types Types::IssueType, Types::MergeRequestType
+ possible_types Types::IssueType, Types::MergeRequestType, Types::WorkItemType
def self.resolve_type(object, context)
case object
+ when WorkItem
+ Types::WorkItemType
when Issue
Types::IssueType
when MergeRequest
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 46fe91feae4..ee57961ee4a 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -21,10 +21,8 @@ module Types
description: "Internal ID of the issue."
field :title, GraphQL::Types::String, null: false,
description: 'Title of the issue.'
- markdown_field :title_html, null: true
field :description, GraphQL::Types::String, null: true,
description: 'Description of the issue.'
- markdown_field :description_html, null: true
field :state, IssueStateEnum, null: false,
description: 'State of the issue.'
@@ -143,6 +141,9 @@ module Types
field :escalation_status, Types::IncidentManagement::EscalationStatusEnum, null: true,
description: 'Escalation status of the issue.'
+ markdown_field :title_html, null: true
+ markdown_field :description_html, null: true
+
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
@@ -168,13 +169,11 @@ module Types
end
def hidden?
- object.hidden? if Feature.enabled?(:ban_user_feature_flag)
+ object.hidden? if Feature.enabled?(:ban_user_feature_flag, default_enabled: :yaml)
end
def escalation_status
- return unless Feature.enabled?(:incident_escalations, object.project) && object.supports_escalation?
-
- object.escalation_status&.status_name
+ object.supports_escalation? ? object.escalation_status&.status_name : nil
end
end
end
diff --git a/app/graphql/types/label_type.rb b/app/graphql/types/label_type.rb
index bb2d561014e..5a10bcfee74 100644
--- a/app/graphql/types/label_type.rb
+++ b/app/graphql/types/label_type.rb
@@ -12,7 +12,6 @@ module Types
description: 'Label ID.'
field :description, GraphQL::Types::String, null: true,
description: 'Description of the label (Markdown rendered as HTML for caching).'
- markdown_field :description_html, null: true
field :title, GraphQL::Types::String, null: false,
description: 'Content of the label.'
field :color, GraphQL::Types::String, null: false,
@@ -23,5 +22,7 @@ module Types
description: 'When this label was created.'
field :updated_at, Types::TimeType, null: false,
description: 'When this label was last updated.'
+
+ markdown_field :description_html, null: true
end
end
diff --git a/app/graphql/types/member_interface.rb b/app/graphql/types/member_interface.rb
index c5623cd4710..67d0e18b522 100644
--- a/app/graphql/types/member_interface.rb
+++ b/app/graphql/types/member_interface.rb
@@ -25,6 +25,12 @@ module Types
field :user, Types::UserType, null: true,
description: 'User that is associated with the member object.'
+ field :merge_request_interaction, Types::UserMergeRequestInteractionType,
+ null: true,
+ description: 'Find a merge request.' do
+ argument :id, ::Types::GlobalIDType[::MergeRequest], required: true, description: 'Global ID of the merge request.'
+ end
+
definition_methods do
def resolve_type(object, context)
case object
@@ -37,5 +43,11 @@ module Types
end
end
end
+
+ def merge_request_interaction(id: nil)
+ Gitlab::Graphql::Lazy.with_value(GitlabSchema.object_from_id(id, expected_class: ::MergeRequest)) do |merge_request|
+ Users::MergeRequestInteraction.new(user: object.user, merge_request: merge_request) if merge_request
+ end
+ end
end
end
diff --git a/app/graphql/types/merge_request_sort_enum.rb b/app/graphql/types/merge_request_sort_enum.rb
index d75eae6abc4..a74c5a01769 100644
--- a/app/graphql/types/merge_request_sort_enum.rb
+++ b/app/graphql/types/merge_request_sort_enum.rb
@@ -9,5 +9,7 @@ module Types
value 'MERGED_AT_DESC', 'Merge time by descending order.', value: :merged_at_desc
value 'CLOSED_AT_ASC', 'Closed time by ascending order.', value: :closed_at_asc
value 'CLOSED_AT_DESC', 'Closed time by descending order.', value: :closed_at_desc
+ value 'TITLE_ASC', 'Title by ascending order.', value: :title_asc
+ value 'TITLE_DESC', 'Title by descending order.', value: :title_desc
end
end
diff --git a/app/graphql/types/merge_requests/assignee_type.rb b/app/graphql/types/merge_requests/assignee_type.rb
index 8448477370e..24321d057a3 100644
--- a/app/graphql/types/merge_requests/assignee_type.rb
+++ b/app/graphql/types/merge_requests/assignee_type.rb
@@ -3,11 +3,12 @@
module Types
module MergeRequests
class AssigneeType < ::Types::UserType
+ graphql_name 'MergeRequestAssignee'
+ description 'A user assigned to a merge request.'
+
include FindClosest
include ::Types::MergeRequests::InteractsWithMergeRequest
- graphql_name 'MergeRequestAssignee'
- description 'A user assigned to a merge request.'
authorize :read_user
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
index d4a1f2faa8d..15621ef1472 100644
--- a/app/graphql/types/merge_requests/interacts_with_merge_request.rb
+++ b/app/graphql/types/merge_requests/interacts_with_merge_request.rb
@@ -5,6 +5,8 @@ module Types
module InteractsWithMergeRequest
extend ActiveSupport::Concern
+ include FindClosest
+
included do
field :merge_request_interaction,
type: ::Types::UserMergeRequestInteractionType,
@@ -13,8 +15,9 @@ module Types
description: "Details of this user's interactions with the merge request."
end
- def merge_request_interaction(parent:)
+ def merge_request_interaction(parent:, id: nil)
merge_request = closest_parent([::Types::MergeRequestType], parent)
+
return unless merge_request
Users::MergeRequestInteraction.new(user: object, merge_request: merge_request)
diff --git a/app/graphql/types/merge_requests/reviewer_type.rb b/app/graphql/types/merge_requests/reviewer_type.rb
index 1ced821c839..11f7ceaf461 100644
--- a/app/graphql/types/merge_requests/reviewer_type.rb
+++ b/app/graphql/types/merge_requests/reviewer_type.rb
@@ -3,11 +3,12 @@
module Types
module MergeRequests
class ReviewerType < ::Types::UserType
+ graphql_name 'MergeRequestReviewer'
+ description 'A user assigned to a merge request as a reviewer.'
+
include FindClosest
include ::Types::MergeRequests::InteractsWithMergeRequest
- graphql_name 'MergeRequestReviewer'
- description 'A user assigned to a merge request as a reviewer.'
authorize :read_user
end
end
diff --git a/app/graphql/types/metrics/dashboards/annotation_type.rb b/app/graphql/types/metrics/dashboards/annotation_type.rb
index fb35f2bd9a1..0c787476f54 100644
--- a/app/graphql/types/metrics/dashboards/annotation_type.rb
+++ b/app/graphql/types/metrics/dashboards/annotation_type.rb
@@ -4,8 +4,8 @@ module Types
module Metrics
module Dashboards
class AnnotationType < ::Types::BaseObject
- authorize :read_metrics_dashboard_annotation
graphql_name 'MetricsDashboardAnnotation'
+ authorize :read_metrics_dashboard_annotation
field :description, GraphQL::Types::String, null: true,
description: 'Description of the annotation.'
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index c350f4dd922..3c735231595 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -2,10 +2,10 @@
module Types
class MutationType < BaseObject
- include Gitlab::Graphql::MountMutation
-
graphql_name 'Mutation'
+ include Gitlab::Graphql::MountMutation
+
mount_mutation Mutations::Admin::SidekiqQueues::DeleteJobs
mount_mutation Mutations::AlertManagement::CreateAlertIssue
mount_mutation Mutations::AlertManagement::UpdateAlertStatus
@@ -121,10 +121,13 @@ module Types
mount_mutation Mutations::Namespace::PackageSettings::Update
mount_mutation Mutations::Groups::Update
mount_mutation Mutations::UserCallouts::Create
+ mount_mutation Mutations::UserPreferences::Update
mount_mutation Mutations::Packages::Destroy
mount_mutation Mutations::Packages::DestroyFile
mount_mutation Mutations::Echo
- mount_mutation Mutations::WorkItems::Create, feature_flag: :work_items
+ mount_mutation Mutations::WorkItems::Create
+ mount_mutation Mutations::WorkItems::Delete
+ mount_mutation Mutations::WorkItems::Update
end
end
diff --git a/app/graphql/types/notes/discussion_type.rb b/app/graphql/types/notes/discussion_type.rb
index 56579c357a7..ffe61c9ff88 100644
--- a/app/graphql/types/notes/discussion_type.rb
+++ b/app/graphql/types/notes/discussion_type.rb
@@ -3,10 +3,10 @@
module Types
module Notes
class DiscussionType < BaseObject
- DiscussionID = ::Types::GlobalIDType[::Discussion]
-
graphql_name 'Discussion'
+ DiscussionID = ::Types::GlobalIDType[::Discussion]
+
authorize :read_note
implements(Types::ResolvableInterface)
diff --git a/app/graphql/types/packages/package_details_type.rb b/app/graphql/types/packages/package_details_type.rb
index 1d2cf9649d8..444ecb5e792 100644
--- a/app/graphql/types/packages/package_details_type.rb
+++ b/app/graphql/types/packages/package_details_type.rb
@@ -3,16 +3,17 @@
module Types
module Packages
class PackageDetailsType < PackageType
- include ::PackagesHelper
-
graphql_name 'PackageDetailsType'
description 'Represents a package details in the Package Registry. Note that this type is in beta and susceptible to changes'
+
+ include ::PackagesHelper
+
authorize :read_package
field :versions, ::Types::Packages::PackageType.connection_type, null: true,
description: 'Other versions of the package.'
- field :package_files, Types::Packages::PackageFileType.connection_type, null: true, description: 'Package files.'
+ field :package_files, Types::Packages::PackageFileType.connection_type, null: true, method: :installable_package_files, description: 'Package files.'
field :dependency_links, Types::Packages::PackageDependencyLinkType.connection_type, null: true, description: 'Dependency link.'
@@ -36,14 +37,6 @@ module Types
object.versions
end
- def package_files
- if Feature.enabled?(:packages_installable_package_files, default_enabled: :yaml)
- object.installable_package_files
- else
- object.package_files
- end
- end
-
def composer_config_repository_url
composer_config_repository_name(object.project.group&.id)
end
diff --git a/app/graphql/types/permission_types/issue.rb b/app/graphql/types/permission_types/issue.rb
index 94e1bffd685..b38971b64cd 100644
--- a/app/graphql/types/permission_types/issue.rb
+++ b/app/graphql/types/permission_types/issue.rb
@@ -3,8 +3,8 @@
module Types
module PermissionTypes
class Issue < BasePermissionType
- description 'Check permissions for the current user on a issue'
graphql_name 'IssuePermissions'
+ description 'Check permissions for the current user on a issue'
abilities :read_issue, :admin_issue, :update_issue, :reopen_issue,
:read_design, :create_design, :destroy_design,
diff --git a/app/graphql/types/permission_types/merge_request.rb b/app/graphql/types/permission_types/merge_request.rb
index 52c11fe5588..73a2f820f79 100644
--- a/app/graphql/types/permission_types/merge_request.rb
+++ b/app/graphql/types/permission_types/merge_request.rb
@@ -3,15 +3,16 @@
module Types
module PermissionTypes
class MergeRequest < BasePermissionType
+ graphql_name 'MergeRequestPermissions'
+ description 'Check permissions for the current user on a merge request'
+
+ present_using MergeRequestPresenter
+
PERMISSION_FIELDS = %i[push_to_source_branch
remove_source_branch
cherry_pick_on_current_merge_request
revert_on_current_merge_request].freeze
- present_using MergeRequestPresenter
- description 'Check permissions for the current user on a merge request'
- graphql_name 'MergeRequestPermissions'
-
abilities :read_merge_request, :admin_merge_request,
:update_merge_request, :create_note
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index d49244f6b65..dc428e7bdce 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -15,6 +15,8 @@ module Types
description: 'Full path of the project.'
field :path, GraphQL::Types::String, null: false,
description: 'Path of the project.'
+ field :ci_config_path_or_default, GraphQL::Types::String, null: false,
+ description: 'Path of the CI configuration file.'
field :sast_ci_configuration, Types::CiConfiguration::Sast::Type, null: true,
calls_gitaly: true,
@@ -195,6 +197,12 @@ module Types
extras: [:lookahead],
resolver: Resolvers::ProjectPipelineResolver
+ field :pipeline_counts,
+ Types::Ci::PipelineCountsType,
+ null: true,
+ description: 'Build pipeline counts of the project.',
+ resolver: Resolvers::Ci::ProjectPipelineCountsResolver
+
field :ci_cd_settings,
Types::Ci::CiCdSettingType,
null: true,
@@ -231,6 +239,12 @@ module Types
max_page_size: 2000,
resolver: Resolvers::BoardsResolver
+ field :recent_issue_boards,
+ Types::BoardType.connection_type,
+ null: true,
+ description: 'List of recently visited boards of the project. Maximum size is 4.',
+ resolver: Resolvers::RecentBoardsResolver
+
field :board,
Types::BoardType,
null: true,
diff --git a/app/graphql/types/query_complexity_type.rb b/app/graphql/types/query_complexity_type.rb
index 3f58a15aef7..13b618cf5ce 100644
--- a/app/graphql/types/query_complexity_type.rb
+++ b/app/graphql/types/query_complexity_type.rb
@@ -3,10 +3,10 @@
module Types
# rubocop: disable Graphql/AuthorizeTypes
class QueryComplexityType < ::Types::BaseObject
- ANALYZER = GraphQL::Analysis::QueryComplexity.new { |_query, complexity| complexity }
-
graphql_name 'QueryComplexity'
+ ANALYZER = GraphQL::Analysis::QueryComplexity.new { |_query, complexity| complexity }
+
alias_method :query, :object
field :limit, GraphQL::Types::Int,
diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb
index 28339093172..bfd59763a07 100644
--- a/app/graphql/types/repository/blob_type.rb
+++ b/app/graphql/types/repository/blob_type.rb
@@ -4,10 +4,10 @@ module Types
# rubocop: disable Graphql/AuthorizeTypes
# This is presented through `Repository` that has its own authorization
class BlobType < BaseObject
- present_using BlobPresenter
-
graphql_name 'RepositoryBlob'
+ present_using BlobPresenter
+
field :id, GraphQL::Types::ID, null: false,
description: 'ID of the blob.'
@@ -87,6 +87,14 @@ module Types
description: 'Web path to blob permalink.',
calls_gitaly: true
+ field :environment_formatted_external_url, GraphQL::Types::String, null: true,
+ description: 'Environment on which the blob is available.',
+ calls_gitaly: true
+
+ field :environment_external_url_for_route_map, GraphQL::Types::String, null: true,
+ description: 'Web path to blob on an environment.',
+ calls_gitaly: true
+
field :code_owners, [Types::UserType], null: true,
description: 'List of code owners for the blob.',
calls_gitaly: true
@@ -117,6 +125,12 @@ module Types
field :archived, GraphQL::Types::Boolean, null: true, method: :archived?,
description: 'Whether the current project is archived.'
+ field :language, GraphQL::Types::String,
+ description: 'Blob language.',
+ method: :blob_language,
+ null: true,
+ calls_gitaly: true
+
def raw_text_blob
object.data unless object.binary?
end
diff --git a/app/graphql/types/root_storage_statistics_type.rb b/app/graphql/types/root_storage_statistics_type.rb
index 88dc6036bfd..4dcadf1274f 100644
--- a/app/graphql/types/root_storage_statistics_type.rb
+++ b/app/graphql/types/root_storage_statistics_type.rb
@@ -15,5 +15,6 @@ module Types
field :snippets_size, GraphQL::Types::Float, null: false, description: 'Snippets size in bytes.'
field :pipeline_artifacts_size, GraphQL::Types::Float, null: false, description: 'CI pipeline artifacts size in bytes.'
field :uploads_size, GraphQL::Types::Float, null: false, description: 'Uploads size in bytes.'
+ field :dependency_proxy_size, GraphQL::Types::Float, null: false, description: 'Dependency Proxy sizes in bytes.'
end
end
diff --git a/app/graphql/types/subscription_type.rb b/app/graphql/types/subscription_type.rb
index 3629edb5b33..db6a247179d 100644
--- a/app/graphql/types/subscription_type.rb
+++ b/app/graphql/types/subscription_type.rb
@@ -9,5 +9,8 @@ module Types
field :issue_crm_contacts_updated, subscription: Subscriptions::IssuableUpdated, null: true,
description: 'Triggered when the crm contacts of an issuable are updated.'
+
+ field :issuable_title_updated, subscription: Subscriptions::IssuableUpdated, null: true,
+ description: 'Triggered when the title of an issuable is updated.'
end
end
diff --git a/app/graphql/types/terraform/state_version_type.rb b/app/graphql/types/terraform/state_version_type.rb
index bf1af4565bc..59da550aa1b 100644
--- a/app/graphql/types/terraform/state_version_type.rb
+++ b/app/graphql/types/terraform/state_version_type.rb
@@ -3,10 +3,10 @@
module Types
module Terraform
class StateVersionType < BaseObject
- include ::API::Helpers::RelatedResourcesHelpers
-
graphql_name 'TerraformStateVersion'
+ include ::API::Helpers::RelatedResourcesHelpers
+
authorize :read_terraform_state
field :id, GraphQL::Types::ID,
diff --git a/app/graphql/types/tree/blob_type.rb b/app/graphql/types/tree/blob_type.rb
index bb15d91a62f..bcff65be652 100644
--- a/app/graphql/types/tree/blob_type.rb
+++ b/app/graphql/types/tree/blob_type.rb
@@ -4,12 +4,11 @@ module Types
# rubocop: disable Graphql/AuthorizeTypes
# This is presented through `Repository` that has its own authorization
class BlobType < BaseObject
- implements Types::Tree::EntryType
+ graphql_name 'Blob'
+ implements Types::Tree::EntryType
present_using BlobPresenter
- graphql_name 'Blob'
-
field :web_url, GraphQL::Types::String, null: true,
description: 'Web URL of the blob.'
field :web_path, GraphQL::Types::String, null: true,
diff --git a/app/graphql/types/tree/submodule_type.rb b/app/graphql/types/tree/submodule_type.rb
index 05d8c1a951a..bc7828dbffa 100644
--- a/app/graphql/types/tree/submodule_type.rb
+++ b/app/graphql/types/tree/submodule_type.rb
@@ -4,10 +4,10 @@ module Types
# rubocop: disable Graphql/AuthorizeTypes
# This is presented through `Repository` that has its own authorization
class SubmoduleType < BaseObject
- implements Types::Tree::EntryType
-
graphql_name 'Submodule'
+ implements Types::Tree::EntryType
+
field :web_url, type: GraphQL::Types::String, null: true,
description: 'Web URL for the sub-module.'
field :tree_url, type: GraphQL::Types::String, null: true,
diff --git a/app/graphql/types/tree/tree_entry_type.rb b/app/graphql/types/tree/tree_entry_type.rb
index 998b3617574..cdc84c8e318 100644
--- a/app/graphql/types/tree/tree_entry_type.rb
+++ b/app/graphql/types/tree/tree_entry_type.rb
@@ -4,13 +4,12 @@ module Types
# rubocop: disable Graphql/AuthorizeTypes
# This is presented through `Repository` that has its own authorization
class TreeEntryType < BaseObject
- implements Types::Tree::EntryType
-
- present_using TreeEntryPresenter
-
graphql_name 'TreeEntry'
description 'Represents a directory'
+ implements Types::Tree::EntryType
+ present_using TreeEntryPresenter
+
field :web_url, GraphQL::Types::String, null: true,
description: 'Web URL for the tree entry (directory).'
field :web_path, GraphQL::Types::String, null: true,
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 6bb4cb29cdd..24fca80d5a9 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -31,7 +31,7 @@ module Types
null: false,
resolver_method: :redacted_name,
description: 'Human-readable name of the user. ' \
- 'Will return `****` if the user is a project bot and the requester does not have permission to read resource access tokens.'
+ 'Returns `****` if the user is a project bot and the requester does not have permission to view the project.'
field :state,
type: Types::UserStateEnum,
@@ -127,7 +127,7 @@ module Types
def redacted_name
return object.name unless object.project_bot?
- return object.name if context[:current_user]&.can?(:read_resource_access_tokens, object.projects.first)
+ return object.name if context[:current_user]&.can?(:read_project, object.projects.first)
# If the requester does not have permission to read the project bot name,
# the API returns an arbitrary string. UI changes will be addressed in a follow up issue:
diff --git a/app/graphql/types/user_preferences_type.rb b/app/graphql/types/user_preferences_type.rb
new file mode 100644
index 00000000000..9a1ea4a2e4f
--- /dev/null
+++ b/app/graphql/types/user_preferences_type.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop: disable Graphql/AuthorizeTypes
+ # Only used to render the current user's own preferences
+ class UserPreferencesType < BaseObject
+ graphql_name 'UserPreferences'
+
+ field :issues_sort, Types::IssueSortEnum,
+ description: 'Sort order for issue lists.',
+ null: true
+
+ def issues_sort
+ object.issues_sort.to_sym
+ end
+ end
+end
diff --git a/app/graphql/types/work_item_state_enum.rb b/app/graphql/types/work_item_state_enum.rb
new file mode 100644
index 00000000000..8fe58f76d9a
--- /dev/null
+++ b/app/graphql/types/work_item_state_enum.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Types
+ class WorkItemStateEnum < BaseEnum
+ graphql_name 'WorkItemState'
+ description 'State of a GitLab work item'
+
+ value 'OPEN', 'In open state.', value: 'opened'
+ value 'CLOSED', 'In closed state.', value: 'closed'
+ end
+end
diff --git a/app/graphql/types/work_item_type.rb b/app/graphql/types/work_item_type.rb
index 486c1e52987..15a5557b489 100644
--- a/app/graphql/types/work_item_type.rb
+++ b/app/graphql/types/work_item_type.rb
@@ -12,6 +12,8 @@ module Types
description: 'Global ID of the work item.'
field :iid, GraphQL::Types::ID, null: false,
description: 'Internal ID of the work item.'
+ field :state, WorkItemStateEnum, null: false,
+ description: 'State of the work item.'
field :title, GraphQL::Types::String, null: false,
description: 'Title of the work item.'
field :work_item_type, Types::WorkItems::TypeType, null: false,
diff --git a/app/graphql/types/work_items/state_event_enum.rb b/app/graphql/types/work_items/state_event_enum.rb
new file mode 100644
index 00000000000..db54d494c12
--- /dev/null
+++ b/app/graphql/types/work_items/state_event_enum.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ class StateEventEnum < BaseEnum
+ graphql_name 'WorkItemStateEvent'
+ description 'Values for work item state events'
+
+ value 'REOPEN', 'Reopens the work item.', value: 'reopen'
+ value 'CLOSE', 'Closes the work item.', value: 'close'
+ end
+ end
+end