Appearance
config Command
Migrata supports a powerful config-first workflow, allowing you to define your migration commands in reusable YAML or JSON files instead of relying solely on CLI arguments. This approach offers improved readability and reproducibility making it easy to version, share, and automate your migration logic.
Usage
bash
migrata config -f ./path/to/your/config.ymlKey Features
- Config-First Usage: Define all migrata commands and options in a YAML or JSON config file for clarity and repeatability.
- Automation: You can chain together multiple commands into a single config file, to perform multiple actions with the cli
- Secret Interpolation: Securely reference sensitive values (like database connection strings) from external files or environment variables, so secrets never need to be committed to source control.
- Flexible Syntax: Use simple patterns to inject secrets at runtime, supporting both file-based and environment-based sources.
Secret Interpolation Syntax
You can inject secrets into your config using the following patterns:
- File-based:
${file:/path/to/secrets.json:vars.MY_DB_CONN}- Reads the value from a specific property in a JSON or YAML file.
- Environment-based:
${env:MY_DB_CONN}- Reads the value from an environment variable.
This makes it easy to keep your configs safe, portable, and ready for use in CI/CD pipelines or team environments.
Examples
Below is a fairly standard diff command using the regular cli interface
bash
migrata diff \
--from "postgresql://user:pass@host:5432/postgres" \
--to ./proposed.sql \
--format "table"
--include "public*"Below is the equivalent yaml version of the cli command.
yaml
diff:
to: ./path/to/schemas
from: postgresql://user:pass@host:5432/postgres
format: stacked
include: public*Once that file is defined, you can just pass it to the cli like this:
bash
migrata config -f ./path/to/your/config.ymlReading secrets from a file
In the example below we'll assume we have this json file stored inside our repo with our secret connection string. We'll also assume this file is added to the .gitignore file so we don't accidentally track this.
json
{
"vars": {
"YOUR_DB_CONN": "postgresql://user:pass@host:5432/postgres"
}
}Then in our config file, we can use this syntax to point to the exact property within the file. This value will get interpolated into your config at runtime.
yaml
diff:
to: ./path/to/schemas
from: "${file:/some/path/to/secrets.json:vars.MY_DB_CONN}"
format: stacked
include: "public*"File Access Syntax
Lets take closer look at this example to break down how this works
${file:/some/path/to/secrets.json:vars.MY_DB_CONN}
It's important to know that we use : character to separate the parts of this pattern
${}- This pattern tells the tool we are loading in some dynamic valuefile- This prefix tells us that we plan on reading a secret from a file (json or yaml)/some/path/to/secrets.json- is the path to the file that holds the secretsvars.MY_DB_CONN- This tells the cli which property to extract from the file for this secret
ENV Access Syntax
You can also interpolate values from an environment variable into your config.
yaml
diff:
to: ./path/to/schemas
from: "${env:MY_DB_CONN}"
format: stacked
include: "public*"${}- This pattern tells the tool we are loading in some dynamic valueenv- This prefix tells us that we plan on reading a secret from the environmentMY_DB_CONN- is the env name to read
Automation Examples
One other neat feature of this config system, is that you can combine multiple commands into a single config file.
For example, if you wanted to sync the schemas of multiple databases you can just do the following:
yaml
schema:
inspect:
from: postgresql://user:pass@host:5432/db1
to: ./schemas-v1
include: "public*"
schema:
inspect:
from: postgresql://user:pass@host:5432/db2
to: ./schemas-v2
include: "public*"This will execute sequentially and sync both database schemas to their respective directories
Config Key Reference
Each top-level key in the config file maps to a CLI command. Nested keys map to flags (without the -- prefix).
diff
yaml
diff:
from: <SOURCE> # --from (Required)
to: <TARGET> # --to (Required)
include: <GLOB> # --include
exclude: <GLOB> # --exclude
out: <DIR> # -o / --out
postfix: <NAME> # -p / --postfix
format: stacked # --format (stacked, inline, table)
safe-cast: true # --safe-cast
no-styles: true # --no-styles
silent: true # --silent
no-logs: true # --no-logs
log-file: <FILE> # --log-file
approve: true # --approve
abort: true # --abort
skip-lock: true # --skip-lock
dev-image: <IMAGE> # --dev-image
answer: # --answer (repeatable)
- "key1=value1"
- "key2=value2"apply
yaml
apply:
from: <FILE> # --from (Required)
to: <TARGET> # --to (Required)
include: <GLOB> # --include
exclude: <GLOB> # --exclude
silent: true # --silent
no-logs: true # --no-logs
log-file: <FILE> # --log-file
dry-run: true # --dry-run
skip-lock: true # --skip-lockschema inspect
yaml
schema:
inspect:
from: <CONNECTION> # --from (Required)
to: <DIR> # --to (Required)
include: <GLOB> # --include
exclude: <GLOB> # --exclude
silent: true # --silentauth
yaml
auth:
login:
logout: