diff --git a/mistral/engine/actions.py b/mistral/engine/actions.py index 97fb20fbe..9508564ea 100644 --- a/mistral/engine/actions.py +++ b/mistral/engine/actions.py @@ -31,6 +31,7 @@ from mistral.services import action_manager as a_m from mistral.services import security from mistral import utils from mistral.utils import wf_trace +from mistral.workflow import data_flow from mistral.workflow import states from mistral.workflow import utils as wf_utils @@ -338,7 +339,8 @@ class PythonAction(Action): class AdHocAction(PythonAction): """Ad-hoc action.""" - def __init__(self, action_def, action_ex=None, task_ex=None): + def __init__(self, action_def, action_ex=None, task_ex=None, task_ctx=None, + wf_ctx=None): self.action_spec = spec_parser.get_action_spec(action_def.spec) base_action_def = db_api.get_action_definition( @@ -355,6 +357,8 @@ class AdHocAction(PythonAction): ) self.adhoc_action_def = action_def + self.task_ctx = task_ctx or {} + self.wf_ctx = wf_ctx or {} def validate_input(self, input_dict): expected_input = self.action_spec.get_input() @@ -382,9 +386,14 @@ class AdHocAction(PythonAction): base_input_expr = action_spec.get_base_input() if base_input_expr: + ctx_view = data_flow.ContextView( + base_input_dict, + self.task_ctx, + self.wf_ctx + ) base_input_dict = expr.evaluate_recursively( base_input_expr, - base_input_dict + ctx_view ) else: base_input_dict = {} diff --git a/mistral/engine/tasks.py b/mistral/engine/tasks.py index 2864450f5..e04f3a49e 100644 --- a/mistral/engine/tasks.py +++ b/mistral/engine/tasks.py @@ -404,7 +404,9 @@ class RegularTask(Task): ) if action_def.spec: - return actions.AdHocAction(action_def, task_ex=self.task_ex) + return actions.AdHocAction(action_def, task_ex=self.task_ex, + task_ctx=self.ctx, + wf_ctx=self.wf_ex.context) return actions.PythonAction(action_def, task_ex=self.task_ex) diff --git a/mistral/tests/unit/engine/test_adhoc_actions.py b/mistral/tests/unit/engine/test_adhoc_actions.py index ccee4ab42..c46dda0b2 100644 --- a/mistral/tests/unit/engine/test_adhoc_actions.py +++ b/mistral/tests/unit/engine/test_adhoc_actions.py @@ -41,6 +41,11 @@ actions: - s2 output: "<% $ %> and <% $ %>" + test_env: + base: std.echo + base-input: + output: '{{ env().foo }}' + workflows: wf1: type: direct @@ -81,6 +86,20 @@ workflows: tasks: concat: action: concat_twice + + wf4: + type: direct + input: + - str1 + output: + workflow_result: '{{ _.printenv_result }}' + + tasks: + printenv: + action: test_env + publish: + printenv_result: '{{ task().result }}' + """ @@ -135,3 +154,18 @@ class AdhocActionsTest(base.EngineTestCase): self.assertIn("Invalid input", wf_ex.state_info) self.assertEqual(states.ERROR, wf_ex.state) + + def test_run_adhoc_action_with_env(self): + wf_ex = self.engine.start_workflow( + 'my_wb.wf4', {'str1': 'a'}, env={'foo': 'bar'}) + + self.await_workflow_success(wf_ex.id) + with db_api.transaction(): + wf_ex = db_api.get_workflow_execution(wf_ex.id) + + self.assertDictEqual( + { + 'workflow_result': 'bar' + }, + wf_ex.output + ) diff --git a/releasenotes/notes/support-env-in-adhoc-actions-20c98598893aa19f.yaml b/releasenotes/notes/support-env-in-adhoc-actions-20c98598893aa19f.yaml new file mode 100644 index 000000000..936dbcd28 --- /dev/null +++ b/releasenotes/notes/support-env-in-adhoc-actions-20c98598893aa19f.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - Added support for referencing task and workflow context data, including + environment variables via env(), when using YAQL/Jinja2 expressions inside AdHoc Actions. + YAQL/Jinja2 expressions can reference env() and other context data in the base-input section.