Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 117 additions & 24 deletions basic-examples/expressions/README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,136 @@
# Expressions
# String Expressions

## Workflow Description

This workflow demonstrates example expressions as detailed in our [expression documentation](https://arcalot.io/arcaflow/workflows/expressions/).
This workflow demonstrates some example expressions as detailed in our [expression
documentation](https://arcalot.io/arcaflow/workflows/expressions/). Arcaflow
expressions are a way to reference paths within the workflow or their fields, and they
additionally allow you to manipulate the data.
Comment on lines +6 to +8
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The phrase "to reference paths" doesn't seem like it will mean anything to a user. That is, expressions allow a user to reference a piece of data via a path, but the path is a means to an end, not a goal in itself. And, the path should pretty much always end at a field (or a list item). So, I propose rewording this to something like,

Arcaflow expressions provide a way to reference individual data items within the workflow, such as lists, objects, list elements, and object properties, for use in specifying inputs to steps and subworkflows or workflow outputs. In addition, expressions can be used to transform input and output items to produce new data items.


*Note: Arcaflow expressions were inspired by JSONPath, and may look familar, but
expressions have diverged from the JSONPath syntax to enable a rich feature set that is
specific to Arcaflow.*
Comment on lines +10 to +12
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps,

Arcaflow expression syntax was inspired by JSONPath, and may look familiar, but
the syntax has diverged from the JSONPath syntax to enable a rich feature set that is
specific to Arcaflow.

(Note the correction of the spelling of "familiar".)


The basic use of expressions in a workflow YAML looks like this:

```
some_value: !expr $.your.expression.here
```

## Examples

Basic path references are already used across the other example workflows. These
include references in a step to an input from the schema:
Comment on lines +20 to +23
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment about path references already being used elsewhere is non-productive (unless we expect that the reader has already seen them or is just about to see them). Instead, let's just say what we want to say, here:

A basic path reference can be used to specify a value from the workload input as the input to a step:


```
steps:
example:
plugin:
deployment_type: image
src: quay.io/arcalot/arcaflow-plugin-example:0.5.0
input:
name:
_type: nickname
#Expression for an input path reference
nick: !expr $.input.nickname
```

As well as references in the output to a step field:

```
outputs:
success:
#Expression for a step field reference
example: !expr $.steps.example.outputs.success
```

This workflow demonstrates string literals and concatenation:

```
steps:
example1:
plugin:
deployment_type: image
src: quay.io/arcalot/arcaflow-plugin-template-python:0.4.0
input:
#Expression with concatenation and string literal
name: !expr $.input.name + ' -- \"The Noble Workflow Engine\"'
Comment on lines +55 to +57
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment to basic-examples/expressions/workflow.yaml.

```

As well as type conversions and math operations:
Comment on lines +59 to +60
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment refers to a new YAML blob, so replace "As well as" with something like "This workflow demonstrates".


```
steps:
example2:
plugin:
deployment_type: image
src: quay.io/arcalot/arcaflow-plugin-template-python:0.4.0
input:
# Expression with type conversions, math operation, and concatenation
name: >
!expr intToString(floatToInt(intToFloat($.input.int_value) *
$.input.float_value)) + ' User'
```

In this last expression, the plugin requires a string input. The logical steps here are:
Comment on lines +70 to +75
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this text refers to the preceding text, unlike all the previous text blobs which have each been referring to examples which follow them, it would be good to explicitly establish the context first, by inserting a phrase like "in the example above" before the comma.

1. An integer input is converted to a float in order to make it compatible with a math
operation with another float input: `intToFloat($.input_int_value)`
2. The two float values are multiplied: `... * $.input.float_value`
3. The resulting float is converted to an integer (truncating the fractional value):
`floatToInt(...)`
4. The integer is converted to a string: `intToString(...)`
5. Finally, the two strings are concatenated: `... + ' User'`

## Files

- [`workflow.yaml`](workflow.yaml) -- Defines the workflow input schema, the plugins to run
and their data relationships, and the output to present to the user
- [`input.yaml`](input.yaml) -- The input parameters that the user provides for running
the workflow
- [`config.yaml`](config.yaml) -- Global config parameters that are passed to the Arcaflow
engine
- [`workflow.yaml`](workflow.yaml) -- Defines the workflow input schema, the plugins to
run and their data relationships, and the output to present to the user
- [`input.yaml`](input.yaml) -- The input parameters that the user provides for running
the parent workflow
- [`config.yaml`](config.yaml) -- Global config parameters that are passed to the
Arcaflow engine

## Running the Workflow

### Workflow Execution

Download a Go binary of the latest version of the Arcaflow engine from: https://github.com/arcalot/arcaflow-engine/releases
Download a Go binary of the latest version of the Arcaflow engine from:
https://github.com/arcalot/arcaflow-engine/releases

Run the workflow:
```
$ export WFPATH=<path to this workflow directory>
$ arcaflow -input ${WFPATH}/input.yaml -config ${WFPATH}/config.yaml -context ${WFPATH}
```
### Output

Each input expression to the `name` parameter outputs as the same string.

```shell
output_data:
message:
data:
- name: Hello, Here's an apostrophe and "embedded quotes".!
- name: Hello, Here's an apostrophe and "embedded quotes".!
- name: Hello, Here's an apostrophe and "embedded quotes".!
- name: Hello, Here's an apostrophe and "embedded quotes".!
- name: Hello, Here's an apostrophe and "embedded quotes".!
- name: Hello, Here's an apostrophe and "embedded quotes".!
output_id: success
## Workflow Diagram

```
```mermaid title="workflow.yaml"
%% Mermaid markdown workflow
flowchart LR
%% Success path
steps.example2.outputs-->steps.example2.outputs.success
steps.example1.deploy-->steps.example1.starting
steps.example1.outputs.success-->outputs.success
steps.example2.cancelled-->steps.example2.outputs
steps.example2.outputs.success-->outputs.success
steps.example2.running-->steps.example2.outputs
steps.example1.outputs-->steps.example1.outputs.success
steps.example1.cancelled-->steps.example1.outputs
steps.example2.starting-->steps.example2.starting.started
steps.example2.starting-->steps.example2.running
input-->steps.example1.starting
input-->steps.example2.starting
steps.example2.disabled-->steps.example2.disabled.output
steps.example1.starting-->steps.example1.starting.started
steps.example1.starting-->steps.example1.running
steps.example1.enabling-->steps.example1.enabling.resolved
steps.example1.enabling-->steps.example1.starting
steps.example1.enabling-->steps.example1.disabled
steps.example1.disabled-->steps.example1.disabled.output
steps.example1.running-->steps.example1.outputs
steps.example2.enabling-->steps.example2.enabling.resolved
steps.example2.enabling-->steps.example2.starting
steps.example2.enabling-->steps.example2.disabled
steps.example2.deploy-->steps.example2.starting
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the mermaid chart of only the subworkflow. Since we are using a foreach here, it may make sense to include the charts for both the inner and outer workflows.

It's troublesome that both the parent and the subworkflow use the step name example, and I really think that should be changed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the parent workflow

4 changes: 2 additions & 2 deletions basic-examples/expressions/config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
deployers:
image:
deployer_name: docker
deployer_name: podman
log:
level: debug
logged_outputs:
error:
level: error
level: debug
4 changes: 3 additions & 1 deletion basic-examples/expressions/input.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
{}
name: Arcaflow
int_value: 42
float_value: 31.84
20 changes: 0 additions & 20 deletions basic-examples/expressions/subworkflow.yaml

This file was deleted.

58 changes: 42 additions & 16 deletions basic-examples/expressions/workflow.yaml
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
---
version: v0.2.0
input:
root: RootObject
objects:
RootObject:
id: RootObject
properties: {}
properties:
name:
display:
description: Just a name
name: Name
required: true
type:
type_id: string
int_value:
display:
description: Just an integer value
name: Integer Value
required: true
type:
type_id: integer
float_value:
display:
description: Just a float value
name: Float Value
required: true
type:
type_id: float

steps:
example:
kind: foreach
workflow: subworkflow.yaml
items:
- name: !expr '"Here''s an apostrophe and \"embedded quotes\"."'
- name: !expr "'Here\\'s an apostrophe and \"embedded quotes\".'"
- name: !expr |-
'Here\'s an apostrophe and "embedded quotes".'
- name: !expr |-
"Here's an apostrophe and \"embedded quotes\"."
- name: !expr '`Here''s an apostrophe and "embedded quotes".`'
- name: !expr |-
`Here's an apostrophe and "embedded quotes".`
example1:
plugin:
deployment_type: image
src: quay.io/arcalot/arcaflow-plugin-template-python:0.4.0
input:
#Expression with concatenation and string literal
name: !expr $.input.name + ' -- \"The Noble Workflow Engine\"'
Comment on lines -14 to +37
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could someone remind me why we need to escape the double quotes inside a string marked with single quotes? That is, the escapes aren't actually needed, right?

(I guess that \" gets replaced with " so we get the right result, but if we want to demonstrate the application of escape characters when they are actually needed, perhaps the string should be marked with double quotes?)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The escaped double quotes are generating a warning (which doesn't seem to adversely affect the operation of the workflow). There also seems to be a warning (which, again, doesn't seem to have any adverse effect) on the use of the single quotes.

If you replace the single quotes with double quotes, it makes both sets of warnings go away (and, it justifies the escapes...).

example2:
plugin:
deployment_type: image
src: quay.io/arcalot/arcaflow-plugin-template-python:0.4.0
input:
# Expression with type conversions, math operation, and concatenation
name: >
!expr intToString(floatToInt(intToFloat($.input.int_value) *
$.input.float_value)) + ' User'
Comment on lines +42 to +46
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The !expr tag is not part of the data, so it needs to precede the >:

      name: !expr >
        intToString(floatToInt(intToFloat($.input.int_value) * 
        $.input.float_value)) + ' User'

And, the use of single quotes is generating a warning during parsing...but it doesn't seem to adversely affect the operation of the workflow.


outputs:
success:
message: !expr $.steps.example.outputs.success
name: !expr $.steps.example1.outputs.success
message: !expr $.steps.example2.outputs.success