Skip to main content

🌊 Workflows

A workflow is an orchestration of actions. It can be triggered by an event, or it can be invoked by another workflow. In this section, we'll walk you through all the building blocks of a workflow.

AutoPR comes with a few workflows, which you can find in the workflow catalogue.

If you'd like to contribute a workflow, see the tutorial.

🌱 The Hello World Example

hello:
outputs:
- name
- message
steps:
- set_vars:
message:
template: "Hello {{ name }}!"

hello_world:
outputs:
- message
steps:
- workflow: hello
inputs:
name:
const: "world"
outputs:
message: message

🗝️ Workflow Skeleton

A workflow definition has the following structure:

workflow_name:
inputs:
- input1
- input2
outputs:
- output1
- output2
steps:
- action: action1
- workflow: workflow1
- action: action2
- ...

This defines a workflow with the name workflow_name, which has two inputs named input1 and input2, and two outputs named output1 and output2.

In the steps section, we operate with inputs to produce the desired outputs.

Both inputs and outputs are optional.

🏃‍ Steps

There are multiple different possible steps to use in a workflow. Each step has a different purpose and syntax.

set_vars

Workflows use the set_vars step to declare and construct variables.

The same syntax can be used in action and workflow inputs, defaulting to template.

In AutoPR workflows, you can define constants with the const keyword. These hold various types (strings, integers, lists, dictionaries, etc.)

set_constant_workflow:
outputs:
- int_const
- str_const
- list_const
- dict_const
steps:
- set_vars:
int_const:
const: 1
str_const:
const: "Hello world!"
list_const:
const:
- 1
- 2
- 3
dict_const:
const:
key1: value1
key2: value2

Here, we've defined a workflow named set_constant_workflow that defines and outputs four constants:

  • int_const with value 1
  • str_const with value "Hello world!"
  • list_const with value [1, 2, 3]
  • dict_const with value {"key1": "value1", "key2": "value2"}

You'll notice a similar pattern in the other examples as well.

action

action is a step that allows you to invoke an action from the action catalogue.

An action is a predefined operation or task that has inputs and outputs.

One of the actions that comes with AutoPR is the bash action, which allows you to execute arbitrary bash commands, so we'll use it as an example:

bash_workflow:
inputs:
- message
outputs:
- stdout
steps:
- action: bash
inputs:
command:
template: |
'echo "{{ message }}"'
outputs:
stdout: stdout

Note how the inputs use the same syntax as the set_vars step.

When this workflow is triggered, it will execute the bash action with the given command and return its output in the stdout output.

workflow

If you build a workflow that performs a specific task, you can invoke it from another workflow with the workflow step. This is particularly useful if you either want to reduce complexity of the workflows or reuse some of the workflows you've already defined.

The available workflows are listed in the workflow catalogue, or you can use one of your custom-defined workflows.

Like invoking an action, invoking a workflow also has inputs and outputs.

Here's an example workflow that combines two variables using the lambda keyword:

set_vars_workflow:
inputs:
- var1
- var2
outputs:
- var3
steps:
- set_vars:
var3:
lambda: "var1 + var2"

Now, we can define another workflow, which will use the set_vars_workflow we've just defined.

usage_of_set_vars_workflow:
outputs:
- var3
steps:
- workflow: set_vars_workflow
inputs:
var1:
const: 1
var2:
const: 2
outputs:
var3: var3

This workflow, when triggered, will return value 3 in its var3 output.

Note how the inputs use the same syntax as the set_vars step.

if_lambda

Conditionals are decision-making steps based on certain conditions, the first of which is the if_lambda step.

Assuming we've got workflows summarize_file and summarize_dir defined, we can use them in a conditional:

summarize_entry:
inputs:
- path
outputs:
- summary
steps:
- if_lambda: not os.path.isdir(path)
then: summarize_file
else: summarize_dir

This workflow has a very important assumption that the summarize_file and summarize_dir workflows have variable path as its only input and summary as its only output. This is because the summarize_entry workflow uses the path input and outputs.

iterate

If we have a variable that's a list, or we would like to iterate a number of times, we can use the iterate step and perform some action or workflow multiple times.

Workflows can iterate over lists or ranges, and combine with the action and workflow keyword. Most notably, they add an as keyword to define the name of the variable that will be used in the iteration, and change the outputs keyword to list_outputs, to define the list of outputs that will be returned.

If iterate's value is a variable of type list, the workflow will use iteration over a list.

iter_var_action:
inputs:
- list_of_commands
outputs:
- outputs_list
- concatenated_outputs
steps:
- action: bash
iterate: list_of_commands
as: cmd
inputs:
command:
template: |
'{{ cmd }}'
list_outputs:
stdout: outputs_list
- action: bash
inputs:
command:
template: |
echo '{{ outputs_list | join("") }}'
outputs:
stdout: concatenated_outputs

This workflow will execute all the commands in the list_of_commands input and return the list of outputs in the outputs_list output.

🚀 Let's go!

Great, now you know how to define workflows. The next step is to define your own workflow.