You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hop.apache.org by mc...@apache.org on 2026/10/10 09:17:47 UTC
(hop) branch main updated: samples for all actions, stubs for actions that need infrastructure i… (#8790)
This is an automated email from the ASF dual-hosted git repository.
mattcasters 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 2097f72960 samples for all actions, stubs for actions that need infrastructure i… (#8790)
2097f72960 is described below
commit 2097f72960b7a8389920bed89dbc7fd0b94cbe30
Author: Bart Maertens <ba...@know.bi>
AuthorDate: Sat Oct 10 11:17:40 2026 +0200
samples for all actions, stubs for actions that need infrastructure i… (#8790)
* samples for all actions, stubs for actions that need infrastructure in actions/requires-setup. fixes #2238
* Issue #2238 : Sign with local_user in the PGP sample, abort on a failed Shell sample script
---
.../samples/read-samples-build-hop-run.hpl | 15 +
.../abort/src/main/samples/actions/abort.hwf | 142 +++++++++
.../main/samples/actions/check-files-locked.hwf | 171 +++++++++++
.../samples/actions/copy-move-result-filenames.hwf | 289 ++++++++++++++++++
.../main/samples/actions/requires-setup/dbt.hwf | 184 ++++++++++++
.../src/main/samples/actions/delete-folders.hwf | 213 ++++++++++++++
.../samples/actions/delete-result-filenames.hwf | 260 ++++++++++++++++
.../src/main/samples/actions/dos-to-unix.hwf | 212 ++++++++++++++
.../samples/actions/evaluate-files-metrics.hwf | 306 +++++++++++++++++++
.../samples/actions/evaluate-table-content.hwf | 231 +++++++++++++++
.../src/main/samples/actions/file-compare.hwf | 248 ++++++++++++++++
.../src/main/samples/actions/file-exists.hwf | 200 +++++++++++++
.../src/main/samples/actions/folder-is-empty.hwf | 250 ++++++++++++++++
.../src/main/samples/actions/folders-compare.hwf | 326 +++++++++++++++++++++
.../samples/actions/requires-setup/http-get.hwf | 202 +++++++++++++
.../src/main/samples/actions/move-files.hwf | 283 ++++++++++++++++++
.../requires-setup/pgp-encrypt-decrypt-verify.hwf | 320 ++++++++++++++++++++
.../requires-setup/send-nagios-passive-check.hwf | 155 ++++++++++
.../main/samples/actions/set-password-encoder.hwf | 125 ++++++++
.../shell/src/main/samples/actions/shell.hwf | 154 ++++++++++
.../samples/actions/requires-setup/snmp-trap.hwf | 155 ++++++++++
.../sql/src/main/samples/actions/sql-script.hwf | 184 ++++++++++++
.../actions/requires-setup/telnet-a-host.hwf | 167 +++++++++++
.../src/main/samples/actions/truncate-tables.hwf | 209 +++++++++++++
.../src/main/samples/actions/wait-for-file.hwf | 169 +++++++++++
.../src/main/samples/actions/wait-for-sql.hwf | 189 ++++++++++++
.../requires-setup/webservice-available.hwf | 167 +++++++++++
.../src/main/samples/actions/write-to-file.hwf | 150 ++++++++++
.../actions/requires-setup/dtd-validator.hwf | 169 +++++++++++
.../src/main/samples/actions/xml-well-formed.hwf | 152 ++++++++++
.../xml/src/main/samples/actions/xsd-validator.hwf | 145 +++++++++
.../main/samples/actions/xsl-transformation.hwf | 205 +++++++++++++
.../samples/files/xml-actions/orders-to-csv.xsl | 29 ++
.../src/main/samples/files/xml-actions/orders.dtd | 24 ++
.../src/main/samples/files/xml-actions/orders.xml | 29 ++
.../src/main/samples/files/xml-actions/orders.xsd | 36 +++
plugins/databases/as400/src/assembly/assembly.xml | 6 +
.../actions/requires-setup/as400-command.hwf | 151 ++++++++++
.../mssqlnative/src/assembly/assembly.xml | 6 +
.../actions/requires-setup/mssql-bulk-load.hwf | 171 +++++++++++
plugins/databases/mysql/src/assembly/assembly.xml | 6 +
.../requires-setup/mysql-bulk-file-and-load.hwf | 191 ++++++++++++
.../databases/snowflake/src/assembly/assembly.xml | 6 +
.../requires-setup/snowflake-warehouse-manager.hwf | 210 +++++++++++++
.../main/samples/actions/build-documentation.hwf | 153 ++++++++++
.../src/main/samples/actions/mail-validator.hwf | 147 ++++++++++
.../requires-setup/mail-send-and-receive.hwf | 274 +++++++++++++++++
plugins/misc/testing/src/assembly/assembly.xml | 6 +
.../actions/run-pipeline-tests-pipeline.hpl | 190 ++++++++++++
.../main/samples/actions/run-pipeline-tests.hwf | 148 ++++++++++
.../samples/datasets/run-pipeline-tests-golden.csv | 3 +
.../samples/datasets/run-pipeline-tests-input.csv | 3 +
.../dataset/run-pipeline-tests-golden.json | 40 +++
.../metadata/dataset/run-pipeline-tests-input.json | 32 ++
.../unit-test/run-pipeline-tests-unit.json | 62 ++++
plugins/tech/cassandra/src/assembly/assembly.xml | 6 +
.../actions/requires-setup/cassandra-exec-cql.hwf | 153 ++++++++++
plugins/tech/databricks/src/assembly/assembly.xml | 6 +
.../requires-setup/databricks-job-run-and-wait.hwf | 243 +++++++++++++++
.../actions/requires-setup/ftp-put-get-delete.hwf | 283 ++++++++++++++++++
.../actions/requires-setup/mongodb-execute-mql.hwf | 158 ++++++++++
plugins/tech/sftp/src/assembly/assembly.xml | 6 +
.../actions/requires-setup/sftp-put-get.hwf | 230 +++++++++++++++
63 files changed, 9355 insertions(+)
diff --git a/integration-tests/samples/read-samples-build-hop-run.hpl b/integration-tests/samples/read-samples-build-hop-run.hpl
index 364a71bf1a..f04eb88576 100644
--- a/integration-tests/samples/read-samples-build-hop-run.hpl
+++ b/integration-tests/samples/read-samples-build-hop-run.hpl
@@ -962,6 +962,21 @@ var hop_run_cmd = './hop-run.sh -j samples -r ' + run_config + ' -f ' + filename
</value>
<conditions/>
</condition>
+ <condition>
+ <negated>Y</negated>
+ <operator>AND</operator>
+ <leftvalue>filename</leftvalue>
+ <function>CONTAINS</function>
+ <value>
+ <name>constant</name>
+ <type>String</type>
+ <text>/requires-setup/</text>
+ <length>-1</length>
+ <precision>-1</precision>
+ <isnull>N</isnull>
+ </value>
+ <conditions/>
+ </condition>
</conditions>
</condition>
</compare>
diff --git a/plugins/actions/abort/src/main/samples/actions/abort.hwf b/plugins/actions/abort/src/main/samples/actions/abort.hwf
new file mode 100644
index 0000000000..c9c0a4ccfa
--- /dev/null
+++ b/plugins/actions/abort/src/main/samples/actions/abort.hwf
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>abort</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${PROJECT_HOME}/project-config.json</filename>
+ <name>project-config.json exists?</name>
+ <description/>
+ <type>FILE_EXISTS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The file exists, processing continues.</logmessage>
+ <name>Continue</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>Required file ${PROJECT_HOME}/project-config.json is missing</message>
+ <loglevel>Error</loglevel>
+ <name>Abort</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>project-config.json exists?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>project-config.json exists?</from>
+ <to>Continue</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>project-config.json exists?</from>
+ <to>Abort</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Abort action stops the workflow with an error, optionally with a message. Parent workflows and the hop-run command see the workflow as failed.
+It is typically placed on the failure (red) hop of a check, to stop processing when a requirement is not met.
+
+This sample checks for the project-config.json file of the samples project, which is always there, so the Abort action is not executed.
+Change the filename in the File exists action to a file that does not exist to see the Abort action stop the workflow.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>174</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/checkfilelocked/src/main/samples/actions/check-files-locked.hwf b/plugins/actions/checkfilelocked/src/main/samples/actions/check-files-locked.hwf
new file mode 100644
index 0000000000..0664b5d23f
--- /dev/null
+++ b/plugins/actions/checkfilelocked/src/main/samples/actions/check-files-locked.hwf
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>check-files-locked</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/check-files-locked/data.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Some data</content>
+ <encoding>UTF-8</encoding>
+ <name>Write data file</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/check-files-locked</name>
+ <filemask>.*\.txt</filemask>
+ </field>
+ </fields>
+ <name>Files locked?</name>
+ <description/>
+ <type>CHECK_FILES_LOCKED</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>No file is locked, processing can start.</logmessage>
+ <name>Ready to process</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>At least one file is locked, try again later.</logmessage>
+ <name>Files are locked</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write data file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write data file</from>
+ <to>Files locked?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Files locked?</from>
+ <to>Ready to process</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Files locked?</from>
+ <to>Files are locked</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Check files locked action checks whether files are locked by another process, for example a file that is still being written or copied.
+It succeeds when none of the files are locked.
+
+This sample writes a file to ${java.io.tmpdir}/hop-samples/check-files-locked and checks that it is not locked before processing it.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/copymoveresultfilenames/src/main/samples/actions/copy-move-result-filenames.hwf b/plugins/actions/copymoveresultfilenames/src/main/samples/actions/copy-move-result-filenames.hwf
new file mode 100644
index 0000000000..b4705c0139
--- /dev/null
+++ b/plugins/actions/copymoveresultfilenames/src/main/samples/actions/copy-move-result-filenames.hwf
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>copy-move-result-filenames</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/copy-move-result-filenames</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in/file-1.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>File 1</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file 1</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in/file-2.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>File 2</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file 2</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <delete_all_before>N</delete_all_before>
+ <include_subfolders>N</include_subfolders>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in</name>
+ <filemask>.*\.txt</filemask>
+ </field>
+ </fields>
+ <name>Add to result filenames</name>
+ <description/>
+ <type>ADD_RESULT_FILENAMES</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <foldername>${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive</foldername>
+ <fail_of_folder_exists>N</fail_of_folder_exists>
+ <name>Create archive folder</name>
+ <description/>
+ <type>CREATE_FOLDER</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <foldername/>
+ <specify_wildcard>N</specify_wildcard>
+ <wildcard/>
+ <wildcardexclude/>
+ <destination_folder>${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive</destination_folder>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <SpecifyFormat>N</SpecifyFormat>
+ <date_time_format/>
+ <AddDateBeforeExtension>N</AddDateBeforeExtension>
+ <action>copy</action>
+ <OverwriteFile>Y</OverwriteFile>
+ <CreateDestinationFolder>N</CreateDestinationFolder>
+ <RemovedSourceFilename>N</RemovedSourceFilename>
+ <AddDestinationFilename>N</AddDestinationFilename>
+ <name>Copy result files to archive</name>
+ <description/>
+ <type>COPY_MOVE_RESULT_FILENAMES</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive/file-2.txt</filename>
+ <name>file-2.txt archived?</name>
+ <description/>
+ <type>FILE_EXISTS</type>
+ <attributes/>
+ <xloc>1424</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The result files were copied to the archive folder.</logmessage>
+ <name>Files archived</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1616</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>file-2.txt was not copied to the archive folder</message>
+ <loglevel>Error</loglevel>
+ <name>Not archived</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>1424</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Write file 1</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file 1</from>
+ <to>Write file 2</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file 2</from>
+ <to>Add to result filenames</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Add to result filenames</from>
+ <to>Create archive folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create archive folder</from>
+ <to>Copy result files to archive</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Copy result files to archive</from>
+ <to>file-2.txt archived?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>file-2.txt archived?</from>
+ <to>Files archived</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>file-2.txt archived?</from>
+ <to>Not archived</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>Many actions and transforms add the files they read or write to the result filenames of a workflow.
+The Copy or Move result filenames action copies or moves exactly those files, or the ones matching a wildcard, to a destination folder.
+
+This sample writes two files to ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/in, adds them to the result filenames and then copies them to ${java.io.tmpdir}/hop-samples/copy-move-result-filenames/archive.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1696</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/dbt/src/main/samples/actions/requires-setup/dbt.hwf b/plugins/actions/dbt/src/main/samples/actions/requires-setup/dbt.hwf
new file mode 100644
index 0000000000..e6ca39c52a
--- /dev/null
+++ b/plugins/actions/dbt/src/main/samples/actions/requires-setup/dbt.hwf
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>dbt</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <dbt_project>dbt-project</dbt_project>
+ <operation>run</operation>
+ <target>dev</target>
+ <select/>
+ <exclude/>
+ <full_refresh>N</full_refresh>
+ <threads/>
+ <timeout>600</timeout>
+ <emit_openlineage>N</emit_openlineage>
+ <vars/>
+ <env_vars/>
+ <name>dbt run</name>
+ <description/>
+ <type>DBT</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <dbt_project>dbt-project</dbt_project>
+ <operation>test</operation>
+ <target>dev</target>
+ <select/>
+ <exclude/>
+ <full_refresh>N</full_refresh>
+ <threads/>
+ <timeout>600</timeout>
+ <emit_openlineage>N</emit_openlineage>
+ <vars/>
+ <env_vars/>
+ <name>dbt test</name>
+ <description/>
+ <type>DBT</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>dbt models built and tested.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>dbt run</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>dbt run</from>
+ <to>dbt test</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>dbt test</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The dbt action runs a dbt command (run, test, build, seed, ...) for a dbt project, optionally for a selection of models.
+Variables and environment variables (for example database credentials) can be passed to dbt, and lineage can be emitted with OpenLineage.
+
+This sample builds all models of a dbt project and then runs its tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>138</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs dbt (dbt-core and an adapter for your database) installed, a dbt project and a dbt project definition called "dbt-project"
+in the project metadata, and a database to run the models against. Create those before running this sample.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>186</yloc>
+ <width>736</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/deletefolders/src/main/samples/actions/delete-folders.hwf b/plugins/actions/deletefolders/src/main/samples/actions/delete-folders.hwf
new file mode 100644
index 0000000000..b49275e053
--- /dev/null
+++ b/plugins/actions/deletefolders/src/main/samples/actions/delete-folders.hwf
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>delete-folders</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/delete-folders/2026-01/report.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>January report</content>
+ <encoding>UTF-8</encoding>
+ <name>Write January report</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/delete-folders/2026-02/report.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>February report</content>
+ <encoding>UTF-8</encoding>
+ <name>Write February report</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/delete-folders/2026-01</name>
+ </field>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/delete-folders/2026-02</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Delete monthly folders</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/delete-folders/2026-01</filename>
+ <name>January folder still there?</name>
+ <description/>
+ <type>FILE_EXISTS</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The monthly folders and their content were deleted.</logmessage>
+ <name>Folders deleted</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>The January folder still exists</message>
+ <loglevel>Error</loglevel>
+ <name>Folder not deleted</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write January report</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write January report</from>
+ <to>Write February report</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write February report</from>
+ <to>Delete monthly folders</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Delete monthly folders</from>
+ <to>January folder still there?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>January folder still there?</from>
+ <to>Folders deleted</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>January folder still there?</from>
+ <to>Folder not deleted</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Delete folders action deletes one or more folders, including all files and subfolders they contain.
+
+This sample writes a file into two monthly folders below ${java.io.tmpdir}/hop-samples/delete-folders, deletes both folders and then checks that the first folder is gone.
+Deleting a folder that does not exist is not an error, so the workflow can be run again and again.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1120</width>
+ <height>120</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/deleteresultfilenames/src/main/samples/actions/delete-result-filenames.hwf b/plugins/actions/deleteresultfilenames/src/main/samples/actions/delete-result-filenames.hwf
new file mode 100644
index 0000000000..979f1a7ed2
--- /dev/null
+++ b/plugins/actions/deleteresultfilenames/src/main/samples/actions/delete-result-filenames.hwf
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>delete-result-filenames</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/delete-result-filenames</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/delete-result-filenames/data.csv</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>id
+1</content>
+ <encoding>UTF-8</encoding>
+ <name>Write data.csv</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/delete-result-filenames/process.log</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>done</content>
+ <encoding>UTF-8</encoding>
+ <name>Write process.log</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <delete_all_before>N</delete_all_before>
+ <include_subfolders>N</include_subfolders>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/delete-result-filenames</name>
+ <filemask>.*</filemask>
+ </field>
+ </fields>
+ <name>Add to result filenames</name>
+ <description/>
+ <type>ADD_RESULT_FILENAMES</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <script>var files = previous_result.getResultFilesList();
+action.logBasic("Number of result filenames: " + files.size());
+files.size() == 2;</script>
+ <name>2 result filenames?</name>
+ <description/>
+ <type>EVAL</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <specify_wildcard>Y</specify_wildcard>
+ <wildcard>.*\.log</wildcard>
+ <wildcardexclude/>
+ <name>Remove log files from result</name>
+ <description/>
+ <type>DELETE_RESULT_FILENAMES</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <script>var files = previous_result.getResultFilesList();
+action.logBasic("Number of result filenames: " + files.size());
+files.size() == 1;</script>
+ <name>1 result filename?</name>
+ <description/>
+ <type>EVAL</type>
+ <attributes/>
+ <xloc>1424</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Only data.csv is left in the result filenames.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1616</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Write data.csv</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write data.csv</from>
+ <to>Write process.log</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write process.log</from>
+ <to>Add to result filenames</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Add to result filenames</from>
+ <to>2 result filenames?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>2 result filenames?</from>
+ <to>Remove log files from result</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove log files from result</from>
+ <to>1 result filename?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>1 result filename?</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Delete filenames from result action removes filenames from the result filenames of a workflow. The files themselves are not deleted.
+Use a wildcard to only remove some of the filenames, for example to keep the files an action further down the workflow (Mail, Zip file, ...) should process.
+
+This sample adds a .csv and a .log file from ${java.io.tmpdir}/hop-samples/delete-result-filenames to the result filenames and then removes the .log file from the result.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1696</width>
+ <height>156</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/dostounix/src/main/samples/actions/dos-to-unix.hwf b/plugins/actions/dostounix/src/main/samples/actions/dos-to-unix.hwf
new file mode 100644
index 0000000000..96e7727b6c
--- /dev/null
+++ b/plugins/actions/dostounix/src/main/samples/actions/dos-to-unix.hwf
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>dos-to-unix</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/dos-to-unix</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/dos-to-unix/lines.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>line 1
+line 2
+line 3
+</content>
+ <encoding>UTF-8</encoding>
+ <name>Write Unix file</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <resultfilenames>nothing</resultfilenames>
+ <fields>
+ <field>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/dos-to-unix</source_filefolder>
+ <wildcard>.*\.txt</wildcard>
+ <ConversionType>unixtodos</ConversionType>
+ </field>
+ </fields>
+ <name>Unix to DOS</name>
+ <description/>
+ <type>DOS_UNIX_CONVERTER</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <resultfilenames>nothing</resultfilenames>
+ <fields>
+ <field>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/dos-to-unix</source_filefolder>
+ <wildcard>.*\.txt</wildcard>
+ <ConversionType>dostounix</ConversionType>
+ </field>
+ </fields>
+ <name>DOS to Unix</name>
+ <description/>
+ <type>DOS_UNIX_CONVERTER</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Converted ${java.io.tmpdir}/hop-samples/dos-to-unix/lines.txt to Windows and back to Unix line endings.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Write Unix file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write Unix file</from>
+ <to>Unix to DOS</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Unix to DOS</from>
+ <to>DOS to Unix</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>DOS to Unix</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Dos To Unix action converts the line endings of text files between Windows (CR+LF) and Unix (LF).
+The conversion can be set per file or folder: guess (detect the format and convert to the other one), DOS to Unix or Unix to DOS.
+
+This sample writes a text file with Unix line endings to ${java.io.tmpdir}/hop-samples/dos-to-unix, converts it to Windows line endings and then back to Unix line endings.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1120</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/evalfilesmetrics/src/main/samples/actions/evaluate-files-metrics.hwf b/plugins/actions/evalfilesmetrics/src/main/samples/actions/evaluate-files-metrics.hwf
new file mode 100644
index 0000000000..7b673e5b78
--- /dev/null
+++ b/plugins/actions/evalfilesmetrics/src/main/samples/actions/evaluate-files-metrics.hwf
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>evaluate-files-metrics</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/evaluate-files-metrics</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/evaluate-files-metrics/sales-1.csv</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>id,amount
+1,10</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file 1</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/evaluate-files-metrics/sales-2.csv</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>id,amount
+2,20</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file 2</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/evaluate-files-metrics/sales-3.csv</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>id,amount
+3,30</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file 3</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <scale>bytes</scale>
+ <source_files>files</source_files>
+ <evaluation_type>count</evaluation_type>
+ <comparevalue>3</comparevalue>
+ <minvalue/>
+ <maxvalue/>
+ <successnumbercondition>equal</successnumbercondition>
+ <result_filenames_wildcard/>
+ <fields>
+ <field>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/evaluate-files-metrics</source_filefolder>
+ <wildcard>.*\.csv</wildcard>
+ <include_subFolders>N</include_subFolders>
+ </field>
+ </fields>
+ <Result_field_file/>
+ <Result_field_wildcard/>
+ <Result_field_includesubfolders/>
+ <name>3 csv files?</name>
+ <description/>
+ <type>EVAL_FILES_METRICS</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <scale>bytes</scale>
+ <source_files>files</source_files>
+ <evaluation_type>size</evaluation_type>
+ <comparevalue>0</comparevalue>
+ <minvalue/>
+ <maxvalue/>
+ <successnumbercondition>greater</successnumbercondition>
+ <result_filenames_wildcard/>
+ <fields>
+ <field>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/evaluate-files-metrics</source_filefolder>
+ <wildcard>.*\.csv</wildcard>
+ <include_subFolders>N</include_subFolders>
+ </field>
+ </fields>
+ <Result_field_file/>
+ <Result_field_wildcard/>
+ <Result_field_includesubfolders/>
+ <name>Files not empty?</name>
+ <description/>
+ <type>EVAL_FILES_METRICS</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>All 3 csv files were delivered and they contain data.</logmessage>
+ <name>All files delivered</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1424</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>Expected 3 csv files</message>
+ <loglevel>Error</loglevel>
+ <name>Wrong number of files</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>The csv files are empty</message>
+ <loglevel>Error</loglevel>
+ <name>Empty files</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Write file 1</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file 1</from>
+ <to>Write file 2</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file 2</from>
+ <to>Write file 3</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file 3</from>
+ <to>3 csv files?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>3 csv files?</from>
+ <to>Files not empty?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>3 csv files?</from>
+ <to>Wrong number of files</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Files not empty?</from>
+ <to>All files delivered</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Files not empty?</from>
+ <to>Empty files</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Evaluate files metrics action evaluates the total size or the number of files in a folder (or in the result filenames) against a value or a range.
+
+This sample writes three csv files to ${java.io.tmpdir}/hop-samples/evaluate-files-metrics, checks that there are exactly 3 csv files and that they are not empty.
+A typical use is checking that the expected number of files was delivered before starting a load.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1504</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/evaluatetablecontent/src/main/samples/actions/evaluate-table-content.hwf b/plugins/actions/evaluatetablecontent/src/main/samples/actions/evaluate-table-content.hwf
new file mode 100644
index 0000000000..ee001afb43
--- /dev/null
+++ b/plugins/actions/evaluatetablecontent/src/main/samples/actions/evaluate-table-content.hwf
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>evaluate-table-content</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <sql>CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_EVALUATE_TABLE
+(
+ id INT
+, name VARCHAR(50)
+);
+
+DELETE FROM PUBLIC.SAMPLE_EVALUATE_TABLE;
+
+INSERT INTO PUBLIC.SAMPLE_EVALUATE_TABLE VALUES
+(1, 'Apache Hop'),
+(2, 'Apache Beam'),
+(3, 'Apache Spark');</sql>
+ <connection>hop-samples</connection>
+ <useVariableSubstitution>N</useVariableSubstitution>
+ <sqlfromfile>N</sqlfromfile>
+ <sendOneStatement>N</sendOneStatement>
+ <name>Create and fill table</name>
+ <description/>
+ <type>SQL</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <add_rows_result>N</add_rows_result>
+ <clear_result_rows>Y</clear_result_rows>
+ <is_usevars>N</is_usevars>
+ <is_custom_sql>N</is_custom_sql>
+ <custom_sql/>
+ <connection>hop-samples</connection>
+ <tablename>SAMPLE_EVALUATE_TABLE</tablename>
+ <schemaname>PUBLIC</schemaname>
+ <limit>0</limit>
+ <success_condition>rows_count_greater</success_condition>
+ <name>Table not empty?</name>
+ <description/>
+ <type>EVAL_TABLE_CONTENT</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <add_rows_result>N</add_rows_result>
+ <clear_result_rows>Y</clear_result_rows>
+ <is_usevars>N</is_usevars>
+ <is_custom_sql>Y</is_custom_sql>
+ <custom_sql>SELECT * FROM PUBLIC.SAMPLE_EVALUATE_TABLE WHERE name = 'Apache Hop'</custom_sql>
+ <connection>hop-samples</connection>
+ <tablename/>
+ <schemaname/>
+ <limit>1</limit>
+ <success_condition>rows_count_equal</success_condition>
+ <name>One Apache Hop row?</name>
+ <description/>
+ <type>EVAL_TABLE_CONTENT</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Both checks on SAMPLE_EVALUATE_TABLE succeeded.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>SAMPLE_EVALUATE_TABLE should not be empty</message>
+ <loglevel>Error</loglevel>
+ <name>Table is empty</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>Expected exactly one Apache Hop row</message>
+ <loglevel>Error</loglevel>
+ <name>Apache Hop not found</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Create and fill table</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create and fill table</from>
+ <to>Table not empty?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Table not empty?</from>
+ <to>One Apache Hop row?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Table not empty?</from>
+ <to>Table is empty</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>One Apache Hop row?</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>One Apache Hop row?</from>
+ <to>Apache Hop not found</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Evaluate rows number in a table action counts the rows in a table, or the rows returned by a custom SQL query,
+and compares the count with a value (equal, different, smaller, greater, ...).
+
+This sample fills the table SAMPLE_EVALUATE_TABLE with three rows, then checks that the table has more than 0 rows
+and that a custom query finds exactly one row named 'Apache Hop'.
+The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>928</width>
+ <height>174</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/filecompare/src/main/samples/actions/file-compare.hwf b/plugins/actions/filecompare/src/main/samples/actions/file-compare.hwf
new file mode 100644
index 0000000000..c6e2651390
--- /dev/null
+++ b/plugins/actions/filecompare/src/main/samples/actions/file-compare.hwf
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>file-compare</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/file-compare/a.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Hello, Apache Hop!</content>
+ <encoding>UTF-8</encoding>
+ <name>Write a.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/file-compare/b.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Hello, Apache Hop!</content>
+ <encoding>UTF-8</encoding>
+ <name>Write b.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/file-compare/c.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Goodbye!</content>
+ <encoding>UTF-8</encoding>
+ <name>Write c.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename1>${java.io.tmpdir}/hop-samples/file-compare/a.txt</filename1>
+ <filename2>${java.io.tmpdir}/hop-samples/file-compare/b.txt</filename2>
+ <add_filename_result>N</add_filename_result>
+ <name>a.txt = b.txt?</name>
+ <description/>
+ <type>FILE_COMPARE</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename1>${java.io.tmpdir}/hop-samples/file-compare/a.txt</filename1>
+ <filename2>${java.io.tmpdir}/hop-samples/file-compare/c.txt</filename2>
+ <add_filename_result>N</add_filename_result>
+ <name>a.txt = c.txt?</name>
+ <description/>
+ <type>FILE_COMPARE</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>a.txt and b.txt are identical, a.txt and c.txt are different.</logmessage>
+ <name>Files differ</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>a.txt and c.txt should be different</message>
+ <loglevel>Error</loglevel>
+ <name>Unexpected: a = c</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>a.txt and b.txt should be identical</message>
+ <loglevel>Error</loglevel>
+ <name>Unexpected: a <> b</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write a.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write a.txt</from>
+ <to>Write b.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write b.txt</from>
+ <to>Write c.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write c.txt</from>
+ <to>a.txt = b.txt?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>a.txt = b.txt?</from>
+ <to>a.txt = c.txt?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>a.txt = b.txt?</from>
+ <to>Unexpected: a <> b</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>a.txt = c.txt?</from>
+ <to>Unexpected: a = c</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>a.txt = c.txt?</from>
+ <to>Files differ</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The File compare action compares the content of two files. It succeeds when both files are identical and fails when they differ.
+
+This sample writes three files to ${java.io.tmpdir}/hop-samples/file-compare: a.txt and b.txt have the same content, c.txt is different.
+Comparing a.txt with b.txt follows the success (green) hop, comparing a.txt with c.txt follows the failure (red) hop.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1312</width>
+ <height>156</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/fileexists/src/main/samples/actions/file-exists.hwf b/plugins/actions/fileexists/src/main/samples/actions/file-exists.hwf
new file mode 100644
index 0000000000..c8776d42f6
--- /dev/null
+++ b/plugins/actions/fileexists/src/main/samples/actions/file-exists.hwf
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>file-exists</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${PROJECT_HOME}/project-config.json</filename>
+ <name>project-config.json exists?</name>
+ <description/>
+ <type>FILE_EXISTS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The project configuration file was found.</logmessage>
+ <name>Found it</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The project configuration file was not found.</logmessage>
+ <name>Not found</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${PROJECT_HOME}/not-there.txt</filename>
+ <name>not-there.txt exists?</name>
+ <description/>
+ <type>FILE_EXISTS</type>
+ <attributes/>
+ <xloc>752</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Somebody created not-there.txt.</logmessage>
+ <name>Unexpected file</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>992</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>not-there.txt does not exist, the failure hop was followed.</logmessage>
+ <name>File is missing, as expected</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>752</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>project-config.json exists?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>project-config.json exists?</from>
+ <to>Found it</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>project-config.json exists?</from>
+ <to>Not found</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Found it</from>
+ <to>not-there.txt exists?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>not-there.txt exists?</from>
+ <to>Unexpected file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>not-there.txt exists?</from>
+ <to>File is missing, as expected</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The File exists action checks whether a single file (or folder) exists. The action succeeds when the file is found and fails when it is not.
+Use the success (green) and failure (red) hops to choose what happens next.
+
+This sample checks for the project-config.json file of the samples project, which is always there, and for a file that does not exist.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1072</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/folderisempty/src/main/samples/actions/folder-is-empty.hwf b/plugins/actions/folderisempty/src/main/samples/actions/folder-is-empty.hwf
new file mode 100644
index 0000000000..fa12805bcd
--- /dev/null
+++ b/plugins/actions/folderisempty/src/main/samples/actions/folder-is-empty.hwf
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>folder-is-empty</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/folder-is-empty</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <foldername>${java.io.tmpdir}/hop-samples/folder-is-empty</foldername>
+ <fail_of_folder_exists>N</fail_of_folder_exists>
+ <name>Create empty folder</name>
+ <description/>
+ <type>CREATE_FOLDER</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <foldername>${java.io.tmpdir}/hop-samples/folder-is-empty</foldername>
+ <include_subfolders>N</include_subfolders>
+ <specify_wildcard>N</specify_wildcard>
+ <wildcard/>
+ <name>Folder is empty?</name>
+ <description/>
+ <type>FOLDER_IS_EMPTY</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/folder-is-empty/file.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Some content</content>
+ <encoding>UTF-8</encoding>
+ <name>Write a file</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <foldername>${java.io.tmpdir}/hop-samples/folder-is-empty</foldername>
+ <include_subfolders>N</include_subfolders>
+ <specify_wildcard>N</specify_wildcard>
+ <wildcard/>
+ <name>Folder still empty?</name>
+ <description/>
+ <type>FOLDER_IS_EMPTY</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>The folder should no longer be empty</message>
+ <loglevel>Error</loglevel>
+ <name>Unexpected</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The folder contains a file now.</logmessage>
+ <name>Folder is no longer empty</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>A new folder should be empty</message>
+ <loglevel>Error</loglevel>
+ <name>Folder not empty</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Create empty folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create empty folder</from>
+ <to>Folder is empty?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Folder is empty?</from>
+ <to>Write a file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Folder is empty?</from>
+ <to>Folder not empty</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write a file</from>
+ <to>Folder still empty?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Folder still empty?</from>
+ <to>Unexpected</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Folder still empty?</from>
+ <to>Folder is no longer empty</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Folder is empty action succeeds when a folder contains no files. Optionally, only files matching a wildcard (regular expression) are counted.
+
+This sample creates the empty folder ${java.io.tmpdir}/hop-samples/folder-is-empty and checks it, then writes a file into it and checks it again.
+The second check fails, which takes the failure (red) hop.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1312</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/folderscompare/src/main/samples/actions/folders-compare.hwf b/plugins/actions/folderscompare/src/main/samples/actions/folders-compare.hwf
new file mode 100644
index 0000000000..062248adca
--- /dev/null
+++ b/plugins/actions/folderscompare/src/main/samples/actions/folders-compare.hwf
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>folders-compare</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/folders-compare</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/folders-compare/source/a.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>A</content>
+ <encoding>UTF-8</encoding>
+ <name>Write source/a.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/folders-compare/source/b.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>B</content>
+ <encoding>UTF-8</encoding>
+ <name>Write source/b.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/folders-compare/backup/a.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>A</content>
+ <encoding>UTF-8</encoding>
+ <name>Write backup/a.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/folders-compare/backup/b.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>B</content>
+ <encoding>UTF-8</encoding>
+ <name>Write backup/b.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/folders-compare/other/a.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>a different A</content>
+ <encoding>UTF-8</encoding>
+ <name>Write other/a.txt</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <include_subfolders>N</include_subfolders>
+ <compare_filecontent>Y</compare_filecontent>
+ <compare_filesize>Y</compare_filesize>
+ <compareonly>only_files</compareonly>
+ <wildcard/>
+ <filename1>${java.io.tmpdir}/hop-samples/folders-compare/source</filename1>
+ <filename2>${java.io.tmpdir}/hop-samples/folders-compare/backup</filename2>
+ <name>source = backup?</name>
+ <description/>
+ <type>FOLDERS_COMPARE</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <include_subfolders>N</include_subfolders>
+ <compare_filecontent>Y</compare_filecontent>
+ <compare_filesize>Y</compare_filesize>
+ <compareonly>only_files</compareonly>
+ <wildcard/>
+ <filename1>${java.io.tmpdir}/hop-samples/folders-compare/source</filename1>
+ <filename2>${java.io.tmpdir}/hop-samples/folders-compare/other</filename2>
+ <name>source = other?</name>
+ <description/>
+ <type>FOLDERS_COMPARE</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>source and other should be different</message>
+ <loglevel>Error</loglevel>
+ <name>Unexpected: source = other</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>source and backup are identical, source and other are different.</logmessage>
+ <name>Folders compared</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>544</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>source and backup should be identical</message>
+ <loglevel>Error</loglevel>
+ <name>Unexpected: source <> backup</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>544</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Write source/a.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write source/a.txt</from>
+ <to>Write source/b.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write source/b.txt</from>
+ <to>Write backup/a.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write backup/a.txt</from>
+ <to>Write backup/b.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write backup/b.txt</from>
+ <to>Write other/a.txt</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write other/a.txt</from>
+ <to>source = backup?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>source = backup?</from>
+ <to>source = other?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>source = backup?</from>
+ <to>Unexpected: source <> backup</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>source = other?</from>
+ <to>Unexpected: source = other</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>source = other?</from>
+ <to>Folders compared</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Compare folders action compares the content of two folders: the names of the files and folders they contain and, optionally, the size and content of the files.
+It succeeds when both folders are identical.
+
+This sample writes the same two files to ${java.io.tmpdir}/hop-samples/folders-compare/source and ${java.io.tmpdir}/hop-samples/folders-compare/backup, and different files to ${java.io.tmpdir}/hop-samples/folders-compare/other.
+source and backup are identical (success, green hop), source and other are not (failure, red hop).</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1312</width>
+ <height>174</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/http/src/main/samples/actions/requires-setup/http-get.hwf b/plugins/actions/http/src/main/samples/actions/requires-setup/http-get.hwf
new file mode 100644
index 0000000000..b6d200b749
--- /dev/null
+++ b/plugins/actions/http/src/main/samples/actions/requires-setup/http-get.hwf
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>http-get</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <url>https://hop.apache.org</url>
+ <connectTimeOut>5000</connectTimeOut>
+ <readTimeOut>10000</readTimeOut>
+ <name>Website available?</name>
+ <description/>
+ <type>WEBSERVICE_AVAILABLE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <url>https://hop.apache.org</url>
+ <targetfilename>${java.io.tmpdir}/hop-samples/http/hop.html</targetfilename>
+ <file_appended>N</file_appended>
+ <date_time_added>N</date_time_added>
+ <targetfilename_extension/>
+ <uploadfilename/>
+ <url_fieldname/>
+ <upload_fieldname/>
+ <dest_fieldname/>
+ <run_every_row>N</run_every_row>
+ <ignore_ssl>N</ignore_ssl>
+ <proxy_host/>
+ <proxy_port/>
+ <non_proxy_hosts/>
+ <username/>
+ <password>Encrypted </password>
+ <addfilenameresult>N</addfilenameresult>
+ <headers/>
+ <name>Download home page</name>
+ <description/>
+ <type>HTTP</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Home page downloaded to ${java.io.tmpdir}/hop-samples/http/hop.html</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>https://hop.apache.org is not available.</logmessage>
+ <name>Not available</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>544</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Website available?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Website available?</from>
+ <to>Download home page</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Download home page</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Website available?</from>
+ <to>Not available</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Http action downloads the response of a URL to a file, or uploads a file to a URL. Headers, authentication and proxy settings can be configured,
+and the URL can be taken from the result rows to download multiple files.
+
+This sample checks that the Apache Hop website is available and downloads its home page to ${java.io.tmpdir}/hop-samples/http/hop.html.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>138</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs internet access (or change the URL to a server in your network).
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>186</yloc>
+ <width>736</width>
+ <height>70</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/movefiles/src/main/samples/actions/move-files.hwf b/plugins/actions/movefiles/src/main/samples/actions/move-files.hwf
new file mode 100644
index 0000000000..b3d792e5e2
--- /dev/null
+++ b/plugins/actions/movefiles/src/main/samples/actions/move-files.hwf
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>move-files</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/move-files</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/move-files/incoming/orders.csv</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>id,amount
+1,10
+2,20</content>
+ <encoding>UTF-8</encoding>
+ <name>Write orders.csv</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/move-files/incoming/customers.csv</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>id,name
+1,Apache Hop</content>
+ <encoding>UTF-8</encoding>
+ <name>Write customers.csv</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/move-files/incoming/import.log</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>import started</content>
+ <encoding>UTF-8</encoding>
+ <name>Write import.log</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <move_empty_folders>N</move_empty_folders>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <add_result_filesname>N</add_result_filesname>
+ <destination_is_a_file>N</destination_is_a_file>
+ <create_destination_folder>Y</create_destination_folder>
+ <fields>
+ <field>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/move-files/incoming</source_filefolder>
+ <destination_filefolder>${java.io.tmpdir}/hop-samples/move-files/processed</destination_filefolder>
+ <wildcard>.*\.csv</wildcard>
+ </field>
+ </fields>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <SpecifyFormat>N</SpecifyFormat>
+ <date_time_format/>
+ <AddDateBeforeExtension>N</AddDateBeforeExtension>
+ <DoNotKeepFolderStructure>N</DoNotKeepFolderStructure>
+ <iffileexists>overwrite_file</iffileexists>
+ <destinationFolder/>
+ <ifmovedfileexists>do_nothing</ifmovedfileexists>
+ <moved_date_time_format/>
+ <AddMovedDateBeforeExtension>N</AddMovedDateBeforeExtension>
+ <add_moved_date>N</add_moved_date>
+ <add_moved_time>N</add_moved_time>
+ <SpecifyMoveFormat>N</SpecifyMoveFormat>
+ <create_move_to_folder>N</create_move_to_folder>
+ <simulate>N</simulate>
+ <name>Move csv files</name>
+ <description/>
+ <type>MOVE_FILES</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/move-files/processed/orders.csv</filename>
+ <name>orders.csv moved?</name>
+ <description/>
+ <type>FILE_EXISTS</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The csv files were moved to the processed folder.</logmessage>
+ <name>Files moved</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1424</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>orders.csv was not moved</message>
+ <loglevel>Error</loglevel>
+ <name>orders.csv not moved</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Write orders.csv</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write orders.csv</from>
+ <to>Write customers.csv</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write customers.csv</from>
+ <to>Write import.log</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write import.log</from>
+ <to>Move csv files</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Move csv files</from>
+ <to>orders.csv moved?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>orders.csv moved?</from>
+ <to>Files moved</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>orders.csv moved?</from>
+ <to>orders.csv not moved</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Move files action moves files (optionally selected with a regular expression) from a source to a destination folder.
+It can also rename files with a date or time, and decide what to do when a file already exists in the destination.
+
+This sample writes three files to ${java.io.tmpdir}/hop-samples/move-files/incoming and moves the .csv files to ${java.io.tmpdir}/hop-samples/move-files/processed. The .log file stays where it is.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1504</width>
+ <height>156</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf b/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf
new file mode 100644
index 0000000000..3497b287dc
--- /dev/null
+++ b/plugins/actions/pgpfiles/src/main/samples/actions/requires-setup/pgp-encrypt-decrypt-verify.hwf
@@ -0,0 +1,320 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>pgp-encrypt-decrypt-verify</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/pgp/report.csv</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>id,amount
+1,100</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <add_result_filesname>N</add_result_filesname>
+ <destination_is_a_file>Y</destination_is_a_file>
+ <create_destination_folder>N</create_destination_folder>
+ <fields>
+ <field>
+ <action_type>encrypt</action_type>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/pgp/report.csv</source_filefolder>
+ <userid>${PGP_USER_ID}</userid>
+ <destination_filefolder>${java.io.tmpdir}/hop-samples/pgp/report.csv.gpg</destination_filefolder>
+ <wildcard/>
+ </field>
+ </fields>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <SpecifyFormat>N</SpecifyFormat>
+ <date_time_format/>
+ <AddDateBeforeExtension>N</AddDateBeforeExtension>
+ <DoNotKeepFolderStructure>N</DoNotKeepFolderStructure>
+ <iffileexists>overwrite_file</iffileexists>
+ <destinationFolder/>
+ <ifmovedfileexists>do_nothing</ifmovedfileexists>
+ <moved_date_time_format/>
+ <AddMovedDateBeforeExtension>N</AddMovedDateBeforeExtension>
+ <add_moved_date>N</add_moved_date>
+ <add_moved_time>N</add_moved_time>
+ <SpecifyMoveFormat>N</SpecifyMoveFormat>
+ <create_move_to_folder>N</create_move_to_folder>
+ <gpglocation>${PGP_GPG_LOCATION}</gpglocation>
+ <asciiMode>Y</asciiMode>
+ <name>Encrypt file</name>
+ <description/>
+ <type>PGP_ENCRYPT_FILES</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <add_result_filesname>N</add_result_filesname>
+ <destination_is_a_file>Y</destination_is_a_file>
+ <create_destination_folder>N</create_destination_folder>
+ <fields>
+ <field>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/pgp/report.csv.gpg</source_filefolder>
+ <passphrase>${PGP_PASSPHRASE}</passphrase>
+ <destination_filefolder>${java.io.tmpdir}/hop-samples/pgp/report-decrypted.csv</destination_filefolder>
+ <wildcard/>
+ </field>
+ </fields>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <SpecifyFormat>N</SpecifyFormat>
+ <date_time_format/>
+ <AddDateBeforeExtension>N</AddDateBeforeExtension>
+ <DoNotKeepFolderStructure>N</DoNotKeepFolderStructure>
+ <iffileexists>overwrite_file</iffileexists>
+ <destinationFolder/>
+ <ifmovedfileexists>do_nothing</ifmovedfileexists>
+ <moved_date_time_format/>
+ <AddMovedDateBeforeExtension>N</AddMovedDateBeforeExtension>
+ <add_moved_date>N</add_moved_date>
+ <add_moved_time>N</add_moved_time>
+ <SpecifyMoveFormat>N</SpecifyMoveFormat>
+ <create_move_to_folder>N</create_move_to_folder>
+ <gpglocation>${PGP_GPG_LOCATION}</gpglocation>
+ <name>Decrypt file</name>
+ <description/>
+ <type>PGP_DECRYPT_FILES</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <add_result_filesname>N</add_result_filesname>
+ <destination_is_a_file>Y</destination_is_a_file>
+ <create_destination_folder>N</create_destination_folder>
+ <fields>
+ <field>
+ <action_type>sign</action_type>
+ <source_filefolder>${java.io.tmpdir}/hop-samples/pgp/report.csv</source_filefolder>
+ <local_user>${PGP_USER_ID}</local_user>
+ <destination_filefolder>${java.io.tmpdir}/hop-samples/pgp/report.csv.asc</destination_filefolder>
+ <wildcard/>
+ </field>
+ </fields>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <SpecifyFormat>N</SpecifyFormat>
+ <date_time_format/>
+ <AddDateBeforeExtension>N</AddDateBeforeExtension>
+ <DoNotKeepFolderStructure>N</DoNotKeepFolderStructure>
+ <iffileexists>overwrite_file</iffileexists>
+ <destinationFolder/>
+ <ifmovedfileexists>do_nothing</ifmovedfileexists>
+ <moved_date_time_format/>
+ <AddMovedDateBeforeExtension>N</AddMovedDateBeforeExtension>
+ <add_moved_date>N</add_moved_date>
+ <add_moved_time>N</add_moved_time>
+ <SpecifyMoveFormat>N</SpecifyMoveFormat>
+ <create_move_to_folder>N</create_move_to_folder>
+ <gpglocation>${PGP_GPG_LOCATION}</gpglocation>
+ <asciiMode>Y</asciiMode>
+ <name>Sign file</name>
+ <description/>
+ <type>PGP_ENCRYPT_FILES</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <gpglocation>${PGP_GPG_LOCATION}</gpglocation>
+ <filename>${java.io.tmpdir}/hop-samples/pgp/report.csv.asc</filename>
+ <detachedfilename/>
+ <useDetachedSignature>N</useDetachedSignature>
+ <name>Verify signature</name>
+ <description/>
+ <type>PGP_VERIFY_FILES</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The file was encrypted, decrypted, signed and verified.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1232</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file</from>
+ <to>Encrypt file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Encrypt file</from>
+ <to>Decrypt file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Decrypt file</from>
+ <to>Sign file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Sign file</from>
+ <to>Verify signature</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Verify signature</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The PGP actions use GnuPG to protect files: Encrypt files with PGP encrypts and/or signs files, Decrypt files with PGP decrypts them
+and Verify file signature with PGP checks the signature of a signed file.
+
+This sample writes a file to ${java.io.tmpdir}/hop-samples/pgp, encrypts it for the key of PGP_USER_ID, decrypts it again, then signs the file and verifies the signature.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1312</width>
+ <height>138</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs GnuPG (gpg) installed, and a key pair in the keyring of the user running Hop. Set the PGP_GPG_LOCATION (for example /usr/bin/gpg),
+PGP_USER_ID (the user id or e-mail of the key) and PGP_PASSPHRASE variables before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>186</yloc>
+ <width>1312</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/sendnagiospassivecheck/src/main/samples/actions/requires-setup/send-nagios-passive-check.hwf b/plugins/actions/sendnagiospassivecheck/src/main/samples/actions/requires-setup/send-nagios-passive-check.hwf
new file mode 100644
index 0000000000..4fa62b45cf
--- /dev/null
+++ b/plugins/actions/sendnagiospassivecheck/src/main/samples/actions/requires-setup/send-nagios-passive-check.hwf
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>send-nagios-passive-check</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <servername>${NAGIOS_SERVER}</servername>
+ <port>5667</port>
+ <responseTimeOut>10000</responseTimeOut>
+ <connectionTimeOut>5000</connectionTimeOut>
+ <message>Workflow ${Internal.Workflow.Name} finished successfully</message>
+ <senderServerName>hop-server</senderServerName>
+ <senderServiceName>hop-samples</senderServiceName>
+ <encryptionMode>0</encryptionMode>
+ <level>1</level>
+ <password>${NAGIOS_PASSWORD}</password>
+ <name>Report OK</name>
+ <description/>
+ <type>SEND_NAGIOS_PASSIVE_CHECK</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Status sent to Nagios.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Report OK</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Report OK</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Send Nagios passive check action sends the result of a check to a Nagios server running NSCA, so Nagios can monitor your workflows.
+The level (OK, WARNING, CRITICAL, UNKNOWN) and message tell Nagios how the workflow did.
+
+This sample reports OK for the hop-samples service when the workflow succeeds.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>120</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a Nagios server with the NSCA add-on, and a hop-samples service on host hop-server in the Nagios configuration.
+Set the NAGIOS_SERVER and NAGIOS_PASSWORD variables before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>168</yloc>
+ <width>640</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/setpasswordencoder/src/main/samples/actions/set-password-encoder.hwf b/plugins/actions/setpasswordencoder/src/main/samples/actions/set-password-encoder.hwf
new file mode 100644
index 0000000000..dce6a828b7
--- /dev/null
+++ b/plugins/actions/setpasswordencoder/src/main/samples/actions/set-password-encoder.hwf
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>set-password-encoder</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <encoder_plugin_id>Hop</encoder_plugin_id>
+ <key_variable/>
+ <key_file/>
+ <name>Set Hop encoder</name>
+ <description/>
+ <type>SET_PASSWORD_ENCODER</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Passwords are now encoded with the default Hop encoder.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Set Hop encoder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Set Hop encoder</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Set password encoder action changes the encoder Hop uses to encrypt and decrypt passwords (for example in database connections) for the rest of the process.
+Use it when a workflow has to read metadata that was encrypted with a different encoder, for example the AES2 encoder with the key in the HOP_AES_ENCODER_KEY variable.
+
+This sample sets the default Hop encoder, which needs no key. Choose AES or AES2 and a key variable or key file to use one of the AES encoders.
+Note that the encoder is changed for the whole Hop process: when you run this in Hop Gui, it is used until you restart.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>192</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/shell/src/main/samples/actions/shell.hwf b/plugins/actions/shell/src/main/samples/actions/shell.hwf
new file mode 100644
index 0000000000..3b0cba52cb
--- /dev/null
+++ b/plugins/actions/shell/src/main/samples/actions/shell.hwf
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>shell</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename/>
+ <work_directory>${PROJECT_HOME}</work_directory>
+ <arguments/>
+ <arg_from_previous>N</arg_from_previous>
+ <set_logfile>N</set_logfile>
+ <logfile/>
+ <logext/>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <loglevel>Basic</loglevel>
+ <exec_per_row>N</exec_per_row>
+ <set_append_logfile>N</set_append_logfile>
+ <insertScript>Y</insertScript>
+ <script>echo Hello from the Shell action</script>
+ <name>Echo</name>
+ <description/>
+ <type>SHELL</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The script ran successfully.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>The script ended with an error.</message>
+ <loglevel>Error</loglevel>
+ <name>Script failed</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Echo</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Echo</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Echo</from>
+ <to>Script failed</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Shell action runs a script or an operating system command. The script can be a file or be entered in the action.
+On Windows, a script entered in the action runs as a batch file, on Linux and macOS as a shell script. The exit code of the script decides whether the action succeeds.
+
+This sample runs an echo command, which works on all operating systems, and writes the output to the Hop log.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/snmptrap/src/main/samples/actions/requires-setup/snmp-trap.hwf b/plugins/actions/snmptrap/src/main/samples/actions/requires-setup/snmp-trap.hwf
new file mode 100644
index 0000000000..73693d2f6e
--- /dev/null
+++ b/plugins/actions/snmptrap/src/main/samples/actions/requires-setup/snmp-trap.hwf
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>snmp-trap</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <servername>${SNMP_SERVER}</servername>
+ <port>162</port>
+ <timeout>5000</timeout>
+ <nrretry>1</nrretry>
+ <comstring>public</comstring>
+ <message>Workflow ${Internal.Workflow.Name} needs attention</message>
+ <oid>1.3.6.1.4.1.12345.1</oid>
+ <targettype>community</targettype>
+ <user/>
+ <passphrase/>
+ <engineid/>
+ <name>Send trap</name>
+ <description/>
+ <type>SNMP_TRAP</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>SNMP trap sent.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Send trap</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Send trap</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Snmp Trap action sends an SNMP trap to a network management system, for example to raise an alert when a workflow fails.
+It supports community based (SNMP v1/v2c) and user based (SNMP v3) targets.
+
+This sample sends a trap with a message to the SNMP manager in the SNMP_SERVER variable.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>120</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs an SNMP manager that receives traps. Set the SNMP_SERVER variable, and the community string and OID your manager expects, before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>168</yloc>
+ <width>640</width>
+ <height>70</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/sql/src/main/samples/actions/sql-script.hwf b/plugins/actions/sql/src/main/samples/actions/sql-script.hwf
new file mode 100644
index 0000000000..0c13d78ee9
--- /dev/null
+++ b/plugins/actions/sql/src/main/samples/actions/sql-script.hwf
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>sql-script</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <sql>CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_SQL_SCRIPT
+(
+ id INT
+, name VARCHAR(50)
+);
+
+DELETE FROM PUBLIC.SAMPLE_SQL_SCRIPT;
+
+INSERT INTO PUBLIC.SAMPLE_SQL_SCRIPT VALUES
+(1, 'Apache Hop'),
+(2, 'Apache Beam'),
+(3, 'Apache Spark');</sql>
+ <connection>hop-samples</connection>
+ <useVariableSubstitution>N</useVariableSubstitution>
+ <sqlfromfile>N</sqlfromfile>
+ <sendOneStatement>N</sendOneStatement>
+ <name>Create and fill table</name>
+ <description/>
+ <type>SQL</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <add_rows_result>N</add_rows_result>
+ <clear_result_rows>Y</clear_result_rows>
+ <is_usevars>N</is_usevars>
+ <is_custom_sql>N</is_custom_sql>
+ <custom_sql/>
+ <connection>hop-samples</connection>
+ <tablename>SAMPLE_SQL_SCRIPT</tablename>
+ <schemaname>PUBLIC</schemaname>
+ <limit>3</limit>
+ <success_condition>rows_count_equal</success_condition>
+ <name>3 rows?</name>
+ <description/>
+ <type>EVAL_TABLE_CONTENT</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Table SAMPLE_SQL_SCRIPT contains 3 rows.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>SAMPLE_SQL_SCRIPT should contain 3 rows</message>
+ <loglevel>Error</loglevel>
+ <name>Unexpected row count</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Create and fill table</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create and fill table</from>
+ <to>3 rows?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>3 rows?</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>3 rows?</from>
+ <to>Unexpected row count</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The SQL action executes one or more SQL statements against a relational database connection.
+The statements can be entered in the action or read from a file, and can contain variables.
+
+This sample creates the table SAMPLE_SQL_SCRIPT, clears it and inserts three rows.
+The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>120</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/telnet/src/main/samples/actions/requires-setup/telnet-a-host.hwf b/plugins/actions/telnet/src/main/samples/actions/requires-setup/telnet-a-host.hwf
new file mode 100644
index 0000000000..dfc67eb292
--- /dev/null
+++ b/plugins/actions/telnet/src/main/samples/actions/requires-setup/telnet-a-host.hwf
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>telnet-a-host</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <hostname>${DB_HOST}</hostname>
+ <port>5432</port>
+ <timeout>3000</timeout>
+ <name>Database port open?</name>
+ <description/>
+ <type>TELNET</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>${DB_HOST}:5432 is reachable.</logmessage>
+ <name>Reachable</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>${DB_HOST}:5432 is not reachable.</logmessage>
+ <name>Not reachable</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>544</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Database port open?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Database port open?</from>
+ <to>Reachable</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Database port open?</from>
+ <to>Not reachable</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Telnet a host action checks that a TCP port on a host accepts connections within a timeout (in milliseconds).
+Use it to check that a database, mail server or other service is reachable before using it.
+
+This sample checks that the PostgreSQL port 5432 on the host in the DB_HOST variable is reachable.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>120</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a host to connect to. Set the DB_HOST variable, or change the host name and port, before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>168</yloc>
+ <width>640</width>
+ <height>70</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/truncatetables/src/main/samples/actions/truncate-tables.hwf b/plugins/actions/truncatetables/src/main/samples/actions/truncate-tables.hwf
new file mode 100644
index 0000000000..94ce4b04eb
--- /dev/null
+++ b/plugins/actions/truncatetables/src/main/samples/actions/truncate-tables.hwf
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>truncate-tables</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <sql>CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_TRUNCATE_TABLES
+(
+ id INT
+, name VARCHAR(50)
+);
+
+DELETE FROM PUBLIC.SAMPLE_TRUNCATE_TABLES;
+
+INSERT INTO PUBLIC.SAMPLE_TRUNCATE_TABLES VALUES
+(1, 'Apache Hop'),
+(2, 'Apache Beam'),
+(3, 'Apache Spark');</sql>
+ <connection>hop-samples</connection>
+ <useVariableSubstitution>N</useVariableSubstitution>
+ <sqlfromfile>N</sqlfromfile>
+ <sendOneStatement>N</sendOneStatement>
+ <name>Create and fill table</name>
+ <description/>
+ <type>SQL</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <connection>hop-samples</connection>
+ <fields>
+ <field>
+ <name>SAMPLE_TRUNCATE_TABLES</name>
+ <schemaname>PUBLIC</schemaname>
+ </field>
+ </fields>
+ <name>Truncate table</name>
+ <description/>
+ <type>TRUNCATE_TABLES</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <add_rows_result>N</add_rows_result>
+ <clear_result_rows>Y</clear_result_rows>
+ <is_usevars>N</is_usevars>
+ <is_custom_sql>N</is_custom_sql>
+ <custom_sql/>
+ <connection>hop-samples</connection>
+ <tablename>SAMPLE_TRUNCATE_TABLES</tablename>
+ <schemaname>PUBLIC</schemaname>
+ <limit>0</limit>
+ <success_condition>rows_count_equal</success_condition>
+ <name>Table empty?</name>
+ <description/>
+ <type>EVAL_TABLE_CONTENT</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Table SAMPLE_TRUNCATE_TABLES was truncated.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>SAMPLE_TRUNCATE_TABLES should be empty</message>
+ <loglevel>Error</loglevel>
+ <name>Table not empty</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Create and fill table</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create and fill table</from>
+ <to>Truncate table</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Truncate table</from>
+ <to>Table empty?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Table empty?</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Table empty?</from>
+ <to>Table not empty</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Truncate tables action removes all rows from one or more tables in a relational database connection.
+The list of tables can be specified in the action or be taken from the result rows of a previous action.
+
+This sample creates and fills the table SAMPLE_TRUNCATE_TABLES, truncates it and checks that it is empty.
+The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>928</width>
+ <height>120</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/waitforfile/src/main/samples/actions/wait-for-file.hwf b/plugins/actions/waitforfile/src/main/samples/actions/wait-for-file.hwf
new file mode 100644
index 0000000000..b9748a1d66
--- /dev/null
+++ b/plugins/actions/waitforfile/src/main/samples/actions/wait-for-file.hwf
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>wait-for-file</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/wait-for-file/trigger.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>go</content>
+ <encoding>UTF-8</encoding>
+ <name>Write trigger file</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/wait-for-file/trigger.txt</filename>
+ <maximum_timeout>30</maximum_timeout>
+ <check_cycle_time>2</check_cycle_time>
+ <success_on_timeout>N</success_on_timeout>
+ <file_size_check>N</file_size_check>
+ <add_filename_result>N</add_filename_result>
+ <name>Wait for trigger file</name>
+ <description/>
+ <type>WAIT_FOR_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The trigger file arrived.</logmessage>
+ <name>File arrived</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>The trigger file did not arrive within 30 seconds.</logmessage>
+ <name>Timeout</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write trigger file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write trigger file</from>
+ <to>Wait for trigger file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Wait for trigger file</from>
+ <to>File arrived</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Wait for trigger file</from>
+ <to>Timeout</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Wait for file action waits until a file appears, checking every few seconds. It can also wait until the size of the file stops changing.
+Set a maximum timeout to make sure a workflow does not wait forever, and choose whether the action succeeds or fails when the timeout is reached.
+
+In a real workflow another process delivers the file. This sample writes ${java.io.tmpdir}/hop-samples/wait-for-file/trigger.txt itself, so the action finds it at the first check.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>156</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/waitforsql/src/main/samples/actions/wait-for-sql.hwf b/plugins/actions/waitforsql/src/main/samples/actions/wait-for-sql.hwf
new file mode 100644
index 0000000000..3d79056453
--- /dev/null
+++ b/plugins/actions/waitforsql/src/main/samples/actions/wait-for-sql.hwf
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>wait-for-sql</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <sql>CREATE TABLE IF NOT EXISTS PUBLIC.SAMPLE_WAIT_FOR_SQL
+(
+ id INT
+, name VARCHAR(50)
+);
+
+DELETE FROM PUBLIC.SAMPLE_WAIT_FOR_SQL;
+
+INSERT INTO PUBLIC.SAMPLE_WAIT_FOR_SQL VALUES
+(1, 'Apache Hop'),
+(2, 'Apache Beam'),
+(3, 'Apache Spark');</sql>
+ <connection>hop-samples</connection>
+ <useVariableSubstitution>N</useVariableSubstitution>
+ <sqlfromfile>N</sqlfromfile>
+ <sendOneStatement>N</sendOneStatement>
+ <name>Create and fill table</name>
+ <description/>
+ <type>SQL</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <clear_result_rows>Y</clear_result_rows>
+ <add_rows_result>N</add_rows_result>
+ <is_usevars>N</is_usevars>
+ <is_custom_sql>N</is_custom_sql>
+ <custom_sql/>
+ <connection>hop-samples</connection>
+ <tablename>SAMPLE_WAIT_FOR_SQL</tablename>
+ <schemaname>PUBLIC</schemaname>
+ <maximum_timeout>30</maximum_timeout>
+ <check_cycle_time>5</check_cycle_time>
+ <success_on_timeout>N</success_on_timeout>
+ <rows_count_value>3</rows_count_value>
+ <success_condition>rows_count_greater_equal</success_condition>
+ <name>Wait for 3 rows</name>
+ <description/>
+ <type>WAIT_FOR_SQL</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>SAMPLE_WAIT_FOR_SQL contains at least 3 rows.</logmessage>
+ <name>Rows arrived</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>The rows did not arrive within 30 seconds.</logmessage>
+ <name>Timeout</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Create and fill table</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create and fill table</from>
+ <to>Wait for 3 rows</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Wait for 3 rows</from>
+ <to>Rows arrived</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Wait for 3 rows</from>
+ <to>Timeout</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Wait for SQL action runs a query or counts the rows in a table at a regular interval, until the row count meets a condition or a timeout is reached.
+A typical use is waiting until another system has finished loading a table, or until a control table says a load is done.
+
+In a real workflow another process fills the table. This sample creates the table SAMPLE_WAIT_FOR_SQL itself,
+so the action finds the expected 3 rows at the first check.
+The hop-samples connection is an in-memory H2 database, so no database server is needed to run this sample.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>174</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/webserviceavailable/src/main/samples/actions/requires-setup/webservice-available.hwf b/plugins/actions/webserviceavailable/src/main/samples/actions/requires-setup/webservice-available.hwf
new file mode 100644
index 0000000000..6da64a5602
--- /dev/null
+++ b/plugins/actions/webserviceavailable/src/main/samples/actions/requires-setup/webservice-available.hwf
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>webservice-available</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <url>https://hop.apache.org</url>
+ <connectTimeOut>5000</connectTimeOut>
+ <readTimeOut>10000</readTimeOut>
+ <name>Website available?</name>
+ <description/>
+ <type>WEBSERVICE_AVAILABLE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>https://hop.apache.org is available.</logmessage>
+ <name>Available</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>https://hop.apache.org is not available.</logmessage>
+ <name>Not available</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>544</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Website available?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Website available?</from>
+ <to>Available</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Website available?</from>
+ <to>Not available</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Check if webservice is available action succeeds when a URL can be opened within the connect and read timeouts (in milliseconds).
+Use it to check that a REST API or website is up before calling it.
+
+This sample checks the Apache Hop website.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>120</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs internet access (or change the URL to a server in your network).
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>168</yloc>
+ <width>640</width>
+ <height>70</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/writetofile/src/main/samples/actions/write-to-file.hwf b/plugins/actions/writetofile/src/main/samples/actions/write-to-file.hwf
new file mode 100644
index 0000000000..1558e8ff09
--- /dev/null
+++ b/plugins/actions/writetofile/src/main/samples/actions/write-to-file.hwf
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>write-to-file</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/write-to-file/run.log</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Run log of workflow ${Internal.Workflow.Name}
+</content>
+ <encoding>UTF-8</encoding>
+ <name>Write header</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/write-to-file/run.log</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>Y</appendFile>
+ <content>Project home: ${PROJECT_HOME}
+</content>
+ <encoding>UTF-8</encoding>
+ <name>Append line</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Written to ${java.io.tmpdir}/hop-samples/write-to-file/run.log</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write header</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write header</from>
+ <to>Append line</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Append line</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Write to file action writes a piece of text to a file. Variables in the text are resolved, the parent folder can be created
+and the text can be appended to an existing file instead of replacing it.
+
+This sample creates ${java.io.tmpdir}/hop-samples/write-to-file/run.log with a header line and then appends a second line to it.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>138</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/xml/src/main/samples/actions/requires-setup/dtd-validator.hwf b/plugins/actions/xml/src/main/samples/actions/requires-setup/dtd-validator.hwf
new file mode 100644
index 0000000000..3e162d9557
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/actions/requires-setup/dtd-validator.hwf
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>dtd-validator</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <xmlfilename>${PROJECT_HOME}/files/xml-actions/orders.xml</xmlfilename>
+ <dtdfilename>${PROJECT_HOME}/files/xml-actions/orders.dtd</dtdfilename>
+ <dtdintern>N</dtdintern>
+ <name>Validate against DTD</name>
+ <description/>
+ <type>DTD_VALIDATOR</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>orders.xml matches the orders.dtd document type definition.</logmessage>
+ <name>Valid</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>orders.xml could not be validated against orders.dtd. Is XML_ALLOW_DOCTYPE_DECL set to Y?</logmessage>
+ <name>Invalid</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>544</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Validate against DTD</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Validate against DTD</from>
+ <to>Valid</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Validate against DTD</from>
+ <to>Invalid</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The DTD validator action validates an XML file against a Document Type Definition (DTD).
+The DTD can be a separate file, like in this sample, or be included in the XML file itself (the "Intern DTD" option).
+
+This sample validates ${PROJECT_HOME}/files/xml-actions/orders.xml against ${PROJECT_HOME}/files/xml-actions/orders.dtd.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>138</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: DTD validation needs DOCTYPE declarations, which Hop does not allow by default to protect against XML external entity (XXE) attacks.
+Set the XML_ALLOW_DOCTYPE_DECL variable to Y in the system properties of hop-config.json (or use hop-conf) and restart Hop before running this sample.
+Only allow DOCTYPE declarations when you trust the XML files you process.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>186</yloc>
+ <width>640</width>
+ <height>100</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/xml/src/main/samples/actions/xml-well-formed.hwf b/plugins/actions/xml/src/main/samples/actions/xml-well-formed.hwf
new file mode 100644
index 0000000000..b6b954127d
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/actions/xml-well-formed.hwf
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>xml-well-formed</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <include_subfolders>N</include_subfolders>
+ <fields>
+ <field>
+ <source_filefolder>${PROJECT_HOME}/files/xml-actions</source_filefolder>
+ <wildcard>.*\.xml</wildcard>
+ </field>
+ </fields>
+ <nr_errors_less_than>10</nr_errors_less_than>
+ <success_condition>success_if_no_errors</success_condition>
+ <resultfilenames>all_filenames</resultfilenames>
+ <name>XML files well formed?</name>
+ <description/>
+ <type>XML_WELL_FORMED</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>All XML files are well formed.</logmessage>
+ <name>All well formed</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>At least one XML file is not well formed.</logmessage>
+ <name>Malformed XML</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>XML files well formed?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>XML files well formed?</from>
+ <to>All well formed</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>XML files well formed?</from>
+ <to>Malformed XML</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Check if XML file is well formed action checks that files are syntactically correct XML: one root element, properly nested and closed tags, quoted attributes, ...
+It does not check the content against a schema, use the XSD or DTD validator actions for that.
+
+This sample checks all .xml files in ${PROJECT_HOME}/files/xml-actions.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>120</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/xml/src/main/samples/actions/xsd-validator.hwf b/plugins/actions/xml/src/main/samples/actions/xsd-validator.hwf
new file mode 100644
index 0000000000..e864be39f0
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/actions/xsd-validator.hwf
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>xsd-validator</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <xsdSource>filename</xsdSource>
+ <xmlFilename>${PROJECT_HOME}/files/xml-actions/orders.xml</xmlFilename>
+ <xsdFilename>${PROJECT_HOME}/files/xml-actions/orders.xsd</xsdFilename>
+ <allowExternalEntities>N</allowExternalEntities>
+ <name>Validate against XSD</name>
+ <description/>
+ <type>XSD_VALIDATOR</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>orders.xml matches the orders.xsd schema.</logmessage>
+ <name>Valid</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>orders.xml does not match the orders.xsd schema.</logmessage>
+ <name>Invalid</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Validate against XSD</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Validate against XSD</from>
+ <to>Valid</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Validate against XSD</from>
+ <to>Invalid</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The XSD validator action validates an XML file against an XML schema definition (XSD).
+The schema can be specified as a file, or be taken from the schema location in the XML document.
+
+This sample validates ${PROJECT_HOME}/files/xml-actions/orders.xml against ${PROJECT_HOME}/files/xml-actions/orders.xsd.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>120</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/xml/src/main/samples/actions/xsl-transformation.hwf b/plugins/actions/xml/src/main/samples/actions/xsl-transformation.hwf
new file mode 100644
index 0000000000..7fd574c4d0
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/actions/xsl-transformation.hwf
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>xsl-transformation</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/xslt</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove work folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <foldername>${java.io.tmpdir}/hop-samples/xslt</foldername>
+ <fail_of_folder_exists>N</fail_of_folder_exists>
+ <name>Create work folder</name>
+ <description/>
+ <type>CREATE_FOLDER</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <xmlfilename>${PROJECT_HOME}/files/xml-actions/orders.xml</xmlfilename>
+ <xslfilename>${PROJECT_HOME}/files/xml-actions/orders-to-csv.xsl</xslfilename>
+ <outputfilename>${java.io.tmpdir}/hop-samples/xslt/orders.csv</outputfilename>
+ <ifFileExists>1</ifFileExists>
+ <name>Orders to CSV</name>
+ <description/>
+ <type>XSLT</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/xslt/orders.csv</filename>
+ <name>orders.csv created?</name>
+ <description/>
+ <type>FILE_EXISTS</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The orders were written to ${java.io.tmpdir}/hop-samples/xslt/orders.csv</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <message>orders.csv was not created</message>
+ <loglevel>Error</loglevel>
+ <name>No output</name>
+ <description/>
+ <type>ABORT</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove work folder</from>
+ <to>Create work folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create work folder</from>
+ <to>Orders to CSV</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Orders to CSV</from>
+ <to>orders.csv created?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>orders.csv created?</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>orders.csv created?</from>
+ <to>No output</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The XSL transformation action transforms an XML file with an XSL stylesheet and writes the result to a file.
+
+This sample transforms ${PROJECT_HOME}/files/xml-actions/orders.xml into the CSV file ${java.io.tmpdir}/hop-samples/xslt/orders.csv with the orders-to-csv.xsl stylesheet.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1120</width>
+ <height>102</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders-to-csv.xsl b/plugins/actions/xml/src/main/samples/files/xml-actions/orders-to-csv.xsl
new file mode 100644
index 0000000000..6b90fabeb1
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders-to-csv.xsl
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ <xsl:output method="text" encoding="UTF-8"/>
+ <xsl:template match="/orders">
+ <xsl:text>id,customer,amount </xsl:text>
+ <xsl:for-each select="order">
+ <xsl:value-of select="@id"/>,<xsl:value-of select="customer"/>,<xsl:value-of select="amount"/>
+ <xsl:text> </xsl:text>
+ </xsl:for-each>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders.dtd b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.dtd
new file mode 100644
index 0000000000..b81e1d0849
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.dtd
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<!ELEMENT orders (order+)>
+<!ELEMENT order (customer, amount)>
+<!ATTLIST order id CDATA #REQUIRED>
+<!ELEMENT customer (#PCDATA)>
+<!ELEMENT amount (#PCDATA)>
diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xml b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xml
new file mode 100644
index 0000000000..f10148b3ea
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<orders>
+ <order id="1">
+ <customer>Apache Hop</customer>
+ <amount>100.50</amount>
+ </order>
+ <order id="2">
+ <customer>Apache Beam</customer>
+ <amount>42.00</amount>
+ </order>
+</orders>
diff --git a/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xsd b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xsd
new file mode 100644
index 0000000000..60ef80bf54
--- /dev/null
+++ b/plugins/actions/xml/src/main/samples/files/xml-actions/orders.xsd
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="orders">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="order" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="customer" type="xs:string"/>
+ <xs:element name="amount" type="xs:decimal"/>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:integer" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/plugins/databases/as400/src/assembly/assembly.xml b/plugins/databases/as400/src/assembly/assembly.xml
index d71020ec0a..712f1ec098 100644
--- a/plugins/databases/as400/src/assembly/assembly.xml
+++ b/plugins/databases/as400/src/assembly/assembly.xml
@@ -31,6 +31,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<componentDescriptors>
<componentDescriptor>${maven.multiModuleProjectDirectory}/assemblies/shared/hop-plugin-libs.xml</componentDescriptor>
diff --git a/plugins/databases/as400/src/main/samples/actions/requires-setup/as400-command.hwf b/plugins/databases/as400/src/main/samples/actions/requires-setup/as400-command.hwf
new file mode 100644
index 0000000000..590eab35e0
--- /dev/null
+++ b/plugins/databases/as400/src/main/samples/actions/requires-setup/as400-command.hwf
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>as400-command</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <server>${AS400_SERVER}</server>
+ <user>${AS400_USER}</user>
+ <password>${AS400_PASSWORD}</password>
+ <command>CALL PGM(MYLIB/MYPGM)</command>
+ <proxyHost/>
+ <proxyPort/>
+ <name>Run CL command</name>
+ <description/>
+ <type>AS400Command</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The AS/400 command completed.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Run CL command</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Run CL command</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The AS/400 Command action runs a CL command on an IBM i (AS/400) system, for example to call a program or submit a job.
+The action succeeds when the command completes successfully.
+
+This sample calls the program MYPGM in library MYLIB.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>120</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs an IBM i (AS/400) system. Set the AS400_SERVER, AS400_USER and AS400_PASSWORD variables
+(for example in an environment configuration file) and change the command before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>168</yloc>
+ <width>640</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/databases/mssqlnative/src/assembly/assembly.xml b/plugins/databases/mssqlnative/src/assembly/assembly.xml
index 3c2ca835b4..2efd1cd2dc 100644
--- a/plugins/databases/mssqlnative/src/assembly/assembly.xml
+++ b/plugins/databases/mssqlnative/src/assembly/assembly.xml
@@ -36,6 +36,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<fileSets>
diff --git a/plugins/databases/mssqlnative/src/main/samples/actions/requires-setup/mssql-bulk-load.hwf b/plugins/databases/mssqlnative/src/main/samples/actions/requires-setup/mssql-bulk-load.hwf
new file mode 100644
index 0000000000..755f5dd339
--- /dev/null
+++ b/plugins/databases/mssqlnative/src/main/samples/actions/requires-setup/mssql-bulk-load.hwf
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>mssql-bulk-load</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <schemaname>dbo</schemaname>
+ <tablename>customers</tablename>
+ <filename>/data/customers.csv</filename>
+ <datafiletype>char</datafiletype>
+ <fieldterminator>,</fieldterminator>
+ <lineterminated/>
+ <codepage>RAW</codepage>
+ <specificcodepage/>
+ <startfile>2</startfile>
+ <endfile>0</endfile>
+ <orderby/>
+ <addfiletoresult>N</addfiletoresult>
+ <formatfilename/>
+ <firetriggers>N</firetriggers>
+ <checkconstraints>N</checkconstraints>
+ <keepnulls>N</keepnulls>
+ <tablock>N</tablock>
+ <errorfilename/>
+ <adddatetime>N</adddatetime>
+ <orderdirection>Asc</orderdirection>
+ <maxerrors>0</maxerrors>
+ <batchsize>0</batchsize>
+ <rowsperbatch>0</rowsperbatch>
+ <keepidentity>N</keepidentity>
+ <truncate>Y</truncate>
+ <connection>mssql</connection>
+ <name>Bulk load customers</name>
+ <description/>
+ <type>MSSQL_BULK_LOAD</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>customers loaded.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Bulk load customers</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Bulk load customers</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The SQL Server bulk loader action loads a data file into a SQL Server table with the BULK INSERT statement. It is much faster than inserting rows one by one.
+Note that SQL Server reads the file itself: the file has to be accessible from the database server, not only from the machine running Hop.
+
+This sample truncates the table dbo.customers and loads the comma separated file /data/customers.csv, skipping the header line.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>156</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a SQL Server database and a relational database connection called "mssql" in the project metadata,
+a dbo.customers table and a data file the database server can read. Create those before running this sample.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>204</yloc>
+ <width>640</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/databases/mysql/src/assembly/assembly.xml b/plugins/databases/mysql/src/assembly/assembly.xml
index 644ac1323b..47e6d59630 100644
--- a/plugins/databases/mysql/src/assembly/assembly.xml
+++ b/plugins/databases/mysql/src/assembly/assembly.xml
@@ -31,6 +31,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<fileSets>
diff --git a/plugins/databases/mysql/src/main/samples/actions/requires-setup/mysql-bulk-file-and-load.hwf b/plugins/databases/mysql/src/main/samples/actions/requires-setup/mysql-bulk-file-and-load.hwf
new file mode 100644
index 0000000000..ceb4ca3a26
--- /dev/null
+++ b/plugins/databases/mysql/src/main/samples/actions/requires-setup/mysql-bulk-file-and-load.hwf
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>mysql-bulk-file-and-load</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <tablename>customers</tablename>
+ <schemaname/>
+ <filename>/tmp/customers.csv</filename>
+ <separator>,</separator>
+ <enclosed>"</enclosed>
+ <lineterminated>\n</lineterminated>
+ <limitlines>0</limitlines>
+ <listcolumn/>
+ <highpriority>N</highpriority>
+ <optionenclosed>Y</optionenclosed>
+ <outdumpvalue>0</outdumpvalue>
+ <iffileexists>0</iffileexists>
+ <addfiletoresult>N</addfiletoresult>
+ <connection>mysql</connection>
+ <name>Export customers</name>
+ <description/>
+ <type>MYSQL_BULK_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <schemaname/>
+ <tablename>customers_copy</tablename>
+ <filename>${PROJECT_HOME}/files/customers.csv</filename>
+ <separator>,</separator>
+ <enclosed>"</enclosed>
+ <escaped>\\</escaped>
+ <linestarted/>
+ <lineterminated>\n</lineterminated>
+ <ignorelines>1</ignorelines>
+ <replacedata>Y</replacedata>
+ <listattribut/>
+ <localinfile>Y</localinfile>
+ <prorityvalue>0</prorityvalue>
+ <addfiletoresult>N</addfiletoresult>
+ <connection>mysql</connection>
+ <name>Load customers_copy</name>
+ <description/>
+ <type>MYSQL_BULK_LOAD</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>customers exported, customers_copy loaded.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Export customers</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Export customers</from>
+ <to>Load customers_copy</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Load customers_copy</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The MySQL bulk file action exports a table to a file with SELECT ... INTO OUTFILE. The file is written by the database server, on the database server.
+The MySQL bulk load action loads a file into a table with LOAD DATA [LOCAL] INFILE. With the "Local" option the file is read from the machine running Hop.
+
+This sample exports the table customers to /tmp/customers.csv on the database server, and loads ${PROJECT_HOME}/files/customers.csv into the table customers_copy.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>156</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a MySQL database and a relational database connection called "mysql" in the project metadata,
+the customers and customers_copy tables, and the database user needs the FILE privilege. Create those before running this sample.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>204</yloc>
+ <width>736</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/databases/snowflake/src/assembly/assembly.xml b/plugins/databases/snowflake/src/assembly/assembly.xml
index 7765817016..2cb1e65e46 100644
--- a/plugins/databases/snowflake/src/assembly/assembly.xml
+++ b/plugins/databases/snowflake/src/assembly/assembly.xml
@@ -31,6 +31,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<fileSets>
diff --git a/plugins/databases/snowflake/src/main/samples/actions/requires-setup/snowflake-warehouse-manager.hwf b/plugins/databases/snowflake/src/main/samples/actions/requires-setup/snowflake-warehouse-manager.hwf
new file mode 100644
index 0000000000..6982ae0c4d
--- /dev/null
+++ b/plugins/databases/snowflake/src/main/samples/actions/requires-setup/snowflake-warehouse-manager.hwf
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>snowflake-warehouse-manager</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection>snowflake</connection>
+ <managementAction>create</managementAction>
+ <warehouseName>HOP_SAMPLES_WH</warehouseName>
+ <replace>N</replace>
+ <failIfExists>N</failIfExists>
+ <failIfNotExists>N</failIfNotExists>
+ <warehouseSize>XSMALL</warehouseSize>
+ <warehouseType>Standard</warehouseType>
+ <maxClusterCount>1</maxClusterCount>
+ <minClusterCount>1</minClusterCount>
+ <autoSuspend>60</autoSuspend>
+ <autoResume>N</autoResume>
+ <initiallySuspended>Y</initiallySuspended>
+ <resourceMonitor/>
+ <comment>Created by the Apache Hop samples</comment>
+ <name>Create warehouse</name>
+ <description/>
+ <type>SnowflakeWarehouseManager</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection>snowflake</connection>
+ <managementAction>resume</managementAction>
+ <warehouseName>HOP_SAMPLES_WH</warehouseName>
+ <replace>N</replace>
+ <failIfExists>N</failIfExists>
+ <failIfNotExists>Y</failIfNotExists>
+ <autoResume>N</autoResume>
+ <initiallySuspended>N</initiallySuspended>
+ <name>Resume warehouse</name>
+ <description/>
+ <type>SnowflakeWarehouseManager</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection>snowflake</connection>
+ <managementAction>suspend</managementAction>
+ <warehouseName>HOP_SAMPLES_WH</warehouseName>
+ <replace>N</replace>
+ <failIfExists>N</failIfExists>
+ <failIfNotExists>Y</failIfNotExists>
+ <autoResume>N</autoResume>
+ <initiallySuspended>N</initiallySuspended>
+ <name>Suspend warehouse</name>
+ <description/>
+ <type>SnowflakeWarehouseManager</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>HOP_SAMPLES_WH was resumed and suspended.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Create warehouse</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create warehouse</from>
+ <to>Resume warehouse</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Resume warehouse</from>
+ <to>Suspend warehouse</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Suspend warehouse</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Snowflake warehouse manager action creates, drops, resumes, suspends or alters a Snowflake virtual warehouse.
+A typical use is resuming a warehouse before a load and suspending it afterwards, so you only pay for what you use.
+
+This sample creates the HOP_SAMPLES_WH warehouse (if it does not exist yet), resumes it and suspends it again.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>928</width>
+ <height>156</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a Snowflake account and a Snowflake relational database connection called "snowflake" in the project metadata,
+with a role that can create and operate warehouses. Create the connection before running this sample.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>204</yloc>
+ <width>928</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/misc/documentation/src/main/samples/actions/build-documentation.hwf b/plugins/misc/documentation/src/main/samples/actions/build-documentation.hwf
new file mode 100644
index 0000000000..eafbd58532
--- /dev/null
+++ b/plugins/misc/documentation/src/main/samples/actions/build-documentation.hwf
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>build-documentation</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/documentation</name>
+ </field>
+ </fields>
+ <limit_folders>10</limit_folders>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Remove output folder</name>
+ <description/>
+ <type>DELETE_FOLDERS</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <targetParentFolder>${java.io.tmpdir}/hop-samples/documentation</targetParentFolder>
+ <includingParameters>Y</includingParameters>
+ <includingNotes>Y</includingNotes>
+ <includingMetadata>Y</includingMetadata>
+ <generateHtml>Y</generateHtml>
+ <removeMarkdown>N</removeMarkdown>
+ <name>Build documentation</name>
+ <description/>
+ <type>DOCUMENTATION</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Documentation written to ${java.io.tmpdir}/hop-samples/documentation</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Remove output folder</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Remove output folder</from>
+ <to>Build documentation</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Build documentation</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Documentation action generates documentation for the current project: an overview of all pipelines and workflows with their
+descriptions, parameters and notes, and optionally of the project metadata. It writes Markdown and, optionally, HTML.
+
+This sample documents the samples project in ${java.io.tmpdir}/hop-samples/documentation. Open index.html in that folder in a browser.
+Write the documentation to a folder outside the project, so it does not document its own output the next time it runs.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>736</width>
+ <height>192</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/misc/mail/src/main/samples/actions/mail-validator.hwf b/plugins/misc/mail/src/main/samples/actions/mail-validator.hwf
new file mode 100644
index 0000000000..36a625e5e0
--- /dev/null
+++ b/plugins/misc/mail/src/main/samples/actions/mail-validator.hwf
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>mail-validator</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <smtpCheck>N</smtpCheck>
+ <timeout>0</timeout>
+ <defaultSMTP/>
+ <emailSender/>
+ <emailAddress>dev@hop.apache.org users@hop.apache.org</emailAddress>
+ <name>Valid address?</name>
+ <description/>
+ <type>MAIL_VALIDATOR</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>All addresses are valid.</logmessage>
+ <name>Valid</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>512</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>At least one address is invalid.</logmessage>
+ <name>Invalid</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Valid address?</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Valid address?</from>
+ <to>Valid</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Valid address?</from>
+ <to>Invalid</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Mail validator action checks email addresses. Separate multiple addresses with a space.
+Without the SMTP check, only the format of the addresses is checked. With the SMTP check enabled, the action also looks up the mail server of the domain
+and asks it whether the address exists. That deep check needs network access and is disabled in this sample.
+
+This sample checks two valid addresses. An invalid address takes the failure (red) hop and counts as an error in the workflow result.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>156</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/misc/mail/src/main/samples/actions/requires-setup/mail-send-and-receive.hwf b/plugins/misc/mail/src/main/samples/actions/requires-setup/mail-send-and-receive.hwf
new file mode 100644
index 0000000000..1e00c7b76d
--- /dev/null
+++ b/plugins/misc/mail/src/main/samples/actions/requires-setup/mail-send-and-receive.hwf
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>mail-send-and-receive</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/mail/report.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Report generated by Apache Hop</content>
+ <encoding>UTF-8</encoding>
+ <name>Write attachment</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <arg_from_previous>N</arg_from_previous>
+ <delete_all_before>N</delete_all_before>
+ <include_subfolders>N</include_subfolders>
+ <fields>
+ <field>
+ <name>${java.io.tmpdir}/hop-samples/mail</name>
+ <filemask>report\.txt</filemask>
+ </field>
+ </fields>
+ <name>Add to result filenames</name>
+ <description/>
+ <type>ADD_RESULT_FILENAMES</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <server>${MAIL_SMTP_SERVER}</server>
+ <destination>${MAIL_TO}</destination>
+ <destinationCc/>
+ <destinationBCc/>
+ <replyto>${MAIL_USER}</replyto>
+ <replytoname>Apache Hop</replytoname>
+ <subject>Report from Apache Hop</subject>
+ <include_date>N</include_date>
+ <contact_persion/>
+ <contact_phone/>
+ <comment>Please find the report attached.</comment>
+ <include_files>Y</include_files>
+ <fileTypes>
+ <fileType>GENERAL</fileType>
+ </fileTypes>
+ <zip_files>N</zip_files>
+ <zip_name/>
+ <use_auth>Y</use_auth>
+ <usexoauth2>N</usexoauth2>
+ <auth_user>${MAIL_USER}</auth_user>
+ <auth_password>${MAIL_PASSWORD}</auth_password>
+ <only_comment>N</only_comment>
+ <use_HTML>N</use_HTML>
+ <use_secure_auth>Y</use_secure_auth>
+ <use_Priority>N</use_Priority>
+ <trusted_hosts/>
+ <check_server_identity>Y</check_server_identity>
+ <port>${MAIL_SMTP_PORT}</port>
+ <secureconnectiontype>TLS</secureconnectiontype>
+ <encoding>UTF-8</encoding>
+ <replyToAddresses/>
+ <embeddedimages/>
+ <connectionName/>
+ <name>Mail</name>
+ <description/>
+ <type>MAIL</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <actiontype>get</actiontype>
+ <conditionreceiveddate>ignore</conditionreceiveddate>
+ <valueimaplist>imaplistall</valueimaplist>
+ <aftergetimap>nothing</aftergetimap>
+ <servername>${MAIL_IMAP_SERVER}</servername>
+ <username>${MAIL_USER}</username>
+ <password>${MAIL_PASSWORD}</password>
+ <usessl>Y</usessl>
+ <sslport>993</sslport>
+ <usexoauth2>N</usexoauth2>
+ <useproxy>N</useproxy>
+ <outputdirectory>${java.io.tmpdir}/hop-samples/mail/inbox</outputdirectory>
+ <filenamepattern>name_{SYS|hhmmss_MMddyyyy|}_#IdFile#.mail</filenamepattern>
+ <retrievemails>0</retrievemails>
+ <delete>N</delete>
+ <protocol>IMAP</protocol>
+ <saveattachment>Y</saveattachment>
+ <savemessage>Y</savemessage>
+ <usedifferentfolderforattachment>N</usedifferentfolderforattachment>
+ <imapfirstmails>0</imapfirstmails>
+ <imapfolder>INBOX</imapfolder>
+ <nottermsendersearch>N</nottermsendersearch>
+ <nottermbodysearch>N</nottermbodysearch>
+ <nottermsubjectsearch>N</nottermsubjectsearch>
+ <nottermreceipientsearh>N</nottermreceipientsearh>
+ <nottermreceiveddatesearch>N</nottermreceiveddatesearch>
+ <includesubfolders>N</includesubfolders>
+ <createmovetofolder>N</createmovetofolder>
+ <createlocalfolder>Y</createlocalfolder>
+ <name>Get mails</name>
+ <description/>
+ <type>GET_POP</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Mail sent, inbox downloaded to ${java.io.tmpdir}/hop-samples/mail/inbox</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write attachment</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write attachment</from>
+ <to>Add to result filenames</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Add to result filenames</from>
+ <to>Mail</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Mail</from>
+ <to>Get mails</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Get mails</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Mail action sends an email, optionally with the result files of the workflow as attachments. It can use a server and credentials,
+or a mail server connection from the project metadata.
+
+The Get mails (POP3/IMAP) action reads emails from a mailbox and saves the messages and/or attachments to a folder. It can also delete or move the messages it read.
+
+This sample sends an email with a file attached and then downloads the messages of the inbox to ${java.io.tmpdir}/hop-samples/mail/inbox.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1120</width>
+ <height>192</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a mail server. Set the MAIL_SMTP_SERVER, MAIL_SMTP_PORT, MAIL_IMAP_SERVER, MAIL_USER, MAIL_PASSWORD and MAIL_TO variables
+(for example in an environment configuration file) before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>240</yloc>
+ <width>1120</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/misc/testing/src/assembly/assembly.xml b/plugins/misc/testing/src/assembly/assembly.xml
index 281c2ac2aa..92412e4537 100644
--- a/plugins/misc/testing/src/assembly/assembly.xml
+++ b/plugins/misc/testing/src/assembly/assembly.xml
@@ -31,6 +31,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<fileSets>
<fileSet>
diff --git a/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests-pipeline.hpl b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests-pipeline.hpl
new file mode 100644
index 0000000000..084b372d3f
--- /dev/null
+++ b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests-pipeline.hpl
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+ <info>
+ <pipeline_version/>
+ <capture_transform_performance>N</capture_transform_performance>
+ <transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+ <transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+ <pipeline_status>0</pipeline_status>
+ <parameters/>
+ <name>run-pipeline-tests-pipeline</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ </info>
+ <transform>
+ <type>DataGrid</type>
+ <name>Order lines</name>
+ <fields>
+ <field>
+ <currency/>
+ <decimal/>
+ <group/>
+ <name>product</name>
+ <type>String</type>
+ <format/>
+ <length>-1</length>
+ <precision>-1</precision>
+ <set_empty_string>N</set_empty_string>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <group/>
+ <name>quantity</name>
+ <type>Integer</type>
+ <format/>
+ <length>-1</length>
+ <precision>-1</precision>
+ <set_empty_string>N</set_empty_string>
+ </field>
+ <field>
+ <currency/>
+ <decimal/>
+ <group/>
+ <name>price</name>
+ <type>Integer</type>
+ <format/>
+ <length>-1</length>
+ <precision>-1</precision>
+ <set_empty_string>N</set_empty_string>
+ </field>
+ </fields>
+ <data>
+ <line>
+ <item>Hop T-shirt</item>
+ <item>2</item>
+ <item>20</item>
+ </line>
+ <line>
+ <item>Hop mug</item>
+ <item>3</item>
+ <item>10</item>
+ </line>
+ <line>
+ <item>Hop sticker</item>
+ <item>10</item>
+ <item>1</item>
+ </line>
+ </data>
+ <distribute>Y</distribute>
+ <copies>1</copies>
+ <GUI>
+ <xloc>80</xloc>
+ <yloc>176</yloc>
+ </GUI>
+ <description/>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ </transform>
+ <transform>
+ <type>Calculator</type>
+ <name>Line total</name>
+ <calculation>
+ <field_name>total</field_name>
+ <calc_type>MULTIPLY</calc_type>
+ <field_a>quantity</field_a>
+ <field_b>price</field_b>
+ <value_type>Integer</value_type>
+ <value_length>-1</value_length>
+ <value_precision>-1</value_precision>
+ <remove>N</remove>
+ </calculation>
+ <failIfNoFile>Y</failIfNoFile>
+ <distribute>Y</distribute>
+ <copies>1</copies>
+ <GUI>
+ <xloc>272</xloc>
+ <yloc>176</yloc>
+ </GUI>
+ <description/>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ </transform>
+ <transform>
+ <type>Dummy</type>
+ <name>Output</name>
+ <distribute>Y</distribute>
+ <copies>1</copies>
+ <GUI>
+ <xloc>464</xloc>
+ <yloc>176</yloc>
+ </GUI>
+ <description/>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ </transform>
+ <order>
+ <hop>
+ <from>Order lines</from>
+ <to>Line total</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Line total</from>
+ <to>Output</to>
+ <enabled>Y</enabled>
+ </hop>
+ </order>
+ <notepads>
+ <notepad>
+ <note>This pipeline is tested by the run-pipeline-tests-unit unit test, which is executed by the run-pipeline-tests workflow.
+The unit test replaces the rows of the Order lines data grid with the run-pipeline-tests-input data set
+and compares the rows arriving in Output with the run-pipeline-tests-golden data set.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>90</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+ <transform_error_handling/>
+</pipeline>
diff --git a/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests.hwf b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests.hwf
new file mode 100644
index 0000000000..753b9127ef
--- /dev/null
+++ b/plugins/misc/testing/src/main/samples/actions/run-pipeline-tests.hwf
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>run-pipeline-tests</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <test_names>
+ <test_name>
+ <name>run-pipeline-tests-unit</name>
+ </test_name>
+ </test_names>
+ <name>Run unit tests</name>
+ <description/>
+ <type>RunPipelineTests</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>All unit tests passed.</logmessage>
+ <name>All tests passed</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>256</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>At least one unit test failed.</logmessage>
+ <name>Tests failed</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Run unit tests</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Run unit tests</from>
+ <to>All tests passed</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Run unit tests</from>
+ <to>Tests failed</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Run pipeline unit tests action runs one or more pipeline unit tests and fails when one of them fails.
+Use it to run your unit tests from a workflow, for example in a CI/CD pipeline with hop-run.
+
+This sample runs the run-pipeline-tests-unit test. That test replaces the data grid of run-pipeline-tests-pipeline.hpl with the
+run-pipeline-tests-input data set, and compares the output with the run-pipeline-tests-golden data set.
+Open the pipeline in Hop Gui and select the unit test to see how it is set up.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>156</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-golden.csv b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-golden.csv
new file mode 100644
index 0000000000..b48c5b4803
--- /dev/null
+++ b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-golden.csv
@@ -0,0 +1,3 @@
+product,quantity,price,total
+Hop hoodie,1,50,50
+Hop mug,4,10,40
diff --git a/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-input.csv b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-input.csv
new file mode 100644
index 0000000000..41117151d5
--- /dev/null
+++ b/plugins/misc/testing/src/main/samples/datasets/run-pipeline-tests-input.csv
@@ -0,0 +1,3 @@
+product,quantity,price
+Hop hoodie,1,50
+Hop mug,4,10
diff --git a/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-golden.json b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-golden.json
new file mode 100644
index 0000000000..dae99a2f80
--- /dev/null
+++ b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-golden.json
@@ -0,0 +1,40 @@
+{
+ "base_filename": "run-pipeline-tests-golden.csv",
+ "name": "run-pipeline-tests-golden",
+ "description": "",
+ "dataset_fields": [
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_format": "",
+ "field_name": "product"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 5,
+ "field_precision": -1,
+ "field_format": "",
+ "field_name": "quantity"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 5,
+ "field_precision": -1,
+ "field_format": "",
+ "field_name": "price"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 5,
+ "field_precision": -1,
+ "field_format": "",
+ "field_name": "total"
+ }
+ ],
+ "folder_name": ""
+}
\ No newline at end of file
diff --git a/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-input.json b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-input.json
new file mode 100644
index 0000000000..f329999ff6
--- /dev/null
+++ b/plugins/misc/testing/src/main/samples/metadata/dataset/run-pipeline-tests-input.json
@@ -0,0 +1,32 @@
+{
+ "base_filename": "run-pipeline-tests-input.csv",
+ "name": "run-pipeline-tests-input",
+ "description": "",
+ "dataset_fields": [
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_format": "",
+ "field_name": "product"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 5,
+ "field_precision": -1,
+ "field_format": "",
+ "field_name": "quantity"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 5,
+ "field_precision": -1,
+ "field_format": "",
+ "field_name": "price"
+ }
+ ],
+ "folder_name": ""
+}
\ No newline at end of file
diff --git a/plugins/misc/testing/src/main/samples/metadata/unit-test/run-pipeline-tests-unit.json b/plugins/misc/testing/src/main/samples/metadata/unit-test/run-pipeline-tests-unit.json
new file mode 100644
index 0000000000..24638bda94
--- /dev/null
+++ b/plugins/misc/testing/src/main/samples/metadata/unit-test/run-pipeline-tests-unit.json
@@ -0,0 +1,62 @@
+{
+ "variableValues": [],
+ "database_replacements": [],
+ "autoOpening": true,
+ "basePath": "",
+ "golden_data_sets": [
+ {
+ "field_mappings": [
+ {
+ "transform_field": "product",
+ "data_set_field": "product"
+ },
+ {
+ "transform_field": "quantity",
+ "data_set_field": "quantity"
+ },
+ {
+ "transform_field": "price",
+ "data_set_field": "price"
+ },
+ {
+ "transform_field": "total",
+ "data_set_field": "total"
+ }
+ ],
+ "field_order": [
+ "product"
+ ],
+ "transform_name": "Output",
+ "data_set_name": "run-pipeline-tests-golden"
+ }
+ ],
+ "input_data_sets": [
+ {
+ "field_mappings": [
+ {
+ "transform_field": "product",
+ "data_set_field": "product"
+ },
+ {
+ "transform_field": "quantity",
+ "data_set_field": "quantity"
+ },
+ {
+ "transform_field": "price",
+ "data_set_field": "price"
+ }
+ ],
+ "field_order": [
+ "product"
+ ],
+ "transform_name": "Order lines",
+ "data_set_name": "run-pipeline-tests-input"
+ }
+ ],
+ "name": "run-pipeline-tests-unit",
+ "description": "Unit test sample, executed by the run-pipeline-tests workflow",
+ "trans_test_tweaks": [],
+ "persist_filename": "",
+ "pipeline_filename": "./actions/run-pipeline-tests-pipeline.hpl",
+ "test_type": "UNIT_TEST"
+}
\ No newline at end of file
diff --git a/plugins/tech/cassandra/src/assembly/assembly.xml b/plugins/tech/cassandra/src/assembly/assembly.xml
index c4685a0127..76e8307b32 100644
--- a/plugins/tech/cassandra/src/assembly/assembly.xml
+++ b/plugins/tech/cassandra/src/assembly/assembly.xml
@@ -30,6 +30,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<fileSets>
diff --git a/plugins/tech/cassandra/src/main/samples/actions/requires-setup/cassandra-exec-cql.hwf b/plugins/tech/cassandra/src/main/samples/actions/requires-setup/cassandra-exec-cql.hwf
new file mode 100644
index 0000000000..6f6afd9eea
--- /dev/null
+++ b/plugins/tech/cassandra/src/main/samples/actions/requires-setup/cassandra-exec-cql.hwf
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>cassandra-exec-cql</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection>cassandra</connection>
+ <script>CREATE KEYSPACE IF NOT EXISTS hop_samples
+ WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
+
+CREATE TABLE IF NOT EXISTS hop_samples.customers (
+ id int PRIMARY KEY,
+ name text
+);</script>
+ <replace_variables>N</replace_variables>
+ <name>Create keyspace and table</name>
+ <description/>
+ <type>CASSANDRA_EXEC_CQL</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Keyspace hop_samples and table customers are ready.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Create keyspace and table</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create keyspace and table</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Cassandra Exec Cql action executes CQL statements against a Cassandra (or compatible) database.
+
+This sample creates a keyspace and a table.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>84</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a Cassandra cluster and a Cassandra connection called "cassandra" in the project metadata.
+Create the connection (pointing to your cluster) before running this sample.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>132</yloc>
+ <width>640</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/tech/databricks/src/assembly/assembly.xml b/plugins/tech/databricks/src/assembly/assembly.xml
index 4133e9dd45..35a726456c 100644
--- a/plugins/tech/databricks/src/assembly/assembly.xml
+++ b/plugins/tech/databricks/src/assembly/assembly.xml
@@ -31,6 +31,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<componentDescriptors>
diff --git a/plugins/tech/databricks/src/main/samples/actions/requires-setup/databricks-job-run-and-wait.hwf b/plugins/tech/databricks/src/main/samples/actions/requires-setup/databricks-job-run-and-wait.hwf
new file mode 100644
index 0000000000..202e70a19d
--- /dev/null
+++ b/plugins/tech/databricks/src/main/samples/actions/requires-setup/databricks-job-run-and-wait.hwf
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>databricks-job-run-and-wait</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection>databricks</connection>
+ <run_mode>RUN_EXISTING</run_mode>
+ <job_id>123456789</job_id>
+ <submit_json/>
+ <fat_jar/>
+ <pipeline_file/>
+ <run_configuration/>
+ <dbfs_base>dbfs:/FileStore/hop</dbfs_base>
+ <upload_project_package>N</upload_project_package>
+ <project_home/>
+ <project_package_file/>
+ <environment_config_file/>
+ <cluster_id/>
+ <new_cluster_spark_version/>
+ <new_cluster_node_type/>
+ <new_cluster_num_workers>1</new_cluster_num_workers>
+ <new_cluster_json/>
+ <environment_key/>
+ <environment_client/>
+ <job_name/>
+ <update_existing_job>N</update_existing_job>
+ <wait_mode>FIRE_AND_FORGET</wait_mode>
+ <timeout_seconds>3600</timeout_seconds>
+ <poll_seconds>15</poll_seconds>
+ <var_job_id>DatabricksJobId</var_job_id>
+ <var_run_id>DatabricksRunId</var_run_id>
+ <var_status>DatabricksStatus</var_status>
+ <var_page_url>DatabricksRunPageUrl</var_page_url>
+ <var_error>DatabricksError</var_error>
+ <name>Start job</name>
+ <description/>
+ <type>DATABRICKS_JOB_RUN</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Databricks run ${DatabricksRunId} started: ${DatabricksRunPageUrl}</logmessage>
+ <name>Log run page</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection>databricks</connection>
+ <run_id>${DatabricksRunId}</run_id>
+ <timeout_seconds>3600</timeout_seconds>
+ <poll_seconds>15</poll_seconds>
+ <cancel_on_stop>Y</cancel_on_stop>
+ <var_job_id>DatabricksJobId</var_job_id>
+ <var_run_id>DatabricksRunId</var_run_id>
+ <var_status>DatabricksStatus</var_status>
+ <var_page_url>DatabricksRunPageUrl</var_page_url>
+ <var_error>DatabricksError</var_error>
+ <name>Wait for run</name>
+ <description/>
+ <type>DATABRICKS_JOB_WAIT</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Databricks run ${DatabricksRunId} finished with status ${DatabricksStatus}</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Error</loglevel>
+ <logsubject/>
+ <logmessage>Databricks run ${DatabricksRunId} failed: ${DatabricksError}</logmessage>
+ <name>Run failed</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>544</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Start job</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Start job</from>
+ <to>Log run page</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Log run page</from>
+ <to>Wait for run</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Wait for run</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Wait for run</from>
+ <to>Run failed</to>
+ <evaluation>N</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The Databricks job run action starts a Databricks job: an existing job, a one-off run from JSON, or a Hop pipeline it deploys itself.
+It can wait for the run to finish, or start it and continue ("fire and forget"). The ids, status and page URL of the run are stored in variables.
+
+The Databricks job wait action waits for a run that was started earlier, for example by a job run action in fire and forget mode.
+
+This sample starts an existing job without waiting, writes the run page URL to the log and then waits for the run to finish.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>928</width>
+ <height>210</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a Databricks workspace and a Databricks connection called "databricks" (host and access token) in the project metadata.
+Create the connection and change the job id to one of your jobs before running this sample.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>258</yloc>
+ <width>928</width>
+ <height>100</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/tech/ftp/src/main/samples/actions/requires-setup/ftp-put-get-delete.hwf b/plugins/tech/ftp/src/main/samples/actions/requires-setup/ftp-put-get-delete.hwf
new file mode 100644
index 0000000000..1f4ae926ee
--- /dev/null
+++ b/plugins/tech/ftp/src/main/samples/actions/requires-setup/ftp-put-get-delete.hwf
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>ftp-put-get-delete</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/ftp/hop-ftp-sample.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Uploaded by Apache Hop</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection/>
+ <servername>${FTP_SERVER}</servername>
+ <serverport>${FTP_PORT}</serverport>
+ <username>${FTP_USER}</username>
+ <password>${FTP_PASSWORD}</password>
+ <remoteDirectory/>
+ <localDirectory>${java.io.tmpdir}/hop-samples/ftp</localDirectory>
+ <wildcard>hop-ftp-sample\.txt</wildcard>
+ <binary>N</binary>
+ <timeout>0</timeout>
+ <remove>N</remove>
+ <only_new>N</only_new>
+ <active>N</active>
+ <control_encoding>ISO-8859-1</control_encoding>
+ <proxy_host/>
+ <proxy_port/>
+ <proxy_username/>
+ <proxy_password>Encrypted </proxy_password>
+ <socksproxy_host/>
+ <socksproxy_port>1080</socksproxy_port>
+ <socksproxy_username/>
+ <socksproxy_password>Encrypted </socksproxy_password>
+ <name>Put a file with FTP</name>
+ <description/>
+ <type>FTP_PUT</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection/>
+ <servername>${FTP_SERVER}</servername>
+ <username>${FTP_USER}</username>
+ <password>${FTP_PASSWORD}</password>
+ <ftpdirectory/>
+ <targetdirectory>${java.io.tmpdir}/hop-samples/ftp/download</targetdirectory>
+ <wildcard>hop-ftp-sample\.txt</wildcard>
+ <binary>N</binary>
+ <timeout>0</timeout>
+ <remove>N</remove>
+ <only_new>N</only_new>
+ <active>N</active>
+ <control_encoding>ISO-8859-1</control_encoding>
+ <movefiles>N</movefiles>
+ <movetodirectory/>
+ <adddate>N</adddate>
+ <addtime>N</addtime>
+ <SpecifyFormat>N</SpecifyFormat>
+ <date_time_format/>
+ <AddDateBeforeExtension>N</AddDateBeforeExtension>
+ <isaddresult>N</isaddresult>
+ <createmovefolder>N</createmovefolder>
+ <port>${FTP_PORT}</port>
+ <proxy_host/>
+ <proxy_port/>
+ <proxy_username/>
+ <proxy_password>Encrypted </proxy_password>
+ <socksproxy_host/>
+ <socksproxy_port>1080</socksproxy_port>
+ <socksproxy_username/>
+ <socksproxy_password>Encrypted </socksproxy_password>
+ <ifFileExists>ifFileExistsSkip</ifFileExists>
+ <nr_limit>10</nr_limit>
+ <success_condition>success_if_no_errors</success_condition>
+ <name>Get a file with FTP</name>
+ <description/>
+ <type>FTP</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <connection/>
+ <sftp_connection/>
+ <servername>${FTP_SERVER}</servername>
+ <port>${FTP_PORT}</port>
+ <username>${FTP_USER}</username>
+ <password>${FTP_PASSWORD}</password>
+ <ftpdirectory/>
+ <wildcard>hop-ftp-sample\.txt</wildcard>
+ <timeout>0</timeout>
+ <active>N</active>
+ <publicpublickey>N</publicpublickey>
+ <keyfilename/>
+ <keyfilepass>Encrypted </keyfilepass>
+ <useproxy>N</useproxy>
+ <proxy_host/>
+ <proxy_port/>
+ <proxy_username/>
+ <proxy_password>Encrypted </proxy_password>
+ <socksproxy_host/>
+ <socksproxy_port>1080</socksproxy_port>
+ <socksproxy_username/>
+ <socksproxy_password>Encrypted </socksproxy_password>
+ <protocol>FTP</protocol>
+ <nr_limit_success>10</nr_limit_success>
+ <success_condition>success_if_no_errors</success_condition>
+ <copyprevious>N</copyprevious>
+ <name>FTP delete</name>
+ <description/>
+ <type>FTP_DELETE</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The file was uploaded, downloaded and deleted.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>1040</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file</from>
+ <to>Put a file with FTP</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Put a file with FTP</from>
+ <to>Get a file with FTP</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Get a file with FTP</from>
+ <to>FTP delete</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>FTP delete</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The FTP actions transfer files to and from an FTP server: Put a file with FTP uploads files, Get a file with FTP downloads them and FTP delete removes them.
+Files are selected with a regular expression. Instead of a server name and credentials, the actions can also use an FTP connection from the project metadata.
+
+This sample writes a file to ${java.io.tmpdir}/hop-samples/ftp, uploads it, downloads it again to ${java.io.tmpdir}/hop-samples/ftp/download and deletes it from the server.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>1120</width>
+ <height>156</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs an FTP server. Set the FTP_SERVER, FTP_PORT, FTP_USER and FTP_PASSWORD variables
+(for example in an environment configuration file) before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>204</yloc>
+ <width>1120</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/tech/mongodb/src/main/samples/actions/requires-setup/mongodb-execute-mql.hwf b/plugins/tech/mongodb/src/main/samples/actions/requires-setup/mongodb-execute-mql.hwf
new file mode 100644
index 0000000000..58d5d356d6
--- /dev/null
+++ b/plugins/tech/mongodb/src/main/samples/actions/requires-setup/mongodb-execute-mql.hwf
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>mongodb-execute-mql</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <mql>[
+ {"create": "hop_samples"},
+ {
+ "insert": "hop_samples",
+ "documents": [
+ {"name": "Apache Hop", "type": "data orchestration"},
+ {"name": "Apache Beam", "type": "data processing"}
+ ]
+ }
+]</mql>
+ <connection>mongodb</connection>
+ <useExternalFile>N</useExternalFile>
+ <commandFile/>
+ <useVariableSubstitution>N</useVariableSubstitution>
+ <name>Create and fill collection</name>
+ <description/>
+ <type>MQL</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>Collection hop_samples created.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Create and fill collection</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Create and fill collection</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The MongoDB Execute MQL action runs one or more MongoDB database commands, written as a JSON array. The commands can also be read from a file.
+
+This sample creates a collection and inserts two documents in it.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>640</width>
+ <height>102</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs a MongoDB server and a MongoDB connection called "mongodb" in the project metadata.
+Create the connection before running this sample.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>150</yloc>
+ <width>640</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git a/plugins/tech/sftp/src/assembly/assembly.xml b/plugins/tech/sftp/src/assembly/assembly.xml
index 13bf612ad6..bf593a910a 100644
--- a/plugins/tech/sftp/src/assembly/assembly.xml
+++ b/plugins/tech/sftp/src/assembly/assembly.xml
@@ -30,6 +30,12 @@
<filtered>true</filtered>
</file>
</files>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/src/main/samples</directory>
+ <outputDirectory>config/projects/samples/</outputDirectory>
+ </fileSet>
+ </fileSets>
<fileSets>
diff --git a/plugins/tech/sftp/src/main/samples/actions/requires-setup/sftp-put-get.hwf b/plugins/tech/sftp/src/main/samples/actions/requires-setup/sftp-put-get.hwf
new file mode 100644
index 0000000000..492c51afb6
--- /dev/null
+++ b/plugins/tech/sftp/src/main/samples/actions/requires-setup/sftp-put-get.hwf
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>sftp-put-get</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <created_user>-</created_user>
+ <modified_user>-</modified_user>
+ <created_date>2026/10/07 10:00:00.000</created_date>
+ <modified_date>2026/10/07 10:00:00.000</modified_date>
+ <created_hop_version/>
+ <modified_hop_version/>
+ <workflow_version/>
+ <parameters/>
+ <actions>
+ <action>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <intervalSeconds>0</intervalSeconds>
+ <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
+ <weekDay>1</weekDay>
+ <minutes>0</minutes>
+ <hour>12</hour>
+ <doNotWaitOnFirstExecution>N</doNotWaitOnFirstExecution>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <xloc>80</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <filename>${java.io.tmpdir}/hop-samples/sftp/hop-sftp-sample.txt</filename>
+ <createParentFolder>Y</createParentFolder>
+ <appendFile>N</appendFile>
+ <content>Uploaded by Apache Hop</content>
+ <encoding>UTF-8</encoding>
+ <name>Write file</name>
+ <description/>
+ <type>WRITE_TO_FILE</type>
+ <attributes/>
+ <xloc>272</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <servername>${SFTP_SERVER}</servername>
+ <serverport>${SFTP_PORT}</serverport>
+ <username>${SFTP_USER}</username>
+ <password>${SFTP_PASSWORD}</password>
+ <sftpdirectory>/upload</sftpdirectory>
+ <localdirectory>${java.io.tmpdir}/hop-samples/sftp</localdirectory>
+ <wildcard>hop-sftp-sample\.txt</wildcard>
+ <copyprevious>N</copyprevious>
+ <copypreviousfiles>N</copypreviousfiles>
+ <addFilenameResut>N</addFilenameResut>
+ <usekeyfilename>N</usekeyfilename>
+ <keyfilename/>
+ <keyfilepass>Encrypted </keyfilepass>
+ <compression>none</compression>
+ <createRemoteFolder>Y</createRemoteFolder>
+ <aftersftpput>nothing</aftersftpput>
+ <preserveTargetFileTimestamp>N</preserveTargetFileTimestamp>
+ <proxyType/>
+ <proxyHost/>
+ <proxyPort/>
+ <proxyUsername/>
+ <proxyPassword>Encrypted </proxyPassword>
+ <destinationfolder/>
+ <createdestinationfolder>N</createdestinationfolder>
+ <successWhenNoFile>N</successWhenNoFile>
+ <name>Put a file with SFTP</name>
+ <description/>
+ <type>SFTPPUT</type>
+ <attributes/>
+ <xloc>464</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <servername>${SFTP_SERVER}</servername>
+ <serverport>${SFTP_PORT}</serverport>
+ <username>${SFTP_USER}</username>
+ <password>${SFTP_PASSWORD}</password>
+ <sftpdirectory>/upload</sftpdirectory>
+ <targetdirectory>${java.io.tmpdir}/hop-samples/sftp/download</targetdirectory>
+ <wildcard>hop-sftp-sample\.txt</wildcard>
+ <remove>N</remove>
+ <isaddresult>N</isaddresult>
+ <createtargetfolder>Y</createtargetfolder>
+ <copyprevious>N</copyprevious>
+ <usekeyfilename>N</usekeyfilename>
+ <preserveTargetFileTimestamp>Y</preserveTargetFileTimestamp>
+ <keyfilename/>
+ <keyfilepass>Encrypted </keyfilepass>
+ <compression>none</compression>
+ <proxyType/>
+ <proxyHost/>
+ <proxyPort/>
+ <proxyUsername/>
+ <proxyPassword>Encrypted </proxyPassword>
+ <name>Get a file with SFTP</name>
+ <description/>
+ <type>SFTP</type>
+ <attributes/>
+ <xloc>656</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ <action>
+ <loglevel>Basic</loglevel>
+ <logsubject/>
+ <logmessage>The file was uploaded and downloaded again.</logmessage>
+ <name>Done</name>
+ <description/>
+ <type>WRITE_TO_LOG</type>
+ <attributes/>
+ <xloc>848</xloc>
+ <yloc>400</yloc>
+ <parallel>N</parallel>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>Write file</to>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Write file</from>
+ <to>Put a file with SFTP</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Put a file with SFTP</from>
+ <to>Get a file with SFTP</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Get a file with SFTP</from>
+ <to>Done</to>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ <enabled>Y</enabled>
+ </hop>
+ </hops>
+ <notepads>
+ <notepad>
+ <note>The SFTP actions transfer files over SSH: Put a file with SFTP uploads files and Get a file with SFTP downloads them.
+Files are selected with a regular expression. Authentication can use a password or a private key file.
+
+This sample writes a file to ${java.io.tmpdir}/hop-samples/sftp, uploads it to the /upload folder and downloads it again to ${java.io.tmpdir}/hop-samples/sftp/download.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>14</fontcolorred>
+ <fontcolorgreen>58</fontcolorgreen>
+ <fontcolorblue>90</fontcolorblue>
+ <backgroundcolorred>201</backgroundcolorred>
+ <backgroundcolorgreen>232</backgroundcolorgreen>
+ <backgroundcolorblue>251</backgroundcolorblue>
+ <bordercolorred>14</bordercolorred>
+ <bordercolorgreen>58</bordercolorgreen>
+ <bordercolorblue>90</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>32</yloc>
+ <width>928</width>
+ <height>138</height>
+ </notepad>
+ <notepad>
+ <note>Requires setup: this sample needs an SFTP server. Set the SFTP_SERVER, SFTP_PORT, SFTP_USER and SFTP_PASSWORD variables
+(for example in an environment configuration file) before running it.
+This sample is excluded from the samples integration tests.</note>
+ <markdown>N</markdown>
+ <notetype>GENERAL</notetype>
+ <fontname>Segoe UI</fontname>
+ <fontsize>11</fontsize>
+ <fontbold>N</fontbold>
+ <fontitalic>N</fontitalic>
+ <fontcolorred>110</fontcolorred>
+ <fontcolorgreen>50</fontcolorgreen>
+ <fontcolorblue>0</fontcolorblue>
+ <backgroundcolorred>255</backgroundcolorred>
+ <backgroundcolorgreen>220</backgroundcolorgreen>
+ <backgroundcolorblue>180</backgroundcolorblue>
+ <bordercolorred>230</bordercolorred>
+ <bordercolorgreen>126</bordercolorgreen>
+ <bordercolorblue>34</bordercolorblue>
+ <xloc>80</xloc>
+ <yloc>186</yloc>
+ <width>928</width>
+ <height>110</height>
+ </notepad>
+ </notepads>
+ <attributes/>
+</workflow>