summaryrefslogtreecommitdiff
path: root/app/graphql/mutations
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/mutations')
-rw-r--r--app/graphql/mutations/base_mutation.rb18
-rw-r--r--app/graphql/mutations/ci/pipeline/destroy.rb13
-rw-r--r--app/graphql/mutations/ci/runner/update.rb4
-rw-r--r--app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb21
-rw-r--r--app/graphql/mutations/incident_management/timeline_event/create.rb4
-rw-r--r--app/graphql/mutations/incident_management/timeline_event/promote_from_note.rb3
-rw-r--r--app/graphql/mutations/issues/set_crm_contacts.rb2
-rw-r--r--app/graphql/mutations/merge_requests/set_draft.rb4
-rw-r--r--app/graphql/mutations/packages/cleanup/policy/update.rb48
-rw-r--r--app/graphql/mutations/packages/destroy_files.rb54
-rw-r--r--app/graphql/mutations/releases/create.rb4
-rw-r--r--app/graphql/mutations/security/ci_configuration/configure_sast.rb2
-rw-r--r--app/graphql/mutations/terraform/state/delete.rb4
-rw-r--r--app/graphql/mutations/user_preferences/update.rb17
-rw-r--r--app/graphql/mutations/work_items/create.rb3
-rw-r--r--app/graphql/mutations/work_items/create_from_task.rb2
-rw-r--r--app/graphql/mutations/work_items/delete.rb2
-rw-r--r--app/graphql/mutations/work_items/delete_task.rb3
-rw-r--r--app/graphql/mutations/work_items/update.rb13
-rw-r--r--app/graphql/mutations/work_items/update_task.rb77
-rw-r--r--app/graphql/mutations/work_items/update_widgets.rb59
21 files changed, 307 insertions, 50 deletions
diff --git a/app/graphql/mutations/base_mutation.rb b/app/graphql/mutations/base_mutation.rb
index d57a097a9e2..5f98b222099 100644
--- a/app/graphql/mutations/base_mutation.rb
+++ b/app/graphql/mutations/base_mutation.rb
@@ -39,14 +39,16 @@ module Mutations
true
end
- def load_application_object(argument, lookup_as_type, id, context)
- ::Gitlab::Graphql::Lazy.new { super }.catch(::GraphQL::UnauthorizedError) do |e|
- Gitlab::ErrorTracking.track_exception(e)
- # The default behaviour is to abort processing and return nil for the
- # entire mutation field, but not set any top-level errors. We prefer to
- # at least say that something went wrong.
- raise_resource_not_available_error!
- end
+ def load_application_object(argument, id, context)
+ ::Gitlab::Graphql::Lazy.new { super }
+ end
+
+ def unauthorized_object(error)
+ # The default behavior is to abort processing and return nil for the
+ # entire mutation field, but not set any top-level errors. We prefer to
+ # at least say that something went wrong.
+ Gitlab::ErrorTracking.track_exception(error)
+ raise_resource_not_available_error!
end
def self.authorizes_object?
diff --git a/app/graphql/mutations/ci/pipeline/destroy.rb b/app/graphql/mutations/ci/pipeline/destroy.rb
index 3f933818ce1..935cf45c4ab 100644
--- a/app/graphql/mutations/ci/pipeline/destroy.rb
+++ b/app/graphql/mutations/ci/pipeline/destroy.rb
@@ -12,12 +12,25 @@ module Mutations
pipeline = authorized_find!(id: id)
project = pipeline.project
+ return undergoing_refresh_error(project) if project.refreshing_build_artifacts_size?
+
result = ::Ci::DestroyPipelineService.new(project, current_user).execute(pipeline)
{
success: result.success?,
errors: result.errors
}
end
+
+ private
+
+ def undergoing_refresh_error(project)
+ Gitlab::ProjectStatsRefreshConflictsLogger.warn_request_rejected_during_stats_refresh(project.id)
+
+ {
+ success: false,
+ errors: ['Action temporarily disabled. The project this pipeline belongs to is undergoing stats refresh.']
+ }
+ end
end
end
end
diff --git a/app/graphql/mutations/ci/runner/update.rb b/app/graphql/mutations/ci/runner/update.rb
index faccd1273e5..b6d8c20c40b 100644
--- a/app/graphql/mutations/ci/runner/update.rb
+++ b/app/graphql/mutations/ci/runner/update.rb
@@ -18,6 +18,10 @@ module Mutations
required: false,
description: 'Description of the runner.'
+ argument :maintenance_note, GraphQL::Types::String,
+ required: false,
+ description: 'Runner\'s maintenance notes.'
+
argument :maximum_timeout, GraphQL::Types::Int,
required: false,
description: 'Maximum timeout (in seconds) for jobs processed by the runner.'
diff --git a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
new file mode 100644
index 00000000000..6a91a097a17
--- /dev/null
+++ b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ module UpdateArguments
+ extend ActiveSupport::Concern
+
+ included do
+ 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)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/incident_management/timeline_event/create.rb b/app/graphql/mutations/incident_management/timeline_event/create.rb
index cbc708a2530..1907954cada 100644
--- a/app/graphql/mutations/incident_management/timeline_event/create.rb
+++ b/app/graphql/mutations/incident_management/timeline_event/create.rb
@@ -23,7 +23,9 @@ module Mutations
authorize!(incident)
- response ::IncidentManagement::TimelineEvents::CreateService.new(incident, current_user, args).execute
+ response ::IncidentManagement::TimelineEvents::CreateService.new(
+ incident, current_user, args.merge(editable: true)
+ ).execute
end
private
diff --git a/app/graphql/mutations/incident_management/timeline_event/promote_from_note.rb b/app/graphql/mutations/incident_management/timeline_event/promote_from_note.rb
index 73a20b8a380..31ae29d896b 100644
--- a/app/graphql/mutations/incident_management/timeline_event/promote_from_note.rb
+++ b/app/graphql/mutations/incident_management/timeline_event/promote_from_note.rb
@@ -21,7 +21,8 @@ module Mutations
current_user,
promoted_from_note: note,
note: note.note,
- occurred_at: note.created_at
+ occurred_at: note.created_at,
+ editable: true
).execute
end
diff --git a/app/graphql/mutations/issues/set_crm_contacts.rb b/app/graphql/mutations/issues/set_crm_contacts.rb
index 4df65e4769c..cc718b4ae33 100644
--- a/app/graphql/mutations/issues/set_crm_contacts.rb
+++ b/app/graphql/mutations/issues/set_crm_contacts.rb
@@ -48,7 +48,7 @@ module Mutations
private
def feature_enabled?(project)
- Feature.enabled?(:customer_relations, project.group) && project.group&.crm_enabled?
+ project.group&.crm_enabled?
end
end
end
diff --git a/app/graphql/mutations/merge_requests/set_draft.rb b/app/graphql/mutations/merge_requests/set_draft.rb
index ab4ca73e5dc..f83c1a0caf4 100644
--- a/app/graphql/mutations/merge_requests/set_draft.rb
+++ b/app/graphql/mutations/merge_requests/set_draft.rb
@@ -27,8 +27,8 @@ module Mutations
private
- def wip_event(wip)
- wip ? 'wip' : 'unwip'
+ def wip_event(draft)
+ draft ? 'draft' : 'ready'
end
end
end
diff --git a/app/graphql/mutations/packages/cleanup/policy/update.rb b/app/graphql/mutations/packages/cleanup/policy/update.rb
new file mode 100644
index 00000000000..e7ab7439949
--- /dev/null
+++ b/app/graphql/mutations/packages/cleanup/policy/update.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Packages
+ module Cleanup
+ module Policy
+ class Update < Mutations::BaseMutation
+ graphql_name 'UpdatePackagesCleanupPolicy'
+
+ include FindsProject
+
+ authorize :admin_package
+
+ argument :project_path,
+ GraphQL::Types::ID,
+ required: true,
+ description: 'Project path where the packages cleanup policy is located.'
+
+ argument :keep_n_duplicated_package_files,
+ Types::Packages::Cleanup::KeepDuplicatedPackageFilesEnum,
+ required: false,
+ description: copy_field_description(
+ Types::Packages::Cleanup::PolicyType,
+ :keep_n_duplicated_package_files
+ )
+
+ field :packages_cleanup_policy,
+ Types::Packages::Cleanup::PolicyType,
+ null: true,
+ description: 'Packages cleanup policy after mutation.'
+
+ def resolve(project_path:, **args)
+ project = authorized_find!(project_path)
+
+ result = ::Packages::Cleanup::UpdatePolicyService
+ .new(project: project, current_user: current_user, params: args)
+ .execute
+
+ {
+ packages_cleanup_policy: result.payload[:packages_cleanup_policy],
+ errors: result.errors
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/packages/destroy_files.rb b/app/graphql/mutations/packages/destroy_files.rb
new file mode 100644
index 00000000000..3900a2c46ae
--- /dev/null
+++ b/app/graphql/mutations/packages/destroy_files.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Packages
+ class DestroyFiles < ::Mutations::BaseMutation
+ graphql_name 'DestroyPackageFiles'
+
+ include FindsProject
+
+ MAXIMUM_FILES = 100
+
+ authorize :destroy_package
+
+ argument :project_path,
+ GraphQL::Types::ID,
+ required: true,
+ description: 'Project path where the packages cleanup policy is located.'
+
+ argument :ids,
+ [::Types::GlobalIDType[::Packages::PackageFile]],
+ required: true,
+ description: 'IDs of the Package file.'
+
+ def resolve(project_path:, ids:)
+ project = authorized_find!(project_path)
+ raise_resource_not_available_error! "Cannot delete more than #{MAXIMUM_FILES} files" if ids.size > MAXIMUM_FILES
+
+ package_files = ::Packages::PackageFile.where(id: parse_gids(ids)) # rubocop:disable CodeReuse/ActiveRecord
+
+ ensure_file_access!(project, package_files)
+
+ result = ::Packages::MarkPackageFilesForDestructionService.new(package_files).execute
+
+ errors = result.error? ? Array.wrap(result[:message]) : []
+
+ { errors: errors }
+ end
+
+ private
+
+ def ensure_file_access!(project, package_files)
+ project_ids = package_files.map(&:project_id).uniq
+
+ unless project_ids.size == 1 && project_ids.include?(project.id)
+ raise_resource_not_available_error! 'All files must be in the requested project'
+ end
+ end
+
+ def parse_gids(gids)
+ gids.map { |gid| GitlabSchema.parse_gid(gid, expected_type: ::Packages::PackageFile).model_id }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/releases/create.rb b/app/graphql/mutations/releases/create.rb
index 037ade2589c..70a0e71c869 100644
--- a/app/graphql/mutations/releases/create.rb
+++ b/app/graphql/mutations/releases/create.rb
@@ -14,6 +14,10 @@ module Mutations
required: true, as: :tag,
description: 'Name of the tag to associate with the release.'
+ argument :tag_message, GraphQL::Types::String,
+ required: false,
+ description: 'Message to use if creating a new annotated tag.'
+
argument :ref, GraphQL::Types::String,
required: false,
description: 'Commit SHA or branch name to use if creating a new tag.'
diff --git a/app/graphql/mutations/security/ci_configuration/configure_sast.rb b/app/graphql/mutations/security/ci_configuration/configure_sast.rb
index 7ce0bf83a4b..cc3c1d6033b 100644
--- a/app/graphql/mutations/security/ci_configuration/configure_sast.rb
+++ b/app/graphql/mutations/security/ci_configuration/configure_sast.rb
@@ -16,7 +16,7 @@ module Mutations
description: 'SAST CI configuration for the project.'
def configure_analyzer(project, **args)
- ::Security::CiConfiguration::SastCreateService.new(project, current_user, args[:configuration]).execute
+ ::Security::CiConfiguration::SastCreateService.new(project, current_user, args[:configuration].to_h).execute
end
end
end
diff --git a/app/graphql/mutations/terraform/state/delete.rb b/app/graphql/mutations/terraform/state/delete.rb
index f08219cb395..f52ace07393 100644
--- a/app/graphql/mutations/terraform/state/delete.rb
+++ b/app/graphql/mutations/terraform/state/delete.rb
@@ -8,9 +8,9 @@ module Mutations
def resolve(id:)
state = authorized_find!(id: id)
- state.destroy
+ response = ::Terraform::States::TriggerDestroyService.new(state, current_user: current_user).execute
- { errors: errors_on_object(state) }
+ { errors: response.errors }
end
end
end
diff --git a/app/graphql/mutations/user_preferences/update.rb b/app/graphql/mutations/user_preferences/update.rb
index b71c952b0f2..c92c6d725b7 100644
--- a/app/graphql/mutations/user_preferences/update.rb
+++ b/app/graphql/mutations/user_preferences/update.rb
@@ -14,15 +14,6 @@ module Mutations
null: true,
description: 'User preferences after mutation.'
- def ready?(**args)
- if disabled_sort_value?(args)
- raise Gitlab::Graphql::Errors::ArgumentError,
- 'Feature flag `incident_escalations` must be enabled to use this sort order.'
- end
-
- super
- end
-
def resolve(**attributes)
user_preferences = current_user.user_preference
user_preferences.update(attributes)
@@ -32,14 +23,6 @@ module Mutations
errors: errors_on_object(user_preferences)
}
end
-
- private
-
- def disabled_sort_value?(args)
- return false unless [:escalation_status_asc, :escalation_status_desc].include?(args[:issues_sort])
-
- Feature.disabled?(:incident_escalations)
- end
end
end
end
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index 2e136d409ab..2ae26ed0e1a 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -8,8 +8,7 @@ module Mutations
include Mutations::SpamProtection
include FindsProject
- 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."
+ description "Creates a work item. Available only when feature flag `work_items` is enabled."
authorize :create_work_item
diff --git a/app/graphql/mutations/work_items/create_from_task.rb b/app/graphql/mutations/work_items/create_from_task.rb
index 4da709401a6..5ebe8b2c6d7 100644
--- a/app/graphql/mutations/work_items/create_from_task.rb
+++ b/app/graphql/mutations/work_items/create_from_task.rb
@@ -8,7 +8,7 @@ module Mutations
include Mutations::SpamProtection
description "Creates a work item from a task in another work item's description." \
- " Available only when feature flag `work_items` is enabled. This feature is experimental and is subject to change without notice."
+ " Available only when feature flag `work_items` is enabled."
authorize :update_work_item
diff --git a/app/graphql/mutations/work_items/delete.rb b/app/graphql/mutations/work_items/delete.rb
index 1830ab5443c..240a8b4c11e 100644
--- a/app/graphql/mutations/work_items/delete.rb
+++ b/app/graphql/mutations/work_items/delete.rb
@@ -5,7 +5,7 @@ module Mutations
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."
+ " Available only when feature flag `work_items` is enabled."
authorize :delete_work_item
diff --git a/app/graphql/mutations/work_items/delete_task.rb b/app/graphql/mutations/work_items/delete_task.rb
index 87620a28fa1..b1bfed0cbf1 100644
--- a/app/graphql/mutations/work_items/delete_task.rb
+++ b/app/graphql/mutations/work_items/delete_task.rb
@@ -6,8 +6,7 @@ module Mutations
graphql_name 'WorkItemDeleteTask'
description "Deletes a task in a work item's description." \
- ' Available only when feature flag `work_items` is enabled. This feature is experimental and' \
- ' is subject to change without notice.'
+ ' Available only when feature flag `work_items` is enabled.'
authorize :update_work_item
diff --git a/app/graphql/mutations/work_items/update.rb b/app/graphql/mutations/work_items/update.rb
index 20319301482..c495da00f41 100644
--- a/app/graphql/mutations/work_items/update.rb
+++ b/app/graphql/mutations/work_items/update.rb
@@ -5,22 +5,13 @@ module Mutations
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."
+ " Available only when feature flag `work_items` is enabled."
include Mutations::SpamProtection
+ include Mutations::WorkItems::UpdateArguments
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.'
diff --git a/app/graphql/mutations/work_items/update_task.rb b/app/graphql/mutations/work_items/update_task.rb
new file mode 100644
index 00000000000..35fbe672b66
--- /dev/null
+++ b/app/graphql/mutations/work_items/update_task.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ class UpdateTask < BaseMutation
+ graphql_name 'WorkItemUpdateTask'
+ description "Updates a work item's task by Global ID." \
+ " Available only when feature flag `work_items` is enabled."
+
+ include Mutations::SpamProtection
+
+ authorize :read_work_item
+
+ argument :id, ::Types::GlobalIDType[::WorkItem],
+ required: true,
+ description: 'Global ID of the work item.'
+ argument :task_data, ::Types::WorkItems::UpdatedTaskInputType,
+ required: true,
+ description: 'Arguments necessary to update a task.'
+
+ field :task, Types::WorkItemType,
+ null: true,
+ description: 'Updated task.'
+ field :work_item, Types::WorkItemType,
+ null: true,
+ description: 'Updated work item.'
+
+ def resolve(id:, task_data:)
+ task_data_hash = task_data.to_h
+ work_item = authorized_find!(id: id)
+ task = authorized_find_task!(task_data_hash[:id])
+
+ unless work_item.project.work_items_feature_flag_enabled?
+ 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: task.project,
+ current_user: current_user,
+ params: task_data_hash.except(:id),
+ spam_params: spam_params
+ ).execute(task)
+
+ check_spam_action_response!(task)
+
+ response = { errors: errors_on_object(task) }
+
+ if task.valid?
+ work_item.expire_etag_cache
+
+ response.merge(work_item: work_item, task: task)
+ else
+ response
+ end
+ end
+
+ private
+
+ def authorized_find_task!(task_id)
+ task = task_id.find
+
+ if current_user.can?(:update_work_item, task)
+ task
+ else
+ # Fail early if user cannot update task
+ raise_resource_not_available_error!
+ end
+ end
+
+ def find_object(id:)
+ id.find
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/update_widgets.rb b/app/graphql/mutations/work_items/update_widgets.rb
new file mode 100644
index 00000000000..d19da0abaac
--- /dev/null
+++ b/app/graphql/mutations/work_items/update_widgets.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ class UpdateWidgets < BaseMutation
+ graphql_name 'WorkItemUpdateWidgets'
+ description "Updates the attributes of a work item's widgets by global ID." \
+ " Available only when feature flag `work_items` is enabled."
+
+ include Mutations::SpamProtection
+
+ authorize :update_work_item
+
+ argument :id, ::Types::GlobalIDType[::WorkItem],
+ required: true,
+ description: 'Global ID of the work item.'
+
+ argument :description_widget, ::Types::WorkItems::Widgets::DescriptionInputType,
+ required: false,
+ description: 'Input for description widget.'
+
+ field :work_item, Types::WorkItemType,
+ null: true,
+ description: 'Updated work item.'
+
+ def resolve(id:, **widget_attributes)
+ work_item = authorized_find!(id: id)
+
+ unless work_item.project.work_items_feature_flag_enabled?
+ 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,
+ # Cannot use prepare to use `.to_h` on each input due to
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87472#note_945199865
+ widget_params: widget_attributes.transform_values { |values| values.to_h },
+ 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:)
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+end