Commit 332aa765 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Implement upstream pipeline status attribution

This only implements one of three upcoming strategies of connecting
upstream pipeline with a downstream pipeline. Here we change bridge job
status to success as soon as downstream pipeline gets enqueued for
processing.
parent c1a39f2c
......@@ -10,6 +10,7 @@ module Ci
belongs_to :source_project, class_name: Project, foreign_key: :source_project_id
belongs_to :source_job, class_name: CommitStatus, foreign_key: :source_job_id
belongs_to :source_bridge, class_name: Ci::Bridge, foreign_key: :source_job_id
belongs_to :source_pipeline, class_name: Ci::Pipeline, foreign_key: :source_pipeline_id
validates :project, presence: true
......
......@@ -11,25 +11,9 @@ module EE
foreign_key: :source_job_id
state_machine :status do
after_transition any => [:pending] do |bridge|
after_transition created: :pending do |bridge|
bridge.run_after_commit do
bridge.schedule_downstream_pipeline!
# 1. schedule pipeline creation async
# 2. scheduled pipeline calls-back to change state to success or
# running when it gets created successfully
# 3. if no downstream pipeline can be created because of various
# reasons, like lack of access, then we change state of this
# job to failed with a reason
# 4. Status of this job depends on the trigger specification,
# it can `wait` for the status, `depend` on the status or
# be just instant trigger without status attribution.
# 5. In the first iteration it supports no status attribution.
end
end
after_transition pending: :running do |bridge|
bridge.run_after_commit do
end
end
end
......
......@@ -21,6 +21,7 @@ module EE
has_many :sourced_pipelines, class_name: ::Ci::Sources::Pipeline, foreign_key: :source_pipeline_id
has_one :triggered_by_pipeline, through: :source_pipeline, source: :source_pipeline
has_one :source_bridge, through: :source_pipeline, source: :source_bridge
has_many :triggered_pipelines, through: :sourced_pipelines, source: :pipeline
has_many :auto_canceled_pipelines, class_name: 'Ci::Pipeline', foreign_key: 'auto_canceled_by_id'
......@@ -95,9 +96,25 @@ module EE
StoreSecurityReportsWorker.perform_async(pipeline.id)
end
end
after_transition created: :pending do |pipeline|
next unless pipeline.bridge_triggered?
pipeline.update_bridge_status!
end
end
end
def bridge_triggered?
source_bridge.present?
end
def update_bridge_status!
raise HasStatus::UnknownStatusError if source_bridge.complete?
source_bridge.success!
end
def any_report_artifact_for_type(file_type)
report_artifact_for_file_type(file_type) || legacy_report_artifact_for_file_type(file_type)
end
......
require 'spec_helper'
describe Ci::CreateCrossProjectPipelineService, '#execute' do
set(:user) { create(:user) }
set(:upstream_project) { create(:project, :repository) }
set(:downstream_project) { create(:project, :repository) }
set(:upstream_pipeline) { create(:ci_pipeline, project: upstream_project) }
set(:user) { create(:user) }
set(:upstream_pipeline) do
create(:ci_pipeline, :running, project: upstream_project)
end
let(:trigger) do
{
......@@ -16,7 +19,8 @@ describe Ci::CreateCrossProjectPipelineService, '#execute' do
end
let(:bridge) do
create(:ci_bridge, user: user,
create(:ci_bridge, status: :pending,
user: user,
options: trigger,
pipeline: upstream_pipeline)
end
......@@ -51,17 +55,19 @@ describe Ci::CreateCrossProjectPipelineService, '#execute' do
it 'creates a new pipeline in a downstream project' do
pipeline = service.execute(bridge)
expect(pipeline.user).to eq bridge.user
expect(pipeline.project).to eq downstream_project
expect(bridge.sourced_pipelines.first.pipeline).to eq pipeline
expect(pipeline.source_pipeline.source_pipeline).to eq upstream_pipeline
expect(pipeline.source_pipeline.source_job).to eq bridge
expect(pipeline.source_pipeline.source_job).to be_a ::Ci::Bridge
expect(pipeline.triggered_by_pipeline).to eq upstream_pipeline
expect(pipeline.source_bridge).to eq bridge
expect(pipeline.source_bridge).to be_a ::Ci::Bridge
end
it 'delegates permissions to newly created pipelines' do
it 'changes bridge status when downstream pipeline gets proceesed' do
pipeline = service.execute(bridge)
expect(pipeline.user).to eq bridge.user
expect(pipeline.reload).to be_pending
expect(bridge.reload).to be_success
end
end
end
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