Aircast Deploy Bot

Automatic preview deployments for every pull request

How It Works

Every pull request to aircast-web or aircast-api automatically gets a preview deployment. No commands needed — just push code.

PR opened / pushed → Bot posts "⏳ Building..." comment with build progress → Bot dispatches build to source repo workflow → Source repo: checkout → install → lint → build → push Docker image → Source repo dispatches to gitops (ArgoCD ApplicationSet) → Gitops writes config.json → ArgoCD creates preview namespace → Gitops calls back to bot with build result → Bot polls preview URL until healthy (up to 90s) → Bot updates comment to "✅ Ready" with preview link PR closed / merged → Bot detects "preview" label → Bot dispatches cleanup to gitops → ArgoCD deletes preview namespace and resources

Commands

Comment on any PR to trigger these commands:

CommandDescriptionExample
/deploy devCreate or rebuild previewForces a fresh preview build
/deploy stagingDeploy to stagingUpdates staging image tag
/deploy prodDeploy to productionUpdates production image tag
/destroyTear down previewRemoves preview namespace
/env set K=VSet env vars/env set VITE_DEBUG=true
/env listShow env varsLists current overrides
/env clearRemove all env varsResets to defaults + rebuilds

Examples

Auto-deploy on PR open

Simply open a PR — the bot deploys automatically:

You: Open PR #42 with branch feat/new-feature

Bot: Adds preview label, posts comment:

### Preview Deployment
| Name | Status | Preview | Updated |
|------|--------|---------|--------|
| aircast-web | ⏳ Building (logs) | deploying... | abc12345 |

After build completes (~2-3 min):

### Preview Deployment
| Name | Status | Preview | Updated |
|------|--------|---------|--------|
| aircast-web | ✅ Ready (logs) | Visit Preview | abc12345 |

Build complete (2m 34s)
| Step | Status | Duration |
|------|--------|----------|
| Run actions/checkout | ✅ | 3s |
| Install dependencies | ✅ | 45s |
| Run linting | ✅ | 12s |
| Build frontend | ✅ | 1m 15s |
| Build and push Docker image | ✅ | 19s |

Override environment variables

You: Comment /env set VITE_PUBLIC_API_HOST=custom.api.com VITE_DEBUG=true

Bot: Reacts with 👍, stores env vars, triggers rebuild:

### Environment Variables Updated
| Variable | Value |
|----------|-------|
| VITE_PUBLIC_API_HOST | custom.api.com |
| VITE_DEBUG | true |

Redeploying preview with new config...

Deploy to staging

You: Comment /deploy staging

Bot: Reacts with 🚀, deploys PR branch to staging environment

Failed build

When a build fails, the bot shows the failed step and error output:

### Preview Deployment
| Name | Status | Preview | Updated |
|------|--------|---------|--------|
| aircast-web | ❌ Failed (logs) | — | abc12345 |

Build failed at: Run linting (1m 2s total)
| Step | Status | Duration |
|------|--------|----------|
| Run actions/checkout | ✅ | 3s |
| Install dependencies | ✅ | 45s |
| Run linting | ❌ | 14s |
| Build frontend | ⬜ | — |

Error: src/App.tsx(15,3): error TS2322: Type 'string' is
not assignable to type 'number'.

Environment Variables

Each preview environment can have custom env vars that override the defaults:

Set variables

/env set KEY1=value1 KEY2=value2

Multiple vars in one command. Triggers a rebuild with the new config.

List current

/env list

Shows all custom env vars for this PR's preview.

Clear all

/env clear

Removes all custom vars and rebuilds with defaults.

Common overrides

/env set VITE_PUBLIC_API_HOST=api.custom.test
/env set VITE_DEV_LOGIN_ENABLED=true
/env set VITE_PUBLIC_SFU_URL=wss://sfu.test

Build Log Streaming

The bot tracks build progress in real-time by polling GitHub Actions workflow steps:

Dashboard

A web dashboard is available at /dashboard (requires GitHub OAuth login):

Preview URLs

AppPreview URL PatternExample
aircast-webhttps://pr-{N}.app.dev.aircast.onepr-117.app.dev.aircast.one
aircast-apihttps://pr-{N}.api.dev.aircast.onepr-25.api.dev.aircast.one
aircast-websitehttps://pr-{N}.www.dev.aircast.onepr-5.www.dev.aircast.one
aircast-sfuhttps://pr-{N}.sfu.dev.aircast.onepr-3.sfu.dev.aircast.one

Status Phases

StatusMeaningWhat to do
⏳ BuildingSource repo is building Docker imageWait ~3 min for build to complete
🔨 Building (with progress)Build in progress with step detailsExpand to see which step is running
🔄 Deployed, syncing...Image built, ArgoCD syncingWait ~30s for ArgoCD to sync
✅ ReadyPreview is live and health-checkedClick "Visit Preview"
⚠️ Deployed (not responding)Health check timed out (90s)Try again in a moment, check pod logs
❌ FailedBuild or deploy failedClick "logs" link, check error output
⚪ CancelledBuild cancelled (newer push)New build auto-started for latest commit
🗑️ DestroyedPreview cleaned upUse /deploy dev to recreate

API Endpoints

EndpointMethodAuthDescription
/GETThis documentation page
/healthGETHealth check (returns "ok")
/metricsGETPrometheus metrics
/dashboardGETGitHub OAuthDeployment management UI
/api/github/webhookPOSTWebhook signatureGitHub webhook receiver
/api/deploy/completePOSTBearer tokenDeploy completion callback

Supported Repos

Installed on all aircast-one repositories. Auto-deploy enabled for:

Other repos receive webhook events but won't auto-deploy previews (no ApplicationSet configured).

Architecture

Bot Status: Operational  |  Health  |  Metrics  |  Dashboard  |  Source Code