This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new ff7c5daf50 Issue #2430 : verify internal pipeline and workflow
variables (#7712)
ff7c5daf50 is described below
commit ff7c5daf507143bf33754d15923d5873953b1e4f
Author: Matt Casters <[email protected]>
AuthorDate: Fri Jul 31 12:14:27 2026 +0200
Issue #2430 : verify internal pipeline and workflow variables (#7712)
Confirm Internal.Pipeline.Filename.Directory/Name and related workflow
variables are populated at runtime and design-time via unit tests and
stronger parameters_and_variables integration checks (expected values,
not only presence).
---
.../org/apache/hop/pipeline/PipelineMetaTest.java | 44 +++++
.../org/apache/hop/workflow/WorkflowMetaTest.java | 43 +++++
.../0007-internal-pipeline-variables.hpl | 209 ++++++++++++++-------
.../0007-internal-variables.hwf | 64 +++++--
.../main-0007-internal-variables.hwf | 2 +-
5 files changed, 274 insertions(+), 88 deletions(-)
diff --git a/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
b/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
index 1ee4349d05..c5024c15a7 100644
--- a/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
+++ b/engine/src/test/java/org/apache/hop/pipeline/PipelineMetaTest.java
@@ -460,6 +460,50 @@ class PipelineMetaTest {
return newSmi;
}
+ @Test
+ void testSetInternalHopVariablesWithFilename() {
+ // Issue #2430: Internal.Pipeline.Filename.Directory / .Name /
Internal.Pipeline.Name
+ // must be populated when a filename is set (design-time and runtime API
path).
+ PipelineMeta meta = new PipelineMeta();
+ meta.setNameSynchronizedWithFilename(true);
+
meta.setFilename("/tmp/parameters_and_variables/0007-internal-pipeline-variables.hpl");
+
+ IVariables vars = new Variables();
+ meta.setInternalHopVariables(vars);
+
+ assertEquals(
+ "0007-internal-pipeline-variables.hpl",
+ vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_FILENAME_NAME));
+ assertEquals(
+ "0007-internal-pipeline-variables",
+ vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_NAME));
+
assertNotNull(vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_FILENAME_DIRECTORY));
+
assertFalse(vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_FILENAME_DIRECTORY).isEmpty());
+ assertTrue(
+ vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_FILENAME_DIRECTORY)
+ .contains("parameters_and_variables"));
+ assertEquals(
+ vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_FILENAME_DIRECTORY),
+ vars.getVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER));
+ }
+
+ @Test
+ void testSetInternalHopVariablesWithoutFilename() {
+ PipelineMeta meta = new PipelineMeta();
+ meta.setNameSynchronizedWithFilename(false);
+ meta.setName("unsaved-pipeline");
+ meta.setFilename(null);
+
+ IVariables vars = new Variables();
+ vars.setVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER,
"parent-folder");
+ meta.setInternalHopVariables(vars);
+
+ assertEquals("",
vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_FILENAME_NAME));
+ assertEquals("",
vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_FILENAME_DIRECTORY));
+ assertEquals("unsaved-pipeline",
vars.getVariable(Const.INTERNAL_VARIABLE_PIPELINE_NAME));
+ assertEquals("parent-folder",
vars.getVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER));
+ }
+
@Test
void testSetInternalEntryCurrentDirectoryWithFilename() {
PipelineMeta pipelineMetaTest = new PipelineMeta();
diff --git a/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
b/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
index 3e723c803d..d9d9a9e22f 100644
--- a/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
+++ b/engine/src/test/java/org/apache/hop/workflow/WorkflowMetaTest.java
@@ -267,6 +267,49 @@ class WorkflowMetaTest {
return actionMeta;
}
+ @Test
+ void testSetInternalHopVariablesWithFilename() {
+ // Issue #2430: Internal.Workflow.Filename.Folder / .Name /
Internal.Workflow.Name
+ // must be populated when a filename is set (design-time and runtime API
path).
+ WorkflowMeta meta = new WorkflowMeta();
+ meta.setNameSynchronizedWithFilename(true);
+
meta.setFilename("/tmp/parameters_and_variables/0007-internal-variables.hwf");
+
+ IVariables vars = new Variables();
+ meta.setInternalHopVariables(vars);
+
+ assertEquals(
+ "0007-internal-variables.hwf",
+ vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_FILENAME_NAME));
+ assertEquals(
+ "0007-internal-variables",
vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_NAME));
+
assertNotNull(vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_FILENAME_FOLDER));
+
assertFalse(vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_FILENAME_FOLDER).isEmpty());
+ assertTrue(
+ vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_FILENAME_FOLDER)
+ .contains("parameters_and_variables"));
+ assertEquals(
+ vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_FILENAME_FOLDER),
+ vars.getVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER));
+ }
+
+ @Test
+ void testSetInternalHopVariablesWithoutFilename() {
+ WorkflowMeta meta = new WorkflowMeta();
+ meta.setNameSynchronizedWithFilename(false);
+ meta.setName("unsaved-workflow");
+ meta.setFilename(null);
+
+ IVariables vars = new Variables();
+ vars.setVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER,
"parent-folder");
+ meta.setInternalHopVariables(vars);
+
+ assertEquals("",
vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_FILENAME_NAME));
+ assertEquals("",
vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_FILENAME_FOLDER));
+ assertEquals("unsaved-workflow",
vars.getVariable(Const.INTERNAL_VARIABLE_WORKFLOW_NAME));
+ assertEquals("parent-folder",
vars.getVariable(Const.INTERNAL_VARIABLE_ENTRY_CURRENT_FOLDER));
+ }
+
@Test
void testSetInternalEntryCurrentDirectoryWithFilename() {
WorkflowMeta workflowMetaTest = new WorkflowMeta();
diff --git
a/integration-tests/parameters_and_variables/0007-internal-pipeline-variables.hpl
b/integration-tests/parameters_and_variables/0007-internal-pipeline-variables.hpl
index c76033548c..dd4ee335f4 100644
---
a/integration-tests/parameters_and_variables/0007-internal-pipeline-variables.hpl
+++
b/integration-tests/parameters_and_variables/0007-internal-pipeline-variables.hpl
@@ -19,9 +19,9 @@ limitations under the License.
-->
<pipeline>
<info>
- <name>0006-internal-pipeline-variables</name>
+ <name>0007-internal-pipeline-variables</name>
<name_sync_with_filename>Y</name_sync_with_filename>
- <description/>
+ <description>Issue #2430: verify internal pipeline variables are set with
expected values at runtime</description>
<extended_description/>
<pipeline_version/>
<pipeline_type>Normal</pipeline_type>
@@ -41,62 +41,28 @@ limitations under the License.
</notepads>
<order>
<hop>
- <from>internal.entry.current.folder</from>
- <to>fields</to>
+ <from>Get internal variables</from>
+ <to>Log internal variables</to>
<enabled>Y</enabled>
</hop>
<hop>
- <from>fields</from>
- <to>not resolved?</to>
+ <from>Log internal variables</from>
+ <to>Assert values</to>
<enabled>Y</enabled>
</hop>
<hop>
- <from>not resolved?</from>
+ <from>Assert values</from>
+ <to>Test succeeded</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Assert values</from>
<to>Abort</to>
<enabled>Y</enabled>
</hop>
</order>
<transform>
- <name>fields</name>
- <type>WriteToLog</type>
- <description/>
- <distribute>Y</distribute>
- <custom_distribution/>
- <copies>1</copies>
- <partitioning>
- <method>none</method>
- <schema_name/>
- </partitioning>
- <loglevel>log_level_basic</loglevel>
- <displayHeader>Y</displayHeader>
- <limitRows>N</limitRows>
- <limitRowsNumber>0</limitRowsNumber>
- <logmessage/>
- <fields>
- <field>
- <name>internal.entry.current.folder</name>
- </field>
- <field>
- <name>internal.pipeline.filename.name</name>
- </field>
- <field>
- <name>internal.pipeline.name</name>
- </field>
- <field>
- <name>internal.transform.name</name>
- </field>
- <field>
- <name>internal.transform.copynr</name>
- </field>
- </fields>
- <attributes/>
- <GUI>
- <xloc>352</xloc>
- <yloc>112</yloc>
- </GUI>
- </transform>
- <transform>
- <name>internal.entry.current.folder</name>
+ <name>Get internal variables</name>
<type>GetVariable</type>
<description/>
<distribute>Y</distribute>
@@ -119,6 +85,18 @@ limitations under the License.
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
+ <field>
+ <name>internal.pipeline.filename.directory</name>
+ <variable>${Internal.Pipeline.Filename.Directory}</variable>
+ <type>String</type>
+ <format/>
+ <currency/>
+ <decimal/>
+ <group/>
+ <length>-1</length>
+ <precision>-1</precision>
+ <trim_type>none</trim_type>
+ </field>
<field>
<name>internal.pipeline.filename.name</name>
<variable>${Internal.Pipeline.Filename.Name}</variable>
@@ -170,13 +148,13 @@ limitations under the License.
</fields>
<attributes/>
<GUI>
- <xloc>179</xloc>
- <yloc>110</yloc>
+ <xloc>160</xloc>
+ <yloc>112</yloc>
</GUI>
</transform>
<transform>
- <name>not resolved?</name>
- <type>FilterRows</type>
+ <name>Log internal variables</name>
+ <type>WriteToLog</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
@@ -185,21 +163,63 @@ limitations under the License.
<method>none</method>
<schema_name/>
</partitioning>
- <send_true_to/>
- <send_false_to/>
+ <loglevel>log_level_basic</loglevel>
+ <displayHeader>Y</displayHeader>
+ <limitRows>N</limitRows>
+ <limitRowsNumber>0</limitRowsNumber>
+ <logmessage>Issue #2430 internal pipeline variables</logmessage>
+ <fields>
+ <field>
+ <name>internal.entry.current.folder</name>
+ </field>
+ <field>
+ <name>internal.pipeline.filename.directory</name>
+ </field>
+ <field>
+ <name>internal.pipeline.filename.name</name>
+ </field>
+ <field>
+ <name>internal.pipeline.name</name>
+ </field>
+ <field>
+ <name>internal.transform.name</name>
+ </field>
+ <field>
+ <name>internal.transform.copynr</name>
+ </field>
+ </fields>
+ <attributes/>
+ <GUI>
+ <xloc>352</xloc>
+ <yloc>112</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Assert values</name>
+ <type>FilterRows</type>
+ <description>True when Internal.Pipeline.Filename.Directory/Name/Name and
related vars match expected runtime values</description>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <send_true_to>Test succeeded</send_true_to>
+ <send_false_to>Abort</send_false_to>
<compare>
<condition>
<negated>N</negated>
<conditions>
<condition>
<negated>N</negated>
- <leftvalue>internal.entry.current.folder</leftvalue>
+ <leftvalue>internal.pipeline.filename.name</leftvalue>
<function>=</function>
<rightvalue/>
<value>
<name>constant</name>
<type>String</type>
- <text>${Internal.Entry.Current.Folder}</text>
+ <text>0007-internal-pipeline-variables.hpl</text>
<length>-1</length>
<precision>-1</precision>
<isnull>N</isnull>
@@ -208,14 +228,14 @@ limitations under the License.
</condition>
<condition>
<negated>N</negated>
- <operator>OR</operator>
- <leftvalue>internal.pipeline.filename.name</leftvalue>
+ <operator>AND</operator>
+ <leftvalue>internal.pipeline.name</leftvalue>
<function>=</function>
<rightvalue/>
<value>
<name>constant</name>
<type>String</type>
- <text>${Internal.Pipeline.Filename.Name}</text>
+ <text>0007-internal-pipeline-variables</text>
<length>-1</length>
<precision>-1</precision>
<isnull>N</isnull>
@@ -224,14 +244,21 @@ limitations under the License.
</condition>
<condition>
<negated>N</negated>
- <operator>OR</operator>
- <leftvalue>internal.pipeline.name</leftvalue>
- <function>=</function>
+ <operator>AND</operator>
+ <leftvalue>internal.pipeline.filename.directory</leftvalue>
+ <function>IS NOT NULL</function>
+ <rightvalue/>
+ </condition>
+ <condition>
+ <negated>N</negated>
+ <operator>AND</operator>
+ <leftvalue>internal.pipeline.filename.directory</leftvalue>
+ <function><></function>
<rightvalue/>
<value>
<name>constant</name>
<type>String</type>
- <text>${Internal.Pipeline.Name}</text>
+ <text/>
<length>-1</length>
<precision>-1</precision>
<isnull>N</isnull>
@@ -240,14 +267,37 @@ limitations under the License.
</condition>
<condition>
<negated>N</negated>
- <operator>OR</operator>
+ <operator>AND</operator>
+ <leftvalue>internal.pipeline.filename.directory</leftvalue>
+ <function>CONTAINS</function>
+ <rightvalue/>
+ <value>
+ <name>constant</name>
+ <type>String</type>
+ <text>parameters_and_variables</text>
+ <length>-1</length>
+ <precision>-1</precision>
+ <isnull>N</isnull>
+ <mask/>
+ </value>
+ </condition>
+ <condition>
+ <negated>N</negated>
+ <operator>AND</operator>
+ <leftvalue>internal.entry.current.folder</leftvalue>
+ <function>=</function>
+ <rightvalue>internal.pipeline.filename.directory</rightvalue>
+ </condition>
+ <condition>
+ <negated>N</negated>
+ <operator>AND</operator>
<leftvalue>internal.transform.name</leftvalue>
<function>=</function>
<rightvalue/>
<value>
<name>constant</name>
<type>String</type>
- <text>${Internal.Transform.Name}</text>
+ <text>Get internal variables</text>
<length>-1</length>
<precision>-1</precision>
<isnull>N</isnull>
@@ -256,14 +306,14 @@ limitations under the License.
</condition>
<condition>
<negated>N</negated>
- <operator>OR</operator>
+ <operator>AND</operator>
<leftvalue>internal.transform.copynr</leftvalue>
<function>=</function>
<rightvalue/>
<value>
<name>constant</name>
<type>String</type>
- <text>${Internal.Transform.CopyNr}</text>
+ <text>0</text>
<length>-1</length>
<precision>-1</precision>
<isnull>N</isnull>
@@ -275,7 +325,24 @@ limitations under the License.
</compare>
<attributes/>
<GUI>
- <xloc>496</xloc>
+ <xloc>560</xloc>
+ <yloc>112</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Test succeeded</name>
+ <type>Dummy</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ <GUI>
+ <xloc>752</xloc>
<yloc>112</yloc>
</GUI>
</transform>
@@ -291,13 +358,13 @@ limitations under the License.
<schema_name/>
</partitioning>
<row_threshold>0</row_threshold>
- <message/>
+ <message>Issue #2430: one or more internal pipeline variables missing or
incorrect</message>
<always_log_rows>Y</always_log_rows>
- <abort_option>ABORT</abort_option>
+ <abort_option>ABORT_WITH_ERROR</abort_option>
<attributes/>
<GUI>
- <xloc>640</xloc>
- <yloc>112</yloc>
+ <xloc>752</xloc>
+ <yloc>224</yloc>
</GUI>
</transform>
<transform_error_handling>
diff --git
a/integration-tests/parameters_and_variables/0007-internal-variables.hwf
b/integration-tests/parameters_and_variables/0007-internal-variables.hwf
index 508989fe2f..b13a44ab65 100644
--- a/integration-tests/parameters_and_variables/0007-internal-variables.hwf
+++ b/integration-tests/parameters_and_variables/0007-internal-variables.hwf
@@ -20,7 +20,7 @@ limitations under the License.
<workflow>
<name>0007-internal-variables</name>
<name_sync_with_filename>Y</name_sync_with_filename>
- <description/>
+ <description>Issue #2430: verify internal workflow variables are set with
expected values at runtime</description>
<extended_description/>
<workflow_version/>
<created_user>-</created_user>
@@ -50,7 +50,7 @@ limitations under the License.
<attributes_hac/>
</action>
<action>
- <name>${Internal.Entry.Current.Folder}</name>
+ <name>Internal.Entry.Current.Folder is set</name>
<description/>
<type>SIMPLE_EVAL</type>
<attributes/>
@@ -73,7 +73,7 @@ limitations under the License.
<attributes_hac/>
</action>
<action>
- <name>${Internal.Workflow.Filename.Name}</name>
+ <name>Internal.Workflow.Filename.Name equals file</name>
<description/>
<type>SIMPLE_EVAL</type>
<attributes/>
@@ -82,13 +82,13 @@ limitations under the License.
<variablename>Internal.Workflow.Filename.Name</variablename>
<fieldtype>string</fieldtype>
<mask/>
- <comparevalue/>
+ <comparevalue>0007-internal-variables.hwf</comparevalue>
<minvalue/>
<maxvalue/>
<successcondition>equal</successcondition>
<successnumbercondition>equal</successnumbercondition>
<successbooleancondition>false</successbooleancondition>
- <successwhenvarset>Y</successwhenvarset>
+ <successwhenvarset>N</successwhenvarset>
<parallel>N</parallel>
<nr>0</nr>
<xloc>544</xloc>
@@ -96,7 +96,7 @@ limitations under the License.
<attributes_hac/>
</action>
<action>
- <name>${Internal.Workflow.Name}</name>
+ <name>Internal.Workflow.Name equals basename</name>
<description/>
<type>SIMPLE_EVAL</type>
<attributes/>
@@ -105,13 +105,13 @@ limitations under the License.
<variablename>Internal.Workflow.Name</variablename>
<fieldtype>string</fieldtype>
<mask/>
- <comparevalue/>
+ <comparevalue>0007-internal-variables</comparevalue>
<minvalue/>
<maxvalue/>
<successcondition>equal</successcondition>
<successnumbercondition>equal</successnumbercondition>
<successbooleancondition>false</successbooleancondition>
- <successwhenvarset>Y</successwhenvarset>
+ <successwhenvarset>N</successwhenvarset>
<parallel>N</parallel>
<nr>0</nr>
<xloc>336</xloc>
@@ -119,7 +119,7 @@ limitations under the License.
<attributes_hac/>
</action>
<action>
- <name>${Internal.Workflow.Filename.Folder}</name>
+ <name>Internal.Workflow.Filename.Folder is set</name>
<description/>
<type>SIMPLE_EVAL</type>
<attributes/>
@@ -141,11 +141,34 @@ limitations under the License.
<yloc>192</yloc>
<attributes_hac/>
</action>
+ <action>
+ <name>Internal.Workflow.Filename.Folder contains project dir</name>
+ <description>Folder must contain the parameters_and_variables project
directory name (VFS URI form)</description>
+ <type>SIMPLE_EVAL</type>
+ <attributes/>
+ <valuetype>variable</valuetype>
+ <fieldname/>
+ <variablename>Internal.Workflow.Filename.Folder</variablename>
+ <fieldtype>string</fieldtype>
+ <mask/>
+ <comparevalue>parameters_and_variables</comparevalue>
+ <minvalue/>
+ <maxvalue/>
+ <successcondition>contains</successcondition>
+ <successnumbercondition>equal</successnumbercondition>
+ <successbooleancondition>false</successbooleancondition>
+ <successwhenvarset>N</successwhenvarset>
+ <parallel>N</parallel>
+ <nr>0</nr>
+ <xloc>752</xloc>
+ <yloc>192</yloc>
+ <attributes_hac/>
+ </action>
</actions>
<hops>
<hop>
<from>Start</from>
- <to>${Internal.Entry.Current.Folder}</to>
+ <to>Internal.Entry.Current.Folder is set</to>
<from_nr>0</from_nr>
<to_nr>0</to_nr>
<enabled>Y</enabled>
@@ -153,8 +176,17 @@ limitations under the License.
<unconditional>Y</unconditional>
</hop>
<hop>
- <from>${Internal.Entry.Current.Folder}</from>
- <to>${Internal.Workflow.Filename.Name}</to>
+ <from>Internal.Entry.Current.Folder is set</from>
+ <to>Internal.Workflow.Filename.Name equals file</to>
+ <from_nr>0</from_nr>
+ <to_nr>0</to_nr>
+ <enabled>Y</enabled>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ </hop>
+ <hop>
+ <from>Internal.Workflow.Filename.Name equals file</from>
+ <to>Internal.Workflow.Name equals basename</to>
<from_nr>0</from_nr>
<to_nr>0</to_nr>
<enabled>Y</enabled>
@@ -162,8 +194,8 @@ limitations under the License.
<unconditional>N</unconditional>
</hop>
<hop>
- <from>${Internal.Workflow.Filename.Name}</from>
- <to>${Internal.Workflow.Name}</to>
+ <from>Internal.Workflow.Name equals basename</from>
+ <to>Internal.Workflow.Filename.Folder is set</to>
<from_nr>0</from_nr>
<to_nr>0</to_nr>
<enabled>Y</enabled>
@@ -171,8 +203,8 @@ limitations under the License.
<unconditional>N</unconditional>
</hop>
<hop>
- <from>${Internal.Workflow.Name}</from>
- <to>${Internal.Workflow.Filename.Folder}</to>
+ <from>Internal.Workflow.Filename.Folder is set</from>
+ <to>Internal.Workflow.Filename.Folder contains project dir</to>
<from_nr>0</from_nr>
<to_nr>0</to_nr>
<enabled>Y</enabled>
diff --git
a/integration-tests/parameters_and_variables/main-0007-internal-variables.hwf
b/integration-tests/parameters_and_variables/main-0007-internal-variables.hwf
index 3c6b503bb3..cb5089adb5 100644
---
a/integration-tests/parameters_and_variables/main-0007-internal-variables.hwf
+++
b/integration-tests/parameters_and_variables/main-0007-internal-variables.hwf
@@ -20,7 +20,7 @@ limitations under the License.
<workflow>
<name>main-0007-internal-variables</name>
<name_sync_with_filename>Y</name_sync_with_filename>
- <description/>
+ <description>Issue #2430: verify internal pipeline and workflow variables
are populated at runtime</description>
<extended_description/>
<workflow_version/>
<created_user>-</created_user>