Skip to content

Commit d429f32

Browse files
author
Tom Brandenburg
committed
feat: expose workflow schema
1 parent b9127b0 commit d429f32

7 files changed

Lines changed: 48 additions & 4 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ uvx flowsh-cli .made/workflows.yml --force
6262
6363
# Show version
6464
uvx flowsh-cli --version
65+
66+
# Show the workflow YAML schema
67+
uvx flowsh-cli --schema
6568
```
6669

6770
You can also run it via `uv run flowsh-cli` if installed locally.
@@ -85,6 +88,7 @@ Options:
8588
--dry-run Print planned output paths without writing scripts.
8689
--force Overwrite existing files. Without this, existing files cause a failure.
8790
--version Show the flowsh-cli version and exit.
91+
--schema Show the workflow YAML schema and exit.
8892
--help Show this message and exit.
8993
```
9094

@@ -97,6 +101,7 @@ Exit codes:
97101
|---|---:|---|---|
98102
| `--help` | `0` | Help text | Empty |
99103
| `--version` | `0` | `flowsh-cli <version>` | Empty |
104+
| `--schema` | `0` | Workflow schema as YAML-formatted JSON Schema | Empty |
100105
| Valid generation | `0` | One `Wrote <path>` line per harness | Empty |
101106
| Valid `--dry-run` | `0` | One `DRY-RUN would write <path>` line per selected workflow | Empty |
102107
| Missing required CLI argument | `2` | Empty | Typer usage error |

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "uv_build"
44

55
[project]
66
name = "flowsh-cli"
7-
version = "0.2.2"
7+
version = "0.3.0"
88
description = "Generate Bash harness scripts from workflow YAML files."
99
readme = "README.md"
1010
requires-python = ">=3.11"

src/flowsh_cli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from flowsh_cli.models import Workflow, WorkflowParseError, parse_workflows
44
from flowsh_cli.render import harness_path, render_harness
55

6-
__version__ = "0.2.2"
6+
__version__ = "0.3.0"
77

88
__all__ = [
99
"Workflow",

src/flowsh_cli/cli.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import typer
1212

1313
from flowsh_cli import __version__
14-
from flowsh_cli.models import Workflow, WorkflowParseError, parse_workflows
14+
from flowsh_cli.models import Workflow, WorkflowParseError, parse_workflows, workflow_schema_yaml
1515
from flowsh_cli.render import harness_path, render_harness
1616

1717
app = typer.Typer(
@@ -62,10 +62,20 @@ def generate(
6262
is_eager=True,
6363
),
6464
] = False,
65+
schema: Annotated[
66+
bool,
67+
typer.Option(
68+
"--schema",
69+
callback=lambda value: print_schema(value),
70+
help="Show the workflow YAML schema and exit.",
71+
is_eager=True,
72+
),
73+
] = False,
6574
) -> None:
6675
"""Generate Bash harnesses from workflow YAML."""
6776

6877
_ = version
78+
_ = schema
6979

7080
try:
7181
workflows = parse_workflows(workflow_yaml)
@@ -99,6 +109,14 @@ def print_version(value: bool) -> None:
99109
raise typer.Exit
100110

101111

112+
def print_schema(value: bool) -> None:
113+
if not value:
114+
return
115+
116+
print(workflow_schema_yaml(), end="")
117+
raise typer.Exit
118+
119+
102120
def write_harnesses(workflows: list[Workflow], *, dry_run: bool, force: bool) -> None:
103121
output_paths = [(workflow, harness_path(workflow)) for workflow in workflows]
104122

src/flowsh_cli/models.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ def parse_workflows(path: Path) -> list[Workflow]:
176176
raise WorkflowParseError(format_validation_error(error)) from error
177177

178178

179+
def workflow_schema_yaml() -> str:
180+
return yaml.safe_dump(
181+
WorkflowFile.model_json_schema(),
182+
sort_keys=False,
183+
allow_unicode=False,
184+
)
185+
186+
179187
def format_validation_error(error: ValidationError) -> str:
180188
messages: list[str] = []
181189
for item in error.errors(include_url=False, include_input=False, include_context=False):

tests/test_workflow_to_harness.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
--dry-run Print planned output paths without writing scripts.
2525
--force Overwrite existing files. Without this, existing files cause a failure.
2626
--version Show the flowsh-cli version and exit.
27+
--schema Show the workflow YAML schema and exit.
2728
--help Show this message and exit.
2829
"""
2930

@@ -469,6 +470,17 @@ def test_cli_exposes_version_without_workflow_argument() -> None:
469470
assert result.output.strip().startswith("flowsh-cli ")
470471

471472

473+
def test_cli_exposes_schema_without_workflow_argument() -> None:
474+
result = runner.invoke(app, ["--schema"])
475+
476+
assert result.exit_code == 0, result.output
477+
assert result.stderr == ""
478+
assert "title: WorkflowFile" in result.output
479+
assert "const: vars" in result.output
480+
assert "const: bash" in result.output
481+
assert "const: agent" in result.output
482+
483+
472484
def test_cli_reports_missing_required_workflow_argument() -> None:
473485
result = subprocess.run(
474486
[sys.executable, "-m", "flowsh_cli"],
@@ -934,6 +946,7 @@ def test_uv_console_entrypoint_help_matches_contract() -> None:
934946
assert "--dry-run" in result.stdout
935947
assert "--force" in result.stdout
936948
assert "--version" in result.stdout
949+
assert "--schema" in result.stdout
937950

938951

939952
def test_direct_script_entrypoint_help_matches_contract() -> None:

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)