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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /app/graphql
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'app/graphql')
-rw-r--r--app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb9
-rw-r--r--app/graphql/mutations/concerns/mutations/work_items/widgetable.rb25
-rw-r--r--app/graphql/mutations/notes/create/diff_note.rb3
-rw-r--r--app/graphql/mutations/pages/base.rb13
-rw-r--r--app/graphql/mutations/pages/mark_onboarding_complete.rb27
-rw-r--r--app/graphql/mutations/snippets/create.rb2
-rw-r--r--app/graphql/mutations/snippets/update.rb2
-rw-r--r--app/graphql/mutations/user_callouts/create.rb2
-rw-r--r--app/graphql/mutations/work_items/create.rb16
-rw-r--r--app/graphql/mutations/work_items/update.rb9
-rw-r--r--app/graphql/mutations/work_items/update_widgets.rb1
-rw-r--r--app/graphql/queries/container_registry/get_container_repositories.query.graphql8
-rw-r--r--app/graphql/queries/repository/path_last_commit.query.graphql59
-rw-r--r--app/graphql/resolvers/ci/jobs_resolver.rb8
-rw-r--r--app/graphql/resolvers/ci/runners_resolver.rb5
-rw-r--r--app/graphql/resolvers/ci/test_suite_resolver.rb2
-rw-r--r--app/graphql/resolvers/clusters/agents_resolver.rb6
-rw-r--r--app/graphql/resolvers/todo_resolver.rb66
-rw-r--r--app/graphql/resolvers/todos_resolver.rb69
-rw-r--r--app/graphql/types/alert_management/alert_type.rb2
-rw-r--r--app/graphql/types/ci/job_type.rb12
-rw-r--r--app/graphql/types/ci/runner_type.rb7
-rw-r--r--app/graphql/types/ci/runner_upgrade_status_type_enum.rb11
-rw-r--r--app/graphql/types/ci/variable_type.rb40
-rw-r--r--app/graphql/types/ci/variable_type_enum.rb13
-rw-r--r--app/graphql/types/group_type.rb7
-rw-r--r--app/graphql/types/issue_type_enum.rb4
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/graphql/types/permission_types/group_enum.rb2
-rw-r--r--app/graphql/types/project_type.rb11
-rw-r--r--app/graphql/types/query_type.rb15
-rw-r--r--app/graphql/types/release_type.rb2
-rw-r--r--app/graphql/types/user_interface.rb2
-rw-r--r--app/graphql/types/work_item_id_type.rb1
-rw-r--r--app/graphql/types/work_items/widget_interface.rb8
-rw-r--r--app/graphql/types/work_items/widgets/assignees_type.rb31
-rw-r--r--app/graphql/types/work_items/widgets/hierarchy_create_input_type.rb16
-rw-r--r--app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb22
-rw-r--r--app/graphql/types/work_items/widgets/weight_input_type.rb15
-rw-r--r--app/graphql/types/work_items/widgets/weight_type.rb21
40 files changed, 466 insertions, 109 deletions
diff --git a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
index 6a91a097a17..cbe1cfb4099 100644
--- a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
+++ b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
@@ -15,6 +15,15 @@ module Mutations
argument :title, GraphQL::Types::String,
required: false,
description: copy_field_description(Types::WorkItemType, :title)
+ argument :description_widget, ::Types::WorkItems::Widgets::DescriptionInputType,
+ required: false,
+ description: 'Input for description widget.'
+ argument :weight_widget, ::Types::WorkItems::Widgets::WeightInputType,
+ required: false,
+ description: 'Input for weight widget.'
+ argument :hierarchy_widget, ::Types::WorkItems::Widgets::HierarchyUpdateInputType,
+ required: false,
+ description: 'Input for hierarchy widget.'
end
end
end
diff --git a/app/graphql/mutations/concerns/mutations/work_items/widgetable.rb b/app/graphql/mutations/concerns/mutations/work_items/widgetable.rb
new file mode 100644
index 00000000000..445b2eb6441
--- /dev/null
+++ b/app/graphql/mutations/concerns/mutations/work_items/widgetable.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ module Widgetable
+ extend ActiveSupport::Concern
+
+ def extract_widget_params!(work_item_type, attributes)
+ # Get the list of widgets for the work item's type to extract only the supported attributes
+ widget_keys = ::WorkItems::Type.available_widgets.map(&:api_symbol)
+ widget_params = attributes.extract!(*widget_keys)
+
+ not_supported_keys = widget_params.keys - work_item_type.widgets.map(&:api_symbol)
+ if not_supported_keys.present?
+ raise Gitlab::Graphql::Errors::ArgumentError,
+ "Following widget keys are not supported by #{work_item_type.name} type: #{not_supported_keys}"
+ end
+
+ # 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.transform_values { |values| values.to_h }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/notes/create/diff_note.rb b/app/graphql/mutations/notes/create/diff_note.rb
index 019e7cb8623..7b8c06fd104 100644
--- a/app/graphql/mutations/notes/create/diff_note.rb
+++ b/app/graphql/mutations/notes/create/diff_note.rb
@@ -32,7 +32,8 @@ module Mutations
def create_note_params(noteable, args)
super(noteable, args).merge({
type: 'DiffNote',
- position: position(noteable, args)
+ position: position(noteable, args),
+ merge_request_diff_head_sha: args[:position][:head_sha]
})
end
diff --git a/app/graphql/mutations/pages/base.rb b/app/graphql/mutations/pages/base.rb
new file mode 100644
index 00000000000..5eb8ecdf0ba
--- /dev/null
+++ b/app/graphql/mutations/pages/base.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Pages
+ class Base < BaseMutation
+ include FindsProject
+
+ argument :project_path, GraphQL::Types::ID,
+ required: true,
+ description: 'Full path of the project.'
+ end
+ end
+end
diff --git a/app/graphql/mutations/pages/mark_onboarding_complete.rb b/app/graphql/mutations/pages/mark_onboarding_complete.rb
new file mode 100644
index 00000000000..2f5ce5db54a
--- /dev/null
+++ b/app/graphql/mutations/pages/mark_onboarding_complete.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Pages
+ class MarkOnboardingComplete < Base
+ graphql_name 'PagesMarkOnboardingComplete'
+
+ field :onboarding_complete,
+ Boolean,
+ null: false,
+ description: "Indicates the new onboarding_complete state of the project's Pages metadata."
+
+ authorize :admin_project
+
+ def resolve(project_path:)
+ project = authorized_find!(project_path)
+
+ project.mark_pages_onboarding_complete
+
+ {
+ onboarding_complete: project.pages_metadatum.onboarding_complete,
+ errors: errors_on_object(project)
+ }
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb
index 2921a77b86d..96ac3f8a113 100644
--- a/app/graphql/mutations/snippets/create.rb
+++ b/app/graphql/mutations/snippets/create.rb
@@ -54,7 +54,7 @@ module Mutations
# Only when the user is not an api user and the operation was successful
if !api_user? && service_response.success?
- ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user)
+ ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user, project: project)
end
snippet = service_response.payload[:snippet]
diff --git a/app/graphql/mutations/snippets/update.rb b/app/graphql/mutations/snippets/update.rb
index 2a2941c5328..39843a3714a 100644
--- a/app/graphql/mutations/snippets/update.rb
+++ b/app/graphql/mutations/snippets/update.rb
@@ -43,7 +43,7 @@ module Mutations
# Only when the user is not an api user and the operation was successful
if !api_user? && service_response.success?
- ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user)
+ ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user, project: snippet.project)
end
snippet = service_response.payload[:snippet]
diff --git a/app/graphql/mutations/user_callouts/create.rb b/app/graphql/mutations/user_callouts/create.rb
index 1be99ea0ecd..7f372053e84 100644
--- a/app/graphql/mutations/user_callouts/create.rb
+++ b/app/graphql/mutations/user_callouts/create.rb
@@ -15,7 +15,7 @@ module Mutations
description: 'User callout dismissed.'
def resolve(feature_name:)
- callout = Users::DismissCalloutService.new(
+ callout = ::Users::DismissCalloutService.new(
container: nil, current_user: current_user, params: { feature_name: feature_name }
).execute
errors = errors_on_object(callout)
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index 2ae26ed0e1a..350153eaf19 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -7,6 +7,7 @@ module Mutations
include Mutations::SpamProtection
include FindsProject
+ include Mutations::WorkItems::Widgetable
description "Creates a work item. Available only when feature flag `work_items` is enabled."
@@ -15,6 +16,9 @@ module Mutations
argument :description, GraphQL::Types::String,
required: false,
description: copy_field_description(Types::WorkItemType, :description)
+ argument :hierarchy_widget, ::Types::WorkItems::Widgets::HierarchyCreateInputType,
+ required: false,
+ description: 'Input for hierarchy widget.'
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Full path of the project the work item is associated with.'
@@ -36,10 +40,18 @@ module Mutations
return { errors: ['`work_items` feature flag disabled for this project'] }
end
+ spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
+ type = ::WorkItems::Type.find(attributes[:work_item_type_id])
+ widget_params = extract_widget_params!(type, params)
- spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
- create_result = ::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,
+ widget_params: widget_params
+ ).execute
check_spam_action_response!(create_result[:work_item]) if create_result[:work_item]
diff --git a/app/graphql/mutations/work_items/update.rb b/app/graphql/mutations/work_items/update.rb
index c495da00f41..5d8c574877a 100644
--- a/app/graphql/mutations/work_items/update.rb
+++ b/app/graphql/mutations/work_items/update.rb
@@ -9,6 +9,7 @@ module Mutations
include Mutations::SpamProtection
include Mutations::WorkItems::UpdateArguments
+ include Mutations::WorkItems::Widgetable
authorize :update_work_item
@@ -24,19 +25,21 @@ module Mutations
end
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
+ widget_params = extract_widget_params!(work_item.work_item_type, attributes)
- ::WorkItems::UpdateService.new(
+ update_result = ::WorkItems::UpdateService.new(
project: work_item.project,
current_user: current_user,
params: attributes,
+ widget_params: widget_params,
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)
+ work_item: (update_result[:work_item] if update_result[:status] == :success),
+ errors: Array.wrap(update_result[:message])
}
end
diff --git a/app/graphql/mutations/work_items/update_widgets.rb b/app/graphql/mutations/work_items/update_widgets.rb
index d19da0abaac..7037b7e5a2a 100644
--- a/app/graphql/mutations/work_items/update_widgets.rb
+++ b/app/graphql/mutations/work_items/update_widgets.rb
@@ -2,6 +2,7 @@
module Mutations
module WorkItems
+ # TODO: Deprecate in favor of using WorkItemUpdate. See https://gitlab.com/gitlab-org/gitlab/-/issues/366300
class UpdateWidgets < BaseMutation
graphql_name 'WorkItemUpdateWidgets'
description "Updates the attributes of a work item's widgets by global ID." \
diff --git a/app/graphql/queries/container_registry/get_container_repositories.query.graphql b/app/graphql/queries/container_registry/get_container_repositories.query.graphql
index 264878ccaa2..5f995eb958b 100644
--- a/app/graphql/queries/container_registry/get_container_repositories.query.graphql
+++ b/app/graphql/queries/container_registry/get_container_repositories.query.graphql
@@ -32,6 +32,10 @@ query getProjectContainerRepositories(
createdAt
expirationPolicyStartedAt
expirationPolicyCleanupStatus
+ project {
+ id
+ path
+ }
__typename
}
pageInfo {
@@ -67,6 +71,10 @@ query getProjectContainerRepositories(
createdAt
expirationPolicyStartedAt
expirationPolicyCleanupStatus
+ project {
+ id
+ path
+ }
__typename
}
pageInfo {
diff --git a/app/graphql/queries/repository/path_last_commit.query.graphql b/app/graphql/queries/repository/path_last_commit.query.graphql
index bcb07ae3182..914be3a72c1 100644
--- a/app/graphql/queries/repository/path_last_commit.query.graphql
+++ b/app/graphql/queries/repository/path_last_commit.query.graphql
@@ -4,43 +4,46 @@ query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
id
repository {
__typename
- tree(path: $path, ref: $ref) {
+ paginatedTree(path: $path, ref: $ref) {
__typename
- lastCommit {
+ nodes {
__typename
- id
- sha
- title
- titleHtml
- descriptionHtml
- message
- webPath
- authoredDate
- authorName
- authorGravatar
- author {
+ lastCommit {
__typename
id
- name
- avatarUrl
+ sha
+ title
+ titleHtml
+ descriptionHtml
+ message
webPath
- }
- signatureHtml
- pipelines(ref: $ref, first: 1) {
- __typename
- edges {
+ authoredDate
+ authorName
+ authorGravatar
+ author {
+ __typename
+ id
+ name
+ avatarUrl
+ webPath
+ }
+ signatureHtml
+ pipelines(ref: $ref, first: 1) {
__typename
- node {
+ edges {
__typename
- id
- detailedStatus {
+ node {
__typename
id
- detailsPath
- icon
- tooltip
- text
- group
+ detailedStatus {
+ __typename
+ id
+ detailsPath
+ icon
+ tooltip
+ text
+ group
+ }
}
}
}
diff --git a/app/graphql/resolvers/ci/jobs_resolver.rb b/app/graphql/resolvers/ci/jobs_resolver.rb
index df138a15538..91f29948ad0 100644
--- a/app/graphql/resolvers/ci/jobs_resolver.rb
+++ b/app/graphql/resolvers/ci/jobs_resolver.rb
@@ -15,9 +15,15 @@ module Resolvers
required: false,
description: 'Filter jobs by status.'
- def resolve(statuses: nil, security_report_types: [])
+ argument :retried, ::GraphQL::Types::Boolean,
+ required: false,
+ description: 'Filter jobs by retry-status.'
+
+ def resolve(statuses: nil, security_report_types: [], retried: nil)
jobs = init_collection(security_report_types)
jobs = jobs.with_status(statuses) if statuses.present?
+ jobs = jobs.retried if retried
+ jobs = jobs.latest if retried == false
jobs
end
diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb
index e221dfea4d0..64738608b60 100644
--- a/app/graphql/resolvers/ci/runners_resolver.rb
+++ b/app/graphql/resolvers/ci/runners_resolver.rb
@@ -36,6 +36,10 @@ module Resolvers
required: false,
description: 'Sort order of results.'
+ argument :upgrade_status, ::Types::Ci::RunnerUpgradeStatusTypeEnum,
+ required: false,
+ description: 'Filter by upgrade status.'
+
def resolve_with_lookahead(**args)
apply_lookahead(
::Ci::RunnersFinder
@@ -54,6 +58,7 @@ module Resolvers
status_status: params[:status]&.to_s,
type_type: params[:type],
tag_name: params[:tag_list],
+ upgrade_status: params[:upgrade_status],
search: params[:search],
sort: params[:sort]&.to_s,
preload: {
diff --git a/app/graphql/resolvers/ci/test_suite_resolver.rb b/app/graphql/resolvers/ci/test_suite_resolver.rb
index 5d61d9e986b..f758e217b47 100644
--- a/app/graphql/resolvers/ci/test_suite_resolver.rb
+++ b/app/graphql/resolvers/ci/test_suite_resolver.rb
@@ -28,7 +28,7 @@ module Resolvers
def load_test_suite_data(builds)
suite = builds.sum do |build|
- build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
+ build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
end
Gitlab::Ci::Reports::TestFailureHistory.new(suite.failed.values, pipeline.project).load!
diff --git a/app/graphql/resolvers/clusters/agents_resolver.rb b/app/graphql/resolvers/clusters/agents_resolver.rb
index 28618bef807..0b9eb361dbd 100644
--- a/app/graphql/resolvers/clusters/agents_resolver.rb
+++ b/app/graphql/resolvers/clusters/agents_resolver.rb
@@ -15,12 +15,10 @@ module Resolvers
description: 'Name of the cluster agent.'
end
- alias_method :project, :object
-
def resolve_with_lookahead(**args)
apply_lookahead(
::Clusters::AgentsFinder
- .new(project, current_user, params: args)
+ .new(object, current_user, params: args)
.execute
)
end
@@ -36,3 +34,5 @@ module Resolvers
end
end
end
+
+Resolvers::Clusters::AgentsResolver.prepend_mod_with('Resolvers::Clusters::AgentsResolver')
diff --git a/app/graphql/resolvers/todo_resolver.rb b/app/graphql/resolvers/todo_resolver.rb
index f0be1b6e9a5..0653cd27b4d 100644
--- a/app/graphql/resolvers/todo_resolver.rb
+++ b/app/graphql/resolvers/todo_resolver.rb
@@ -2,68 +2,16 @@
module Resolvers
class TodoResolver < BaseResolver
- type Types::TodoType.connection_type, null: true
+ description 'Retrieve a single to-do item'
- alias_method :target, :object
+ type Types::TodoType, null: true
- argument :action, [Types::TodoActionEnum],
- required: false,
- description: 'Action to be filtered.'
+ argument :id, Types::GlobalIDType[Todo],
+ required: true,
+ description: 'ID of the to-do item.'
- argument :author_id, [GraphQL::Types::ID],
- required: false,
- description: 'ID of an author.'
-
- argument :project_id, [GraphQL::Types::ID],
- required: false,
- description: 'ID of a project.'
-
- argument :group_id, [GraphQL::Types::ID],
- required: false,
- description: 'ID of a group.'
-
- argument :state, [Types::TodoStateEnum],
- required: false,
- description: 'State of the todo.'
-
- argument :type, [Types::TodoTargetEnum],
- required: false,
- description: 'Type of the todo.'
-
- before_connection_authorization do |nodes, current_user|
- Preloaders::UserMaxAccessLevelInProjectsPreloader.new(
- nodes.map(&:project).compact,
- current_user
- ).execute
- end
-
- def resolve(**args)
- return Todo.none unless current_user.present? && target.present?
- return Todo.none if target.is_a?(User) && target != current_user
-
- TodosFinder.new(current_user, todo_finder_params(args)).execute.with_entity_associations
- end
-
- private
-
- def todo_finder_params(args)
- {
- state: args[:state],
- type: args[:type],
- group_id: args[:group_id],
- author_id: args[:author_id],
- action_id: args[:action],
- project_id: args[:project_id]
- }.merge(target_params)
- end
-
- def target_params
- return {} unless TodosFinder::TODO_TYPES.include?(target.class.name)
-
- {
- type: target.class.name,
- target_id: target.id
- }
+ def resolve(id:)
+ GitlabSchema.find_by_gid(id)
end
end
end
diff --git a/app/graphql/resolvers/todos_resolver.rb b/app/graphql/resolvers/todos_resolver.rb
new file mode 100644
index 00000000000..3e8dddb4859
--- /dev/null
+++ b/app/graphql/resolvers/todos_resolver.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class TodosResolver < BaseResolver
+ type Types::TodoType.connection_type, null: true
+
+ alias_method :target, :object
+
+ argument :action, [Types::TodoActionEnum],
+ required: false,
+ description: 'Action to be filtered.'
+
+ argument :author_id, [GraphQL::Types::ID],
+ required: false,
+ description: 'ID of an author.'
+
+ argument :project_id, [GraphQL::Types::ID],
+ required: false,
+ description: 'ID of a project.'
+
+ argument :group_id, [GraphQL::Types::ID],
+ required: false,
+ description: 'ID of a group.'
+
+ argument :state, [Types::TodoStateEnum],
+ required: false,
+ description: 'State of the todo.'
+
+ argument :type, [Types::TodoTargetEnum],
+ required: false,
+ description: 'Type of the todo.'
+
+ before_connection_authorization do |nodes, current_user|
+ Preloaders::UserMaxAccessLevelInProjectsPreloader.new(
+ nodes.map(&:project).compact,
+ current_user
+ ).execute
+ end
+
+ def resolve(**args)
+ return Todo.none unless current_user.present? && target.present?
+ return Todo.none if target.is_a?(User) && target != current_user
+
+ TodosFinder.new(current_user, todo_finder_params(args)).execute.with_entity_associations
+ end
+
+ private
+
+ def todo_finder_params(args)
+ {
+ state: args[:state],
+ type: args[:type],
+ group_id: args[:group_id],
+ author_id: args[:author_id],
+ action_id: args[:action],
+ project_id: args[:project_id]
+ }.merge(target_params)
+ end
+
+ def target_params
+ return {} unless TodosFinder::TODO_TYPES.include?(target.class.name)
+
+ {
+ type: target.class.name,
+ target_id: target.id
+ }
+ end
+ end
+end
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index 43b7bbb419f..a0d19229d3d 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -116,7 +116,7 @@ module Types
null: true,
description: 'Runbook for the alert as defined in alert details.'
- field :todos, description: 'To-do items of the current user for the alert.', resolver: Resolvers::TodoResolver
+ field :todos, description: 'To-do items of the current user for the alert.', resolver: Resolvers::TodosResolver
field :details_url,
GraphQL::Types::String,
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index b20a671179b..42b55f47f92 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -70,6 +70,8 @@ module Types
description: 'Downstream pipeline for a bridge.'
field :manual_job, GraphQL::Types::Boolean, null: true,
description: 'Whether the job has a manual action.'
+ field :manual_variables, VariableType.connection_type, null: true,
+ description: 'Variables added to a manual job when the job is triggered.'
field :playable, GraphQL::Types::Boolean, null: false, method: :playable?,
description: 'Indicates the job can be played.'
field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, null: true,
@@ -78,6 +80,8 @@ module Types
description: 'Ref name of the job.'
field :ref_path, GraphQL::Types::String, null: true,
description: 'Path to the ref.'
+ field :retried, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates that the job has been retried.'
field :retryable, GraphQL::Types::Boolean, null: false, method: :retryable?,
description: 'Indicates the job can be retried.'
field :scheduling_type, GraphQL::Types::String, null: true,
@@ -188,6 +192,14 @@ module Types
def triggered
object.try(:trigger_request)
end
+
+ def manual_variables
+ if object.manual? && object.respond_to?(:job_variables)
+ object.job_variables
+ else
+ []
+ end
+ end
end
end
end
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 949e216a982..ac5ffd39407 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -159,12 +159,19 @@ module Types
owner_ids = runner_owner_ids_by_runner_id.values.flatten.uniq
owners = assoc_type.where(id: owner_ids).index_by(&:id)
+ # Preload projects namespaces to avoid N+1 queries when checking the `read_project` policy for each
+ preload_projects_namespaces(owners.values) if assoc_type == Project
+
runner_ids.each do |runner_id|
loader.call(runner_id, runner_owner_ids_by_runner_id[runner_id]&.map { |owner_id| owners[owner_id] } || [])
end
end
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ def preload_projects_namespaces(_projects)
+ # overridden in EE
+ end
end
end
end
diff --git a/app/graphql/types/ci/runner_upgrade_status_type_enum.rb b/app/graphql/types/ci/runner_upgrade_status_type_enum.rb
index 02feafe3df9..8e32eee5e6e 100644
--- a/app/graphql/types/ci/runner_upgrade_status_type_enum.rb
+++ b/app/graphql/types/ci/runner_upgrade_status_type_enum.rb
@@ -5,10 +5,15 @@ module Types
class RunnerUpgradeStatusTypeEnum < BaseEnum
graphql_name 'CiRunnerUpgradeStatusType'
- value 'UNKNOWN', description: 'Upgrade status is unknown.', value: :unknown
+ ::Ci::RunnerVersion::STATUS_DESCRIPTIONS.each do |status, description|
+ status_name_src =
+ if status == :invalid_version
+ :invalid
+ else
+ status
+ end
- Gitlab::Ci::RunnerUpgradeCheck::STATUSES.each do |status, description|
- value status.to_s.upcase, description: description, value: status
+ value status_name_src.to_s.upcase, description: description, value: status
end
end
end
diff --git a/app/graphql/types/ci/variable_type.rb b/app/graphql/types/ci/variable_type.rb
new file mode 100644
index 00000000000..63f89b6d207
--- /dev/null
+++ b/app/graphql/types/ci/variable_type.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ # rubocop: disable Graphql/AuthorizeTypes
+ class VariableType < BaseObject
+ graphql_name 'CiVariable'
+
+ field :id, GraphQL::Types::ID, null: false,
+ description: 'ID of the variable.'
+
+ field :key, GraphQL::Types::String, null: true,
+ description: 'Name of the variable.'
+
+ field :value, GraphQL::Types::String, null: true,
+ description: 'Value of the variable.'
+
+ field :variable_type, ::Types::Ci::VariableTypeEnum, null: true,
+ description: 'Type of the variable.'
+
+ field :protected, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates whether the variable is protected.'
+
+ field :masked, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates whether the variable is masked.'
+
+ field :raw, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates whether the variable is raw.'
+
+ field :environment_scope, GraphQL::Types::String, null: true,
+ description: 'Scope defining the environments in which the variable can be used.'
+
+ def environment_scope
+ if object.respond_to?(:environment_scope)
+ object.environment_scope
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/variable_type_enum.rb b/app/graphql/types/ci/variable_type_enum.rb
new file mode 100644
index 00000000000..44430754a2e
--- /dev/null
+++ b/app/graphql/types/ci/variable_type_enum.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ class VariableTypeEnum < BaseEnum
+ graphql_name 'CiVariableType'
+
+ ::Ci::Variable.variable_types.keys.each do |variable_type|
+ value variable_type.upcase, value: variable_type, description: "#{variable_type.humanize} type."
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 49971d52a30..52e9f808066 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -194,6 +194,13 @@ module Types
complexity: 5,
resolver: Resolvers::GroupsResolver
+ field :ci_variables,
+ Types::Ci::VariableType.connection_type,
+ null: true,
+ description: "List of the group's CI/CD variables.",
+ authorize: :admin_group,
+ method: :variables
+
field :runners, Types::Ci::RunnerType.connection_type,
null: true,
resolver: Resolvers::Ci::GroupRunnersResolver,
diff --git a/app/graphql/types/issue_type_enum.rb b/app/graphql/types/issue_type_enum.rb
index b18c8b90e96..bc21b802179 100644
--- a/app/graphql/types/issue_type_enum.rb
+++ b/app/graphql/types/issue_type_enum.rb
@@ -8,5 +8,9 @@ module Types
::WorkItems::Type.allowed_types_for_issues.each do |issue_type|
value issue_type.upcase, value: issue_type, description: "#{issue_type.titleize} issue type"
end
+
+ value 'TASK', value: 'task',
+ description: 'Task issue type. Available only when feature flag `work_items` is enabled.',
+ deprecated: { milestone: '15.2', reason: :alpha }
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 8642957af02..46ab3f3f432 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -148,6 +148,7 @@ module Types
mount_mutation Mutations::WorkItems::UpdateTask, deprecated: { milestone: '15.1', reason: :alpha }
mount_mutation Mutations::SavedReplies::Create
mount_mutation Mutations::SavedReplies::Update
+ mount_mutation Mutations::Pages::MarkOnboardingComplete
mount_mutation Mutations::SavedReplies::Destroy
end
end
diff --git a/app/graphql/types/permission_types/group_enum.rb b/app/graphql/types/permission_types/group_enum.rb
index cc4f5e9f1f0..8b0fee8898c 100644
--- a/app/graphql/types/permission_types/group_enum.rb
+++ b/app/graphql/types/permission_types/group_enum.rb
@@ -7,6 +7,8 @@ module Types
description 'User permission on groups'
value 'CREATE_PROJECTS', value: :create_projects, description: 'Groups where the user can create projects.'
+ value 'TRANSFER_PROJECTS', value: :transfer_projects,
+ description: 'Groups where the user can transfer projects to.'
end
end
end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 603d5ead540..7e3800c6a13 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -70,10 +70,10 @@ module Types
description: 'Indicates if shared runners are enabled for the project.'
field :service_desk_enabled, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if the project has service desk enabled.'
+ description: 'Indicates if the project has Service Desk enabled.'
field :service_desk_address, GraphQL::Types::String, null: true,
- description: 'E-mail address of the service desk.'
+ description: 'E-mail address of the Service Desk.'
field :avatar_url, GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'URL to avatar image file of the project.'
@@ -220,6 +220,13 @@ module Types
description: 'Build pipeline counts of the project.',
resolver: Resolvers::Ci::ProjectPipelineCountsResolver
+ field :ci_variables,
+ Types::Ci::VariableType.connection_type,
+ null: true,
+ description: "List of the project's CI/CD variables.",
+ authorize: :admin_build,
+ method: :variables
+
field :ci_cd_settings,
Types::Ci::CiCdSettingType,
null: true,
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index 46d121f6552..9207a867639 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -123,6 +123,11 @@ module Types
resolver: Resolvers::Ci::RunnersResolver,
description: "Find runners visible to the current user."
+ field :ci_variables,
+ Types::Ci::VariableType.connection_type,
+ null: true,
+ description: "List of the instance's CI/CD variables."
+
field :ci_config, resolver: Resolvers::Ci::ConfigResolver, complexity: 126 # AUTHENTICATED_MAX_COMPLEXITY / 2 + 1
field :timelogs, Types::TimelogType.connection_type,
@@ -136,6 +141,10 @@ module Types
null: true,
resolver: Resolvers::BoardListResolver
+ field :todo,
+ null: true,
+ resolver: Resolvers::TodoResolver
+
field :topics, Types::Projects::TopicType.connection_type,
null: true,
resolver: Resolvers::TopicsResolver,
@@ -174,6 +183,12 @@ module Types
application_settings
end
+ def ci_variables
+ return unless current_user.can_admin_all_resources?
+
+ ::Ci::InstanceVariable.all
+ end
+
def application_settings
Gitlab::CurrentSettings.current_application_settings
end
diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb
index 43dc0c4ce85..d906c577aa5 100644
--- a/app/graphql/types/release_type.rb
+++ b/app/graphql/types/release_type.rb
@@ -40,6 +40,8 @@ module Types
authorize: :download_code
field :upcoming_release, GraphQL::Types::Boolean, null: true, method: :upcoming_release?,
description: 'Indicates the release is an upcoming release.'
+ field :historical_release, GraphQL::Types::Boolean, null: true, method: :historical_release?,
+ description: 'Indicates the release is an historical release.'
field :author, Types::UserType, null: true,
description: 'User that created the release.'
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 1c8a1352c72..edbc8aee9c5 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -88,7 +88,7 @@ module Types
null: true,
description: 'Personal namespace of the user.'
- field :todos, resolver: Resolvers::TodoResolver, description: 'To-do items of the user.'
+ field :todos, resolver: Resolvers::TodosResolver, description: 'To-do items of the user.'
# Merge request field: MRs can be authored, assigned, or assigned-for-review:
field :authored_merge_requests,
diff --git a/app/graphql/types/work_item_id_type.rb b/app/graphql/types/work_item_id_type.rb
index ddcf3416014..bb01f865414 100644
--- a/app/graphql/types/work_item_id_type.rb
+++ b/app/graphql/types/work_item_id_type.rb
@@ -27,6 +27,7 @@ module Types
def coerce_input(string, ctx)
gid = super
+ return if gid.nil?
# Always return a WorkItemID even if an Issue Global ID is provided as input
return work_item_gid(gid) if suitable?(gid)
diff --git a/app/graphql/types/work_items/widget_interface.rb b/app/graphql/types/work_items/widget_interface.rb
index f3cf1d74829..1b752393296 100644
--- a/app/graphql/types/work_items/widget_interface.rb
+++ b/app/graphql/types/work_items/widget_interface.rb
@@ -16,13 +16,19 @@ module Types
::Types::WorkItems::Widgets::DescriptionType
when ::WorkItems::Widgets::Hierarchy
::Types::WorkItems::Widgets::HierarchyType
+ when ::WorkItems::Widgets::Assignees
+ ::Types::WorkItems::Widgets::AssigneesType
+ when ::WorkItems::Widgets::Weight
+ ::Types::WorkItems::Widgets::WeightType
else
raise "Unknown GraphQL type for widget #{object}"
end
end
orphan_types ::Types::WorkItems::Widgets::DescriptionType,
- ::Types::WorkItems::Widgets::HierarchyType
+ ::Types::WorkItems::Widgets::HierarchyType,
+ ::Types::WorkItems::Widgets::AssigneesType,
+ ::Types::WorkItems::Widgets::WeightType
end
end
end
diff --git a/app/graphql/types/work_items/widgets/assignees_type.rb b/app/graphql/types/work_items/widgets/assignees_type.rb
new file mode 100644
index 00000000000..08ee06fdfa0
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/assignees_type.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ # Disabling widget level authorization as it might be too granular
+ # and we already authorize the parent work item
+ # rubocop:disable Graphql/AuthorizeTypes
+ class AssigneesType < BaseObject
+ graphql_name 'WorkItemWidgetAssignees'
+ description 'Represents an assignees widget'
+
+ implements Types::WorkItems::WidgetInterface
+
+ field :assignees, Types::UserType.connection_type, null: true,
+ description: 'Assignees of the work item.'
+
+ field :allows_multiple_assignees, GraphQL::Types::Boolean, null: true, method: :allows_multiple_assignees?,
+ description: 'Indicates whether multiple assignees are allowed.'
+
+ field :can_invite_members, GraphQL::Types::Boolean, null: false, resolver_method: :can_invite_members?,
+ description: 'Indicates whether the current user can invite members to the work item\'s project.'
+
+ def can_invite_members?
+ Ability.allowed?(current_user, :admin_project_member, object.work_item.project)
+ end
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+ end
+end
diff --git a/app/graphql/types/work_items/widgets/hierarchy_create_input_type.rb b/app/graphql/types/work_items/widgets/hierarchy_create_input_type.rb
new file mode 100644
index 00000000000..cee6d69cd0c
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/hierarchy_create_input_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ class HierarchyCreateInputType < BaseInputObject
+ graphql_name 'WorkItemWidgetHierarchyCreateInput'
+
+ argument :parent_id, ::Types::GlobalIDType[::WorkItem],
+ required: false,
+ loads: ::Types::WorkItemType,
+ description: 'Global ID of the parent work item.'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb b/app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb
new file mode 100644
index 00000000000..e1a9ebb76e9
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ class HierarchyUpdateInputType < BaseInputObject
+ graphql_name 'WorkItemWidgetHierarchyUpdateInput'
+
+ argument :parent_id, ::Types::GlobalIDType[::WorkItem],
+ required: false,
+ loads: ::Types::WorkItemType,
+ description: 'Global ID of the parent work item. Use `null` to remove the association.'
+
+ argument :children_ids, [::Types::GlobalIDType[::WorkItem]],
+ required: false,
+ description: 'Global IDs of children work items.',
+ loads: ::Types::WorkItemType,
+ as: :children
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/work_items/widgets/weight_input_type.rb b/app/graphql/types/work_items/widgets/weight_input_type.rb
new file mode 100644
index 00000000000..a01c63222a5
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/weight_input_type.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ class WeightInputType < BaseInputObject
+ graphql_name 'WorkItemWidgetWeightInput'
+
+ argument :weight, GraphQL::Types::Int,
+ required: true,
+ description: 'Weight of the work item.'
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/work_items/widgets/weight_type.rb b/app/graphql/types/work_items/widgets/weight_type.rb
new file mode 100644
index 00000000000..c8eaf560268
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/weight_type.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ # Disabling widget level authorization as it might be too granular
+ # and we already authorize the parent work item
+ # rubocop:disable Graphql/AuthorizeTypes
+ class WeightType < BaseObject
+ graphql_name 'WorkItemWidgetWeight'
+ description 'Represents a weight widget'
+
+ implements Types::WorkItems::WidgetInterface
+
+ field :weight, GraphQL::Types::Int, null: true,
+ description: 'Weight of the work item.'
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+ end
+ end
+end