mirror of
https://github.com/github/spec-kit.git
synced 2026-08-03 06:26:30 +08:00
fix(workflows): enforce disabled state for direct paths to installed workflows
Running the installed copy's YAML directly (specify workflow run .specify/workflows/align-wf/workflow.yml) skipped the registry check. File sources resolving inside .specify/workflows/<id>/ now map back to the workflow ID and refuse to run while disabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -349,9 +349,10 @@ def workflow_run(
|
||||
|
||||
err = _error_console(json_output)
|
||||
|
||||
if not is_file_source:
|
||||
from .catalog import WorkflowRegistry
|
||||
from .catalog import WorkflowRegistry
|
||||
|
||||
registered_id: str | None = None
|
||||
if not is_file_source:
|
||||
# Reject path-equivalent spellings ("align-wf/", "align-wf/.") that
|
||||
# would miss the registry lookup yet still load the installed file,
|
||||
# bypassing the disabled check below.
|
||||
@@ -360,12 +361,23 @@ def workflow_run(
|
||||
f"[red]Error:[/red] Invalid workflow ID: {_escape_markup(repr(source))}"
|
||||
)
|
||||
raise typer.Exit(1)
|
||||
registered_id = source
|
||||
else:
|
||||
# A direct YAML path may still point at an installed workflow's own
|
||||
# file; map it back to its ID so disabled state is enforced there too.
|
||||
workflows_root = (project_root / ".specify" / "workflows").resolve()
|
||||
resolved = source_path.resolve()
|
||||
if resolved.is_relative_to(workflows_root):
|
||||
rel_parts = resolved.relative_to(workflows_root).parts
|
||||
if rel_parts:
|
||||
registered_id = rel_parts[0]
|
||||
|
||||
installed_meta = WorkflowRegistry(project_root).get(source)
|
||||
if registered_id is not None:
|
||||
installed_meta = WorkflowRegistry(project_root).get(registered_id)
|
||||
if isinstance(installed_meta, dict) and installed_meta.get("enabled", True) is False:
|
||||
err.print(
|
||||
f"[red]Error:[/red] Workflow '{_escape_markup(source)}' is disabled. "
|
||||
f"Enable with: specify workflow enable {_escape_markup(source)}"
|
||||
f"[red]Error:[/red] Workflow '{_escape_markup(registered_id)}' is disabled. "
|
||||
f"Enable with: specify workflow enable {_escape_markup(registered_id)}"
|
||||
)
|
||||
raise typer.Exit(1)
|
||||
|
||||
|
||||
@@ -8040,6 +8040,13 @@ steps:
|
||||
assert result.exit_code != 0, spelling
|
||||
assert "Invalid workflow ID" in result.output, spelling
|
||||
|
||||
# Direct path to the installed workflow's own YAML must also refuse.
|
||||
installed_yaml = ".specify/workflows/align-wf/workflow.yml"
|
||||
assert (project_dir / installed_yaml).is_file()
|
||||
result = runner.invoke(app, ["workflow", "run", installed_yaml])
|
||||
assert result.exit_code != 0
|
||||
assert "disabled" in result.output
|
||||
|
||||
def test_disable_shows_marker_in_list(self, project_dir, monkeypatch):
|
||||
from typer.testing import CliRunner
|
||||
from specify_cli import app
|
||||
|
||||
Reference in New Issue
Block a user