See the building workflows page if you have not already. If you are looking for the documentation for a specific input field, find the name of the field from the sidebar on the right. Expression documentation can be found here.
Inputs
In addition to defining what your workflow does with jobs, you can define the workflow form users will fill out when running the workflow. This form is what's displayed in the Run Workflow tab, and the values of the inputs can be accessed from inside jobs using expressions. Inputs are defined in the following structure:
on:
execute:
inputs:
name_of_input_1:
type: type_of_input_1
... other fields (potentially type specific) ...
name-of-input-2:
type: type_of_input_2
... other fields (potentially type specific) ...
The name of an input must be composed of alphanumeric characters, dashes, and underscores. When defining the YAML file in the Build tab, the form is previewed on the right side of the screen:
Input Types
Below is a list of each type
and its modifying attributes. Unless otherwise noted, each type
can be modified by any of the universal attributes.
boolean
A checkbox or toggle switch representing a boolean value (true/false).
Useful for optional settings, enabling/disabling features, or making binary choices (such as "Enable logging?").
color-picker
An input field that allows users to select a color.
Useful for customizing the appearance of visual elements, such as selecting colors for charts, backgrounds, or UI components.
compute-clusters
Represents a selection of compute clusters.
Attributes:
csp
: Specifies the CSP (cloud service provider). Options areaws
,azure
, andgoogle
.include-workspace
: Indicates whether to include workspace clusters.provider
: Specifies the compute resource provider.
Allows users to select the specific compute cluster where their job will run, essential for distributing workloads across available resources.
editor
A code editor input field with syntax highlighting.
Attributes:
language
: Specifies the language for syntax highlighting (such as yaml, json, etc.).
Useful for entering and editing code snippets, configuration files, or scripts directly within the workflow.
dropdown
A dropdown menu allowing the user to select from a list of predefined options.
Attributes:
options
: A list of options with label and value.option-key
: A key to determine the selected option.
Ideal for selecting from multiple predefined options, such as job schedulers, input methods, or configuration settings.
group
A collapsible group of related input fields.
Attributes:
items
: A list of inputs that belong to this group.collapsed
: Boolean to indicate if the group should be initially collapsed.
Organizes related inputs together. Especially useful for advanced settings or additional information that can be optionally expanded by the user.
header
Creates a header in the input form.
Attributes:
text
: The header text.bold
: Indicates if the text should be bold.size
: Font size of the header.
Adds titles or section headers in the input form for better organization and readability.
instance-type
Represents a selection of instance types for a specific CSP (cloud service provider) and region.
Attributes:
csp
: Specifies the CSP (aws
,azure
, orgoogle
).region
: The region associated with the instance types.
Allows users to choose specific instance types for their compute tasks. Important for matching job requirements with appropriate resources.
list
A list of items, typically used for repeating input patterns.
Attributes:
template
: The template defining the type of items in the list.
Useful for inputs where multiple entries of the same type are needed, such as a list of regions, parameters, or configuration items.
multi-dropdown
A dropdown menu allowing the user to select multiple options.
Attributes:
options
: A list of options withlabel
andvalue
.
Ideal for selecting multiple items from a list, such as tags, categories, or resource groups.
number
An input field for entering numerical values.
Attributes:
min
: The minimum allowable value.max
: The maximum allowable value.step
: The increment step for the number input.slider
: Boolean to indicate if the input should be displayed as a slider.
Useful for specifying numerical parameters, such as counts, thresholds, limits, or any other numeric settings.
organization-groups
Represents a selection of organization groups.
Attributes:
csp
: Specifies the CSP (cloud service provider). Options areaws
,azure
, andgoogle
.
Allows users to select organizational groups for permissions, access control, or grouping related resources.
region
Represents a geographic region associated with a CSP.
Attributes:
csp
: Specifies the CSP (cloud service provider). Options areaws
,azure
, andgoogle
.
Allows users to select a specific geographic region for their resources, essential for optimizing latency, compliance, and availability.
slurm-accounts
Represents a selection of SLURM accounts.
Attributes:
resource
: The compute resource associated with the SLURM accounts.
Allows users to select SLURM accounts for job submissions. Essential for managing resource allocation and accounting in SLURM environments.
slurm-partitions
Represents a selection of SLURM partitions.
Attributes:
resource
: The compute resource associated with the SLURM partitions.account
: Specifies the SLURM account associated with the partitions.
Allows users to select SLURM partitions for job submissions. Essential for organizing and managing job queues in SLURM environments.
slurm-qos
Represents a selection of SLURM QoS (Quality of Service) settings.
Attributes:
account
: Specifies the SLURM account associated with the QoS settings.partition
: Specifies the SLURM partition associated with the QoS settings.resource
: The compute resource associated with the SLURM QoS.
Allows users to select SLURM QoS settings for job submissions. Essential for prioritizing and managing job performance in SLURM environments.
storage-image
Represents a selection of storage images.
Attributes:
csp
: Specifies the CSP (cloud service provider). Options areaws
,azure
, andgoogle
.subtype
: Specifies the subtype of the storage image (such aslustre
).
Allows users to select storage images for their jobs. Essential for specifying the data environment and ensuring compatibility with compute tasks.
string
A single-line text input or a multi-line text area for string values.
Attributes:
placeholder
: Placeholder text for the input field.textarea
: Indicates if the input should be a text area.
Collects textual input from users. Suitable for names, descriptions, commands, or any other text-based configuration.
zone
Represents a selection of zones within a region for a specific CSP (cloud service provider).
Attributes:
csp
: Specifies the CSP. Options areaws
,azure
, andgoogle
.region
: Specifies the region associated with the zone.
Allows users to select specific zones for their resources. Important for optimizing resource placement, redundancy, and compliance.
Universal Input Attributes
Most input types above can be modified by a set of common attributes, which help in configuring the basic behavior and presentation of the input fields. The only type
without these universal attributes is header
, which has its own unique set of attributes focused on display rather than interaction.
default
Sets the default value for the input field.
Usage: Provides an initial value if the user does not input one.
Example:
default: 'Enter description here'
disable
Disables the input field, making it read-only and uneditable by the user.
Usage: Use this when you want to display information without allowing the user to change it.
Example:
disable: true
hidden
A condition to hide or show the input field based on other inputs or logic.
Usage: Creates a dynamic form where inputs can be conditionally displayed.
Example:
hidden: ${{ inputs.show_advanced == false }}
ignore
When set to true
, the input field's value is ignored and not sent to the backend.
Usage: Useful for fields that are needed for UI logic but should not be part of the final payload.
Example:
ignore: true
label
A human-readable name for the input field that will be displayed in the UI.
Usage: Helps users understand what data is expected.
Example:
label: Job Description
optional
Indicates whether the input field is optional or required.
Usage: Determines whether the user must provide a value.
Example:
optional: true
tooltip
A tooltip text providing additional information about the input field.
Usage: Assists users by offering more context or instructions when they hover over the input field.
Example:
tooltip: 'Provide a detailed description of the job'
Expressions
Expressions allow workflow authors to programatically control the input form based on other inputs and access contexts inside of jobs.
In order for expressions to be evaluated, they must be wrapped in ${{ }}
.
Operators
The following operators are available for use in expressions, and generally correspond to their javascript counterparts. Example expressions and what they evaluate to are included.
&&
: Logical AND${{ true && 'truthy value' }}
= 'truthy value'${{ 'truthy value' && true }}
= true${{ 0 && true }}
= 0${{ 'truthy value' && false }}
= false
||
: Logical OR:${{ false || 'any value' }}
= 'any value'${{ 'truthy value' || 'any value' }}
= 'truthy value'
==
: Equal to${{ 1 == true }}
= true
!=
: Not equal to${{ 1 != true }}
= false
===
: Strict equal to${{ 1 === true }}
= false
!==
: Strict not equal to${{ 1 !== true }}
= true
>
: Greater than${{ 'a' > 'b' }}
= false
<
: Less than${{ 1.5 < 1 }}
= false
>=
: Greater than or equal to${{ 1.0 >= 1 }}
= true
<=
: Less than or equal to${{ false <= true }}
= true
+
: Addition/Concatenation${{ 'a' + 'b' }}
= 'ab'${{ 1 + 1.5 }}
= 2.5
-
: Subtraction${{ 1 - 1.5 }}
= -0.5
*
: Multiplication${{ 4 * 4 }}
= 16
/
: Division${{ 9 / 4 }}
= 2.25
**
: Exponentiation${{ 2 ** 4 }}
= 16
//
: Floor division${{ 4 // 3 }}
= 1
??
: Nullish coalescing${{ 'hello' ?? 'default' }}
= 'hello'${{ undefined ?? 'default' }}
= 'default'
get
: Get index/property:${{ ["a", "b"] get 1 }}
= "b"${{ {"a":"c", "b":"d"} get a }}
= "c"${{ 'ab' get 0 }}
= 'a'
in
: Left in right:${{ "a" in ["a", "b"] }}
= true${{ "b" in {"a":"c", "b":"d"} }}
= true${{ "d" in {"a":"c", "b":"d"} }}
= false
Special operators (not binary):
!
: Logical NOT:${{ !false }}
= true${{ "hello" !in ["hello", "goodbye"] }}
= false
( )
: Logical grouping:${{ true && (true || true) && false }}
= false${{ 10 / (2 + 8) }}
= 1
? :
: Conditional (ternary):${{ true && false ? 'a' : 'b' }}
= 'b'${{ 'truthy value' ? 'a' : 'b' }}
= 'a'
Parser idiosyncracies to take note of:
- Expressions are very much whitespace sensitive, relying on spaces to separate operators and operands. Thus
${{ 1 + 1 }}
will evaluate to 2 but${{ 1+1 }}
will evalutate to the string1+1
. Logical not!
is the only operator that should not be separated with a space. - If an expression has even a minor mistake, the parser will never throw an error but may return any value, screwing up your workflow in strange ways. So double check your expressions.
Contexts
The following contexts are available for use in expressions:
inputs
: Used to access the values and schema of the input fields.needs
: For now onlyneeds.<job>.outputs.<name>
is supported, which allows access to outputs from the current job or its dependency jobs.app
: For apps only,app.target
can be used to fetch the cluster information, in the same format of thecompute-clusters
type.sessions
: Contains a field for each session described in the workflow. For an example, see Building Sessions.org
: Contains organization-specific variables that are set by your administrator. Useorg.<variable name>
in an expression to access these..
and../
: Used to access schema values.
The workflow form can only access the values and schema of the inputs field through the inputs
context and .
self referencing, alongside your organization variables through org
. Information from job dependencies accessed through the needs
context, sessions accessed through the sessions
context, and app cluster information from the app
context are only available during execution, so they should only ever be accessed inside of jobs
.
Accessing outputs
Outputs from a job can be accessed using the needs
context. The following example demonstrates how to access the outputs from within the current job:
jobs:
job1:
steps:
- name: fake output
run: echo PORT=3001 >> $OUTPUTS
- name: Echo output from self
run: echo ${{ needs.job1.outputs.PORT }} # Prints 3001
job2:
needs:
- job1
steps:
- name: Echo output from job 1
run: echo ${{ needs.job1.outputs.PORT }} # Prints 3001
Note that we must utilize the environment variable OUTPUTS to get the path to the output file, and write our key, value pair to the file in the format key=value
. Jobs utilizing outputs of other jobs should generally have the jobs with outputs as dependencies; in our example, job2
runs only once job1
is completed, because otherwise the outputs of job1
are not reliable.
Apps and app context
When converting a workflow into an app, the workflow is moved to the Apps page and gains the additional app
context. Currently, the only property available on the app
context is target
, which represents the compute resource that is targeted by an app on any given run. The example below shows the context and property as app.target
, which is used in this case to print the target's name.
jobs:
main:
steps:
- name: Print app.target
run: echo ${{ app.target }}
Inputs and Self Referencing
How and when to use the inputs
keyword and/or the self referencing .
can be confusing; hopefully this section can make things a bit clearer.
Let us consider the following example of a workflow form defined in the yaml. There are two string inputs:
on:
execute:
inputs:
username:
type: string
workdir:
type: string
username
is the user's username and string_field_2
is a directory I want to create based on the username by default. To access the value of an input, we use the inputs
keyword:
on:
execute:
inputs:
username:
type: string
workdir:
type: string
default: ${{ "~/path/to/directory/" + inputs.username }}
This ensures that every time the user updates the username, the default workdir is updated. Doing it like this allows the user to override the workdir with their own custom directory path in the workflow form if they would like to.
Now let us consider another example:
on:
execute:
inputs:
...
option_1_input:
type: string
hidden: ${{ some long and complicated boolean expression }}
option_2_input:
type: string
We want the option 2 input to appear when the option 1 input is hidden, and be hidden when the option 1 input appears. Rather than rewriting the long and complicated boolean expression, we can access the schema of the input by using ../
:
on:
execute:
inputs:
...
option_1_input:
type: string
hidden: ${{ some long and complicated boolean expression }}
option_2_input:
type: string
hidden: ${{ !../option_1_input.hidden }}
We use the ../
because it represents going backwards in our path to the level of the object containing the property with the expression; if we wanted to access a property inside option_2_input from the hidden
property instead, such as type
, we could simply do ${{ .type }}
, which would be equivalent to ${{ ../option_2_input.type }}
. We can also access the schema by using the inputs
keyword and ensuring the last property is wrapped in brackets; so an equivalent expression for ${{ !../option_1_input.hidden }}
in the example above would be ${{ !inputs.option_1_input[hidden] }}
.
In summary, here are all the different possibilities:
on:
execute:
inputs:
field_1:
type: number
field_2:
type: string
default: ${{ inputs.field_1 }} # The value of field 1, which is whatever the user sets it to on the form
field_3:
type: string
default: ${{ inputs[field_1] }} # This would actually be the field_1 schema object which is {"type": "number"}. It would probably not be rendered as a string properly.
field_4:
type: string
default: ${{ inputs.field_1[type] }} # This would be just the string "number"
field_5:
type: string
default: ${{ ../field_1 }} # This would be the field_1 schema object which is {"type": "number"}.
field_6:
type: string
default: ${{ ../field_1.type }} # This would be just the string "number"
field_7:
type: string
default: ${{ .type }} # This would be just the string "string" since field_7 has type: string
Conditional Visibility
Inputs can be dynamically hidden based on the value or attributes of other inputs. This is useful for creating more dynamic and user-friendly forms where advanced options are only shown when needed.
on:
execute:
inputs:
header:
type: header
text: Starter Local Workflow
size: 20
show_advanced:
type: boolean
label: Show Advanced Settings
default: false
advanced_setting:
type: string
label: Advanced Setting
hidden: ${{ !inputs.show_advanced }}
advanced_setting2:
type: string
label: Advanced Setting 2
hidden: ${{ inputs.advanced_setting[hidden] }}
In this example, advanced_setting
and advanced_setting2
are hidden fields until the user selects Yes from the show_advanced
toggle switch. advanced_setting2
is hidden based on the hidden
attribute of advanced_setting
, whereas advanced_setting
is hidden based on the value of show_advanced
.
Dynamic Default Values
Default values can be calculated based on other input values.
on:
execute:
inputs:
header:
type: header
text: Starter Local Workflow
size: 20
base_value:
type: number
label: Base Value
default: 10
calculated_value:
type: number
label: Calculated Value
default: ${{ inputs.base_value * 2 }}
hidden: true
In this example, the calculated_value
input field has a default value that is twice the value of the base_value
input field.