Preview before production — with a gate where it counts.
GAA deployment ships a specific commit to a named environment. Wire the environment to a provider and TillForge builds and ships it for you — clone, build on the runner, deploy through the provider’s own CLI; or leave it tracking-only and report state back from your own pipeline. Previews land freely; production environments can require approvals. Every deploy records the exact commit, so a crash later traces straight back to what shipped.
Define preview and production
An environment is a named target — preview, staging, production, whatever your flow needs. Mark the ones that matter --production and set --approvals so a deploy to them waits for sign-off. Preview environments stay open, so a branch or a pull request can go live for review with no ceremony.
# Define your environments. A preview env is open; a production env can
# require approvals before anything lands.
tilldev forge env set acme-api --name preview --url https://preview.acme.dev
tilldev forge env set acme-api --name production --production \
--url https://acme.dev --approvals 1
tilldev forge env ls acme-apiLet TillForge build and ship it
Wire an environment to a provider and TillForge owns the whole deploy. Connect a provider credential once — a static host (Cloudflare Pages, Netlify, Vercel, Firebase, Surge, Azure Static Web Apps), object storage (AWS S3 + CloudFront), edge functions (Supabase), or a container platform (Railway, Fly.io) — and it’s envelope-encrypted under your org key the moment it arrives; the dashboard only ever shows a hint. Then point an environment at that credential and a build recipe, and every deploy runs on your own CI runner: it clones the exact commit, builds it in the hardened container, and ships the output through the provider’s CLI. The credential is injected into the build only at run time — never stored in the job, never printed in the log.
# 1 · Connect a provider credential once (envelope-encrypted at rest).
tilldev forge provider connect --name "prod cloudflare" --provider cloudflare \
--credential 'api_token=cf_xxx,account_id=abc123'
# 2 · Wire an environment to it + a build recipe, and auto-deploy on push to main.
tilldev forge env set acme-api --name production --production \
--provider cloudflare --credential <credential-id> \
--target 'project=acme-web' --build 'npm run build' --output dist \
--auto-deploy main
# 3 · Deploy — TillForge clones, builds on the runner, and ships via wrangler.
tilldev forge deploy create acme-api --env production --ref main
tilldev forge deploy logs acme-api <id> # the live build + ship log
tilldev forge deploy promote acme-api <id> --env production
tilldev forge deploy rollback acme-api <id> # redeploy a known-good commit| Provider | Credential | Target |
|---|---|---|
| Cloudflare Pages | api_token (Pages:Edit) · account_id | project |
| Vercel | token | project_id · org_id |
| Netlify | auth_token | site_id |
| Supabase Edge Functions | access_token | project_ref · function (optional) |
| AWS (S3 + CloudFront) | access_key_id · secret_access_key · session_token (optional) | bucket · region · distribution_id (optional) |
| Firebase Hosting | service_account (JSON) | project_id · site (optional) |
| Surge.sh | login · token | domain |
| Azure Static Web Apps | deployment_token | environment (optional) |
| Railway | token | service (optional) |
| Fly.io | api_token | app |
| Desktop bundles | signing: none · pfx · azure_trusted | framework · platforms |
electron-builder cross-builds Linux (.AppImage/.deb) and Windows (.exe/.msi) from one Linux runner; Tauri builds Linux. Point the deploy’s ref at a release tag and the installers attach to that release with published sha256 checksums.none to ship unsigned installers (Windows shows a SmartScreen warning; the sha256checksums still prove integrity). Choose Azure Trusted Signing(azure_trusted, recommended) and the private key never leaves Azure’s HSM — the runner holds only a short-lived token — which is also the only path that earns a new certificate public SmartScreen trust. Or bring your own Authenticode certificate (pfx) for an enterprise or legacy cert you already hold. Linux binaries are never run-signed. The signing secret is envelope-encrypted in the vault and only ever reaches the runner as claim-time environment — never the recipe or the build log.A desktop bundle end to end — connect a signing credential, wire the target (framework · platforms), and cut installers on a release tag:
# 1 · Connect a desktop signing credential (envelope-encrypted at rest).
# Azure Trusted Signing (recommended) — the key never leaves Azure's HSM;
# the runner only ever holds a short-lived token.
tilldev forge provider connect --name "desktop signing" --provider desktop \
--credential 'signing=azure_trusted,tenant_id=…,client_id=…,client_secret=…,\
endpoint=https://eus.codesigning.azure.net,account=my-ts-account,certificate_profile=my-profile'
# …or bring your own Authenticode cert:
# --credential 'signing=pfx,cert_base64=<base64 of your .pfx>,cert_password=…'
# …or skip signing entirely (sha256 checksums still prove integrity):
# --credential 'signing=none'
# 2 · Wire an environment: electron cross-builds Linux + Windows from one runner.
tilldev forge env set acme-app --name desktop --provider desktop \
--credential <credential-id> --target 'framework=electron,platforms=linux,windows'
# 3 · Deploy against a release tag — the installers attach to that release,
# each with a published sha256 checksum. Windows binaries are signed per the
# credential; Linux is never run-signed.
tilldev forge deploy create acme-app --env desktop --ref v1.4.0
tilldev forge deploy logs acme-app <id> # the live build + sign + publish log--auto-deploy main and a push to that branch ships production on its own; mark another environment --auto-preview and every other branch push gets its own preview URL. Push access is the gate, so a fork’s pull request never touches your provider secrets. Watch a build with deploy logs, move a known-good commit forward with promote, or back with rollback.Or track a deploy you ship elsewhere
Leave an environment’s provider unset and it stays a tracking-only record: you deploy a ref — a branch, a tag, or a release — from your own pipeline and report its state back. The natural path is still preview first, then promote the very same commit to production once it’s reviewed. Because a deploy names a commit, a promotion is provably the thing you already saw, not a fresh build that drifted.
# Deploy a ref to an environment. Previews first — a branch or a PR.
tilldev forge deploy create acme-api --env preview --ref feat/checkout \
--url https://checkout.preview.acme.dev
# Promote to production by deploying the same commit to the gated env.
tilldev forge deploy create acme-api --env production --ref v1.4.0
# Move a deployment through its lifecycle as your pipeline reports back.
tilldev forge deploy status acme-api <id> --state success
tilldev forge deploy ls acme-api --env productionTrack every deploy
A first-party deploy moves through these states on its own as the build runs; a tracking deploy is moved by your pipeline. Either way the Deploy tab shows the current state of every environment and the full history beneath it.
| State | Meaning |
|---|---|
queued | Accepted, waiting to start (or for approval). |
in_progress | Rolling out now. |
success | Live. This is the current deploy for the environment. |
failure | The rollout failed; the previous deploy stays live. |
error | The pipeline errored before it could finish. |
inactive | Superseded by a newer deploy, or torn down. |
Each deployment can carry a --url (where the deploy is reachable) and a link to its run. A deployment event fires on every state change, so your own dashboards and chat can follow along.
From deploy to the crash it caused
Because a deployment is pinned to a commit, TillForge can line up commit → deploy → incident. When something breaks after a release, the trail runs from the crash back to the deploy that shipped it and the exact change inside it — the same correlation that powers a pull request’s release view.
Next: Releases & builds for what you promote, or Events & webhooks to wire deploys into your own pipeline. Back to the TillForge overview.