Allow Chain::SeedBlock to run only predefined actions
Problem
In the pipeline creation chain we have Chain::SeedBlock
step that evaluates a block passed to Ci::CreatePipelineService#execute
. This block can really do anything to a pipeline being created.
We consider Ci::CreatePipelineService
part of CI domain's public interface as it's called in many places in the monolith. Because of that, we need to make this service safe to use.
In the past we added custom steps later in the chain to avoid some data be overridden by the SeedBlock
.
Details
This block today is used in the following places:
- https://gitlab.com/gitlab-org/gitlab/-/blob/055d4db1b84bf1082a8b4e983bc8c1bc0ec217ed/ee/app/services/ci/trigger_downstream_subscription_service.rb#L9
- https://gitlab.com/gitlab-org/gitlab/-/blob/055d4db1b84bf1082a8b4e983bc8c1bc0ec217ed/lib/gitlab/chat/command.rb#L57
- https://gitlab.com/gitlab-org/gitlab/-/blob/055d4db1b84bf1082a8b4e983bc8c1bc0ec217ed/app/services/ci/pipeline_trigger_service.rb
Proposal
Make SeedBlock
return some kind of Seeder
object that in turn has only some defined methods that allow the caller to modify the pipeline.
# Example: in Ci::PipelineTriggerService#create_pipelin_from_job
Ci::CreatePipelineService.new(...).execute do |seeder|
seeder.add_source_job(job)
end
class Ci::Pipeline::Chain::SeedBlock::Seeder
def initialize(pipeline)
@pipeline = pipeline
end
def add_source_job(job)
source = job.sourced_pipelines.build(
source_pipeline: job.pipeline,
source_project: job.project,
pipeline: pipeline,
project: pipeline.project)
pipeline.source_pipeline = source
end
def created_via_trigger(trigger)
pipeline.trigger_requests.build(trigger: trigger)
end
private
attr_reader :pipeline
end
Edited by Fabio Pitino