summaryrefslogtreecommitdiff
path: root/app/graphql/types/ci/stage_type.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/types/ci/stage_type.rb')
-rw-r--r--app/graphql/types/ci/stage_type.rb33
1 files changed, 33 insertions, 0 deletions
diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb
index fd0bde90836..695e7c61bd9 100644
--- a/app/graphql/types/ci/stage_type.rb
+++ b/app/graphql/types/ci/stage_type.rb
@@ -9,6 +9,7 @@ module Types
field :name, GraphQL::STRING_TYPE, null: true,
description: 'Name of the stage'
field :groups, Ci::GroupType.connection_type, null: true,
+ extras: [:lookahead],
description: 'Group of jobs for the stage'
field :detailed_status, Types::Ci::DetailedStatusType, null: true,
description: 'Detailed status of the stage'
@@ -16,6 +17,38 @@ module Types
def detailed_status
object.detailed_status(context[:current_user])
end
+
+ # Issues one query per pipeline
+ def groups(lookahead:)
+ key = ::Gitlab::Graphql::BatchKey.new(object, lookahead, object_name: :stage)
+
+ 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]) }
+
+ by_pipeline.each do |pl, key_group|
+ project = pl.project
+ indexed = key_group.index_by(&:id)
+
+ jobs_for_pipeline(pl, indexed.keys, include_needs).each do |stage_id, statuses|
+ key = indexed[stage_id]
+ groups = ::Ci::Group.fabricate(project, key.stage, statuses)
+ loader.call(key, groups)
+ end
+ end
+ end
+ end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def jobs_for_pipeline(pipeline, stage_ids, include_needs)
+ results = pipeline.latest_statuses.where(stage_id: stage_ids)
+ results = results.preload(:needs) if include_needs
+
+ results.group_by(&:stage_id)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
end
end