github actions → staging → production
Every push to main triggers the full pipeline. Tests and linting run in parallel,
then the build step produces a Docker image. Staging deploys automatically; production requires
manual approval via a GitHub environment gate.
graph TD
A["Push"] --> B{"Branch?"}
B -->|"feature"| P["Preview deploy"]
B -->|"main"| C["Run tests<br/>lint, unit, integration"]
C --> G["Build image"]
G --> H["Deploy to staging"]
H --> K{"Smoke tests pass?"}
K -->|"no"| M["Alert and roll back"]
K -->|"yes"| L["Manual approval"]
L --> N["Deploy to production"]
N --> O["Health check"]
layout: 'elk' engine mis-measures HTML labels in some environments and can
produce a giant, unreadable canvas — avoid it unless verified in the target browser.