Skip to main content

The for_each Step

The for_each step in Bosun allows you to iterate over a list of items, executing a sub-step (which can contain agent or run steps) for each item. This is effective for automating repetitive tasks across multiple files, configurations, or data entries.

for_each steps are executed in parallel batches. If you need to run them sequentially, you can set parallel: false within the for_each definition.

Key properties of a for_each step include:

  • from: A templated expression that defines the list of items to iterate over. This can be any JSON array. If needed you can use templating functions like split(), slice(), and json_encode() to transform outputs from previous steps into the required format.
  • for_each.value: Inside the for_each loop, this variable holds the current item being processed in the iteration.

Example from Workflow

Consider the for_each step from an example workflow, which processes multiple source files:

  - name: Get source files
run: find src -name "*.js"

- name: Apply linting fixes
for_each:
from: '{{ outputs.1 | split(pat="\n") | slice(end=5) | json_encode() }}'
agent:
extends: Coding
instructions: "Apply automatic linting fixes to the file {{ for_each.value }}"
role: "You are a meticulous code formatter."
constraints:
- "Use the project's ESLint configuration"
- "Only apply fixes that do not change code logic"
- "Ensure the file remains syntactically correct"
- "Focus only on the specified file"

In this example:

  1. run: find src -name "*.js": This step (which would be outputs.1 in this snippet) finds all .js files in the src/ directory and outputs their paths, one per line.
  2. from: '{{ outputs.1 | split(pat="\n") | slice(end=5) | json_encode() }}':
    • outputs.1: Retrieves the output (list of file paths) from the "Get source files" step.
    • split(pat="\n"): Splits the string output into an array of file paths.
    • slice(end=5): Takes only the first 5 file paths from the array (for demonstration purposes).
    • json_encode(): Converts the array into a JSON string, which the for_each step can then iterate over.
  3. instructions: "Apply automatic linting fixes to the file {{ for_each.value }}": Inside the for_each loop, an agent step is defined. The {{ for_each.value }} template dynamically inserts the current file path from the iteration into the agent's instructions, allowing the agent to process each file individually.

Error handling

Every iteration runs as its own sub-task. With the default settings a single failure stops the step, but continue_on_error: true lets the loop finish and collects each failure under errors.<step> along with the failed iteration index and input. See Error handling for strategies.