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.
Control ordering

Set parallel: false when order matters or when the target system cannot handle concurrent writes. Leave it omitted for maximum throughput.

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.