name: Build & Deploy KLZ Cables on: push: branches: [main] jobs: build-and-deploy: runs-on: docker steps: # ═══════════════════════════════════════════════════════════════════════════════ # LOGGING: Workflow Start - Full Transparency # ═══════════════════════════════════════════════════════════════════════════════ - name: 📋 Log Workflow Start run: | echo "🚀 Starting deployment for ${{ github.repository }} (${{ github.ref }})" echo " • Commit: ${{ github.sha }}" echo " • Timestamp: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" - name: Checkout repository uses: actions/checkout@v4 # ═══════════════════════════════════════════════════════════════════════════════ # LOGGING: Registry Login Phase # ═══════════════════════════════════════════════════════════════════════════════ - name: 🔐 Login to private registry run: | echo "🔐 Authenticating with registry.infra.mintel.me..." echo "${{ secrets.REGISTRY_PASS }}" | docker login registry.infra.mintel.me -u "${{ secrets.REGISTRY_USER }}" --password-stdin # ═══════════════════════════════════════════════════════════════════════════════ # LOGGING: Build Phase # ═══════════════════════════════════════════════════════════════════════════════ - name: 🏗️ Build Docker image run: | echo "🏗️ Building Docker image (linux/arm64)..." docker buildx build \ --pull \ --platform linux/arm64 \ --build-arg NEXT_PUBLIC_BASE_URL="${{ secrets.NEXT_PUBLIC_BASE_URL }}" \ --build-arg NEXT_PUBLIC_UMAMI_WEBSITE_ID="${{ secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID }}" \ --build-arg NEXT_PUBLIC_UMAMI_SCRIPT_URL="${{ secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL }}" \ -t registry.infra.mintel.me/mintel/klz-cables.com:latest \ --push . # ═══════════════════════════════════════════════════════════════════════════════ # LOGGING: Deployment Phase # ═══════════════════════════════════════════════════════════════════════════════ - name: 🚀 Deploy to production server run: | echo "🚀 Deploying to alpha.mintel.me..." # Setup SSH mkdir -p ~/.ssh echo "${{ secrets.ALPHA_SSH_KEY }}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -H alpha.mintel.me >> ~/.ssh/known_hosts 2>/dev/null # Create .env file content cat > /tmp/klz-cables.env << EOF # ============================================================================ # KLZ Cables - Production Environment Configuration # ============================================================================ # Auto-generated by CI/CD workflow # DO NOT EDIT MANUALLY - Changes will be overwritten on next deployment # ============================================================================ # Application NODE_ENV=production NEXT_PUBLIC_BASE_URL=${{ secrets.NEXT_PUBLIC_BASE_URL }} # Analytics (Umami) NEXT_PUBLIC_UMAMI_WEBSITE_ID=${{ secrets.NEXT_PUBLIC_UMAMI_WEBSITE_ID }} NEXT_PUBLIC_UMAMI_SCRIPT_URL=${{ secrets.NEXT_PUBLIC_UMAMI_SCRIPT_URL }} # Error Tracking (GlitchTip/Sentry) SENTRY_DSN=${{ secrets.SENTRY_DSN }} # Email Configuration (Mailgun) MAIL_HOST=${{ secrets.MAIL_HOST }} MAIL_PORT=${{ secrets.MAIL_PORT }} MAIL_USERNAME=${{ secrets.MAIL_USERNAME }} MAIL_PASSWORD=${{ secrets.MAIL_PASSWORD }} MAIL_FROM=${{ secrets.MAIL_FROM }} MAIL_RECIPIENTS=${{ secrets.MAIL_RECIPIENTS }} EOF # Upload .env and deploy scp -o StrictHostKeyChecking=accept-new /tmp/klz-cables.env root@alpha.mintel.me:/home/deploy/sites/klz-cables.com/.env ssh -o StrictHostKeyChecking=accept-new root@alpha.mintel.me bash << EOF set -e cd /home/deploy/sites/klz-cables.com chmod 600 .env chown deploy:deploy .env echo "${{ secrets.REGISTRY_PASS }}" | docker login registry.infra.mintel.me -u "${{ secrets.REGISTRY_USER }}" --password-stdin docker pull registry.infra.mintel.me/mintel/klz-cables.com:latest docker-compose down echo "🚀 Starting containers..." docker-compose up -d echo "⏳ Giving the app a few seconds to warm up..." sleep 10 echo "🔍 Checking container status..." docker-compose ps if ! docker-compose ps | grep -q "Up"; then echo "❌ Container failed to start" docker-compose logs --tail=100 exit 1 fi echo "✅ Deployment complete!" EOF rm -f /tmp/klz-cables.env # ═══════════════════════════════════════════════════════════════════════════════ # LOGGING: Workflow Summary # ═══════════════════════════════════════════════════════════════════════════════ - name: 📊 Workflow Summary if: always() run: | echo "📊 Status: ${{ job.status }}" echo "🎯 Target: alpha.mintel.me" # ═══════════════════════════════════════════════════════════════════════════════ # NOTIFICATION: Gotify # ═══════════════════════════════════════════════════════════════════════════════ - name: 🔔 Gotify Notification (Success) if: success() run: | echo "Sending success notification to Gotify..." RESPONSE=$(curl -k -s -w "\n%{http_code}" -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \ -F "title=✅ Deployment Success: ${{ github.repository }}" \ -F "message=The deployment of ${{ github.repository }} (branch: ${{ github.ref }}) was successful. Commit: ${{ github.sha }} Actor: ${{ github.actor }} Run ID: ${{ github.run_id }}" \ -F "priority=5") HTTP_CODE=$(echo "$RESPONSE" | tail -n1) BODY=$(echo "$RESPONSE" | sed '$d') echo "HTTP Status: $HTTP_CODE" echo "Response Body: $BODY" if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then echo "Failed to send Gotify notification" exit 0 # Don't fail the workflow because of notification failure fi - name: 🔔 Gotify Notification (Failure) if: failure() run: | echo "Sending failure notification to Gotify..." RESPONSE=$(curl -k -s -w "\n%{http_code}" -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \ -F "title=❌ Deployment Failed: ${{ github.repository }}" \ -F "message=The deployment of ${{ github.repository }} (branch: ${{ github.ref }}) failed! Commit: ${{ github.sha }} Actor: ${{ github.actor }} Run ID: ${{ github.run_id }} Please check the logs for details." \ -F "priority=8") HTTP_CODE=$(echo "$RESPONSE" | tail -n1) BODY=$(echo "$RESPONSE" | sed '$d') echo "HTTP Status: $HTTP_CODE" echo "Response Body: $BODY" if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then echo "Failed to send Gotify notification" exit 0 # Don't fail the workflow because of notification failure fi