Workflows
A workflow is a named sequence of steps defined in YAML. Run it with
atmos workflow <name> -f <file> for repeatable tasks such as validation,
deployment, or maintenance.
Workflows combine Atmos commands, external tools, scripts, and tests. Run the same workflow locally or from CI; keep CI triggers and approvals in your CI system.
Workflow syntax
Configure workflows.base_path in atmos.yaml to locate workflow files.
Each file contains a workflows map, keyed by workflow name:
workflows:
greet:
description: Print a greeting
steps:
- name: report
type: script
interpreter: starlark
script: ui.success("Hello from a workflow")
steps run in order by default. Each step's type selects a task; a Starlark
script step uses type: script and interpreter: starlark. Add parallel or
matrix groups for independent work. See the workflow reference
for file discovery and the step reference for execution settings.
Inputs and results
A script reads its declared env values and returns a step value by assigning
output. Later steps can reference .steps.<name>.value, or named results from
an outputs mapping. Structured values cross step boundaries as JSON; decode
them with json.decode in a receiving script.
Prompt steps can collect values interactively. Set explicit defaults for CI; a prompt without a default fails when no terminal is available.
Test the workflow
Group script assertions, command checks, and HTTP checks under a type: test
step. Atmos displays their results and shows failing output, so the workflow can
verify its own results as part of the runbook. A test group can also run in a
custom command or lifecycle hook.
See testing automation for a complete suite and checks written in Starlark.
Share program logic
Move a reusable program into a .star file and include it in the script step.
Use load() within that program to share functions with custom commands, hooks,
or standalone CLI apps. File-backed imports resolve beside the script rather
than whichever directory invoked the workflow.
See source files and includes for inline scripts, included step lists, and path resolution.
Run parallel functions
Within a script, steps.task describes a function
call and steps.parallel runs a collection with a concurrency limit. Task
results retain input order, and output identifies the task that produced it.
Each task can have its own retry and timeout policy. Retrying runs the entire function again; choose operations that are safe to repeat. See the task API for parameterized calls and cancellation behavior.
Preview and execution environment
Add --dry-run to the workflow command to validate the script syntax
without executing its code. Embedded scripts in parallel and matrix children
also remain unexecuted during a dry run.
An embedded script runs inside Atmos. When a workflow uses containers, set
container: false on its Starlark script steps. External commands started by a
script still need their tools and credentials available in the execution environment.
Continue with the language overview, or explore the release-plan walkthrough for reusable functions and component-aware parallel work.
Example: calculate capacity
With Atmos installed and on your PATH, save this configuration as atmos.yaml.
It tells Atmos to look for workflow files in the workflows directory:
Create workflows/capacity.yaml with a script step:
From the directory containing atmos.yaml, run the workflow:
atmos workflow capacity -f capacity
The program prints Total workers: 12. capacity here is a workflow name;
it does not register an atmos capacity subcommand. Use
custom commands to register an Atmos subcommand.
Example: collect input and pass results
Use input, choose, and
confirm steps to collect values through Atmos's native
prompts. Each answer becomes a step value. Pass it into a script through env,
then assign the script's output to provide a result for later steps.
With workflows.base_path: workflows in atmos.yaml, save this as workflows/release-inputs.yaml:
workflows:
prepare:
steps:
- name: target
type: choose
prompt: Select target environment
options: [dev, staging, prod]
default: dev
- name: release
type: script
interpreter: starlark
env:
STACK: '{{ .steps.target.value }}'
script: |
ui.info("Preparing release for " + env["STACK"])
output = {"stack": env["STACK"], "image": "api:v1.2.3"}
outputs:
image: '{{ (fromJson .value).image }}'
stack: '{{ (fromJson .value).stack }}'
- name: report
type: script
interpreter: starlark
env:
IMAGE: '{{ .steps.release.outputs.image }}'
STACK: '{{ .steps.release.outputs.stack }}'
script: |
print("Ready to deploy {} to {}".format(env["IMAGE"], env["STACK"]))
Run atmos workflow prepare -f release-inputs. In a terminal, select an
environment. Without a TTY, such as in CI, the prompt uses the explicit default
dev, and the final step prints Ready to deploy api:v1.2.3 to dev. This example
prepares and reports data; it does not deploy anything. A prompt without a default
fails in a noninteractive run instead of waiting for input.
The script's dictionary is JSON-encoded as the step value. The YAML outputs:
mapping extracts named results from that value with fromJson; later steps read
them through .steps.release.outputs.image and .steps.release.outputs.stack.
To pass the whole result instead, bind .steps.release.value to an environment
entry and decode it with json.decode in the next script. Status messages from
ui.info remain on stderr.
Inside a script, ordinary function returns and steps.parallel results can be
passed directly to other functions without JSON encoding. See output
for accepted values and stdout behavior.