Refactor pipeline execution policy stages injection
We should refactor the stages injection logic and place them under Gitlab::Ci::Config
(!178199 (comment 2332013877)):
These 3 classes should be all placed closely together and be agnostic from Pipeline Execution Policy:
Gitlab::Ci::Config::EdgeStagesInjector
Gitlab::Ci::Config::ReservedStagesInjector
Gitlab::Ci::Config::StagesMerger
I think we need to keep generic concepts inside the Gitlab::Ci::Config
so they can become reusable building blocks and more encouraged to working together cohesively. Since these classes modify the internal config structure, they should be owned by CI.
Further feedback to consider (!178199 (comment 2326225590)):
def enforce_pipeline_execution_policy_stages(config)
pipeline_policy_context&.enforce_stages!(config: config, raise_error: ::Gitlab::Ci::Config::ConfigError)
end
# in pipeline_policy_context
def enforce_stages(config:, raise_error:)
# ...
rescue ::Gitlab::Ci::Pipeline::PipelineExecutionPolicies::CustomStagesInjector::InvalidStageConditionError => e
raise raise_error, e.message
end
This should allow us to:
- Keep all the logic inside
pipeline_policy_context
and not leaking into CI - Make
Ci::Config
agnostic of downstream exceptions - Have less complexity here.
The general theme is that we should keep most of the logic and state inside pipeline_policy_context
with regards to PEP. The CI code should simply call high-level methods.
Later we can breakdown pipeline_policy_context
into smaller classes. Ideally I would like us to invert the dependencies more like a plug-in system:
- A Plugin
PipelineExecutionPolicy
is registered inCi::CreatePipelineService1
. - The plugin component defines callback methods based on a supported list of callbacks.
- The logic in
Ci::CreatePipelineService
fires callbacks to registered plugins, passing data to each callback. - The plugin can modify the pipeline data structure along the way.