name: Deploy to route.crispygoat.com on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "22" - name: Install dependencies run: npm install - name: Run migrations env: DATABASE_URL: ${{ secrets.DATABASE_URL }} run: | npm run migrate:one || echo "No migration script or migrations already applied" - name: Build env: NODE_ENV: production DATABASE_URL: ${{ secrets.DATABASE_URL }} NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }} NEON_AUTH_BASE_URL: ${{ secrets.NEON_AUTH_BASE_URL }} NEON_AUTH_COOKIE_SECRET: ${{ secrets.NEON_AUTH_COOKIE_SECRET }} AUTH_SECRET: ${{ secrets.AUTH_SECRET }} AUTH_URL: ${{ secrets.AUTH_URL }} NEXT_PUBLIC_AUTH_URL: ${{ secrets.NEXT_PUBLIC_AUTH_URL }} GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} ALLOW_DEV_LOGIN: ${{ secrets.ALLOW_DEV_LOGIN }} ADMIN_ALLOWED_EMAILS: ${{ secrets.ADMIN_ALLOWED_EMAILS }} NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY }} STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }} STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }} STRIPE_PRICE_STARTER: ${{ secrets.STRIPE_PRICE_STARTER }} STRIPE_PRICE_FARM: ${{ secrets.STRIPE_PRICE_FARM }} STRIPE_PRICE_ENTERPRISE: ${{ secrets.STRIPE_PRICE_ENTERPRISE }} STRIPE_PRICE_HARVEST_REACH: ${{ secrets.STRIPE_PRICE_HARVEST_REACH }} STRIPE_PRICE_WHOLESALE_PORTAL: ${{ secrets.STRIPE_PRICE_WHOLESALE_PORTAL }} STRIPE_PRICE_WATER_LOG: ${{ secrets.STRIPE_PRICE_WATER_LOG }} STRIPE_PRICE_AI_TOOLS: ${{ secrets.STRIPE_PRICE_AI_TOOLS }} STRIPE_PRICE_SQUARE_SYNC: ${{ secrets.STRIPE_PRICE_SQUARE_SYNC }} STRIPE_PRICE_SMS_CAMPAIGNS: ${{ secrets.STRIPE_PRICE_SMS_CAMPAIGNS }} RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} FROM_EMAIL: ${{ secrets.FROM_EMAIL }} MINIO_ENDPOINT: ${{ secrets.MINIO_ENDPOINT }} MINIO_REGION: ${{ secrets.MINIO_REGION }} MINIO_ACCESS_KEY: ${{ secrets.MINIO_ACCESS_KEY }} MINIO_SECRET_KEY: ${{ secrets.MINIO_SECRET_KEY }} MINIO_PUBLIC_URL: ${{ secrets.MINIO_PUBLIC_URL }} MINIO_BUCKET_PRODUCTS: ${{ secrets.MINIO_BUCKET_PRODUCTS }} MINIO_BUCKET_BRAND_LOGOS: ${{ secrets.MINIO_BUCKET_BRAND_LOGOS }} MINIO_BUCKET_WATER_LOGS: ${{ secrets.MINIO_BUCKET_WATER_LOGS }} MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }} MINIMAX_BASE_URL: ${{ secrets.MINIMAX_BASE_URL }} run: npm run build - name: Deploy env: DATABASE_URL: ${{ secrets.DATABASE_URL }} NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }} NEON_AUTH_BASE_URL: ${{ secrets.NEON_AUTH_BASE_URL }} NEON_AUTH_COOKIE_SECRET: ${{ secrets.NEON_AUTH_COOKIE_SECRET }} AUTH_SECRET: ${{ secrets.AUTH_SECRET }} AUTH_URL: ${{ secrets.AUTH_URL }} NEXT_PUBLIC_AUTH_URL: ${{ secrets.NEXT_PUBLIC_AUTH_URL }} GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} ALLOW_DEV_LOGIN: ${{ secrets.ALLOW_DEV_LOGIN }} ADMIN_ALLOWED_EMAILS: ${{ secrets.ADMIN_ALLOWED_EMAILS }} NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY }} STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }} STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }} STRIPE_PRICE_STARTER: ${{ secrets.STRIPE_PRICE_STARTER }} STRIPE_PRICE_FARM: ${{ secrets.STRIPE_PRICE_FARM }} STRIPE_PRICE_ENTERPRISE: ${{ secrets.STRIPE_PRICE_ENTERPRISE }} STRIPE_PRICE_HARVEST_REACH: ${{ secrets.STRIPE_PRICE_HARVEST_REACH }} STRIPE_PRICE_WHOLESALE_PORTAL: ${{ secrets.STRIPE_PRICE_WHOLESALE_PORTAL }} STRIPE_PRICE_WATER_LOG: ${{ secrets.STRIPE_PRICE_WATER_LOG }} STRIPE_PRICE_AI_TOOLS: ${{ secrets.STRIPE_PRICE_AI_TOOLS }} STRIPE_PRICE_SQUARE_SYNC: ${{ secrets.STRIPE_PRICE_SQUARE_SYNC }} STRIPE_PRICE_SMS_CAMPAIGNS: ${{ secrets.STRIPE_PRICE_SMS_CAMPAIGNS }} RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} FROM_EMAIL: ${{ secrets.FROM_EMAIL }} MINIO_ENDPOINT: ${{ secrets.MINIO_ENDPOINT }} MINIO_REGION: ${{ secrets.MINIO_REGION }} MINIO_ACCESS_KEY: ${{ secrets.MINIO_ACCESS_KEY }} MINIO_SECRET_KEY: ${{ secrets.MINIO_SECRET_KEY }} MINIO_PUBLIC_URL: ${{ secrets.MINIO_PUBLIC_URL }} MINIO_BUCKET_PRODUCTS: ${{ secrets.MINIO_BUCKET_PRODUCTS }} MINIO_BUCKET_BRAND_LOGOS: ${{ secrets.MINIO_BUCKET_BRAND_LOGOS }} MINIO_BUCKET_WATER_LOGS: ${{ secrets.MINIO_BUCKET_WATER_LOGS }} MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }} MINIMAX_BASE_URL: ${{ secrets.MINIMAX_BASE_URL }} CRON_SECRET: ${{ secrets.CRON_SECRET }} run: | APP_DIR=/home/tyler/route-commerce # Write production env file { printf "DATABASE_URL=%s\n" "$DATABASE_URL" printf "NEXT_PUBLIC_SITE_URL=%s\n" "$NEXT_PUBLIC_SITE_URL" printf "NEON_AUTH_BASE_URL=%s\n" "$NEON_AUTH_BASE_URL" printf "NEON_AUTH_COOKIE_SECRET=%s\n" "$NEON_AUTH_COOKIE_SECRET" printf "AUTH_SECRET=%s\n" "$AUTH_SECRET" printf "AUTH_URL=%s\n" "$AUTH_URL" printf "NEXT_PUBLIC_AUTH_URL=%s\n" "$NEXT_PUBLIC_AUTH_URL" printf "GOOGLE_CLIENT_ID=%s\n" "$GOOGLE_CLIENT_ID" printf "GOOGLE_CLIENT_SECRET=%s\n" "$GOOGLE_CLIENT_SECRET" printf "ALLOW_DEV_LOGIN=%s\n" "$ALLOW_DEV_LOGIN" printf "ADMIN_ALLOWED_EMAILS=%s\n" "$ADMIN_ALLOWED_EMAILS" printf "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=%s\n" "$NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY" printf "STRIPE_SECRET_KEY=%s\n" "$STRIPE_SECRET_KEY" printf "STRIPE_WEBHOOK_SECRET=%s\n" "$STRIPE_WEBHOOK_SECRET" printf "STRIPE_PRICE_STARTER=%s\n" "$STRIPE_PRICE_STARTER" printf "STRIPE_PRICE_FARM=%s\n" "$STRIPE_PRICE_FARM" printf "STRIPE_PRICE_ENTERPRISE=%s\n" "$STRIPE_PRICE_ENTERPRISE" printf "STRIPE_PRICE_HARVEST_REACH=%s\n" "$STRIPE_PRICE_HARVEST_REACH" printf "STRIPE_PRICE_WHOLESALE_PORTAL=%s\n" "$STRIPE_PRICE_WHOLESALE_PORTAL" printf "STRIPE_PRICE_WATER_LOG=%s\n" "$STRIPE_PRICE_WATER_LOG" printf "STRIPE_PRICE_AI_TOOLS=%s\n" "$STRIPE_PRICE_AI_TOOLS" printf "STRIPE_PRICE_SQUARE_SYNC=%s\n" "$STRIPE_PRICE_SQUARE_SYNC" printf "STRIPE_PRICE_SMS_CAMPAIGNS=%s\n" "$STRIPE_PRICE_SMS_CAMPAIGNS" printf "RESEND_API_KEY=%s\n" "$RESEND_API_KEY" printf "FROM_EMAIL=%s\n" "$FROM_EMAIL" printf "MINIO_ENDPOINT=%s\n" "$MINIO_ENDPOINT" printf "MINIO_REGION=%s\n" "$MINIO_REGION" printf "MINIO_ACCESS_KEY=%s\n" "$MINIO_ACCESS_KEY" printf "MINIO_SECRET_KEY=%s\n" "$MINIO_SECRET_KEY" printf "MINIO_PUBLIC_URL=%s\n" "$MINIO_PUBLIC_URL" printf "MINIO_BUCKET_PRODUCTS=%s\n" "$MINIO_BUCKET_PRODUCTS" printf "MINIO_BUCKET_BRAND_LOGOS=%s\n" "$MINIO_BUCKET_BRAND_LOGOS" printf "MINIO_BUCKET_WATER_LOGS=%s\n" "$MINIO_BUCKET_WATER_LOGS" printf "MINIMAX_API_KEY=%s\n" "$MINIMAX_API_KEY" printf "MINIMAX_BASE_URL=%s\n" "$MINIMAX_BASE_URL" printf "CRON_SECRET=%s\n" "$CRON_SECRET" } > $APP_DIR/.env.production # Sync build output and required files rsync -a --delete .next/ $APP_DIR/.next/ rsync -a --delete public/ $APP_DIR/public/ cp package.json $APP_DIR/ cp next.config.ts $APP_DIR/ 2>/dev/null || true # Install production deps only cd $APP_DIR npm install --omit=dev # Start or restart PM2 if pm2 describe route-commerce > /dev/null 2>&1; then pm2 restart route-commerce else pm2 start npm --name route-commerce -- start -- -p 3100 pm2 save fi echo "Deployed successfully"