feat: Add voice and video stage functionality with multi-platform project setup.
Some checks failed
Build and Release / build-and-release (push) Has been cancelled

This commit is contained in:
Bryan1029384756
2026-02-21 15:48:48 -06:00
parent 84aa458012
commit 948f8c7aa7
9 changed files with 141 additions and 17 deletions

View File

@@ -16,6 +16,7 @@ const RELEASES_DIR = '/app/releases';
const LOADING_HTML = readFileSync(join(__dirname, 'loading.html'), 'utf-8');
let currentDistPath = null;
let currentCommitHash = null;
let building = false;
let lastBuildStatus = { status: 'idle', timestamp: null, error: null };
@@ -39,8 +40,15 @@ function run(cmd, opts = {}) {
execSync(cmd, { stdio: 'inherit', timeout: 600_000, ...opts });
}
async function triggerBuild() {
async function triggerBuild(webhookCommit) {
if (building) return;
// Fast path: skip clone entirely if webhook provides the commit and it matches
if (webhookCommit && webhookCommit === currentCommitHash) {
log(`Commit ${webhookCommit} is already deployed, skipping build (webhook fast path).`);
return;
}
building = true;
lastBuildStatus = { status: 'building', timestamp: Date.now(), error: null };
@@ -54,6 +62,17 @@ async function triggerBuild() {
// Clone
run(`git clone --depth 1 --branch ${GIT_BRANCH} ${GIT_REPO_URL} ${buildDir}`);
// Read the cloned commit hash
const clonedHash = execSync('git rev-parse HEAD', { cwd: buildDir, encoding: 'utf-8' }).trim();
log(`Cloned commit: ${clonedHash}`);
// Skip if this commit is already deployed
if (clonedHash === currentCommitHash) {
log(`Commit ${clonedHash} is already deployed, skipping build.`);
lastBuildStatus = { status: 'skipped', timestamp: Date.now(), error: null };
return;
}
// Install deps (web workspaces only)
run(
'npm ci --workspace=apps/web --workspace=packages/shared --workspace=packages/platform-web --include-workspace-root',
@@ -73,7 +92,8 @@ async function triggerBuild() {
// Swap — instant, zero downtime
const oldDist = currentDistPath;
currentDistPath = releaseDir;
log(`Swapped to new release: ${releaseDir}`);
currentCommitHash = clonedHash;
log(`Swapped to new release: ${releaseDir} (commit ${clonedHash})`);
// Clean up old release
if (oldDist && existsSync(oldDist) && oldDist !== releaseDir) {
@@ -105,13 +125,16 @@ app.use(compression());
app.post('/api/webhook', express.json(), (req, res) => {
if (building) return res.status(409).json({ error: 'Build already in progress' });
triggerBuild();
// Extract commit SHA from Gitea/GitHub push webhook payload
const webhookCommit = req.body?.after || null;
triggerBuild(webhookCommit);
res.json({ message: 'Build triggered' });
});
// Status endpoint
app.get('/api/status', (_req, res) => {
res.json({ building, ...lastBuildStatus });
res.json({ building, commitHash: currentCommitHash, ...lastBuildStatus });
});
// Static file serving + SPA fallback