Commit 825b6f36 authored by Fabio Pitino's avatar Fabio Pitino Committed by Sean McGivern

Render source job info in TriggeredPipelineEntity

Allow frontend to display which job triggered the downstream
pipeline.
parent bdefe8a7
...@@ -447,6 +447,10 @@ module Ci ...@@ -447,6 +447,10 @@ module Ci
end end
end end
def triggered_pipelines_with_preloads
triggered_pipelines.preload(:source_job)
end
def legacy_stages def legacy_stages
if ::Gitlab::Ci::Features.composite_status?(project) if ::Gitlab::Ci::Features.composite_status?(project)
legacy_stages_using_composite_status legacy_stages_using_composite_status
......
...@@ -60,8 +60,8 @@ class PipelineSerializer < BaseSerializer ...@@ -60,8 +60,8 @@ class PipelineSerializer < BaseSerializer
}, },
pending_builds: :project, pending_builds: :project,
project: [:route, { namespace: :route }], project: [:route, { namespace: :route }],
triggered_by_pipeline: [:project, :user], triggered_by_pipeline: [{ project: [:route, { namespace: :route }] }, :user],
triggered_pipelines: [:project, :user] triggered_pipelines: [{ project: [:route, { namespace: :route }] }, :user, :source_job]
} }
] ]
end end
......
...@@ -11,6 +11,12 @@ class TriggeredPipelineEntity < Grape::Entity ...@@ -11,6 +11,12 @@ class TriggeredPipelineEntity < Grape::Entity
expose :coverage expose :coverage
expose :source expose :source
expose :source_job do
expose :name do |pipeline|
pipeline.source_job&.name
end
end
expose :path do |pipeline| expose :path do |pipeline|
project_pipeline_path(pipeline.project, pipeline) project_pipeline_path(pipeline.project, pipeline)
end end
...@@ -27,7 +33,7 @@ class TriggeredPipelineEntity < Grape::Entity ...@@ -27,7 +33,7 @@ class TriggeredPipelineEntity < Grape::Entity
as: :triggered_by, with: TriggeredPipelineEntity, as: :triggered_by, with: TriggeredPipelineEntity,
if: -> (_, opts) { can_read_details? && expand_for_path?(opts) } if: -> (_, opts) { can_read_details? && expand_for_path?(opts) }
expose :triggered_pipelines, expose :triggered_pipelines_with_preloads,
as: :triggered, using: TriggeredPipelineEntity, as: :triggered, using: TriggeredPipelineEntity,
if: -> (_, opts) { can_read_details? && expand_for_path?(opts) } if: -> (_, opts) { can_read_details? && expand_for_path?(opts) }
......
---
title: Render source job info in TriggeredPipelineEntity
merge_request: 35232
author:
type: added
...@@ -157,20 +157,30 @@ RSpec.describe PipelineDetailsEntity do ...@@ -157,20 +157,30 @@ RSpec.describe PipelineDetailsEntity do
context 'when pipeline triggered other pipeline' do context 'when pipeline triggered other pipeline' do
let(:pipeline) { create(:ci_empty_pipeline) } let(:pipeline) { create(:ci_empty_pipeline) }
let(:build) { create(:ci_build, pipeline: pipeline) } let(:build) { create(:ci_build, name: 'child', stage: 'test', pipeline: pipeline) }
let(:bridge) { create(:ci_bridge, name: 'cross-project', stage: 'build', pipeline: pipeline) }
let(:child_pipeline) { create(:ci_pipeline, project: pipeline.project) }
let(:cross_project_pipeline) { create(:ci_pipeline) }
before do before do
create(:ci_sources_pipeline, source_job: build) create(:ci_sources_pipeline, source_job: build, pipeline: child_pipeline)
create(:ci_sources_pipeline, source_job: build) create(:ci_sources_pipeline, source_job: bridge, pipeline: cross_project_pipeline)
end end
it 'contains an information about depedent pipeline' do it 'contains an information about dependent pipeline', :aggregate_failures do
expect(subject[:triggered]).to be_a(Array) expect(subject[:triggered]).to be_a(Array)
expect(subject[:triggered].length).to eq(2) expect(subject[:triggered].length).to eq(2)
expect(subject[:triggered].first[:path]).not_to be_nil expect(subject[:triggered].first[:path]).not_to be_nil
expect(subject[:triggered].first[:details]).not_to be_nil expect(subject[:triggered].first[:details]).not_to be_nil
expect(subject[:triggered].first[:details][:status]).not_to be_nil expect(subject[:triggered].first[:details][:status]).not_to be_nil
expect(subject[:triggered].first[:project]).not_to be_nil expect(subject[:triggered].first[:project]).not_to be_nil
source_jobs = subject[:triggered]
.index_by { |pipeline| pipeline[:id] }
.transform_values { |pipeline| pipeline.fetch(:source_job) }
expect(source_jobs[cross_project_pipeline.id][:name]).to eq('cross-project')
expect(source_jobs[child_pipeline.id][:name]).to eq('child')
end end
end end
end end
......
...@@ -211,6 +211,33 @@ RSpec.describe PipelineSerializer do ...@@ -211,6 +211,33 @@ RSpec.describe PipelineSerializer do
end end
end end
context 'with triggered pipelines' do
let(:ref) { 'feature' }
before do
pipeline_1 = create(:ci_pipeline)
build_1 = create(:ci_build, pipeline: pipeline_1)
create(:ci_sources_pipeline, source_job: build_1)
pipeline_2 = create(:ci_pipeline)
build_2 = create(:ci_build, pipeline: pipeline_2)
create(:ci_sources_pipeline, source_job: build_2)
end
it 'verifies number of queries', :request_store do
recorded = ActiveRecord::QueryRecorder.new { subject }
# 99 queries by default + 2 related to preloading
# :source_pipeline and :source_job
# Existing numbers are high and require performance optimization
# https://gitlab.com/gitlab-org/gitlab/-/issues/225156
expected_queries = Gitlab.ee? ? 101 : 92
expect(recorded.count).to be_within(2).of(expected_queries)
expect(recorded.cached_count).to eq(0)
end
end
def create_pipeline(status) def create_pipeline(status)
create(:ci_empty_pipeline, create(:ci_empty_pipeline,
project: project, project: project,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment