Test fixes #43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy to Production | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: deploy-production | |
| cancel-in-progress: false | |
| jobs: | |
| test: | |
| name: Run Tests and Linting | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Cache bun dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }} | |
| restore-keys: bun-${{ runner.os }}- | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Run linting | |
| run: bun run lint | |
| - name: Run tests | |
| run: bun test --run | |
| deploy: | |
| name: Deploy to Production | |
| runs-on: ubuntu-latest | |
| needs: test | |
| environment: | |
| name: production | |
| url: https://luvora.love | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Deploy to VPS via SSH | |
| uses: appleboy/ssh-action@v1 | |
| with: | |
| host: ${{ secrets.PRODUCTION_VPS_HOST }} | |
| username: ${{ secrets.PRODUCTION_VPS_USER }} | |
| key: ${{ secrets.PRODUCTION_VPS_SSH_KEY }} | |
| script: | | |
| set -e # Exit on any error | |
| # Setup Bun environment | |
| export BUN_INSTALL="$HOME/.bun" | |
| export PATH="$BUN_INSTALL/bin:$PATH" | |
| APP_DIR="/home/luvora-production" | |
| REPO_DIR="$APP_DIR/Luvora" | |
| # Create directory if it doesn't exist | |
| mkdir -p "$APP_DIR" | |
| # Clone repo if it doesn't exist, otherwise pull | |
| if [ ! -d "$REPO_DIR" ]; then | |
| echo "📦 First time setup: Cloning repository..." | |
| cd "$APP_DIR" | |
| git clone https://github.com/HMAHD/Luvora.git | |
| cd "$REPO_DIR" | |
| git checkout main | |
| else | |
| echo "🔄 Updating existing repository..." | |
| cd "$REPO_DIR" | |
| git fetch origin | |
| git reset --hard origin/main | |
| fi | |
| # Check if .env.local exists | |
| if [ ! -f "$REPO_DIR/.env.local" ]; then | |
| echo "⚠️ Warning: .env.local not found! Please create it manually." | |
| echo "Deployment will continue but app may not work correctly." | |
| fi | |
| # Create logs directory | |
| mkdir -p "$REPO_DIR/logs" | |
| # Install dependencies | |
| echo "📦 Installing dependencies..." | |
| bun install --frozen-lockfile | |
| # Build the application | |
| echo "🔨 Building application..." | |
| bun run build | |
| # Check if PM2 process exists | |
| if pm2 describe luvora-production-3002 > /dev/null 2>&1; then | |
| echo "♻️ Reloading PM2 process..." | |
| pm2 reload luvora-production-3002 --update-env | |
| else | |
| echo "🚀 Starting PM2 process for first time..." | |
| pm2 start ecosystem.config.js --only luvora-production-3002 | |
| fi | |
| pm2 save | |
| # Setup automated spark delivery cron job | |
| echo "⏰ Setting up spark delivery cron job..." | |
| # Create log directory for cron | |
| sudo mkdir -p /var/log/luvora | |
| sudo chown $(whoami):$(whoami) /var/log/luvora | |
| # Make cron script executable | |
| chmod +x "$REPO_DIR/scripts/cron-deliver.sh" | |
| # Store cron secret in a secure file instead of crontab | |
| sudo mkdir -p /etc/luvora | |
| if [ -f "$REPO_DIR/.env.local" ]; then | |
| CRON_SECRET=$(grep -E "^CRON_SECRET=" "$REPO_DIR/.env.local" | cut -d= -f2-) | |
| fi | |
| if [ -z "$CRON_SECRET" ]; then | |
| echo "⚠️ Warning: CRON_SECRET not found in .env.local - cron job will not work" | |
| else | |
| echo "APP_URL=http://localhost:3002" | sudo tee /etc/luvora/cron.env > /dev/null | |
| echo "CRON_SECRET=$CRON_SECRET" | sudo tee -a /etc/luvora/cron.env > /dev/null | |
| sudo chmod 600 /etc/luvora/cron.env | |
| sudo chown $(whoami):$(whoami) /etc/luvora/cron.env | |
| fi | |
| # Create cron entry that sources secrets from file | |
| CRON_ENTRY="* * * * * . /etc/luvora/cron.env && $REPO_DIR/scripts/cron-deliver.sh >> /var/log/luvora/cron.log 2>&1" | |
| # Remove old cron entry if exists and add new one | |
| (crontab -l 2>/dev/null | grep -v "cron-deliver.sh" | grep -v "Luvora Spark Delivery"; \ | |
| echo "# Luvora Spark Delivery - Auto-configured by GitHub Actions"; \ | |
| echo "$CRON_ENTRY") | crontab - | |
| echo "✅ Cron job configured - runs every minute" | |
| echo " Check logs: tail -f /var/log/luvora/cron.log" | |
| echo "✅ Deployment completed successfully!" | |
| - name: Health check | |
| run: | | |
| for i in 1 2 3; do | |
| sleep 10 | |
| if curl -sf --max-time 10 https://luvora.love/api/health; then | |
| echo "Health check passed" | |
| exit 0 | |
| fi | |
| echo "Attempt $i failed, retrying..." | |
| done | |
| echo "Health check failed after 3 attempts" | |
| exit 1 | |
| - name: Notify Sentry of deployment | |
| if: success() && env.SENTRY_AUTH_TOKEN != '' | |
| uses: getsentry/action-release@v3 | |
| env: | |
| SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
| SENTRY_ORG: akash-hasendra | |
| SENTRY_PROJECT: luvora | |
| with: | |
| environment: production | |
| version: ${{ github.sha }} |