diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/ci/create_cross_project_pipeline_service.rb | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/app/services/ci/create_cross_project_pipeline_service.rb b/app/services/ci/create_cross_project_pipeline_service.rb index 22b8e37a7e8..99f232bc892 100644 --- a/app/services/ci/create_cross_project_pipeline_service.rb +++ b/app/services/ci/create_cross_project_pipeline_service.rb @@ -5,9 +5,19 @@ module Ci class CreateCrossProjectPipelineService < ::BaseService include Gitlab::Utils::StrongMemoize + DuplicateDownstreamPipelineError = Class.new(StandardError) + def execute(bridge) @bridge = bridge + if bridge.has_downstream_pipeline? + Gitlab::ErrorTracking.track_exception( + DuplicateDownstreamPipelineError.new, + bridge_id: @bridge.id, project_id: @bridge.project_id + ) + return + end + pipeline_params = @bridge.downstream_pipeline_params target_ref = pipeline_params.dig(:target_revision, :ref) @@ -18,14 +28,32 @@ module Ci current_user, pipeline_params.fetch(:target_revision)) - service.execute( + downstream_pipeline = service.execute( pipeline_params.fetch(:source), pipeline_params[:execute_params]) do |pipeline| pipeline.variables.build(@bridge.downstream_variables) end + + downstream_pipeline.tap do |pipeline| + next if Feature.disabled?(:ci_drop_bridge_on_downstream_errors, project, default_enabled: true) + + update_bridge_status!(@bridge, pipeline) + end end private + def update_bridge_status!(bridge, pipeline) + Gitlab::OptimisticLocking.retry_lock(bridge) do |subject| + if pipeline.created_successfully? + # If bridge uses `strategy:depend` we leave it running + # and update the status when the downstream pipeline completes. + subject.success! unless subject.dependent? + else + subject.drop!(:downstream_pipeline_creation_failed) + end + end + end + def ensure_preconditions!(target_ref) unless downstream_project_accessible? @bridge.drop!(:downstream_bridge_project_not_found) |