mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-14 23:22:51 +00:00
Require version config to be workflow.toml beside its graph
WorkflowLocation dispatches any `.toml` path to the config loader, so a supplied entrypoint such as `sub/run.toml` was accepted, its graph became the version entrypoint, and the config file was registered under its own name. Runtime only reads WorkflowVersion::config_path(), the fixed sibling `workflow.toml`, so the version's goal, environment, and Dockerfile settings were silently dropped on every run. In workflow-version projection, reject a config whose collected path is not the graph's sibling `workflow.toml`. This applies to every caller that packages versions, including `fabro run <dir>/other.toml`, which previously registered the config and then ignored it; failing at packaging replaces a silent drop. Manifest bundling for the legacy run path does not project versions and is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
70b1090f58
commit
44dccfa3d2
2 changed files with 55 additions and 2 deletions
|
|
@ -254,6 +254,46 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_entrypoint_must_be_workflow_toml_beside_its_graph() {
|
||||
let config = "_version = 1\n[workflow]\ngraph = \"g.fabro\"\n[run]\ngoal = \"hello\"\n";
|
||||
let accepted = supplied("sub/workflow.toml", &[
|
||||
("sub/workflow.toml", config),
|
||||
("sub/g.fabro", "digraph W {}"),
|
||||
]);
|
||||
let root = collect(&accepted)
|
||||
.versions()
|
||||
.last()
|
||||
.unwrap()
|
||||
.1
|
||||
.version()
|
||||
.clone();
|
||||
assert!(root.files().contains_key(&root.config_path()));
|
||||
|
||||
// Same tree under another config name: runtime would never read it.
|
||||
let renamed = supplied("sub/run.toml", &[
|
||||
("sub/run.toml", config),
|
||||
("sub/g.fabro", "digraph W {}"),
|
||||
]);
|
||||
let error =
|
||||
collect_supplied_workflow_versions(&renamed.entrypoint, &renamed.files).unwrap_err();
|
||||
assert!(
|
||||
format!("{error:#}").contains("must be `sub/workflow.toml`"),
|
||||
"{error:#}"
|
||||
);
|
||||
// A config that selects a graph in another directory is not its sibling.
|
||||
let elsewhere = supplied("sub/workflow.toml", &[
|
||||
(
|
||||
"sub/workflow.toml",
|
||||
"_version = 1\n[workflow]\ngraph = \"../g.fabro\"\n",
|
||||
),
|
||||
("g.fabro", "digraph W {}"),
|
||||
]);
|
||||
assert!(
|
||||
collect_supplied_workflow_versions(&elsewhere.entrypoint, &elsewhere.files).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_literal_scripts_without_executing() {
|
||||
let directory = tempfile::tempdir().unwrap();
|
||||
|
|
|
|||
|
|
@ -97,9 +97,22 @@ impl<'a> WorkflowBundler<'a> {
|
|||
|
||||
let source = self.read_package_file(&location.graph)?;
|
||||
let config = if let Some(workflow_toml_path) = location.toml.as_ref() {
|
||||
let config_path = manifest_path_from_absolute(workflow_toml_path, self.package_root)?;
|
||||
if self.workflow_version_projection {
|
||||
// A version's config is read at run time from the fixed
|
||||
// sibling path only, so a config file under any other name
|
||||
// would be registered and then silently ignored.
|
||||
let expected = dot_path.parent_or_dot().join("workflow.toml");
|
||||
if config_path.as_path() != expected {
|
||||
bail!(
|
||||
"workflow configuration `{config_path}` must be `{}` beside its graph \
|
||||
`{dot_path}`",
|
||||
expected.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
Some(types::ManifestWorkflowConfig {
|
||||
path: manifest_path_from_absolute(workflow_toml_path, self.package_root)?
|
||||
.to_string(),
|
||||
path: config_path.to_string(),
|
||||
source: self.read_package_file(workflow_toml_path)?,
|
||||
})
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue