Versioning & git
Docs / Templates

Versioning & git

Keep templates in a repository you already review and deploy from. Connect it once per account; every push becomes an immutable version, and every message records the version and the commit it rendered from.

Repository layout

templates/
  welcome.twig            body (Twig) — or welcome.liquid
  welcome.text.twig       optional plain-text part
  welcome.json            optional sidecar: subject, name, variables,
                          is_sensitive, content_retention_days, layout
layouts/
  base.twig               optional; the body replaces {# body #}

The file name is the slug. The extension picks the engine; a sidecar that disagrees is an error, not a guess. A retention number above your plan ceiling is lowered to it, never refused. Everything is compile-checked at sync, and one bad file holds back the whole push — a sync is a single transaction.

Connecting a repository

  1. Templates → Sync from git → paste the SSH clone URL, the branch, and an optional folder inside the repo.
  2. We generate an ed25519 deploy key. Add the public half to the repository as a read-only deploy key (GitHub: Settings → Deploy keys; GitLab: Settings → Repository → Deploy keys). The private half never leaves our keyring.
  3. Add the push webhook URL shown once at connect. The token in the URL is the secret; the body is ignored. Without it, changes still arrive on the hourly fetch.
  4. Press Sync now.

We only ever read. The remote must be a public host — nothing on a private network — and an HTTPS URL is accepted only for a public repository, never with a token in it.

What a sync does

A new version is minted only when the subject, a body, the engine or the variables changed; a metadata-only edit updates the template without a version. Versions are immutable and never deleted. A file removed from the repository leaves its template sendable and listed as an orphan — retiring it is a deliberate act from the CLI, never a side effect of a push. A template created in the panel is never overwritten by a file of the same slug; the sync stops and says so.

HONESTY NOTE — WHAT WE RECORDEach version stores the last commit that touched its file. The Message Log shows that sha next to the version a message rendered from, so “what exactly did it say” has a git answer.