.destesi.yml
.destesi.yml
Section titled “.destesi.yml”Commit your preview’s env list to your repo. The file ships with the PR, so adding an env var is a normal code change reviewable in the same diff.
Minimal example
Section titled “Minimal example”Drop this at your repo root and push:
version: 1
preview: enabled: true env: - name: DATABASE_URL value: ${postgres.dsn} - name: APP_ENV value: previewOn the next pull_request webhook, the GitHub App reads this file from your PR’s head SHA via the contents API and uses its env list as the authoritative config_json for the preview — before the controller even picks up the work item. Templates like ${postgres.dsn} resolve server-side the same way the dashboard’s env editor does — see Env templates for the reference list.
Who reads it: the GitHub App
Section titled “Who reads it: the GitHub App”For PR-driven previews the GitHub App is the decision point. On every pull_request webhook, it fetches .destesi.yml from your PR’s head SHA via the contents API, parses it, and dispatches per-product side effects (just preview today; review when it lands). Each product’s controller stays focused on its own job — preview’s controller doesn’t read the file at all; the parse-and-apply happens on the API side (the same is true of the tarball-upload path — see Where the file is read from).
This means: products are independently opt-in (preview block alone, review block alone, both, or neither). Adding a new product later doesn’t change the file shape — it adds a new top-level block.
Read source: PR branch
Section titled “Read source: PR branch”The file is read from the PR branch, not the default branch. This matches preview’s “what the PR proposes is what gets deployed” model — adding an env var to .destesi.yml in the same PR that adds a service to docker-compose.yml is the natural workflow.
Implication: a contributor with PR access can effectively change preview env behavior on their own branch. This is consistent with what they can already do via docker-compose.yml; if your security model needs stricter governance, gate which contributors can open PRs at the repo level.
File-wins-strict precedence
Section titled “File-wins-strict precedence”When the file is present with preview.enabled: true, its env list is the authoritative config_json. The dashboard’s previously-saved env list is overwritten, not merged.
| File state | Effect on config_json |
|---|---|
| absent | Dashboard env survives. The preview behaves exactly as it did before this feature shipped. |
present + enabled: false |
File is parsed but ignored. Dashboard env survives. |
present + enabled: true + non-empty env |
Dashboard env is overwritten with file’s env. |
present + enabled: true + empty env |
Dashboard env is cleared. (Explicit “I want zero env vars from yml.”) |
| present but parse error | Preview build fails loud. Fix the file before the next push. |
If you maintain env via the dashboard today and want to migrate, copy your env entries into the file in one PR — the next merged build will use the file from then on.
Validation
Section titled “Validation”Same rules as the dashboard editor:
- Names must match
[A-Z_][A-Z0-9_]*(uppercase POSIX-ish). - No duplicate names.
- Templates must use
${namespace.field}with a known namespace + field — see the env reference table. - Mark sensitive values
secret: trueto redact them from web UI and API list responses.
Validation runs api-side when the controller POSTs the file’s env. Malformed entries fail the build with a clear message rather than landing in the runner with surprises.
Larger example with secrets
Section titled “Larger example with secrets”version: 1
preview: enabled: true env: - name: DATABASE_URL value: postgres://${postgres.user}:${postgres.password}@${postgres.host}:${postgres.port}/${postgres.database}?sslmode=disable
- name: APP_ENV value: preview
- name: STRIPE_SECRET_KEY value: sk_test_xxx secret: true
- name: NODE_ENV value: productionWhere the file is read from
Section titled “Where the file is read from”Two entry points read .destesi.yml and apply the same preview: block effects:
- The Destesi GitHub App on a
pull_requestwebhook — fetches the file at the PR’s head SHA via the contents API. dst preview create --from-dir(CLI / GitHub Actions tarball uploads) — the uploaded tarball is scanned for a root.destesi.yml.
Both paths apply preview.env, preview.oauth, and preview.snap.connector block-for-block. Dashboard-managed previews that never commit the file keep using their dashboard config.
The preview: block
Section titled “The preview: block”preview.enabled gates the rest. The recognized sub-keys are:
env— the authoritative env list (overwrites dashboard env when present; see the precedence table above).oauth— per-provider OAuth passthrough mappings (callback_path+ optionalscopes), the file equivalent of the CLI’s--oauthflag. See OAuth passthrough.snap.connector— link the preview to a Snap data source by remote name, the file equivalent of--from-remote.
Not in the file
Section titled “Not in the file”- Notifications config — per-workspace, not per-repo, so the dashboard remains the right home.
- Prewarm settings — per (repo, branch) rather than per-PR.