.finalrun/env/<name>.yaml, then activate it with --env <name> or by setting env: <name> in .finalrun/config.yaml. Separating environments lets you run the same test specs against development, staging, and production configurations without touching the tests themselves.
Environment file structure
Each environment file lives at.finalrun/env/<name>.yaml and can contain three top-level blocks:
Per-environment app identity override. Values here take priority over the workspace default in
config.yaml. Useful when your staging or debug build uses a different package name or bundle ID.Placeholder bindings for sensitive values. Each value uses
${SHELL_ENV_VAR} syntax. The CLI resolves each placeholder from the shell environment or from workspace-root dotenv files at runtime. Do not put real secrets in this file.Plain, non-sensitive values such as locale strings, feature flags, or base URLs. Safe to commit.
Full example
.finalrun/env/dev.yaml
${secrets.email} and ${variables.locale}.
Dotenv files for secret values
Real secret values — API keys, passwords, tokens — belong in dotenv files at the workspace root, not in the YAML binding file.
FinalRun finds the workspace root by walking up from your shell’s current directory, so dotenv paths are always anchored to the folder that contains
.finalrun/, regardless of where you run the CLI from.
Load order
For an active environment namedN, the CLI loads values in this order:
1
Load .env.N
Environment-specific dotenv file is read first. Keys set here take precedence over the shared file.
2
Load .env
Shared dotenv file fills in any keys not already set by
.env.N.3
Apply process.env
Shell environment variables win if the same key exists in both a dotenv file and the current shell session.
secrets placeholder resolution and AI provider API key resolution.
Using environments with the CLI
Pass--env to activate a named environment for any command:
env: dev in .finalrun/config.yaml, --env becomes optional and the CLI uses dev by default.

