Control flow
workflow
Section titled “workflow”Calls another workflow in the same .rigg project.
- id: call_plan type: workflow with: workflow: plan inputs: requirements: ${{ inputs.requirements }} retries: 3 dry_run: trueRules:
with.workflowmust be a static string, not a template expression- String
with.inputsvalues are rendered as templates in the caller scope - Boolean and number YAML literals pass through unchanged
steps.call_plan.resultisnullin v1, so workflows stay independent and share data through files or git stateworkflowsteps may setretry
Encapsulates steps into a single unit. Internal results are hidden unless exported.
- id: gather type: group steps: - id: log type: shell with: command: git log --oneline -20 stdout: mode: text - id: diff type: shell with: command: git diff --stat stdout: mode: text exports: log: ${{ steps.log.result }} diff: ${{ steps.diff.result }}Downstream steps access exports via steps.gather.result.log.
Repeats until a condition is met or max iterations is reached.
- id: fix_loop type: loop max: 5 # required until: ${{ len(steps.review.result.findings) == 0 }} # optional steps: - id: review type: codex with: kind: review target: type: uncommitted - id: fix if: ${{ len(steps.review.result.findings) > 0 }} retry: max: 3 delay: 1s type: codex with: kind: turn prompt: | Address these review findings: ${{ toJSON(steps.review.result) }} exports: clean: ${{ len(steps.review.result.findings) == 0 }}Loop results always include reason.
until_satisfiedwhenuntilbecomes truthymax_reachedwhen the loop uses all iterations
Loop context variables
Section titled “Loop context variables”Inside loop bodies, run.* variables are available:
| Variable | Type | Description |
|---|---|---|
run.iteration | integer | Current iteration (1-based) |
run.max_iterations | integer | Max iterations value |
run.node_path | string | Node path |
branch
Section titled “branch”Conditional execution. First matching if wins. else is the fallback.
- id: decide type: branch cases: - if: ${{ steps.check.result == 'needs_fix' }} steps: - id: fix type: codex with: kind: turn prompt: Fix the issues. exports: outcome: ${{ steps.fix.result }} - else: steps: [] exports: outcome: "no issues"Rules:
- All cases must export the same shape, or none at all
- If any case has
exports, anelsecase is required else:takes no value (justelse:on its own)
parallel
Section titled “parallel”Runs branches concurrently.
- id: checks type: parallel branches: - id: unit # id required on each branch steps: - id: run_unit type: shell with: command: npm test - id: lint steps: - id: run_lint type: shell with: command: npm run lint exports: unit: ${{ steps.run_unit.result }} lint: ${{ steps.run_lint.result }}Exports can reference steps.* from any branch in the parallel block.
Exports
Section titled “Exports”All control flow types (group, loop, branch, parallel) support exports to promote internal results to the outer scope:
exports: name: ${{ steps.inner_step.result }} field: ${{ steps.inner_step.result.nested_field }}Without exports, inner step results are invisible to downstream steps.