Apply
Stoobly Scaffold Apply - Questions & Answers
scaffold apply runs an ordered list of scaffold CLI commands from a config file (by convention, .stoobly/scaffold.yml). Each step in the config maps 1:1 to stoobly-agent scaffold <resource> <action> …, so an entire app-and-services setup can be written once, reviewed in a pull request, checked into version control, and reproduced by anyone on the team with a single command — instead of typing out a sequence of scaffold app create / scaffold service create invocations by hand.
Getting Started
Q: How do I apply a scaffold config?
A: Point scaffold apply at the config file. Validate first with --dry-run, then apply for real.
Example:
stoobly-agent scaffold apply .stoobly/scaffold.yml --dry-run
stoobly-agent scaffold apply .stoobly/scaffold.ymlQ: What does the CLI command look like?
A:
Usage: stoobly-agent scaffold apply [OPTIONS] PATH
Apply scaffold commands from a config file
Options:
--dry-run If set, runs validation and logs only.
--format [yaml|json] Config file format. [default: yaml]
-h, --help Show this message and exit.PATH
Path to the config file. Required — there is no implicit lookup of .stoobly/scaffold.yml; you must always pass the path. Must be an existing regular file (not a directory).
--dry-run
Validates the config and logs what each step would do, without invoking any commands.
--format
yaml (default) or json. Does not sniff the file extension — a .json file applied without --format json is parsed as YAML.
The Config File
Q: What's the top-level structure of scaffold.yml?
A: Two required keys: version (must be the integer 1) and commands (a non-empty ordered list of steps).
Example:
Steps run in order and stop on the first failure.
Q: What does a step look like?
A: Each entry in commands has a resource, an action, and an optional options mapping.
resource
yes
The scaffold command group, e.g. app, service.
action
yes
The subcommand under that group, e.g. create.
options
no
Mapping of options and positional arguments for that command. Defaults to {}.
Q: Which resources and actions can I use in a config file?
A: scaffold apply only supports two levels — resource then a leaf action — so any scaffold subcommand nested deeper than that (like scaffold request logs list) can't be expressed in a config file. The complete, usable set is:
resource
valid action values
app
create
service
create, list, show, delete, update
workflow
create, copy, show, up, down, logs, mkcert, rewrite, filter, validate
hostname
install, uninstall
apply and describe aren't usable as a resource (they're standalone commands, not groups), and request is a group whose only child (logs) is itself a group, so it has no usable leaf action either.
Q: How do I translate a CLI flag into an options key?
A: Use the snake_case version of the flag name — --app-dir-path becomes app_dir_path, --copy-on-workflow-up becomes copy_on_workflow_up. Positional arguments (like the app or service name) use their argument name as the key.
Flag
boolean: quiet: true
Single value
scalar: hostname: api.example.com
Multi-value option (multiple=True)
list: plugin: [playwright] (a bare scalar is also accepted as a single value)
Positional argument
key matching the argument name: app_name: my-app, service_name: api
An option key that doesn't exist on the target command is a validation error before anything runs.
Some frequently used options have a fixed set of accepted values:
app create:plugin: [cypress, playwright],proxy_mode: [forward, reverse],runtime: [docker, local]service create:scheme/upstream_scheme:[http, https],workflow: [develop, mock, record, test]
Q: Which paths get resolved automatically, and against what?
A: These six option keys are path-expanded: app_dir_path, context_dir_path, script_path, ca_certs_dir_path, certs_dir_path, docker_socket_path. For each, ~ is expanded first, then — if the path is still relative — it's resolved against the config file's directory, not your current working directory. So a relative path in .stoobly/scaffold.yml resolves relative to .stoobly/, no matter where you run scaffold apply from. Lists of paths (e.g. multiple context_dir_path entries) are expanded element-wise. All other options are passed through unchanged.
scaffold apply never creates directories. If an option is required to already exist (for example context_dir_path), the underlying command's validation will fail if it doesn't.
Q: Can I use JSON instead of YAML?
A: Yes — pass --format json. The schema is identical, just expressed as JSON.
Example:
Full Example
Q: What does a larger, multi-service config look like?
A: A config can chain any number of app, service, and workflow steps. This example creates an app across two directories in a monorepo, adds three services (one local, one external with an OpenAPI spec, one with a custom test workflow), a custom ci workflow, and starts the mock workflow.
Validation and Failure Behavior
Q: When does validation happen?
A: The entire config is validated up front, before any step runs — every step's resource, action, and options are checked. A typo in the last step means the first step never runs either; you find out immediately rather than partway through applying.
Q: What happens if a step fails partway through?
A: scaffold apply stops at the first failing step and exits with that step's own exit code. Steps that already ran are not rolled back — their side effects (files created, services registered, etc.) remain in place. Later steps in the config are not run.
Q: Does --dry-run guarantee the real apply will succeed?
A: Not entirely. --dry-run runs full config validation (schema, unknown resource/action/option, accepted values, missing required options) and logs one line per step, but it never actually invokes a command. That means checks that only happen when a command runs — like a required directory existing on disk — are not exercised by --dry-run. Treat a clean dry run as "the config itself is well-formed," not as "applying it will definitely succeed."
Example:
Without --dry-run, the same steps log as applying … before each one actually runs:
Q: What are the common validation errors, and what do they mean?
A: All of the following are checked before any step is invoked and exit with code 1:
Missing version
Missing required property: version
Unsupported version
Unsupported version: … Supported versions: 1
Missing or empty commands
commands must be a non-empty list
Config file is empty, or its root isn't a mapping
Config file is empty / Config root must be a mapping
Invalid YAML/JSON
Failed to parse config file: …
Step missing resource or action
commands[i] missing required property: resource
Unknown resource
Unknown resource: …
resource isn't a command group
Resource '…' is not a command group
Unknown action
Unknown action '…' for resource '…'
action is a group, not a leaf command
Action '…' for resource '…' is a group, not a command
Unknown option key
commands[i]: Unknown options for command: …
Flag given a non-boolean value
commands[i].options.… must be a boolean flag
Value not in the accepted list
commands[i].options.… has invalid value …. Accepted values: …
Missing a required option/argument
commands[i] missing required option(s): …
A PATH that doesn't exist or is a directory fails Click's own argument check and exits with code 2 instead.
Related
Applying a Scaffold ConfigHow to Update a ScaffoldLast updated