Development & Deployment Workflow¶
Updated April 2026 — we simplified from feature → staging → main to single-branch. All PRs now target main directly. The staging branch still exists for internal validation deploys but is no longer part of the contribution flow.
The flow¶
┌──────────────┐ ┌──────────────┐
│ feature/* │────►│ main │
│ (develop) │ PR │ (prod) │
└──────────────┘ └──────┬───────┘
│
auto-deploy
│
┌──────▼───────┐
│ Prod VPS │
│89.116.31.109 │
│ editor │
│.astradial.com│
└──────────────┘
Maintainers test PRs locally or on open.astradial.com before approving. Main is protected — only approved PRs merge.
Step-by-step¶
1. Branch from main¶
Use conventional prefixes: feat/, fix/, docs/, refactor/, chore/.
2. Develop and test locally¶
cd editor
npm install
npm run dev # local dev server (port 3001)
npm run build # verify build
npx tsc --noEmit # verify TypeScript
For backend services: docker compose up mariadb redis asterisk api workflow-engine.
3. Push and open PR to main¶
git push origin feat/add-whatsapp-templates
# GitHub → New PR → base: main → compare: feat/add-whatsapp-templates
Fill out the PR template. Link the issue (Closes #<number>). Tick the shadcn-only and no-secrets boxes.
4. Review + merge¶
Maintainer reviews. On merge → auto-deploys to production via self-hosted runner.
5. Verify production¶
Open https://editor.astradial.com — confirm live.
Why the flow changed¶
The old feature → staging → main flow added a mandatory extra PR and slowed contributions without catching issues that local testing + reviewer validation didn't already catch. Staging VPS is still running for longer-lived validation of platform-level changes (schema migrations, NUC routing, etc.) — but we promote to it manually from main rather than gating every PR through it.
When to still use staging (manually):
- Schema migrations that need real data shape validation before prod.
- Platform changes touching NUC / Asterisk / WireGuard routing.
- Any change a maintainer flags as "test on staging first" during review.
For those, cherry-pick to the staging branch after the PR lands on main, validate on stageeditor.astradial.com, then deploy to prod.
Repositories¶
As of the April 17 2026 monorepo cutover, all four apps live in astradial/astradial:
| Path | What it is |
|---|---|
editor/ | Next.js dashboard + editor UI |
api/ | Node.js PBX API server (AstraPBX) |
workflow-engine/ | Bull job scheduler |
pipecat-flow/ | Python AI voice bot gateway |
One repo, one PR, one auto-deploy pipeline. See docs/development/cicd.md for runner details.
Branch retention policy¶
Branches are never auto-deleted after merge across all Astradial repositories. This is enforced via the GitHub repo setting ("Automatically delete head branches" = off).
Why: merged branches serve as an audit trail — they let you trace exactly what code shipped in a given PR, check out the state at any point, and diff against main without reconstructing history from commits.
If you want to clean up your local working copies after a PR merges, that's fine:
Never run git push origin --delete feat/my-feature on a merged branch.
Keeping staging in sync with prod hotfixes¶
When production bugs are fixed directly on the prod VPS (89.116.31.109) and not yet in git, those fixes must be manually applied to staging (94.136.188.221) before they diverge further. Do this immediately after the prod fix is confirmed working.
Checklist for a prod-to-staging sync:
- DB schema — run the same
ALTER TABLE/ migration on staging MariaDB - nginx — apply the same config changes in
/etc/nginx/sites-enabled/stageeditor.astradial.com, thennginx -t && nginx -s reload - server.js — apply the same endpoint additions/fixes; restart astrapbx:
pm2 restart astrapbx - Editor source — apply the same file edits under
/opt/pipecat-flow-editor/; rebuild and restart:npm run build && pm2 restart editor - Verify — check
pm2 statuson staging, confirmunstable restarts = 0
The goal is that staging always has a superset of what prod has, so that staging tests don't fail on bugs already fixed in prod.
What NOT to do¶
- Never push directly to
main— always open a PR. - Never commit
.env,.env.local,firebase-sa-key.json, or any secret. - Never use custom colors — only shadcn/ui default tokens.
- Never deploy via manual
scp(use the PR flow). - Never run
pm2 restarton prod — alwayspm2 reload(graceful, no downtime). - Never target a PR at
stagingunless a maintainer explicitly asked for it. - Never delete a merged branch — branches are kept for audit purposes (see above).