diff --git a/task-templates/workflow/frozen-fixture-emit@1.yaml b/task-templates/workflow/frozen-fixture-emit@1.yaml index 78c60fd..5f40d50 100644 --- a/task-templates/workflow/frozen-fixture-emit@1.yaml +++ b/task-templates/workflow/frozen-fixture-emit@1.yaml @@ -20,4 +20,7 @@ nodes: - id: state-tx kind: script cmd: scripts/workflow/state-tx - on_fail: continue \ No newline at end of file + on_fail: continue + runtime_env: + CP_URL: "http://controlplane.agent-runtimes.svc.cluster.local:8100" + STATE_TX_NEW_STATE: test-skeleton-ready diff --git a/task-templates/workflow/test-validate@1.yaml b/task-templates/workflow/test-validate@1.yaml index 79936f2..33a16be 100644 --- a/task-templates/workflow/test-validate@1.yaml +++ b/task-templates/workflow/test-validate@1.yaml @@ -28,4 +28,7 @@ nodes: - id: state-tx kind: script cmd: scripts/workflow/state-tx - on_fail: continue \ No newline at end of file + on_fail: continue + runtime_env: + CP_URL: "http://controlplane.agent-runtimes.svc.cluster.local:8100" + STATE_TX_NEW_STATE: test-validated diff --git a/tests/invariants/test_state_tx_runtime_env.py b/tests/invariants/test_state_tx_runtime_env.py new file mode 100644 index 0000000..434cbef --- /dev/null +++ b/tests/invariants/test_state_tx_runtime_env.py @@ -0,0 +1,29 @@ +"""state-tx script nodes must declare CP_URL and STATE_TX_NEW_STATE. + +scripts/workflow/state-tx fails with exit 2 when either is missing. +CP_SERVICE_TOKEN_FILE is supplied by the workflow-script/v1 composite, not +runtime_env, and must not be declared here. STATE_TX_NEW_STATE must equal the +template's own output.state. +""" +from __future__ import annotations + +from pathlib import Path + +import pytest +import yaml + +_DIR = Path(__file__).resolve().parents[2] / "task-templates" / "workflow" + + +@pytest.mark.parametrize( + "name", ["test-validate@1.yaml", "frozen-fixture-emit@1.yaml"] +) +def test_state_tx_node_declares_required_runtime_env(name): + doc = yaml.safe_load((_DIR / name).read_text()) + nodes = [n for n in doc["nodes"] if n.get("cmd") == "scripts/workflow/state-tx"] + assert len(nodes) == 1 + env = nodes[0].get("runtime_env") or {} + assert env.get("CP_URL") + assert env.get("STATE_TX_NEW_STATE") == doc["output"]["state"] + assert "CP_SERVICE_TOKEN_FILE" not in env + assert not any(k.startswith("OIDC_") for k in env)