#!/bin/bash set -euo pipefail export NODE_OPTIONS="--max_old_space_size=4096" export CI="true" export npm_config_progress="false" export npm_config_loglevel="warn" export FORCE_COLOR="0" LOG_FILE="/var/log/bssapp_deploy.log" APP_DIR="/opt/bssapp" LOCK_FILE="/tmp/bssapp_deploy.lock" RUNTIME_BACKUP_DIR="" RUNTIME_PRESERVE_FILES=( ".env" "mail.env" "svc/.env" "svc/mail.env" "svc/fonts" "svc/public" ) backup_runtime_files() { RUNTIME_BACKUP_DIR="$(mktemp -d /tmp/bssapp-runtime.XXXXXX)" for rel in "${RUNTIME_PRESERVE_FILES[@]}"; do src="$APP_DIR/$rel" dst="$RUNTIME_BACKUP_DIR/$rel" if [[ -e "$src" ]]; then mkdir -p "$(dirname "$dst")" cp -a "$src" "$dst" fi done } restore_runtime_files() { [[ -n "$RUNTIME_BACKUP_DIR" && -d "$RUNTIME_BACKUP_DIR" ]] || return 0 find "$RUNTIME_BACKUP_DIR" -mindepth 1 -print -quit | grep -q . || return 0 cp -a "$RUNTIME_BACKUP_DIR/." "$APP_DIR/" } cleanup_runtime_backup() { if [[ -n "$RUNTIME_BACKUP_DIR" && -d "$RUNTIME_BACKUP_DIR" ]]; then rm -rf "$RUNTIME_BACKUP_DIR" fi } ensure_runtime_env_files() { # Bazı unit dosyaları EnvironmentFile olarak bu path'leri bekliyor. # Dosyalar yoksa systemd "Failed to load environment files" ile düşüyor. [[ -f "$APP_DIR/.env" ]] || touch "$APP_DIR/.env" [[ -f "$APP_DIR/mail.env" ]] || touch "$APP_DIR/mail.env" [[ -f "$APP_DIR/svc/.env" ]] || touch "$APP_DIR/svc/.env" [[ -f "$APP_DIR/svc/mail.env" ]] || touch "$APP_DIR/svc/mail.env" } ensure_pdf_fonts() { font_dir="$APP_DIR/svc/fonts" sys_font_dir="/usr/share/fonts/truetype/dejavu" mkdir -p "$font_dir" if [[ ! -f "$font_dir/DejaVuSans.ttf" && -f "$sys_font_dir/DejaVuSans.ttf" ]]; then cp -a "$sys_font_dir/DejaVuSans.ttf" "$font_dir/DejaVuSans.ttf" fi if [[ ! -f "$font_dir/DejaVuSans-Bold.ttf" && -f "$sys_font_dir/DejaVuSans-Bold.ttf" ]]; then cp -a "$sys_font_dir/DejaVuSans-Bold.ttf" "$font_dir/DejaVuSans-Bold.ttf" fi if [[ ! -f "$font_dir/DejaVuSans.ttf" || ! -f "$font_dir/DejaVuSans-Bold.ttf" ]]; then echo "ERROR: Required PDF fonts missing in $font_dir (DejaVuSans.ttf / DejaVuSans-Bold.ttf)" return 1 fi } build_api_binary() { if ! command -v go >/dev/null 2>&1; then echo "go command not found; cannot build backend binary." return 1 fi export GOPATH="${GOPATH:-/var/cache/bssapp-go}" export GOMODCACHE="${GOMODCACHE:-$GOPATH/pkg/mod}" export GOCACHE="${GOCACHE:-/var/cache/bssapp-go-build}" mkdir -p "$GOPATH" "$GOMODCACHE" "$GOCACHE" cd "$APP_DIR/svc" GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" -o "$APP_DIR/svc/bssapp" ./main.go chmod +x "$APP_DIR/svc/bssapp" } run_deploy() { trap cleanup_runtime_backup EXIT exec 9>"$LOCK_FILE" if ! flock -n 9; then echo "[$(date '+%F %T')] Deploy already running. Skipping new request." return 0 fi echo "==============================" echo "[DEPLOY START] $(date '+%F %T')" echo "==============================" cd "$APP_DIR" echo "== GIT SYNC ==" backup_runtime_files git fetch origin git reset --hard origin/master git clean -fdx \ -e .env \ -e mail.env \ -e svc/.env \ -e svc/mail.env \ -e svc/fonts \ -e svc/public \ -e svc/bssapp restore_runtime_files echo "== BUILD UI ==" cd "$APP_DIR/ui" npm ci --no-audit --no-fund --include=optional # Linux'ta sass --embedded hatasını engellemek için # deploy sırasında çalışan node_modules ağacına doğrudan yazıyoruz. npm i -D --no-audit --no-fund sass-embedded@1.93.2 npm run build echo "== BUILD API ==" build_api_binary echo "== ENSURE ENV FILES ==" ensure_runtime_env_files echo "== ENSURE PDF FONTS ==" ensure_pdf_fonts echo "== RESTART SERVICE ==" systemctl restart bssapp echo "[DEPLOY FINISHED] $(date '+%F %T')" } if [[ "${1:-}" == "--run" ]]; then run_deploy >>"$LOG_FILE" 2>&1 exit 0 fi # Fully detach webhook-triggered process to avoid EPIPE from closed request sockets. nohup /bin/bash "$0" --run /dev/null 2>&1 & exit 0