diff options
Diffstat (limited to 'app/graphql/types/ci/stage_type.rb')
-rw-r--r-- | app/graphql/types/ci/stage_type.rb | 33 |
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 |