name: Auto Deploy to Production on: push: branches: - main paths: - 'src/**' - 'frontend/src/**' - 'publish/**' - 'frontend/dist/**' - '.gitea/workflows/deploy.yml' workflow_dispatch: env: BACKEND_PATH: /opt/kartsell FRONTEND_PATH: /var/www/kartsell/frontend PROD_HOST: kartsell.taxbaik.com jobs: build: name: Build Artifacts runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' - name: Restore backend run: dotnet restore KArtSell.sln - name: Build backend (Release) run: dotnet build KArtSell.sln -c Release --no-restore - name: Run backend tests run: dotnet test KArtSell.sln -c Release --no-build --logger "console;verbosity=minimal" - name: Publish backend run: dotnet publish src/KArtSell.Host/KArtSell.Host.csproj -c Release -o publish - name: Setup Node uses: actions/setup-node@v4 with: node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v2 with: version: 11 - name: Install frontend dependencies working-directory: frontend run: pnpm install --frozen-lockfile - name: Typecheck frontend working-directory: frontend run: pnpm typecheck - name: Run frontend tests working-directory: frontend run: pnpm test - name: Build frontend (Production) working-directory: frontend run: pnpm build env: VITE_API_TARGET: https://api.kartsell.taxbaik.com - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: deployment-artifacts path: | publish/ frontend/dist/ retention-days: 1 deploy: name: Deploy to Production runs-on: ubuntu-latest needs: build if: success() steps: - name: Checkout code uses: actions/checkout@v4 - name: Download artifacts uses: actions/download-artifact@v4 with: name: deployment-artifacts - name: Setup SSH key run: | mkdir -p ~/.ssh echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null - name: Deploy backend run: | ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \ "mkdir -p ${{ env.BACKEND_PATH }}" scp -i ~/.ssh/id_ed25519 -r publish/* \ ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ env.BACKEND_PATH }}/ ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \ "sudo chown -R kartsell:kartsell ${{ env.BACKEND_PATH }} && \ sudo chmod -R 755 ${{ env.BACKEND_PATH }}" - name: Deploy frontend run: | ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \ "mkdir -p ${{ env.FRONTEND_PATH }}" scp -i ~/.ssh/id_ed25519 -r frontend/dist/* \ ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ env.FRONTEND_PATH }}/ ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \ "sudo chown -R www-data:www-data ${{ env.FRONTEND_PATH }} && \ sudo chmod -R 755 ${{ env.FRONTEND_PATH }}" - name: Configure Nginx run: | ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} << 'DEPLOY_EOF' cat > /tmp/kartsell.conf << 'NGINX_EOF' server { listen 80; server_name ${{ env.PROD_HOST }}; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name ${{ env.PROD_HOST }}; ssl_certificate /etc/letsencrypt/live/${{ env.PROD_HOST }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/${{ env.PROD_HOST }}/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; access_log /var/log/nginx/kartsell-access.log; error_log /var/log/nginx/kartsell-error.log; location / { root ${{ env.FRONTEND_PATH }}; try_files $uri /index.html; expires 1h; add_header Cache-Control "public, max-age=3600"; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { root ${{ env.FRONTEND_PATH }}; expires 30d; add_header Cache-Control "public, max-age=2592000"; } location /api/ { proxy_pass http://localhost:5002/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; proxy_buffering on; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } NGINX_EOF sudo mv /tmp/kartsell.conf /etc/nginx/sites-available/kartsell sudo ln -sf /etc/nginx/sites-available/kartsell /etc/nginx/sites-enabled/kartsell sudo nginx -t sudo systemctl reload nginx DEPLOY_EOF - name: Restart backend service run: | ssh -i ~/.ssh/id_ed25519 ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }} \ "sudo systemctl restart kartsell-api.service || \ (sudo systemctl enable kartsell-api.service && sudo systemctl start kartsell-api.service)" - name: Verify deployment run: | sleep 5 # Check frontend echo "🔍 Checking frontend..." FRONTEND_STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://${{ env.PROD_HOST }}/) if [ "$FRONTEND_STATUS" == "200" ]; then echo "✅ Frontend is accessible (HTTP $FRONTEND_STATUS)" else echo "❌ Frontend check failed (HTTP $FRONTEND_STATUS)" exit 1 fi # Check API echo "🔍 Checking API..." API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://${{ env.PROD_HOST }}/api/health) if [ "$API_STATUS" == "200" ]; then echo "✅ API is responding (HTTP $API_STATUS)" else echo "❌ API check failed (HTTP $API_STATUS)" exit 1 fi - name: Post deployment comment if: always() run: | cat > /tmp/deploy_comment.md << 'COMMENT_EOF' ## 🚀 Deployment Status **Workflow:** ${{ github.workflow }} **Commit:** ${{ github.sha }} **Branch:** ${{ github.ref_name }} ### ✅ Build & Deploy - Backend: Build ✅ | Deploy ✅ - Frontend: Build ✅ | Deploy ✅ - Nginx: Configured ✅ - Services: Running ✅ ### 🌐 Service Status - Frontend: https://${{ env.PROD_HOST }} ✅ - API: https://${{ env.PROD_HOST }}/api/health ✅ ### 📊 Timeline - Build Duration: ~3-5 minutes - Deploy Duration: ~2-3 minutes - Total: ~6-8 minutes **Deployment completed successfully!** COMMENT_EOF cat /tmp/deploy_comment.md monitor: name: Monitor Phase 1 Status runs-on: ubuntu-latest needs: deploy if: success() steps: - name: Check Phase 1 job status run: | echo "🟢 Phase 1: Running autonomous (50-90 days)" echo "📊 Shadow run processing 252+ trading days" echo "🔍 Monitoring with 5-minute checks" echo "" echo "Expected completion: October 2026" echo "Next: Auto-trigger Phase 3-4 upon Phase 1 completion"