feat: add artifact create-from-plan cli

This commit is contained in:
lda
2026-06-15 03:49:16 +07:00 Verified
parent a77483c628
commit acd599d09f
4 changed files with 180 additions and 1 deletions
+100
View File
@@ -36,6 +36,31 @@ class _ArtifactHandlers:
"blocked_by_deployments": [],
}
async def create_artifact_from_plan(
self,
*,
artifact_id: str,
version: int,
title: str,
plan: dict[str, Any],
outcomes: tuple[str, ...],
kind: str = "workflow",
description: str | None = None,
required_capabilities: dict[str, dict[str, Any]] | None = None,
source_bindings: dict[str, str] | None = None,
created_from_catalog_version: str | None = None,
) -> dict[str, Any]:
self.calls.append((artifact_id, version))
return {
"artifact_id": artifact_id,
"version": version,
"title": title,
"plan_name": plan["name"],
"outcomes": list(outcomes),
"kind": kind,
"source_bindings": source_bindings,
}
class _BlockedArtifactHandlers:
def __init__(self) -> None:
@@ -140,3 +165,78 @@ def test_artifact_delete_blocked_returns_blocker_ids(monkeypatch) -> None:
payload = json.loads(result.output)
assert payload["deleted"] is False
assert payload["blocked_by_deployments"] == ["echo.default"]
def test_artifact_create_from_plan_reads_yaml(monkeypatch, tmp_path) -> None:
handlers = _ArtifactHandlers()
monkeypatch.setattr(
"wf_cli.commands.artifacts.load_cli_context",
lambda _ctx: _Context(handlers=handlers),
)
plan_file = tmp_path / "plan.yaml"
plan_file.write_text(
"""
name: yaml_plan
input_schema: {type: object, properties: {}}
state_schema: {type: object, properties: {}}
output_schema: {type: object, properties: {}}
outcomes: [ok]
start: __end__
nodes: []
edges: []
""",
encoding="utf-8",
)
result = CliRunner().invoke(
app,
[
"artifact",
"create-from-plan",
str(plan_file),
"--artifact",
"yaml_artifact",
"--version",
"1",
"--title",
"YAML Artifact",
"--outcome",
"ok",
"--binding",
"local.ops=local.ops",
],
)
assert result.exit_code == 0, result.output
payload = json.loads(result.output)
assert payload["artifact_id"] == "yaml_artifact"
assert payload["plan_name"] == "yaml_plan"
assert payload["source_bindings"] == {"local.ops": "local.ops"}
def test_artifact_create_from_plan_rejects_non_object_yaml(monkeypatch, tmp_path) -> None:
handlers = _ArtifactHandlers()
monkeypatch.setattr(
"wf_cli.commands.artifacts.load_cli_context",
lambda _ctx: _Context(handlers=handlers),
)
plan_file = tmp_path / "plan.yaml"
plan_file.write_text("- not\n- object\n", encoding="utf-8")
result = CliRunner().invoke(
app,
[
"artifact",
"create-from-plan",
str(plan_file),
"--artifact",
"bad",
"--version",
"1",
"--title",
"Bad",
],
)
assert result.exit_code != 0
assert "structured file must contain an object" in result.output.lower()