name: Deploy DummyBot on: push: branches: [main] workflow_dispatch: env: DEPLOY_HOST: 157.180.77.232 DEPLOY_USER: root DEPLOY_PATH: /root/dummybot APP_PORT: 18080 jobs: deploy: name: Build & Deploy to ${{ env.DEPLOY_HOST }} runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.4' extensions: mbstring, pdo, pdo_mysql, bcmath, curl, zip, intl coverage: none - name: Validate composer.json working-directory: . run: composer validate --strict --no-check-publish - name: Cache Composer uses: actions/cache@v4 with: path: ~/.composer/cache key: ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-php- - name: Install Composer dependencies (no-dev) run: composer install --no-dev --no-interaction --no-progress --optimize-autoloader - name: Setup Node uses: actions/setup-node@v4 with: node-version: '20' - name: Install npm dependencies run: npm ci --no-audit --no-fund || npm install --no-audit --no-fund - name: Build frontend assets run: npm run build - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: ssh-private-key: ${{ secrets.DEPLOY_SSH_KEY }} - name: Setup known_hosts run: | mkdir -p ~/.ssh ssh-keyscan -p 22 -H ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null - name: Deploy to server run: | ssh -A ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} << 'ENDSSH' set -e cd ${{ env.DEPLOY_PATH }} echo "→ Fetching latest code" git fetch origin main git reset --hard origin/main git clean -fd echo "→ Pulling env file (preserves local config)" cp -n .env.example .env 2>/dev/null || true if [ -f /root/dummybot.env ]; then cp /root/dummybot.env .env fi echo "→ Installing composer dependencies" composer install --no-dev --no-interaction --no-progress --optimize-autoloader echo "→ Installing npm dependencies and building assets" npm ci --no-audit --no-fund || npm install --no-audit --no-fund npm run build echo "→ Caching build state for rollback" DEPLOY_TS=$(date -u +%Y%m%d%H%M%S) echo "$DEPLOY_TS" > .last_deploy echo "→ Running migrations" docker compose exec -T app php artisan migrate --force echo "→ Clearing caches" docker compose exec -T app php artisan config:clear docker compose exec -T app php artisan route:clear docker compose exec -T app php artisan view:clear docker compose exec -T app php artisan event:clear docker compose exec -T app php artisan optimize echo "→ Restarting services" docker compose up -d --remove-orphans echo "→ Healthcheck" sleep 5 HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:${{ env.APP_PORT }}/up --max-time 10 || echo "fail") if [ "$HTTP_CODE" != "200" ]; then echo "HEALTHCHECK FAILED: $HTTP_CODE" exit 1 fi echo "✓ Healthcheck OK ($HTTP_CODE)" echo "→ Cleaning up old images" docker image prune -f >/dev/null 2>&1 || true ENDSSH - name: Notify success if: success() run: | echo "✅ Deploy successful" echo "🌐 https://${{ env.DEPLOY_HOST }}:${{ env.APP_PORT }}" - name: Notify failure if: failure() run: | echo "❌ Deploy failed" echo "Check the logs above for details"