Problem
Although the patch pipeline is already config-selectable (PatchesConfig in cli/localci/core/config.py:199-237, assembled by PatchPipeline.from_config in cli/localci/core/patch_pipeline.py:66-84), the individual steps in cli/localci/core/patch_steps.py hardcode Boost/Capy build assumptions and cannot be retargeted to other C++/GitHub-Actions projects. B2SourceCacheStep matches the literal string cp -rL boost-source boost-root (lines 88-91); RestoreCapyTimestampsStep keys off a step literally named Patch Boost and paths under capy-root/ (lines 120-141); CapyCopyPreservationStep matches cp -r "$workspace_root" ... libs/ (line 160); B2BootstrapSkipStep looks for a b2-workflow uses: step (line 188). The command builder further defaults the repo to cppalliance/capy (cli/localci/core/command_builder.py:56) and gates 386-arch on a capy- image prefix (line 190). The result: the tool advertises "works with any GitHub Actions workflow" (README.md:7) but its transformation layer only works for Boost.Capy.
Acceptance Criteria
Implementation Notes
- Core files:
cli/localci/core/patch_steps.py (the seven step classes + PATCH_STEP_REGISTRY), cli/localci/core/patch_pipeline.py (PatchStep ABC, PatchContext, PatchPipeline.from_config), cli/localci/core/config.py (PATCH_STEP_NAMES:188-196, PatchesConfig:199-237), and cli/localci/core/command_builder.py (repo/image defaults at lines 56 and 185-192).
- Recommended approach: keep the ordered-pipeline architecture (it is sound) and thread project-specific literals through
PatchContext/config rather than rewriting the engine. PatchContext (patch_pipeline.py:39-52) already carries config, so new configurable literals can ride along without changing step signatures.
- Gotcha: patches intentionally operate on raw text lines, not parsed YAML, to avoid round-trip formatting changes (
PatchContext docstring, patch_pipeline.py:41-45). Preserve this — do not switch steps to YAML round-tripping.
- Gotcha:
PatchesConfig.validate_order / validate_order_completeness (config.py:211-237) enforce that PATCH_STEP_NAMES and enabled steps stay aligned; any new plugin/registration path must keep these validators consistent (or extend them) so an enabled-but-unregistered step still fails loudly as it does today (from_config raises at patch_pipeline.py:78-82).
- Consider splitting "generic" steps (
ContainerMountsStep, ImageSubstitutionStep, CodecovSkipStep) from "Boost-only" steps in docs so downstream users know which apply out of the box.
References
- Eval finding: Test 22 (abstraction-coherence) — "Boost-specific patch steps limit generality"
- Related files:
cli/localci/core/patch_steps.py, cli/localci/core/patch_pipeline.py, cli/localci/core/config.py, cli/localci/core/command_builder.py
Problem
Although the patch pipeline is already config-selectable (
PatchesConfigincli/localci/core/config.py:199-237, assembled byPatchPipeline.from_configincli/localci/core/patch_pipeline.py:66-84), the individual steps incli/localci/core/patch_steps.pyhardcode Boost/Capy build assumptions and cannot be retargeted to other C++/GitHub-Actions projects.B2SourceCacheStepmatches the literal stringcp -rL boost-source boost-root(lines 88-91);RestoreCapyTimestampsStepkeys off a step literally namedPatch Boostand paths undercapy-root/(lines 120-141);CapyCopyPreservationStepmatchescp -r "$workspace_root" ... libs/(line 160);B2BootstrapSkipSteplooks for ab2-workflowuses:step (line 188). The command builder further defaults the repo tocppalliance/capy(cli/localci/core/command_builder.py:56) and gates 386-arch on acapy-image prefix (line 190). The result: the tool advertises "works with any GitHub Actions workflow" (README.md:7) but its transformation layer only works for Boost.Capy.Acceptance Criteria
boost-source/boost-root,Patch Boost,capy-root,b2-workflow,libs/$module) are lifted out of the step classes into configurable values (e.g. new fields onPatchesConfig/ a per-step settings model, or a documented plugin registration point)PATCH_STEP_REGISTRYinpatch_steps.py:312-320— either via config-provided parameters to the existing steps or an entry-point/plugin hook wired throughPatchPipeline.from_config.localci.ymlbehavior for Boost.Capy is unchanged (backward compatible): existing fixtures undercli/tests/fixtures/patcher/still patch identicallycommand_builder.pyno longer bakes incppalliance/capy/capy-as non-overridable defaults for non-Boost projects (repo name and image-family gating are configurable)Implementation Notes
cli/localci/core/patch_steps.py(the seven step classes +PATCH_STEP_REGISTRY),cli/localci/core/patch_pipeline.py(PatchStepABC,PatchContext,PatchPipeline.from_config),cli/localci/core/config.py(PATCH_STEP_NAMES:188-196,PatchesConfig:199-237), andcli/localci/core/command_builder.py(repo/image defaults at lines 56 and 185-192).PatchContext/config rather than rewriting the engine.PatchContext(patch_pipeline.py:39-52) already carriesconfig, so new configurable literals can ride along without changing step signatures.PatchContextdocstring, patch_pipeline.py:41-45). Preserve this — do not switch steps to YAML round-tripping.PatchesConfig.validate_order/validate_order_completeness(config.py:211-237) enforce thatPATCH_STEP_NAMESand enabled steps stay aligned; any new plugin/registration path must keep these validators consistent (or extend them) so an enabled-but-unregistered step still fails loudly as it does today (from_configraises at patch_pipeline.py:78-82).ContainerMountsStep,ImageSubstitutionStep,CodecovSkipStep) from "Boost-only" steps in docs so downstream users know which apply out of the box.References
cli/localci/core/patch_steps.py,cli/localci/core/patch_pipeline.py,cli/localci/core/config.py,cli/localci/core/command_builder.py