#!/bin/bash # ============================================================================ # Git Hook: post-receive # ============================================================================ # Este hook executa automaticamente apos cada git push. # Ele faz build e deploy do site sem intervencao manual. # # Instalacao: # cp ci/hooks/post-receive /var/git/site.git/hooks/ # chmod +x /var/git/site.git/hooks/post-receive # ============================================================================ set -e # Cores GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' BLUE='\033[0;34m' NC='\033[0m' # Configuracoes REPO_DIR="$(pwd)" DEPLOY_DIR="/var/tmp/site-deploy-$(date +%s)" CI_DIR="/var/ci" LOG_FILE="/var/ci/logs/deploy-$(date +%Y%m%d-%H%M%S).log" LAST_LOG="/var/ci/logs/last-deploy.log" CONFIG_FILE="/var/ci/config.env" # Criar pasta de logs mkdir -p "$(dirname "$LOG_FILE")" # Funcao de log log() { echo -e "$1" | tee -a "$LOG_FILE" } # Redirect output to log exec > >(tee -a "$LOG_FILE") exec 2>&1 log "${BLUE}============================================================${NC}" log "${BLUE} Avanzato CI/CD - Deploy Automatico${NC}" log "${BLUE}============================================================${NC}" log "" log "Data: $(date)" log "Branch recebida: $1" log "Commit: $2" log "" # Carregar configuracoes if [ -f "$CONFIG_FILE" ]; then source "$CONFIG_FILE" log "${GREEN}[OK]${NC} Configuracoes carregadas." else log "${YELLOW}[AVISO]${NC} Arquivo config.env nao encontrado. Usando defaults." DEPLOY_PATH="/var/www/avanzato" STAGING_PATH="/var/www/avanzato-staging" BACKUP_PATH="/var/ci/backups" fi # Detectar branch while read oldrev newrev refname; do BRANCH=$(git rev-parse --symbolic --abbrev-ref "$refname") log "Processando branch: ${YELLOW}${BRANCH}${NC}" case "$BRANCH" in main|master) TARGET="production" DEPLOY_TARGET="$DEPLOY_PATH" ;; staging) TARGET="staging" DEPLOY_TARGET="$STAGING_PATH" ;; *) log "${YELLOW}[IGNORADO]${NC} Branch '${BRANCH}' nao configurada para deploy." log "Branches validas: main, master, staging" exit 0 ;; esac done log "" log "${BLUE}------------------------------------------------------------${NC}" log "Ambiente: ${YELLOW}${TARGET}${NC}" log "Destino: ${DEPLOY_TARGET}" log "${BLUE}------------------------------------------------------------${NC}" log "" # ========================================================================== # PASSO 1: Checkout do codigo # ========================================================================== log "${BLUE}[1/6]${NC} Checkout do codigo..." mkdir -p "$DEPLOY_DIR" git --git-dir="$REPO_DIR" --work-tree="$DEPLOY_DIR" checkout -f "$BRANCH" 2>&1 log "${GREEN}[OK]${NC} Codigo extraido para ${DEPLOY_DIR}" log "" # ========================================================================== # PASSO 2: Instalar dependencias # ========================================================================== log "${BLUE}[2/6]${NC} Instalando dependencias..." cd "$DEPLOY_DIR" if [ -f "package.json" ]; then npm ci --silent 2>&1 || { log "${RED}[ERRO]${NC} Falha ao instalar dependencias." exit 1 } log "${GREEN}[OK]${NC} Dependencias instaladas." else log "${YELLOW}[AVISO]${NC} package.json nao encontrado. Pulando." fi log "" # ========================================================================== # PASSO 3: Build # ========================================================================== log "${BLUE}[3/6]${NC} Executando build..." cd "$DEPLOY_DIR" if [ -f "package.json" ]; then npm run build 2>&1 || { log "${RED}[ERRO]${NC} Falha no build." exit 1 } # Verificar se a pasta dist foi criada if [ ! -d "dist" ]; then log "${RED}[ERRO]${NC} Pasta dist/ nao encontrada apos build." exit 1 fi log "${GREEN}[OK]${NC} Build concluido com sucesso." log "Tamanho: $(du -sh dist/ | cut -f1)" else # Se nao tem package.json, usar o proprio diretorio log "${YELLOW}[AVISO]${NC} Projeto estatico detectado. Usando arquivos diretamente." fi log "" # ========================================================================== # PASSO 4: Preservar assets # ========================================================================== log "${BLUE}[4/6]${NC} Preservando assets customizados..." cd "$DEPLOY_DIR" # Se existir pasta custom-assets, preservar if [ -d "custom-assets" ]; then log "Assets customizados encontrados. Preservando..." bash "${DEPLOY_DIR}/scripts/preserve-assets.sh" "${DEPLOY_DIR}/dist" 2>&1 || { log "${YELLOW}[AVISO]${NC} Erro ao preservar assets (nao critico)." } else log "${YELLOW}[AVISO]${NC} Nenhum asset customizado encontrado." fi # Se existem assets preservados no /var/ci/assets, copiar if [ -d "/var/ci/assets" ] && [ "$(ls -A /var/ci/assets)" ]; then log "Copiando assets preservados..." cp -r /var/ci/assets/* "${DEPLOY_DIR}/dist/" 2>/dev/null || true fi log "${GREEN}[OK]${NC} Assets processados." log "" # ========================================================================== # PASSO 5: Backup do site atual # ========================================================================== log "${BLUE}[5/6]${NC} Criando backup..." if [ -d "$DEPLOY_TARGET" ] && [ "$(ls -A "$DEPLOY_TARGET" 2>/dev/null)" ]; then BACKUP_NAME="backup-$(date +%Y%m%d-%H%M%S)" mkdir -p "$BACKUP_PATH" # Criar backup (excluindo backups antigos para nao duplicar) tar -czf "${BACKUP_PATH}/${BACKUP_NAME}.tar.gz" \ -C "$(dirname "$DEPLOY_TARGET")" \ --exclude="backups" \ "$(basename "$DEPLOY_TARGET")" 2>/dev/null || true # Limpar backups antigos (manter 10) ls -t "${BACKUP_PATH}"/*.tar.gz 2>/dev/null | tail -n +11 | xargs -r rm -f log "${GREEN}[OK]${NC} Backup criado: ${BACKUP_NAME}.tar.gz" else log "${YELLOW}[AVISO]${NC} Nada para fazer backup (primeiro deploy)." fi log "" # ========================================================================== # PASSO 6: Deploy # ========================================================================== log "${BLUE}[6/6]${NC} Fazendo deploy..." # Criar diretorio se nao existir mkdir -p "$DEPLOY_TARGET" # Limpar conteudo antigo (exceto backups) find "$DEPLOY_TARGET" -mindepth 1 -not -path "${DEPLOY_TARGET}/backups/*" -not -name "backups" -delete 2>/dev/null || rm -rf "${DEPLOY_TARGET:?}"/* # Copiar novos arquivos if [ -d "${DEPLOY_DIR}/dist" ]; then cp -r "${DEPLOY_DIR}/dist/"* "$DEPLOY_TARGET/" else # Se nao tem dist, copiar tudo cp -r "${DEPLOY_DIR}/"* "$DEPLOY_TARGET/" fi # Permissoes chown -R www-data:www-data "$DEPLOY_TARGET" chmod -R 755 "$DEPLOY_TARGET" # Limpar pasta temporaria rm -rf "$DEPLOY_DIR" log "${GREEN}[OK]${NC} Deploy concluido!" log "" # ========================================================================== # FINAL # ========================================================================== log "${BLUE}============================================================${NC}" log "${GREEN} Deploy concluido com sucesso!${NC}" log "${BLUE}============================================================${NC}" log "" log "Ambiente: ${TARGET}" log "Caminho: ${DEPLOY_TARGET}" log "Backup: ${BACKUP_PATH}" log "Log: ${LOG_FILE}" log "Data: $(date)" log "" # Atualizar link do ultimo log ln -sf "$LOG_FILE" "$LAST_LOG" # Notificar via webhook (opcional) # curl -X POST "https://hooks.slack.com/services/..." \ # -H 'Content-Type: application/json' \ # -d "{\"text\":\"Deploy ${TARGET} concluido!\"}" 2>/dev/null || true exit 0