summaryrefslogtreecommitdiff
path: root/app/graphql
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 13:37:47 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 13:37:47 +0000
commitaee0a117a889461ce8ced6fcf73207fe017f1d99 (patch)
tree891d9ef189227a8445d83f35c1b0fc99573f4380 /app/graphql
parent8d46af3258650d305f53b819eabf7ab18d22f59e (diff)
downloadgitlab-ce-aee0a117a889461ce8ced6fcf73207fe017f1d99.tar.gz
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'app/graphql')
-rw-r--r--app/graphql/graphql_triggers.rb4
-rw-r--r--app/graphql/mutations/issues/set_crm_contacts.rb18
-rw-r--r--app/graphql/mutations/jira_import/start.rb6
-rw-r--r--app/graphql/mutations/merge_requests/accept.rb6
-rw-r--r--app/graphql/mutations/user_callouts/create.rb2
-rw-r--r--app/graphql/queries/container_registry/get_container_repositories.query.graphql2
-rw-r--r--app/graphql/queries/design_management/design_permissions.query.graphql1
-rw-r--r--app/graphql/queries/design_management/get_design_list.query.graphql1
-rw-r--r--app/graphql/queries/epic/epic_children.query.graphql132
-rw-r--r--app/graphql/queries/epic/epic_details.query.graphql3
-rw-r--r--app/graphql/queries/pipelines/get_pipeline_details.query.graphql13
-rw-r--r--app/graphql/queries/releases/all_releases.query.graphql4
-rw-r--r--app/graphql/queries/repository/path_last_commit.query.graphql6
-rw-r--r--app/graphql/queries/snippet/project_permissions.query.graphql1
-rw-r--r--app/graphql/queries/snippet/snippet.query.graphql1
-rw-r--r--app/graphql/queries/snippet/user_permissions.query.graphql1
-rw-r--r--app/graphql/resolvers/base_issues_resolver.rb6
-rw-r--r--app/graphql/resolvers/ci/jobs_resolver.rb2
-rw-r--r--app/graphql/resolvers/ci/runner_status_resolver.rb24
-rw-r--r--app/graphql/resolvers/ci/runners_resolver.rb5
-rw-r--r--app/graphql/resolvers/clusters/agent_activity_events_resolver.rb25
-rw-r--r--app/graphql/resolvers/clusters/agents_resolver.rb5
-rw-r--r--app/graphql/resolvers/container_repository_tags_resolver.rb49
-rw-r--r--app/graphql/resolvers/design_management/designs_resolver.rb10
-rw-r--r--app/graphql/resolvers/design_management/version/design_at_version_resolver.rb8
-rw-r--r--app/graphql/resolvers/kas/agent_configurations_resolver.rb2
-rw-r--r--app/graphql/resolvers/package_pipelines_resolver.rb57
-rw-r--r--app/graphql/resolvers/project_jobs_resolver.rb1
-rw-r--r--app/graphql/resolvers/project_pipeline_resolver.rb7
-rw-r--r--app/graphql/resolvers/project_pipelines_resolver.rb2
-rw-r--r--app/graphql/resolvers/snippets/blobs_resolver.rb2
-rw-r--r--app/graphql/resolvers/users/participants_resolver.rb13
-rw-r--r--app/graphql/types/base_edge.rb7
-rw-r--r--app/graphql/types/base_field.rb2
-rw-r--r--app/graphql/types/base_object.rb1
-rw-r--r--app/graphql/types/boards/board_issue_input_type.rb4
-rw-r--r--app/graphql/types/ci/build_need_type.rb2
-rw-r--r--app/graphql/types/ci/job_need_union.rb21
-rw-r--r--app/graphql/types/ci/job_type.rb28
-rw-r--r--app/graphql/types/ci/pipeline_type.rb10
-rw-r--r--app/graphql/types/ci/runner_status_enum.rb49
-rw-r--r--app/graphql/types/ci/runner_type.rb9
-rw-r--r--app/graphql/types/ci/runner_web_url_edge.rb2
-rw-r--r--app/graphql/types/ci/stage_type.rb7
-rw-r--r--app/graphql/types/ci/test_case_type.rb2
-rw-r--r--app/graphql/types/ci/test_report_total_type.rb2
-rw-r--r--app/graphql/types/ci/test_suite_summary_type.rb2
-rw-r--r--app/graphql/types/ci/test_suite_type.rb2
-rw-r--r--app/graphql/types/clusters/agent_activity_event_type.rb38
-rw-r--r--app/graphql/types/clusters/agent_type.rb6
-rw-r--r--app/graphql/types/container_repository_details_type.rb9
-rw-r--r--app/graphql/types/container_repository_tags_sort_enum.rb11
-rw-r--r--app/graphql/types/issue_type.rb3
-rw-r--r--app/graphql/types/issue_type_enum.rb2
-rw-r--r--app/graphql/types/merge_request_connection_type.rb2
-rw-r--r--app/graphql/types/merge_request_type.rb10
-rw-r--r--app/graphql/types/namespace_type.rb3
-rw-r--r--app/graphql/types/notes/note_type.rb4
-rw-r--r--app/graphql/types/packages/package_details_type.rb7
-rw-r--r--app/graphql/types/packages/package_type.rb3
-rw-r--r--app/graphql/types/project_statistics_type.rb20
-rw-r--r--app/graphql/types/project_type.rb7
-rw-r--r--app/graphql/types/repository/blob_type.rb9
-rw-r--r--app/graphql/types/root_storage_statistics_type.rb18
-rw-r--r--app/graphql/types/subscription_type.rb3
-rw-r--r--app/graphql/types/user_callout_feature_name_enum.rb2
66 files changed, 486 insertions, 240 deletions
diff --git a/app/graphql/graphql_triggers.rb b/app/graphql/graphql_triggers.rb
index 671c7c2cd25..290cd4d7146 100644
--- a/app/graphql/graphql_triggers.rb
+++ b/app/graphql/graphql_triggers.rb
@@ -4,4 +4,8 @@ module GraphqlTriggers
def self.issuable_assignees_updated(issuable)
GitlabSchema.subscriptions.trigger('issuableAssigneesUpdated', { issuable_id: issuable.to_gid }, issuable)
end
+
+ def self.issue_crm_contacts_updated(issue)
+ GitlabSchema.subscriptions.trigger('issueCrmContactsUpdated', { issuable_id: issue.to_gid }, issue)
+ end
end
diff --git a/app/graphql/mutations/issues/set_crm_contacts.rb b/app/graphql/mutations/issues/set_crm_contacts.rb
index 7a9e6237eaa..4e49a45d52a 100644
--- a/app/graphql/mutations/issues/set_crm_contacts.rb
+++ b/app/graphql/mutations/issues/set_crm_contacts.rb
@@ -5,7 +5,7 @@ module Mutations
class SetCrmContacts < Base
graphql_name 'IssueSetCrmContacts'
- argument :crm_contact_ids,
+ argument :contact_ids,
[::Types::GlobalIDType[::CustomerRelations::Contact]],
required: true,
description: 'Customer relations contact IDs to set. Replaces existing contacts by default.'
@@ -15,27 +15,27 @@ module Mutations
required: false,
description: 'Changes the operation mode. Defaults to REPLACE.'
- def resolve(project_path:, iid:, crm_contact_ids:, operation_mode: Types::MutationOperationModeEnum.enum[:replace])
+ def resolve(project_path:, iid:, contact_ids:, operation_mode: Types::MutationOperationModeEnum.enum[:replace])
issue = authorized_find!(project_path: project_path, iid: iid)
project = issue.project
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless Feature.enabled?(:customer_relations, project.group, default_enabled: :yaml)
- crm_contact_ids = crm_contact_ids.compact.map do |crm_contact_id|
- raise Gitlab::Graphql::Errors::ArgumentError, "Contact #{crm_contact_id} is invalid." unless crm_contact_id.respond_to?(:model_id)
+ contact_ids = contact_ids.compact.map do |contact_id|
+ raise Gitlab::Graphql::Errors::ArgumentError, "Contact #{contact_id} is invalid." unless contact_id.respond_to?(:model_id)
- crm_contact_id.model_id.to_i
+ contact_id.model_id.to_i
end
attribute_name = case operation_mode
when Types::MutationOperationModeEnum.enum[:append]
- :add_crm_contact_ids
+ :add_ids
when Types::MutationOperationModeEnum.enum[:remove]
- :remove_crm_contact_ids
+ :remove_ids
else
- :crm_contact_ids
+ :replace_ids
end
- response = ::Issues::SetCrmContactsService.new(project: project, current_user: current_user, params: { attribute_name => crm_contact_ids })
+ response = ::Issues::SetCrmContactsService.new(project: project, current_user: current_user, params: { attribute_name => contact_ids })
.execute(issue)
{
diff --git a/app/graphql/mutations/jira_import/start.rb b/app/graphql/mutations/jira_import/start.rb
index 143a9558e38..4929d6f394a 100644
--- a/app/graphql/mutations/jira_import/start.rb
+++ b/app/graphql/mutations/jira_import/start.rb
@@ -14,15 +14,15 @@ module Mutations
null: true,
description: 'Jira import data after mutation.'
- argument :project_path, GraphQL::Types::ID,
- required: true,
- description: 'Project to import the Jira project into.'
argument :jira_project_key, GraphQL::Types::String,
required: true,
description: 'Project key of the importer Jira project.'
argument :jira_project_name, GraphQL::Types::String,
required: false,
description: 'Project name of the importer Jira project.'
+ argument :project_path, GraphQL::Types::ID,
+ required: true,
+ description: 'Project to import the Jira project into.'
argument :users_mapping,
[Types::JiraUsersMappingInputType],
required: false,
diff --git a/app/graphql/mutations/merge_requests/accept.rb b/app/graphql/mutations/merge_requests/accept.rb
index d16b2327f2d..7ce850901af 100644
--- a/app/graphql/mutations/merge_requests/accept.rb
+++ b/app/graphql/mutations/merge_requests/accept.rb
@@ -26,12 +26,12 @@ module Mutations
argument :commit_message, ::GraphQL::Types::String,
required: false,
description: 'Custom merge commit message.'
- argument :squash_commit_message, ::GraphQL::Types::String,
- required: false,
- description: 'Custom squash commit message (if squash is true).'
argument :sha, ::GraphQL::Types::String,
required: true,
description: 'HEAD SHA at the time when this merge was requested.'
+ argument :squash_commit_message, ::GraphQL::Types::String,
+ required: false,
+ description: 'Custom squash commit message (if squash is true).'
argument :should_remove_source_branch, ::GraphQL::Types::Boolean,
required: false,
diff --git a/app/graphql/mutations/user_callouts/create.rb b/app/graphql/mutations/user_callouts/create.rb
index ff6e5cd28dd..1be99ea0ecd 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::DismissUserCalloutService.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/queries/container_registry/get_container_repositories.query.graphql b/app/graphql/queries/container_registry/get_container_repositories.query.graphql
index df0b590acac..40e2934a038 100644
--- a/app/graphql/queries/container_registry/get_container_repositories.query.graphql
+++ b/app/graphql/queries/container_registry/get_container_repositories.query.graphql
@@ -10,6 +10,7 @@ query getProjectContainerRepositories(
) {
project(fullPath: $fullPath) @skip(if: $isGroupPage) {
__typename
+ id
containerRepositoriesCount
containerRepositories(
name: $name
@@ -43,6 +44,7 @@ query getProjectContainerRepositories(
}
group(fullPath: $fullPath) @include(if: $isGroupPage) {
__typename
+ id
containerRepositoriesCount
containerRepositories(
name: $name
diff --git a/app/graphql/queries/design_management/design_permissions.query.graphql b/app/graphql/queries/design_management/design_permissions.query.graphql
index 55dfa35129c..a81afd47625 100644
--- a/app/graphql/queries/design_management/design_permissions.query.graphql
+++ b/app/graphql/queries/design_management/design_permissions.query.graphql
@@ -4,6 +4,7 @@ query permissions($fullPath: ID!, $iid: String!) {
id
issue(iid: $iid) {
__typename
+ id
userPermissions {
__typename
createDesign
diff --git a/app/graphql/queries/design_management/get_design_list.query.graphql b/app/graphql/queries/design_management/get_design_list.query.graphql
index 01503a9572f..f0caa7c5b4c 100644
--- a/app/graphql/queries/design_management/get_design_list.query.graphql
+++ b/app/graphql/queries/design_management/get_design_list.query.graphql
@@ -4,6 +4,7 @@ query getDesignList($fullPath: ID!, $iid: String!, $atVersion: ID) {
id
issue(iid: $iid) {
__typename
+ id
designCollection {
__typename
copyState
diff --git a/app/graphql/queries/epic/epic_children.query.graphql b/app/graphql/queries/epic/epic_children.query.graphql
deleted file mode 100644
index be82813dddb..00000000000
--- a/app/graphql/queries/epic/epic_children.query.graphql
+++ /dev/null
@@ -1,132 +0,0 @@
-fragment PageInfo on PageInfo {
- hasNextPage
- hasPreviousPage
- startCursor
- endCursor
-}
-
-fragment RelatedTreeBaseEpic on Epic {
- id
- iid
- title
- webPath
- relativePosition
- userPermissions {
- __typename
- adminEpic
- createEpic
- }
- descendantWeightSum {
- closedIssues
- openedIssues
- }
- descendantCounts {
- __typename
- openedEpics
- closedEpics
- openedIssues
- closedIssues
- }
- healthStatus {
- __typename
- issuesAtRisk
- issuesOnTrack
- issuesNeedingAttention
- }
-}
-
-fragment EpicNode on Epic {
- ...RelatedTreeBaseEpic
- state
- reference(full: true)
- relationPath
- createdAt
- closedAt
- confidential
- hasChildren
- hasIssues
- group {
- __typename
- fullPath
- }
-}
-
-query childItems(
- $fullPath: ID!
- $iid: ID
- $pageSize: Int = 100
- $epicEndCursor: String = ""
- $issueEndCursor: String = ""
-) {
- group(fullPath: $fullPath) {
- __typename
- id
- path
- fullPath
- epic(iid: $iid) {
- __typename
- ...RelatedTreeBaseEpic
- children(first: $pageSize, after: $epicEndCursor) {
- __typename
- edges {
- __typename
- node {
- __typename
- ...EpicNode
- }
- }
- pageInfo {
- __typename
- ...PageInfo
- }
- }
- issues(first: $pageSize, after: $issueEndCursor) {
- __typename
- edges {
- __typename
- node {
- __typename
- iid
- epicIssueId
- title
- blocked
- closedAt
- state
- createdAt
- confidential
- dueDate
- weight
- webPath
- reference(full: true)
- relationPath
- relativePosition
- assignees {
- __typename
- edges {
- __typename
- node {
- __typename
- webUrl
- name
- username
- avatarUrl
- }
- }
- }
- milestone {
- __typename
- title
- startDate
- dueDate
- }
- healthStatus
- }
- }
- pageInfo {
- __typename
- ...PageInfo
- }
- }
- }
- }
-}
diff --git a/app/graphql/queries/epic/epic_details.query.graphql b/app/graphql/queries/epic/epic_details.query.graphql
index 406d630b180..eb4757a845a 100644
--- a/app/graphql/queries/epic/epic_details.query.graphql
+++ b/app/graphql/queries/epic/epic_details.query.graphql
@@ -1,14 +1,17 @@
query epicDetails($fullPath: ID!, $iid: ID!) {
group(fullPath: $fullPath) {
__typename
+ id
epic(iid: $iid) {
__typename
+ id
participants {
__typename
edges {
__typename
node {
__typename
+ id
name
avatarUrl
webUrl
diff --git a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
index 4e4caa1e27c..dd5c9e07488 100644
--- a/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
+++ b/app/graphql/queries/pipelines/get_pipeline_details.query.graphql
@@ -5,16 +5,19 @@ fragment LinkedPipelineData on Pipeline {
path
status: detailedStatus {
__typename
+ id
group
label
icon
}
sourceJob {
__typename
+ id
name
}
project {
__typename
+ id
name
fullPath
}
@@ -23,6 +26,7 @@ fragment LinkedPipelineData on Pipeline {
query getPipelineDetails($projectPath: ID!, $iid: ID!) {
project(fullPath: $projectPath) {
__typename
+ id
pipeline(iid: $iid) {
__typename
id
@@ -45,11 +49,14 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
__typename
nodes {
__typename
+ id
name
status: detailedStatus {
__typename
+ id
action {
__typename
+ id
icon
path
title
@@ -59,8 +66,10 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
__typename
nodes {
__typename
+ id
status: detailedStatus {
__typename
+ id
label
group
icon
@@ -71,17 +80,20 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
__typename
nodes {
__typename
+ id
name
scheduledAt
needs {
__typename
nodes {
__typename
+ id
name
}
}
status: detailedStatus {
__typename
+ id
icon
tooltip
hasDetails
@@ -89,6 +101,7 @@ query getPipelineDetails($projectPath: ID!, $iid: ID!) {
group
action {
__typename
+ id
buttonTitle
icon
path
diff --git a/app/graphql/queries/releases/all_releases.query.graphql b/app/graphql/queries/releases/all_releases.query.graphql
index ab8cbcb8aa3..150f59832f3 100644
--- a/app/graphql/queries/releases/all_releases.query.graphql
+++ b/app/graphql/queries/releases/all_releases.query.graphql
@@ -11,6 +11,7 @@ query allReleases(
) {
project(fullPath: $fullPath) {
__typename
+ id
releases(first: $first, last: $last, before: $before, after: $after, sort: $sort) {
__typename
nodes {
@@ -50,6 +51,7 @@ query allReleases(
__typename
nodes {
__typename
+ id
filepath
collectedAt
sha
@@ -67,12 +69,14 @@ query allReleases(
}
commit {
__typename
+ id
sha
webUrl
title
}
author {
__typename
+ id
webUrl
avatarUrl
username
diff --git a/app/graphql/queries/repository/path_last_commit.query.graphql b/app/graphql/queries/repository/path_last_commit.query.graphql
index b5c5f653429..bcb07ae3182 100644
--- a/app/graphql/queries/repository/path_last_commit.query.graphql
+++ b/app/graphql/queries/repository/path_last_commit.query.graphql
@@ -1,13 +1,14 @@
query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
project(fullPath: $projectPath) {
- id
__typename
+ id
repository {
__typename
tree(path: $path, ref: $ref) {
__typename
lastCommit {
__typename
+ id
sha
title
titleHtml
@@ -19,6 +20,7 @@ query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
authorGravatar
author {
__typename
+ id
name
avatarUrl
webPath
@@ -30,8 +32,10 @@ query pathLastCommit($projectPath: ID!, $path: String, $ref: String!) {
__typename
node {
__typename
+ id
detailedStatus {
__typename
+ id
detailsPath
icon
tooltip
diff --git a/app/graphql/queries/snippet/project_permissions.query.graphql b/app/graphql/queries/snippet/project_permissions.query.graphql
index 0c38e4f8a07..e0de79f4449 100644
--- a/app/graphql/queries/snippet/project_permissions.query.graphql
+++ b/app/graphql/queries/snippet/project_permissions.query.graphql
@@ -1,6 +1,7 @@
query CanCreateProjectSnippet($fullPath: ID!) {
project(fullPath: $fullPath) {
__typename
+ id
userPermissions {
__typename
createSnippet
diff --git a/app/graphql/queries/snippet/snippet.query.graphql b/app/graphql/queries/snippet/snippet.query.graphql
index ebfc135c51c..24b268ec853 100644
--- a/app/graphql/queries/snippet/snippet.query.graphql
+++ b/app/graphql/queries/snippet/snippet.query.graphql
@@ -49,6 +49,7 @@ query GetSnippetQuery($ids: [SnippetID!]) {
}
project {
__typename
+ id
fullPath
webUrl
}
diff --git a/app/graphql/queries/snippet/user_permissions.query.graphql b/app/graphql/queries/snippet/user_permissions.query.graphql
index a4914189807..4d131c48feb 100644
--- a/app/graphql/queries/snippet/user_permissions.query.graphql
+++ b/app/graphql/queries/snippet/user_permissions.query.graphql
@@ -1,6 +1,7 @@
query CanCreatePersonalSnippet {
currentUser {
__typename
+ id
userPermissions {
__typename
createSnippet
diff --git a/app/graphql/resolvers/base_issues_resolver.rb b/app/graphql/resolvers/base_issues_resolver.rb
index 54ebb697cb2..dca93444907 100644
--- a/app/graphql/resolvers/base_issues_resolver.rb
+++ b/app/graphql/resolvers/base_issues_resolver.rb
@@ -4,13 +4,13 @@ module Resolvers
class BaseIssuesResolver < BaseResolver
prepend IssueResolverArguments
- argument :state, Types::IssuableStateEnum,
- required: false,
- description: 'Current state of this issue.'
argument :sort, Types::IssueSortEnum,
description: 'Sort issues by this criteria.',
required: false,
default_value: :created_desc
+ argument :state, Types::IssuableStateEnum,
+ required: false,
+ description: 'Current state of this issue.'
type Types::IssueType.connection_type, null: true
diff --git a/app/graphql/resolvers/ci/jobs_resolver.rb b/app/graphql/resolvers/ci/jobs_resolver.rb
index 5ae9e721cc8..df138a15538 100644
--- a/app/graphql/resolvers/ci/jobs_resolver.rb
+++ b/app/graphql/resolvers/ci/jobs_resolver.rb
@@ -29,7 +29,7 @@ module Resolvers
job_types: security_report_types
).execute
else
- pipeline.statuses
+ pipeline.statuses_order_id_desc
end
end
end
diff --git a/app/graphql/resolvers/ci/runner_status_resolver.rb b/app/graphql/resolvers/ci/runner_status_resolver.rb
new file mode 100644
index 00000000000..d916a8a13f0
--- /dev/null
+++ b/app/graphql/resolvers/ci/runner_status_resolver.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ # NOTE: This class was introduced to allow modifying the meaning of certain values in RunnerStatusEnum
+ # while preserving backward compatibility. It can be removed in 15.0 once the API has stabilized.
+ class RunnerStatusResolver < BaseResolver
+ type Types::Ci::RunnerStatusEnum, null: false
+
+ alias_method :runner, :object
+
+ argument :legacy_mode,
+ type: GraphQL::Types::String,
+ default_value: '14.5',
+ required: false,
+ description: 'Compatibility mode. A null value turns off compatibility mode.',
+ deprecated: { reason: 'Will be removed in 15.0. From that release onward, the field will behave as if legacyMode is null', milestone: '14.6' }
+
+ def resolve(legacy_mode:, **args)
+ runner.status(legacy_mode)
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb
index 07105701daa..9848b5a503f 100644
--- a/app/graphql/resolvers/ci/runners_resolver.rb
+++ b/app/graphql/resolvers/ci/runners_resolver.rb
@@ -7,6 +7,10 @@ module Resolvers
type Types::Ci::RunnerType.connection_type, null: true
+ argument :active, ::GraphQL::Types::Boolean,
+ required: false,
+ description: 'Filter runners by active (true) or paused (false) status.'
+
argument :status, ::Types::Ci::RunnerStatusEnum,
required: false,
description: 'Filter runners by status.'
@@ -38,6 +42,7 @@ module Resolvers
def runners_finder_params(params)
{
+ active: params[:active],
status_status: params[:status]&.to_s,
type_type: params[:type],
tag_name: params[:tag_list],
diff --git a/app/graphql/resolvers/clusters/agent_activity_events_resolver.rb b/app/graphql/resolvers/clusters/agent_activity_events_resolver.rb
new file mode 100644
index 00000000000..b6fec3d3772
--- /dev/null
+++ b/app/graphql/resolvers/clusters/agent_activity_events_resolver.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Clusters
+ class AgentActivityEventsResolver < BaseResolver
+ type Types::Clusters::AgentActivityEventType, null: true
+
+ alias_method :agent, :object
+
+ delegate :project, to: :agent
+
+ def resolve(**args)
+ return ::Clusters::Agents::ActivityEvent.none unless can_view_activity_events?
+
+ agent.activity_events
+ end
+
+ private
+
+ def can_view_activity_events?
+ current_user.can?(:admin_cluster, project)
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/clusters/agents_resolver.rb b/app/graphql/resolvers/clusters/agents_resolver.rb
index 9b8cea52e3b..5ad66ed7cdd 100644
--- a/app/graphql/resolvers/clusters/agents_resolver.rb
+++ b/app/graphql/resolvers/clusters/agents_resolver.rb
@@ -28,7 +28,10 @@ module Resolvers
private
def preloads
- { tokens: :last_used_agent_tokens }
+ {
+ activity_events: { activity_events: [:user, agent_token: :agent] },
+ tokens: :last_used_agent_tokens
+ }
end
end
end
diff --git a/app/graphql/resolvers/container_repository_tags_resolver.rb b/app/graphql/resolvers/container_repository_tags_resolver.rb
new file mode 100644
index 00000000000..55a83dd49da
--- /dev/null
+++ b/app/graphql/resolvers/container_repository_tags_resolver.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class ContainerRepositoryTagsResolver < BaseResolver
+ type Types::ContainerRepositoryTagType.connection_type, null: true
+
+ argument :sort, Types::ContainerRepositoryTagsSortEnum,
+ description: 'Sort tags by these criteria.',
+ required: false,
+ default_value: nil
+
+ argument :name, GraphQL::Types::String,
+ description: 'Search by tag name.',
+ required: false,
+ default_value: nil
+
+ def resolve(sort:, **filters)
+ result = tags
+
+ if filters[:name]
+ result = tags.filter do |tag|
+ tag.name.include?(filters[:name])
+ end
+ end
+
+ result = sort_tags(result, sort) if sort
+ result
+ end
+
+ private
+
+ def sort_tags(to_be_sorted, sort)
+ raise StandardError unless Types::ContainerRepositoryTagsSortEnum.enum.include?(sort)
+
+ sort_value, _, direction = sort.to_s.rpartition('_')
+
+ sorted = to_be_sorted.sort_by(&sort_value.to_sym)
+ return sorted.reverse if direction == 'desc'
+
+ sorted
+ end
+
+ def tags
+ object.tags
+ rescue Faraday::Error
+ raise ::Gitlab::Graphql::Errors::ResourceNotAvailable, "Can't connect to the Container Registry. If this error persists, please review the troubleshooting documentation."
+ end
+ end
+end
diff --git a/app/graphql/resolvers/design_management/designs_resolver.rb b/app/graphql/resolvers/design_management/designs_resolver.rb
index dec778fac80..a62ef6d76e5 100644
--- a/app/graphql/resolvers/design_management/designs_resolver.rb
+++ b/app/graphql/resolvers/design_management/designs_resolver.rb
@@ -8,16 +8,16 @@ module Resolvers
type ::Types::DesignManagement::DesignType.connection_type, null: true
- argument :ids, [DesignID],
+ argument :at_version, VersionID,
required: false,
- description: 'Filters designs by their ID.'
+ description: 'Filters designs to only those that existed at the version. ' \
+ 'If argument is omitted or nil then all designs will reflect the latest version'
argument :filenames, [GraphQL::Types::String],
required: false,
description: 'Filters designs by their filename.'
- argument :at_version, VersionID,
+ argument :ids, [DesignID],
required: false,
- description: 'Filters designs to only those that existed at the version. ' \
- 'If argument is omitted or nil then all designs will reflect the latest version'
+ description: 'Filters designs by their ID.'
def self.single
::Resolvers::DesignManagement::DesignResolver
diff --git a/app/graphql/resolvers/design_management/version/design_at_version_resolver.rb b/app/graphql/resolvers/design_management/version/design_at_version_resolver.rb
index d879c1434dc..76e365c40b1 100644
--- a/app/graphql/resolvers/design_management/version/design_at_version_resolver.rb
+++ b/app/graphql/resolvers/design_management/version/design_at_version_resolver.rb
@@ -16,16 +16,16 @@ module Resolvers
authorize :read_design
- argument :id, DesignAtVersionID,
- required: false,
- as: :design_at_version_id,
- description: 'ID of the DesignAtVersion.'
argument :design_id, DesignID,
required: false,
description: 'ID of a specific design.'
argument :filename, GraphQL::Types::String,
required: false,
description: 'Filename of a specific design.'
+ argument :id, DesignAtVersionID,
+ required: false,
+ as: :design_at_version_id,
+ description: 'ID of the DesignAtVersion.'
def self.single
self
diff --git a/app/graphql/resolvers/kas/agent_configurations_resolver.rb b/app/graphql/resolvers/kas/agent_configurations_resolver.rb
index 238dae0bf12..a1b1d3bfe4c 100644
--- a/app/graphql/resolvers/kas/agent_configurations_resolver.rb
+++ b/app/graphql/resolvers/kas/agent_configurations_resolver.rb
@@ -14,7 +14,7 @@ module Resolvers
return [] unless can_read_agent_configuration?
kas_client.list_agent_config_files(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/package_pipelines_resolver.rb b/app/graphql/resolvers/package_pipelines_resolver.rb
new file mode 100644
index 00000000000..59a1cd173a4
--- /dev/null
+++ b/app/graphql/resolvers/package_pipelines_resolver.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class PackagePipelinesResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ type Types::Ci::PipelineType.connection_type, null: true
+ extension Gitlab::Graphql::Extensions::ExternallyPaginatedArrayExtension
+
+ authorizes_object!
+ authorize :read_pipeline
+
+ alias_method :package, :object
+
+ def resolve(first: nil, last: nil, after: nil, before: nil, lookahead:)
+ finder = ::Packages::BuildInfosFinder.new(
+ package,
+ first: first,
+ last: last,
+ after: decode_cursor(after),
+ before: decode_cursor(before),
+ max_page_size: context.schema.default_max_page_size,
+ support_next_page: lookahead.selects?(:page_info)
+ )
+
+ build_infos = finder.execute
+
+ # this .pluck_pipeline_ids can load max 101 pipelines ids
+ ::Ci::Pipeline.id_in(build_infos.pluck_pipeline_ids)
+ end
+
+ # we manage the pagination manually, so opt out of the connection field extension
+ def self.field_options
+ super.merge(
+ connection: false,
+ extras: [:lookahead]
+ )
+ end
+
+ private
+
+ def decode_cursor(encoded)
+ return unless encoded
+
+ decoded = Gitlab::Json.parse(context.schema.cursor_encoder.decode(encoded, nonce: true))
+ id_from_cursor(decoded)
+ rescue JSON::ParserError
+ raise Gitlab::Graphql::Errors::ArgumentError, "Please provide a valid cursor"
+ end
+
+ def id_from_cursor(cursor)
+ cursor&.fetch('id')
+ rescue KeyError
+ raise Gitlab::Graphql::Errors::ArgumentError, "Please provide a valid cursor"
+ end
+ end
+end
diff --git a/app/graphql/resolvers/project_jobs_resolver.rb b/app/graphql/resolvers/project_jobs_resolver.rb
index 75068014242..8a2693ee46b 100644
--- a/app/graphql/resolvers/project_jobs_resolver.rb
+++ b/app/graphql/resolvers/project_jobs_resolver.rb
@@ -33,6 +33,7 @@ module Resolvers
def preloads
{
+ previous_stage_jobs_and_needs: [:needs, :pipeline],
artifacts: [:job_artifacts],
pipeline: [:user]
}
diff --git a/app/graphql/resolvers/project_pipeline_resolver.rb b/app/graphql/resolvers/project_pipeline_resolver.rb
index 5acd7f95606..ea733ab08ad 100644
--- a/app/graphql/resolvers/project_pipeline_resolver.rb
+++ b/app/graphql/resolvers/project_pipeline_resolver.rb
@@ -24,7 +24,6 @@ module Resolvers
super
end
- # the preloads are defined on ee/app/graphql/ee/resolvers/project_pipeline_resolver.rb
def resolve(iid: nil, sha: nil, **args)
self.lookahead = args.delete(:lookahead)
@@ -42,5 +41,11 @@ module Resolvers
end
end
end
+
+ def unconditional_includes
+ [
+ { statuses: [:needs] }
+ ]
+ end
end
end
diff --git a/app/graphql/resolvers/project_pipelines_resolver.rb b/app/graphql/resolvers/project_pipelines_resolver.rb
index 5a1e92efc96..47a8b028d4d 100644
--- a/app/graphql/resolvers/project_pipelines_resolver.rb
+++ b/app/graphql/resolvers/project_pipelines_resolver.rb
@@ -18,7 +18,7 @@ module Resolvers
def preloads
{
- jobs: [:statuses],
+ jobs: { statuses_order_id_desc: [:needs] },
upstream: [:triggered_by_pipeline],
downstream: [:triggered_pipelines]
}
diff --git a/app/graphql/resolvers/snippets/blobs_resolver.rb b/app/graphql/resolvers/snippets/blobs_resolver.rb
index 00f41517422..cbbc65d7263 100644
--- a/app/graphql/resolvers/snippets/blobs_resolver.rb
+++ b/app/graphql/resolvers/snippets/blobs_resolver.rb
@@ -35,3 +35,5 @@ module Resolvers
end
end
end
+
+Resolvers::Snippets::BlobsResolver.prepend_mod
diff --git a/app/graphql/resolvers/users/participants_resolver.rb b/app/graphql/resolvers/users/participants_resolver.rb
new file mode 100644
index 00000000000..9e87b60fa34
--- /dev/null
+++ b/app/graphql/resolvers/users/participants_resolver.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Users
+ class ParticipantsResolver < BaseResolver
+ type Types::UserType.connection_type, null: true
+
+ def resolve(**args)
+ object.visible_participants(current_user)
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/base_edge.rb b/app/graphql/types/base_edge.rb
new file mode 100644
index 00000000000..f4409c983f8
--- /dev/null
+++ b/app/graphql/types/base_edge.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Types
+ class BaseEdge < GraphQL::Types::Relay::BaseEdge
+ field_class Types::BaseField
+ end
+end
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb
index 93e17ea6dfc..75909592c6c 100644
--- a/app/graphql/types/base_field.rb
+++ b/app/graphql/types/base_field.rb
@@ -78,6 +78,8 @@ module Types
attr_reader :feature_flag
def field_authorized?(object, ctx)
+ object = object.node if object.is_a?(GraphQL::Pagination::Connection::Edge)
+
authorization.ok?(object, ctx[:current_user])
end
diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb
index cd677e50d28..b5797f07aa6 100644
--- a/app/graphql/types/base_object.rb
+++ b/app/graphql/types/base_object.rb
@@ -7,6 +7,7 @@ module Types
prepend Gitlab::Graphql::MarkdownField
field_class Types::BaseField
+ edge_type_class Types::BaseEdge
def self.accepts(*types)
@accepts ||= []
diff --git a/app/graphql/types/boards/board_issue_input_type.rb b/app/graphql/types/boards/board_issue_input_type.rb
index b4dbe87e32d..afa66c1c510 100644
--- a/app/graphql/types/boards/board_issue_input_type.rb
+++ b/app/graphql/types/boards/board_issue_input_type.rb
@@ -17,6 +17,10 @@ module Types
argument :assignee_wildcard_id, ::Types::Boards::AssigneeWildcardIdEnum,
required: false,
description: 'Filter by assignee wildcard. Incompatible with assigneeUsername.'
+
+ argument :confidential, GraphQL::Types::Boolean,
+ required: false,
+ description: 'Filter by confidentiality.'
end
end
end
diff --git a/app/graphql/types/ci/build_need_type.rb b/app/graphql/types/ci/build_need_type.rb
index 7bd12c99a08..b71d10c4c06 100644
--- a/app/graphql/types/ci/build_need_type.rb
+++ b/app/graphql/types/ci/build_need_type.rb
@@ -8,7 +8,7 @@ module Types
graphql_name 'CiBuildNeed'
field :id, GraphQL::Types::ID, null: false,
- description: 'ID of the job we need to complete.'
+ description: 'ID of the BuildNeed.'
field :name, GraphQL::Types::String, null: true,
description: 'Name of the job we need to complete.'
end
diff --git a/app/graphql/types/ci/job_need_union.rb b/app/graphql/types/ci/job_need_union.rb
new file mode 100644
index 00000000000..59608a6a312
--- /dev/null
+++ b/app/graphql/types/ci/job_need_union.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ module Ci
+ class JobNeedUnion < GraphQL::Schema::Union
+ TypeNotSupportedError = Class.new(StandardError)
+
+ possible_types Types::Ci::JobType, Types::Ci::BuildNeedType
+
+ def self.resolve_type(object, context)
+ if object.is_a?(::Ci::BuildNeed)
+ Types::Ci::BuildNeedType
+ elsif object.is_a?(CommitStatus)
+ Types::Ci::JobType
+ else
+ raise TypeNotSupportedError
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index 48bd91bfc5b..928ca2f597d 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -50,6 +50,8 @@ module Types
null: true,
description: 'How long the job was enqueued before starting.'
+ field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, null: true,
+ description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.'
field :detailed_status, Types::Ci::DetailedStatusType, null: true,
description: 'Detailed status of the job.'
field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true,
@@ -74,7 +76,7 @@ module Types
description: 'Indicates the job is active.'
field :stuck, GraphQL::Types::Boolean, null: false, method: :stuck?,
description: 'Indicates the job is stuck.'
- field :coverage, GraphQL::FLOAT_TYPE, null: true,
+ field :coverage, GraphQL::Types::Float, null: true,
description: 'Coverage level of the job.'
field :created_by_tag, GraphQL::Types::Boolean, null: false,
description: 'Whether the job was created by a tag.'
@@ -101,6 +103,30 @@ module Types
end
end
+ def previous_stage_jobs_or_needs
+ if object.scheduling_type == 'stage'
+ Gitlab::Graphql::Lazy.with_value(previous_stage_jobs) do |jobs|
+ jobs
+ end
+ else
+ object.needs
+ end
+ end
+
+ def previous_stage_jobs
+ BatchLoader::GraphQL.for([object.pipeline, object.stage_idx - 1]).batch(default_value: []) do |tuples, loader|
+ tuples.group_by(&:first).each do |pipeline, keys|
+ positions = keys.map(&:second)
+
+ stages = pipeline.stages.by_position(positions)
+
+ stages.each do |stage|
+ loader.call([pipeline, stage.position], stage.latest_statuses)
+ end
+ end
+ end
+ end
+
def stage
::Gitlab::Graphql::Lazy.with_value(pipeline) do |pl|
BatchLoader::GraphQL.for([pl, object.stage]).batch do |ids, loader|
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index da2f11be9e2..c8ac31bce4d 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -45,7 +45,7 @@ module Types
field :queued_duration, Types::DurationType, null: true,
description: 'How long the pipeline was queued before starting.'
- field :coverage, GraphQL::FLOAT_TYPE, null: true,
+ field :coverage, GraphQL::Types::Float, null: true,
description: 'Coverage percentage.'
field :created_at, Types::TimeType, null: false,
@@ -66,7 +66,7 @@ module Types
field :stages,
type: Types::Ci::StageType.connection_type,
null: true,
- authorize: :read_commit_status,
+ authorize: :read_build,
description: 'Stages of the pipeline.',
extras: [:lookahead],
resolver: Resolvers::Ci::PipelineStagesResolver
@@ -89,14 +89,14 @@ module Types
field :jobs,
::Types::Ci::JobType.connection_type,
null: true,
- authorize: :read_commit_status,
+ authorize: :read_build,
description: 'Jobs belonging to the pipeline.',
resolver: ::Resolvers::Ci::JobsResolver
field :job,
type: ::Types::Ci::JobType,
null: true,
- authorize: :read_commit_status,
+ authorize: :read_build,
description: 'Specific job in this pipeline, either by name or ID.' do
argument :id,
type: ::Types::GlobalIDType[::CommitStatus],
@@ -116,7 +116,7 @@ module Types
field :source_job,
type: Types::Ci::JobType,
null: true,
- authorize: :read_commit_status,
+ authorize: :read_build,
description: 'Job where pipeline was triggered from.'
field :downstream, Types::Ci::PipelineType.connection_type, null: true,
diff --git a/app/graphql/types/ci/runner_status_enum.rb b/app/graphql/types/ci/runner_status_enum.rb
index 8501ce20204..dd056191ceb 100644
--- a/app/graphql/types/ci/runner_status_enum.rb
+++ b/app/graphql/types/ci/runner_status_enum.rb
@@ -5,24 +5,37 @@ module Types
class RunnerStatusEnum < BaseEnum
graphql_name 'CiRunnerStatus'
- ::Ci::Runner::AVAILABLE_STATUSES.each do |status|
- description = case status
- when 'active'
- "A runner that is not paused."
- when 'online'
- "A runner that contacted this instance within the last #{::Ci::Runner::ONLINE_CONTACT_TIMEOUT.inspect}."
- when 'offline'
- "A runner that has not contacted this instance within the last #{::Ci::Runner::ONLINE_CONTACT_TIMEOUT.inspect}."
- when 'not_connected'
- "A runner that has never contacted this instance."
- else
- "A runner that is #{status.to_s.tr('_', ' ')}."
- end
-
- value status.to_s.upcase,
- description: description,
- value: status.to_sym
- end
+ value 'ACTIVE',
+ description: 'Runner that is not paused.',
+ deprecated: { reason: 'Use CiRunnerType.active instead', milestone: '14.6' },
+ value: :active
+
+ value 'PAUSED',
+ description: 'Runner that is paused.',
+ deprecated: { reason: 'Use CiRunnerType.active instead', milestone: '14.6' },
+ value: :paused
+
+ value 'ONLINE',
+ description: "Runner that contacted this instance within the last #{::Ci::Runner::ONLINE_CONTACT_TIMEOUT.inspect}.",
+ value: :online
+
+ value 'OFFLINE',
+ description: "Runner that has not contacted this instance within the last #{::Ci::Runner::ONLINE_CONTACT_TIMEOUT.inspect}.",
+ deprecated: { reason: 'This field will have a slightly different scope starting in 15.0, with STALE being returned after a certain period offline', milestone: '14.6' },
+ value: :offline
+
+ value 'STALE',
+ description: "Runner that has not contacted this instance within the last #{::Ci::Runner::STALE_TIMEOUT.inspect}. Only available if legacyMode is null. Will be a possible return value starting in 15.0.",
+ value: :stale
+
+ value 'NOT_CONNECTED',
+ description: 'Runner that has never contacted this instance.',
+ deprecated: { reason: "Use NEVER_CONTACTED instead. NEVER_CONTACTED will have a slightly different scope starting in 15.0, with STALE being returned instead after #{::Ci::Runner::STALE_TIMEOUT.inspect} of no contact", milestone: '14.6' },
+ value: :not_connected
+
+ value 'NEVER_CONTACTED',
+ description: 'Runner that has never contacted this instance. Set legacyMode to null to utilize this value. Will replace NOT_CONNECTED starting in 15.0.',
+ value: :never_contacted
end
end
end
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 9bf98aa7e86..d37cca0927f 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -27,8 +27,11 @@ module Types
description: 'Access level of the runner.'
field :active, GraphQL::Types::Boolean, null: false,
description: 'Indicates the runner is allowed to receive jobs.'
- field :status, ::Types::Ci::RunnerStatusEnum, null: false,
- description: 'Status of the runner.'
+ field :status,
+ Types::Ci::RunnerStatusEnum,
+ null: false,
+ description: 'Status of the runner.',
+ resolver: ::Resolvers::Ci::RunnerStatusResolver
field :version, GraphQL::Types::String, null: true,
description: 'Version of the runner.'
field :short_sha, GraphQL::Types::String, null: true,
@@ -50,7 +53,7 @@ module Types
field :job_count, GraphQL::Types::Int, null: true,
description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to indicate that more items exist)."
field :admin_url, GraphQL::Types::String, null: true,
- description: 'Admin URL of the runner. Only available for adminstrators.'
+ description: 'Admin URL of the runner. Only available for administrators.'
def job_count
# We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
diff --git a/app/graphql/types/ci/runner_web_url_edge.rb b/app/graphql/types/ci/runner_web_url_edge.rb
index 3b9fdfd1571..368e16f972c 100644
--- a/app/graphql/types/ci/runner_web_url_edge.rb
+++ b/app/graphql/types/ci/runner_web_url_edge.rb
@@ -3,7 +3,7 @@
module Types
module Ci
# rubocop: disable Graphql/AuthorizeTypes
- class RunnerWebUrlEdge < GraphQL::Types::Relay::BaseEdge
+ class RunnerWebUrlEdge < ::Types::BaseEdge
include FindClosest
field :web_url, GraphQL::Types::String, null: true,
diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb
index c0d931b3d31..70e78e391a7 100644
--- a/app/graphql/types/ci/stage_type.rb
+++ b/app/graphql/types/ci/stage_type.rb
@@ -4,7 +4,7 @@ module Types
module Ci
class StageType < BaseObject
graphql_name 'CiStage'
- authorize :read_commit_status
+ authorize :read_build
field :id, GraphQL::Types::ID, null: false,
description: 'ID of the stage.'
@@ -31,7 +31,10 @@ module Types
BatchLoader::GraphQL.for(key).batch(default_value: []) do |keys, loader|
by_pipeline = keys.group_by(&:pipeline)
- include_needs = keys.any? { |k| k.requires?(%i[nodes jobs nodes needs]) }
+ include_needs = keys.any? do |k|
+ k.requires?(%i[nodes jobs nodes needs]) ||
+ k.requires?(%i[nodes jobs nodes previousStageJobsAndNeeds])
+ end
by_pipeline.each do |pl, key_group|
project = pl.project
diff --git a/app/graphql/types/ci/test_case_type.rb b/app/graphql/types/ci/test_case_type.rb
index 9ec5daa44ea..6e5f55aa3ed 100644
--- a/app/graphql/types/ci/test_case_type.rb
+++ b/app/graphql/types/ci/test_case_type.rb
@@ -18,7 +18,7 @@ module Types
field :classname, GraphQL::Types::String, null: true,
description: 'Classname of the test case.'
- field :execution_time, GraphQL::FLOAT_TYPE, null: true,
+ field :execution_time, GraphQL::Types::Float, null: true,
description: 'Test case execution time in seconds.'
field :file, GraphQL::Types::String, null: true,
diff --git a/app/graphql/types/ci/test_report_total_type.rb b/app/graphql/types/ci/test_report_total_type.rb
index aa07a391519..48aea1257c5 100644
--- a/app/graphql/types/ci/test_report_total_type.rb
+++ b/app/graphql/types/ci/test_report_total_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'TestReportTotal'
description 'Total test report statistics.'
- field :time, GraphQL::FLOAT_TYPE, null: true,
+ field :time, GraphQL::Types::Float, null: true,
description: 'Total duration of the tests.'
field :count, GraphQL::Types::Int, null: true,
diff --git a/app/graphql/types/ci/test_suite_summary_type.rb b/app/graphql/types/ci/test_suite_summary_type.rb
index 3db2d80d591..ec7b852213b 100644
--- a/app/graphql/types/ci/test_suite_summary_type.rb
+++ b/app/graphql/types/ci/test_suite_summary_type.rb
@@ -12,7 +12,7 @@ module Types
field :name, GraphQL::Types::String, null: true,
description: 'Name of the test suite.'
- field :total_time, GraphQL::FLOAT_TYPE, null: true,
+ field :total_time, GraphQL::Types::Float, null: true,
description: 'Total duration of the tests in the test suite.'
field :total_count, GraphQL::Types::Int, null: true,
diff --git a/app/graphql/types/ci/test_suite_type.rb b/app/graphql/types/ci/test_suite_type.rb
index f9f37d4045e..7ce479632cc 100644
--- a/app/graphql/types/ci/test_suite_type.rb
+++ b/app/graphql/types/ci/test_suite_type.rb
@@ -12,7 +12,7 @@ module Types
field :name, GraphQL::Types::String, null: true,
description: 'Name of the test suite.'
- field :total_time, GraphQL::FLOAT_TYPE, null: true,
+ field :total_time, GraphQL::Types::Float, null: true,
description: 'Total duration of the tests in the test suite.'
field :total_count, GraphQL::Types::Int, null: true,
diff --git a/app/graphql/types/clusters/agent_activity_event_type.rb b/app/graphql/types/clusters/agent_activity_event_type.rb
new file mode 100644
index 00000000000..79a9fd70505
--- /dev/null
+++ b/app/graphql/types/clusters/agent_activity_event_type.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Types
+ module Clusters
+ class AgentActivityEventType < BaseObject
+ graphql_name 'ClusterAgentActivityEvent'
+
+ authorize :admin_cluster
+
+ connection_type_class(Types::CountableConnectionType)
+
+ field :recorded_at,
+ Types::TimeType,
+ null: true,
+ description: 'Timestamp the event was recorded.'
+
+ field :kind,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Type of event.'
+
+ field :level,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Severity of the event.'
+
+ field :user,
+ Types::UserType,
+ null: true,
+ description: 'User associated with the event.'
+
+ field :agent_token,
+ Types::Clusters::AgentTokenType,
+ null: true,
+ description: 'Agent token associated with the event.'
+ end
+ end
+end
diff --git a/app/graphql/types/clusters/agent_type.rb b/app/graphql/types/clusters/agent_type.rb
index ce748f6e8ae..89316ed4728 100644
--- a/app/graphql/types/clusters/agent_type.rb
+++ b/app/graphql/types/clusters/agent_type.rb
@@ -55,6 +55,12 @@ module Types
complexity: 5,
resolver: ::Resolvers::Kas::AgentConnectionsResolver
+ field :activity_events,
+ Types::Clusters::AgentActivityEventType.connection_type,
+ null: true,
+ description: 'Recent activity for the cluster agent.',
+ resolver: Resolvers::Clusters::AgentActivityEventsResolver
+
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
end
diff --git a/app/graphql/types/container_repository_details_type.rb b/app/graphql/types/container_repository_details_type.rb
index 8190cc9bc25..e713aaebe36 100644
--- a/app/graphql/types/container_repository_details_type.rb
+++ b/app/graphql/types/container_repository_details_type.rb
@@ -12,16 +12,11 @@ module Types
Types::ContainerRepositoryTagType.connection_type,
null: true,
description: 'Tags of the container repository.',
- max_page_size: 20
+ max_page_size: 20,
+ resolver: Resolvers::ContainerRepositoryTagsResolver
def can_delete
Ability.allowed?(current_user, :destroy_container_image, object)
end
-
- def tags
- object.tags
- rescue Faraday::Error
- raise ::Gitlab::Graphql::Errors::ResourceNotAvailable, 'We are having trouble connecting to the Container Registry. If this error persists, please review the troubleshooting documentation.'
- end
end
end
diff --git a/app/graphql/types/container_repository_tags_sort_enum.rb b/app/graphql/types/container_repository_tags_sort_enum.rb
new file mode 100644
index 00000000000..253cffd9a8c
--- /dev/null
+++ b/app/graphql/types/container_repository_tags_sort_enum.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Types
+ class ContainerRepositoryTagsSortEnum < BaseEnum
+ graphql_name 'ContainerRepositoryTagSort'
+ description 'Values for sorting tags'
+
+ value 'NAME_ASC', 'Ordered by name in ascending order.', value: :name_asc
+ value 'NAME_DESC', 'Ordered by name in descending order.', value: :name_desc
+ end
+end
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index 3b0f93d8dc1..498569f11ca 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -80,7 +80,8 @@ module Types
description: 'Relative position of the issue (used for positioning in epic tree and issue boards).'
field :participants, Types::UserType.connection_type, null: true, complexity: 5,
- description: 'List of participants in the issue.'
+ description: 'List of participants in the issue.',
+ resolver: Resolvers::Users::ParticipantsResolver
field :emails_disabled, GraphQL::Types::Boolean, null: false,
method: :project_emails_disabled?,
description: 'Indicates if a project has email notifications disabled: `true` if email notifications are disabled.'
diff --git a/app/graphql/types/issue_type_enum.rb b/app/graphql/types/issue_type_enum.rb
index 6999ea270a2..0cfba6bbbd0 100644
--- a/app/graphql/types/issue_type_enum.rb
+++ b/app/graphql/types/issue_type_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'IssueType'
description 'Issue type'
- ::WorkItem::Type.base_types.keys.each do |issue_type|
+ ::WorkItem::Type.allowed_types_for_issues.each do |issue_type|
value issue_type.upcase, value: issue_type, description: "#{issue_type.titleize} issue type"
end
end
diff --git a/app/graphql/types/merge_request_connection_type.rb b/app/graphql/types/merge_request_connection_type.rb
index d009b67bc0f..9596c812c69 100644
--- a/app/graphql/types/merge_request_connection_type.rb
+++ b/app/graphql/types/merge_request_connection_type.rb
@@ -3,7 +3,7 @@
module Types
# rubocop: disable Graphql/AuthorizeTypes
class MergeRequestConnectionType < Types::CountableConnectionType
- field :total_time_to_merge, GraphQL::FLOAT_TYPE, null: true,
+ field :total_time_to_merge, GraphQL::Types::Float, null: true,
description: 'Total sum of time to merge, in seconds, for the collection of merge requests.'
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index a0f00ddc3c6..0672ec6f0f8 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -21,10 +21,8 @@ module Types
description: 'Internal ID of the merge request.'
field :title, GraphQL::Types::String, null: false,
description: 'Title of the merge request.'
- markdown_field :title_html, null: true
field :description, GraphQL::Types::String, null: true,
description: 'Description of the merge request (Markdown rendered as HTML for caching).'
- markdown_field :description_html, null: true
field :state, MergeRequestStateEnum, null: false,
description: 'State of the merge request.'
field :created_at, Types::TimeType, null: false,
@@ -96,7 +94,7 @@ module Types
description: 'Rebase commit SHA of the merge request.'
field :rebase_in_progress, GraphQL::Types::Boolean, method: :rebase_in_progress?, null: false, calls_gitaly: true,
description: 'Indicates if there is a rebase currently in progress for the merge request.'
- field :default_merge_commit_message, GraphQL::Types::String, null: true,
+ field :default_merge_commit_message, GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'Default merge commit message of the merge request.'
field :default_merge_commit_message_with_description, GraphQL::Types::String, null: true,
description: 'Default merge commit message of the merge request with description. Will have the same value as `defaultMergeCommitMessage` when project has `mergeCommitTemplate` set.',
@@ -148,7 +146,8 @@ module Types
field :author, Types::UserType, null: true,
description: 'User who created this merge request.'
field :participants, Types::UserType.connection_type, null: true, complexity: 15,
- description: 'Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes.'
+ description: 'Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes.',
+ resolver: Resolvers::Users::ParticipantsResolver
field :subscribed, GraphQL::Types::Boolean, method: :subscribed?, null: false, complexity: 5,
description: 'Indicates if the currently logged in user is subscribed to this merge request.'
field :labels, Types::LabelType.connection_type, null: true, complexity: 5,
@@ -201,6 +200,9 @@ module Types
field :timelogs, Types::TimelogType.connection_type, null: false,
description: 'Timelogs on the merge request.'
+ markdown_field :title_html, null: true
+ markdown_field :description_html, null: true
+
def approved_by
object.approved_by_users
end
diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb
index 3c5994ac559..ba90fb06cb2 100644
--- a/app/graphql/types/namespace_type.rb
+++ b/app/graphql/types/namespace_type.rb
@@ -20,7 +20,6 @@ module Types
field :description, GraphQL::Types::String, null: true,
description: 'Description of the namespace.'
- markdown_field :description_html, null: true
field :visibility, GraphQL::Types::String, null: true,
description: 'Visibility of the namespace.'
@@ -47,6 +46,8 @@ module Types
null: true,
description: "Shared runners availability for the namespace and its descendants."
+ markdown_field :description_html, null: true
+
def root_storage_statistics
Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(object.id).find
end
diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb
index da6ea83401d..7314c137010 100644
--- a/app/graphql/types/notes/note_type.rb
+++ b/app/graphql/types/notes/note_type.rb
@@ -33,8 +33,6 @@ module Types
method: :note,
description: 'Content of the note.'
- markdown_field :body_html, null: true, method: :note
-
field :created_at, Types::TimeType, null: false,
description: 'Timestamp of the note creation.'
field :updated_at, Types::TimeType, null: false,
@@ -50,6 +48,8 @@ module Types
null: true,
description: 'URL to view this Note in the Web UI.'
+ markdown_field :body_html, null: true, method: :note
+
def url
::Gitlab::UrlBuilder.build(object)
end
diff --git a/app/graphql/types/packages/package_details_type.rb b/app/graphql/types/packages/package_details_type.rb
index 59a4885e87e..5ac80860fe2 100644
--- a/app/graphql/types/packages/package_details_type.rb
+++ b/app/graphql/types/packages/package_details_type.rb
@@ -14,6 +14,13 @@ module Types
field :dependency_links, Types::Packages::PackageDependencyLinkType.connection_type, null: true, description: 'Dependency link.'
+ # this is an override of Types::Packages::PackageType.pipelines
+ # in order to use a custom resolver: Resolvers::PackagePipelinesResolver
+ field :pipelines,
+ resolver: Resolvers::PackagePipelinesResolver,
+ description: 'Pipelines that built the package.',
+ deprecated: { reason: 'Due to scalability concerns, this field is going to be removed', milestone: '14.6' }
+
def versions
object.versions
end
diff --git a/app/graphql/types/packages/package_type.rb b/app/graphql/types/packages/package_type.rb
index 9851c6aec7e..d1312cb963d 100644
--- a/app/graphql/types/packages/package_type.rb
+++ b/app/graphql/types/packages/package_type.rb
@@ -21,7 +21,8 @@ module Types
field :tags, Types::Packages::PackageTagType.connection_type, null: true, description: 'Package tags.'
field :project, Types::ProjectType, null: false, description: 'Project where the package is stored.'
field :pipelines, Types::Ci::PipelineType.connection_type, null: true,
- description: 'Pipelines that built the package.'
+ description: 'Pipelines that built the package.',
+ deprecated: { reason: 'Due to scalability concerns, this field is going to be removed', milestone: '14.6' }
field :metadata, Types::Packages::MetadataType, null: true,
description: 'Package metadata.'
field :versions, ::Types::Packages::PackageType.connection_type, null: true,
diff --git a/app/graphql/types/project_statistics_type.rb b/app/graphql/types/project_statistics_type.rb
index 60a3d5ce06b..ab2b9c2a3af 100644
--- a/app/graphql/types/project_statistics_type.rb
+++ b/app/graphql/types/project_statistics_type.rb
@@ -6,26 +6,26 @@ module Types
authorize :read_statistics
- field :commit_count, GraphQL::FLOAT_TYPE, null: false,
+ field :commit_count, GraphQL::Types::Float, null: false,
description: 'Commit count of the project.'
- field :storage_size, GraphQL::FLOAT_TYPE, null: false,
+ field :storage_size, GraphQL::Types::Float, null: false,
description: 'Storage size of the project in bytes.'
- field :repository_size, GraphQL::FLOAT_TYPE, null: false,
+ field :repository_size, GraphQL::Types::Float, null: false,
description: 'Repository size of the project in bytes.'
- field :lfs_objects_size, GraphQL::FLOAT_TYPE, null: false,
+ field :lfs_objects_size, GraphQL::Types::Float, null: false,
description: 'Large File Storage (LFS) object size of the project in bytes.'
- field :build_artifacts_size, GraphQL::FLOAT_TYPE, null: false,
+ field :build_artifacts_size, GraphQL::Types::Float, null: false,
description: 'Build artifacts size of the project in bytes.'
- field :packages_size, GraphQL::FLOAT_TYPE, null: false,
+ field :packages_size, GraphQL::Types::Float, null: false,
description: 'Packages size of the project in bytes.'
- field :wiki_size, GraphQL::FLOAT_TYPE, null: true,
+ field :wiki_size, GraphQL::Types::Float, null: true,
description: 'Wiki size of the project in bytes.'
- field :snippets_size, GraphQL::FLOAT_TYPE, null: true,
+ field :snippets_size, GraphQL::Types::Float, null: true,
description: 'Snippets size of the project in bytes.'
- field :pipeline_artifacts_size, GraphQL::FLOAT_TYPE, null: true,
+ field :pipeline_artifacts_size, GraphQL::Types::Float, null: true,
description: 'CI Pipeline artifacts size in bytes.'
- field :uploads_size, GraphQL::FLOAT_TYPE, null: true,
+ field :uploads_size, GraphQL::Types::Float, null: true,
description: 'Uploads size of the project in bytes.'
end
end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index b6cb9cd3302..3d2ee47a499 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -194,7 +194,7 @@ module Types
field :jobs,
type: Types::Ci::JobType.connection_type,
null: true,
- authorize: :read_commit_status,
+ authorize: :read_build,
description: 'Jobs of a project. This field can only be resolved for one project in any single request.',
resolver: Resolvers::ProjectJobsResolver
@@ -386,6 +386,11 @@ module Types
null: true,
description: 'Template used to create merge commit message in merge requests.'
+ field :squash_commit_template,
+ GraphQL::Types::String,
+ null: true,
+ description: 'Template used to create squash commit message in merge requests.'
+
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args|
LabelsFinder
diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb
index 104171e6772..3265c14bdca 100644
--- a/app/graphql/types/repository/blob_type.rb
+++ b/app/graphql/types/repository/blob_type.rb
@@ -71,6 +71,10 @@ module Types
field :pipeline_editor_path, GraphQL::Types::String, null: true,
description: 'Web path to edit .gitlab-ci.yml file.'
+ field :code_owners, [Types::UserType], null: true,
+ description: 'List of code owners for the blob.',
+ calls_gitaly: true
+
field :file_type, GraphQL::Types::String, null: true,
description: 'Expected format of the blob based on the extension.'
@@ -91,6 +95,9 @@ module Types
calls_gitaly: true,
description: 'Whether the current user can modify the blob.'
+ field :can_current_user_push_to_branch, GraphQL::Types::Boolean, null: true, method: :can_current_user_push_to_branch?,
+ description: 'Whether the current user can push to the branch.'
+
def raw_text_blob
object.data unless object.binary?
end
@@ -101,3 +108,5 @@ module Types
end
end
end
+
+Types::Repository::BlobType.prepend_mod_with('Types::Repository::BlobType')
diff --git a/app/graphql/types/root_storage_statistics_type.rb b/app/graphql/types/root_storage_statistics_type.rb
index 47ca195cc4b..88dc6036bfd 100644
--- a/app/graphql/types/root_storage_statistics_type.rb
+++ b/app/graphql/types/root_storage_statistics_type.rb
@@ -6,14 +6,14 @@ module Types
authorize :read_statistics
- field :storage_size, GraphQL::FLOAT_TYPE, null: false, description: 'Total storage in bytes.'
- field :repository_size, GraphQL::FLOAT_TYPE, null: false, description: 'Git repository size in bytes.'
- field :lfs_objects_size, GraphQL::FLOAT_TYPE, null: false, description: 'LFS objects size in bytes.'
- field :build_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'CI artifacts size in bytes.'
- field :packages_size, GraphQL::FLOAT_TYPE, null: false, description: 'Packages size in bytes.'
- field :wiki_size, GraphQL::FLOAT_TYPE, null: false, description: 'Wiki size in bytes.'
- field :snippets_size, GraphQL::FLOAT_TYPE, null: false, description: 'Snippets size in bytes.'
- field :pipeline_artifacts_size, GraphQL::FLOAT_TYPE, null: false, description: 'CI pipeline artifacts size in bytes.'
- field :uploads_size, GraphQL::FLOAT_TYPE, null: false, description: 'Uploads size in bytes.'
+ field :storage_size, GraphQL::Types::Float, null: false, description: 'Total storage in bytes.'
+ field :repository_size, GraphQL::Types::Float, null: false, description: 'Git repository size in bytes.'
+ field :lfs_objects_size, GraphQL::Types::Float, null: false, description: 'LFS objects size in bytes.'
+ field :build_artifacts_size, GraphQL::Types::Float, null: false, description: 'CI artifacts size in bytes.'
+ field :packages_size, GraphQL::Types::Float, null: false, description: 'Packages size in bytes.'
+ field :wiki_size, GraphQL::Types::Float, null: false, description: 'Wiki size in bytes.'
+ 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.'
end
end
diff --git a/app/graphql/types/subscription_type.rb b/app/graphql/types/subscription_type.rb
index 5356a998f0d..3629edb5b33 100644
--- a/app/graphql/types/subscription_type.rb
+++ b/app/graphql/types/subscription_type.rb
@@ -6,5 +6,8 @@ module Types
field :issuable_assignees_updated, subscription: Subscriptions::IssuableUpdated, null: true,
description: 'Triggered when the assignees of an issuable are updated.'
+
+ field :issue_crm_contacts_updated, subscription: Subscriptions::IssuableUpdated, null: true,
+ description: 'Triggered when the crm contacts of an issuable are updated.'
end
end
diff --git a/app/graphql/types/user_callout_feature_name_enum.rb b/app/graphql/types/user_callout_feature_name_enum.rb
index 410ca5e1c95..bcb49a709ed 100644
--- a/app/graphql/types/user_callout_feature_name_enum.rb
+++ b/app/graphql/types/user_callout_feature_name_enum.rb
@@ -5,7 +5,7 @@ module Types
graphql_name 'UserCalloutFeatureNameEnum'
description 'Name of the feature that the callout is for.'
- ::UserCallout.feature_names.keys.each do |feature_name|
+ ::Users::Callout.feature_names.keys.each do |feature_name|
value feature_name.upcase, value: feature_name, description: "Callout feature name for #{feature_name}."
end
end