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::EdgeStagesInjectorGitlab::Ci::Config::ReservedStagesInjectorGitlab::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_contextand not leaking into CI - Make
Ci::Configagnostic 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
PipelineExecutionPolicyis registered inCi::CreatePipelineService1. - The plugin component defines callback methods based on a supported list of callbacks.
- The logic in
Ci::CreatePipelineServicefires callbacks to registered plugins, passing data to each callback. - The plugin can modify the pipeline data structure along the way.