2022-01-26 12:08:38 +05:30
|
|
|
# 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
|
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
# this resolver can be called for 100 packages max and we want to limit the
|
|
|
|
# number of build infos returned for _each_ package when using the new finder.
|
|
|
|
MAX_PAGE_SIZE = 20
|
2022-01-26 12:08:38 +05:30
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
# This returns a promise for a connection of promises for pipelines:
|
|
|
|
# Lazy[Connection[Lazy[Pipeline]]] structure
|
2023-03-04 22:38:38 +05:30
|
|
|
def resolve(lookahead:, first: nil, last: nil, after: nil, before: nil)
|
2022-07-16 23:28:13 +05:30
|
|
|
default_value = default_value_for(first: first, last: last, after: after, before: before)
|
|
|
|
BatchLoader::GraphQL.for(package.id)
|
|
|
|
.batch(default_value: default_value) do |package_ids, loader|
|
|
|
|
build_infos = ::Packages::BuildInfosFinder.new(
|
|
|
|
package_ids,
|
|
|
|
first: first,
|
|
|
|
last: last,
|
|
|
|
after: decode_cursor(after),
|
|
|
|
before: decode_cursor(before),
|
|
|
|
max_page_size: MAX_PAGE_SIZE,
|
|
|
|
support_next_page: lookahead.selects?(:page_info)
|
|
|
|
).execute
|
2022-01-26 12:08:38 +05:30
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
build_infos.each do |build_info|
|
|
|
|
loader.call(build_info.package_id) do |connection|
|
|
|
|
connection.items << lazy_load_pipeline(build_info.pipeline_id)
|
|
|
|
connection
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2022-01-26 12:08:38 +05:30
|
|
|
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
|
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
def lazy_load_pipeline(id)
|
|
|
|
::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Ci::Pipeline, id)
|
|
|
|
.find
|
|
|
|
end
|
|
|
|
|
|
|
|
def default_value_for(first:, last:, after:, before:)
|
|
|
|
Gitlab::Graphql::Pagination::ActiveRecordArrayConnection.new(
|
|
|
|
[],
|
|
|
|
first: first,
|
|
|
|
last: last,
|
|
|
|
after: after,
|
|
|
|
before: before,
|
|
|
|
max_page_size: MAX_PAGE_SIZE
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2022-01-26 12:08:38 +05:30
|
|
|
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
|