fcsc_ipi_backend/app/controllers/deployment.controller.js
2025-12-26 12:44:50 +05:30

128 lines
4.9 KiB
JavaScript

exports.deployment = async (req, res) => {
try {
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: 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()));
// 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 with child id
return res.status(200).json({ ok: true, action: 'deploy_started', pid: child.pid });
// ##############################################################
} catch (err) {
logger.error(err.message);
logger.error(`Stack trace: ${err.stack}`);
res.status(500).send({'status':"failed",'message': "Internal server error" });
}
};