diff --git a/webhook-listener/listener.js b/webhook-listener/listener.js index 973c346..6d30316 100644 --- a/webhook-listener/listener.js +++ b/webhook-listener/listener.js @@ -10,7 +10,7 @@ const LOG_FILE = '/home/deploy/stack/webhook-listener/deploy.log'; function log(message) { const timestamp = new Date().toISOString(); - const logMessage = `[${timestamp}] ${message}\n`; + const logMessage = '[' + timestamp + '] ' + message + '\n'; console.log(message); fs.appendFileSync(LOG_FILE, logMessage, 'utf8'); } @@ -27,16 +27,16 @@ try { let isBuilding = false; const server = http.createServer((req, res) => { - // Apenas aceita requisições POST na rota /webhook + // Apenas aceita requisicoes POST na rota /webhook const urlPath = req.url.split('?')[0]; if (req.method !== 'POST' || urlPath !== '/webhook') { res.writeHead(404, { 'Content-Type': 'application/json' }); - return res.end(JSON.stringify({ error: 'Rota não encontrada' })); + return res.end(JSON.stringify({ error: 'Rota nao encontrada' })); } - // Token de validação nos headers (Gitea envia como x-gitea-token) ou query string (?token=...) + // Token de validacao nos headers (Gitea envia como x-gitea-token) ou query string (?token=...) const tokenHeader = req.headers['x-gitea-token']; - + // Parsear query params manualmente de forma simples let tokenQuery = null; const qIndex = req.url.indexOf('?'); @@ -51,39 +51,58 @@ const server = http.createServer((req, res) => { } } } - + const token = tokenHeader || tokenQuery; if (!token || token !== SECRET_TOKEN) { - log('⚠️ Tentativa de acesso não autorizada: Token inválido ou ausente.'); + log('Tentativa de acesso nao autorizada: Token invalido ou ausente.'); res.writeHead(401, { 'Content-Type': 'application/json' }); - return res.end(JSON.stringify({ error: 'Não autorizado: Token inválido' })); + return res.end(JSON.stringify({ error: 'Nao autorizado: Token invalido' })); } if (isBuilding) { - log('⏳ Requisição de build recebida, mas já existe um build em andamento. Ignorando para evitar conflito de concorrência.'); + log('Requisicao de build recebida, mas ja existe um build em andamento. Ignorando para evitar conflito de concorrencia.'); res.writeHead(429, { 'Content-Type': 'application/json' }); - return res.end(JSON.stringify({ error: 'Um build já está sendo executado neste momento' })); + return res.end(JSON.stringify({ error: 'Um build ja esta sendo executado neste momento' })); } - // Retorna resposta de confirmação imediata (HTTP 202 Accepted) para evitar timeout do Gitea - res.writeHead(202, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify({ status: 'ok', message: 'Deploy automático iniciado em segundo plano' })); + // Ler o body completo para inspecionar o payload do Gitea + let body = ''; + req.on('data', function(chunk) { body += chunk.toString(); }); + req.on('end', function() { + // Verificar se todos os commits sao bumps de versao automaticos (evita loop infinito) + var payload = {}; + try { payload = JSON.parse(body); } catch (e) {} - // Inicia o processo de deploy - isBuilding = true; - log('🚀 Iniciando deploy-prod-builder.sh...'); - - exec(SCRIPT_PATH, (error, stdout, stderr) => { - isBuilding = false; - if (error) { - log(`❌ Erro no processo de deploy: ${error.message}`); - return; + var commits = payload.commits || []; + var headMsg = (payload.head_commit || {}).message || ''; + var allMessages = commits.map(function(c) { return c.message || ''; }).concat(headMsg).filter(function(m) { return m.trim() !== ''; }); + var VERSION_BUMP_RE = /^chore\(deploy\):\s*bump version/i; + if (allMessages.length > 0 && allMessages.every(function(msg) { return VERSION_BUMP_RE.test(msg); })) { + log('Commit de bump de versao detectado -- deploy ignorado para evitar loop de CI.'); + res.writeHead(200, { 'Content-Type': 'application/json' }); + return res.end(JSON.stringify({ status: 'skipped', reason: 'version-bump commit' })); } - log('✅ Processo de deploy finalizado.'); + + // Retorna resposta de confirmacao imediata (HTTP 202 Accepted) para evitar timeout do Gitea + res.writeHead(202, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ status: 'ok', message: 'Deploy automatico iniciado em segundo plano' })); + + // Inicia o processo de deploy + isBuilding = true; + log('Iniciando deploy-prod-builder.sh...'); + + exec(SCRIPT_PATH, function(error, stdout, stderr) { + isBuilding = false; + if (error) { + log('Erro no processo de deploy: ' + error.message); + return; + } + log('Processo de deploy finalizado.'); + }); }); }); -server.listen(PORT, HOST, () => { - log(`📡 Webhook listener ativo em http://${HOST}:${PORT}/webhook`); +server.listen(PORT, HOST, function() { + log('Webhook listener ativo em http://' + HOST + ':' + PORT + '/webhook'); });