Copy all submodule YAMLs referenced (recursively) by the workflow. Submodules are copied under a `submodules/` directory inside the reproducibility snapshot. Paths are preserved relative to the project root when possible, falling back to basenames otherwise.
(
plan_path: Path, project_root: Path, repro_dir: Path
)
| 244 | |
| 245 | |
| 246 | def _copy_submodules_for_workflow( |
| 247 | plan_path: Path, project_root: Path, repro_dir: Path |
| 248 | ) -> None: |
| 249 | """Copy all submodule YAMLs referenced (recursively) by the workflow. |
| 250 | |
| 251 | Submodules are copied under a `submodules/` directory inside the |
| 252 | reproducibility snapshot. Paths are preserved relative to the project root |
| 253 | when possible, falling back to basenames otherwise. |
| 254 | """ |
| 255 | # Discover submodules/modules by parsing YAML relationships. This works |
| 256 | # uniformly for both CLI and YAML Flow Editor runs, since the latter |
| 257 | # produces a self-contained run_<id>.yaml that references its modules. |
| 258 | try: |
| 259 | submodule_paths = _collect_submodule_paths(plan_path) |
| 260 | except Exception: |
| 261 | # Best-effort only: do not fail reproducibility snapshot if this fails |
| 262 | return |
| 263 | |
| 264 | if not submodule_paths: |
| 265 | return |
| 266 | |
| 267 | # For simplicity and portability, store all discovered module/submodule YAMLs |
| 268 | # under a flat `modules/` directory, preserving only the filename. This |
| 269 | # matches the expected layout used for reproducibility. |
| 270 | modules_root = repro_dir / "modules" |
| 271 | for sub_path in sorted(submodule_paths): |
| 272 | try: |
| 273 | dest = modules_root / sub_path.name |
| 274 | dest.parent.mkdir(parents=True, exist_ok=True) |
| 275 | _copy_file_if_exists(sub_path, dest) |
| 276 | except Exception: |
| 277 | # Ignore individual copy errors to keep snapshot best-effort |
| 278 | continue |
| 279 | |
| 280 | |
| 281 | def ensure_workflow_submodules_snapshot( |
no test coverage detected