From d7a18bb216ea76e1b8c0112c9f6a89dc66137bae Mon Sep 17 00:00:00 2001 From: velz Date: Wed, 29 Oct 2025 17:49:04 +0530 Subject: [PATCH 1/4] FEAT_AUTO_DEPLOY_ENABLED --- app/controllers/deployment.controller.js | 116 ++++++++++++++++++++++- server.js | 2 +- 2 files changed, 115 insertions(+), 3 deletions(-) diff --git a/app/controllers/deployment.controller.js b/app/controllers/deployment.controller.js index 79cfd83..7b08834 100644 --- a/app/controllers/deployment.controller.js +++ b/app/controllers/deployment.controller.js @@ -3,8 +3,120 @@ exports.deployment = async (req, res) => { try { - - res.status(201).send({'status':"success",'message':"successfully Deployed" }); + const fs = require('fs'); + const path = require('path'); + const { spawn } = require('child_process'); + const logger = require("../services/logger"); + const providedKey = (req.query.apikey || '').toString(); + const BITBUCKET_API_KEY = process.env.BITBUCKET_API_KEY || ''; + const EXPECTED_REPO = process.env.EXPECTED_REPO; + const EXPECTED_BRANCH = process.env.EXPECTED_BRANCH; + const DEPLOY_SCRIPT = process.env.DEPLOY_SCRIPT; + + // Utility: pick branch name from a changes object + function getBranchNamesFromChanges(changes = []) { + const names = []; + for (const ch of changes) { + if (!ch || typeof ch !== 'object') continue; + if (ch.new && ch.new.name) names.push(ch.new.name); + if (ch.old && ch.old.name) names.push(ch.old.name); + // some payloads may have 'ref' or other places; add if needed + } + return names; + } + + if (!BITBUCKET_API_KEY) { + // appendLog('ERROR: Server API_KEY not configured in env.'); + logger.info("Server misconfigured - API_KEY"); + return res.status(500).json({ ok: false, message: 'Server misconfigured - API_KEY' }); + } + + if (!EXPECTED_REPO) { + // appendLog('ERROR: Server API_KEY not configured in env.'); + logger.info("Server misconfigured - REPO"); + return res.status(500).json({ ok: false, message: 'Server misconfigured - REPO ' }); + } + + if (!EXPECTED_BRANCH) { + // appendLog('ERROR: Server API_KEY not configured in env.'); + logger.info("Server misconfigured - BRANCH"); + return res.status(500).json({ ok: false, message: 'Server misconfigured - BRANCH ' }); + } + + if (!DEPLOY_SCRIPT) { + // appendLog('ERROR: Server API_KEY not configured in env.'); + logger.info("Server misconfigured - Script"); + return res.status(500).json({ ok: false, message: 'Server misconfigured - Script ' }); + } + + + if (!providedKey) { + // appendLog('ERROR: Server API_KEY not configured in env.'); + logger.info("API key missing"); + return res.status(401).json({ ok: false, message: 'API key missing' }); + } + + if (providedKey != BITBUCKET_API_KEY) { + // appendLog('ERROR: Server API_KEY not configured in env.'); + logger.info("Invalid API key"); + return res.status(401).json({ ok: false, message: 'Invalid API key' }); + } + + + // ############################################################## + + const payload = req.body; + if (!payload || typeof payload !== 'object') { + logger.info('BAD_PAYLOAD: empty or invalid JSON body'); + return res.status(400).json({ ok: false, message: 'Invalid payload' }); + } + + const repoFullName = payload.repository && payload.repository.full_name; + if (repoFullName !== EXPECTED_REPO) { + logger.info('IGNORED: repo mismatch', 'expected=' + EXPECTED_REPO, 'got=' + repoFullName); + // do nothing except log + return res.status(200).json({ ok: true, action: 'ignored', reason: 'repository mismatch' }); + } + + const changes = (payload.push && payload.push.changes) || []; + const branchNames = getBranchNamesFromChanges(changes); + + const hasMaster = branchNames.includes(EXPECTED_BRANCH); + + if (!hasMaster) { + logger.info('IGNORED: branch not master', 'branches=' + JSON.stringify(branchNames)); + return res.status(200).json({ ok: true, action: 'ignored', reason: 'branch not as exp' }); + } + + // All checks passed — call the deploy script + if (!fs.existsSync(DEPLOY_SCRIPT)) { + logger.info('ERROR: deploy script not found at', DEPLOY_SCRIPT); + return res.status(500).json({ ok: false, message: 'Deploy script missing' }); + } + + logger.info('DEPLOY_TRIGGER: repo ' + repoFullName + 'branch - ' + EXPECTED_BRANCH + 'script - ' + DEPLOY_SCRIPT); + + // spawn the script (non-blocking). Adjust args as required. + const child = spawn(DEPLOY_SCRIPT, [], { + cwd: path.dirname(DEPLOY_SCRIPT), + env: process.env, + detached: false + }); + + // capture output for logs + child.stdout.on('data', (d) => logger.info('SCRIPT_OUT:' + d.toString().trim())); + child.stderr.on('data', (d) => logger.info('SCRIPT_ERR:' + d.toString().trim())); + + child.on('close', (code) => logger.info('SCRIPT_EXIT:' + `code=${code}`)); + child.on('error', (err) => logger.info('SCRIPT_ERROR:' + (err && err.message ? err.message : String(err))) ); + + // Respond immediately saying it was started + return res.status(200).json({ ok: true, action: 'deploy_started', pid: child.pid }); + + + + + // ############################################################## } catch (err) { diff --git a/server.js b/server.js index a54446d..59a9cb4 100644 --- a/server.js +++ b/server.js @@ -58,7 +58,7 @@ app.get("/api/test", (req, res) => { //deployment route const deploymentController = require("./app/controllers/deployment.controller"); -app.get("/venba/deploy", deploymentController.deployment); +app.post("/deploy", deploymentController.deployment); // Sync DB // db.sequelize.sync({ alter: true }).then(() => { From 14f8f5410a135a9e87dfdfa4cf06b6641c0564e5 Mon Sep 17 00:00:00 2001 From: velz Date: Wed, 29 Oct 2025 18:46:27 +0530 Subject: [PATCH 2/4] FIX_AUTO_DEPLOYE --- app/controllers/deployment.controller.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/deployment.controller.js b/app/controllers/deployment.controller.js index 7b08834..c900f6c 100644 --- a/app/controllers/deployment.controller.js +++ b/app/controllers/deployment.controller.js @@ -100,9 +100,10 @@ exports.deployment = async (req, res) => { const child = spawn(DEPLOY_SCRIPT, [], { cwd: path.dirname(DEPLOY_SCRIPT), env: process.env, - detached: false + detached: true, + stdio: ['ignore', 'ignore', 'ignore'] // detach fully }); - + child.unref(); // capture output for logs child.stdout.on('data', (d) => logger.info('SCRIPT_OUT:' + d.toString().trim())); child.stderr.on('data', (d) => logger.info('SCRIPT_ERR:' + d.toString().trim())); From 393e1c441ec76bdfa4d8c4843caae0a0c20f78e5 Mon Sep 17 00:00:00 2001 From: velz Date: Thu, 30 Oct 2025 10:13:57 +0530 Subject: [PATCH 3/4] FIX_AUTODEPLOY --- app/controllers/deployment.controller.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/deployment.controller.js b/app/controllers/deployment.controller.js index c900f6c..12463b7 100644 --- a/app/controllers/deployment.controller.js +++ b/app/controllers/deployment.controller.js @@ -105,11 +105,11 @@ exports.deployment = async (req, res) => { }); child.unref(); // capture output for logs - child.stdout.on('data', (d) => logger.info('SCRIPT_OUT:' + d.toString().trim())); - child.stderr.on('data', (d) => logger.info('SCRIPT_ERR:' + d.toString().trim())); + // child.stdout.on('data', (d) => logger.info('SCRIPT_OUT:' + d.toString().trim())); + // child.stderr.on('data', (d) => logger.info('SCRIPT_ERR:' + d.toString().trim())); - child.on('close', (code) => logger.info('SCRIPT_EXIT:' + `code=${code}`)); - child.on('error', (err) => logger.info('SCRIPT_ERROR:' + (err && err.message ? err.message : String(err))) ); + // child.on('close', (code) => logger.info('SCRIPT_EXIT:' + `code=${code}`)); + // child.on('error', (err) => logger.info('SCRIPT_ERROR:' + (err && err.message ? err.message : String(err))) ); // Respond immediately saying it was started return res.status(200).json({ ok: true, action: 'deploy_started', pid: child.pid }); From 9a0e47098ab3f13038892da7bd3eb937d491d1f3 Mon Sep 17 00:00:00 2001 From: velz Date: Thu, 30 Oct 2025 11:41:45 +0530 Subject: [PATCH 4/4] TEST_AUTO_DEPLOY --- app/controllers/deployment.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/deployment.controller.js b/app/controllers/deployment.controller.js index 12463b7..a4a1393 100644 --- a/app/controllers/deployment.controller.js +++ b/app/controllers/deployment.controller.js @@ -111,7 +111,7 @@ exports.deployment = async (req, res) => { // child.on('close', (code) => logger.info('SCRIPT_EXIT:' + `code=${code}`)); // child.on('error', (err) => logger.info('SCRIPT_ERROR:' + (err && err.message ? err.message : String(err))) ); - // Respond immediately saying it was started + // Respond immediately saying it was started with child id return res.status(200).json({ ok: true, action: 'deploy_started', pid: child.pid });