Skip to main content

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:

atmos.yaml
base_path: .
workflows:
base_path: workflows

Create workflows/capacity.yaml with a script step:

workflows/capacity.yaml
workflows:
capacity:
description: Report available worker capacity.
steps:
- name: report
type: script
interpreter: starlark
script: |
replicas = 3
workers_per_replica = 4
print("Total workers: {}".format(replicas * workers_per_replica))

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/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.