name: Deploy to Production on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest environment: production steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18.x' cache: 'npm' - name: Install dependencies run: npm ci --only=production - name: Build application run: npm run build - name: Run final tests run: npm test - name: Create backup env: DEPLOY_HOST: ${{ secrets.PROD_HOST }} DEPLOY_USER: ${{ secrets.DEPLOY_USER }} DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} DEPLOY_PATH: ${{ secrets.PROD_DEPLOY_PATH }} run: | mkdir -p ~/.ssh echo "$DEPLOY_KEY" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh-keyscan -H $DEPLOY_HOST >> ~/.ssh/known_hosts # Create backup ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST " if [ -d $DEPLOY_PATH ]; then cp -r $DEPLOY_PATH $DEPLOY_PATH.backup.$(date +%Y%m%d-%H%M%S) fi " - name: Deploy to Production env: DEPLOY_HOST: ${{ secrets.PROD_HOST }} DEPLOY_USER: ${{ secrets.DEPLOY_USER }} DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} DEPLOY_PATH: ${{ secrets.PROD_DEPLOY_PATH }} run: | # Create deployment package mkdir -p deploy cp -r src dist package*.json ecosystem.config.js scripts deploy/ tar -czf deploy-$(date +%Y%m%d-%H%M%S).tar.gz -C deploy . # Upload and deploy scp -i ~/.ssh/deploy_key deploy-*.tar.gz $DEPLOY_USER@$DEPLOY_HOST:/tmp/ ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST "bash -s" < scripts/deploy.sh production - name: Health Check and Rollback on Failure env: DEPLOY_HOST: ${{ secrets.PROD_HOST }} DEPLOY_USER: ${{ secrets.DEPLOY_USER }} DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} HEALTH_CHECK_URL: ${{ secrets.PROD_HEALTH_CHECK_URL }} run: | # Wait for application to start sleep 30 # Health check with retry for i in {1..5}; do if curl -f $HEALTH_CHECK_URL; then echo "Health check passed" exit 0 fi echo "Health check failed, retry $i/5" sleep 10 done # If health check fails, rollback echo "Health check failed, initiating rollback" ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST "bash -s" < scripts/rollback.sh exit 1