name: Deploy to liderra.ru # Запускается вручную через web-интерфейс GitHub или через `gh workflow run`. # Решает проблему «дев-машина не достучится по SSH до прод-сервера через YC backbone»: # GitHub Actions runner — внешний по отношению к YC, его IP не блокируется тем # фильтром что блокирует мой dev-IP `89.144.17.119`. # # Требуемые secrets (Settings → Secrets and variables → Actions): # LIDERRA_SSH_KEY — содержимое приватного ключа `~/.ssh/liderra_deploy` # (начинается с `-----BEGIN OPENSSH PRIVATE KEY-----`). # Host/user захардкожены — публичная информация, нет смысла в secrets. on: workflow_dispatch: inputs: ref: description: 'Branch/tag/SHA для деплоя (по умолчанию main)' required: true default: 'main' type: string backfill_snapshot: description: 'Запустить snapshot:backfill за сегодня (default yes)' required: false default: true type: boolean jobs: deploy: name: Deploy code + run redeploy.sh runs-on: ubuntu-latest timeout-minutes: 20 concurrency: group: liderra-prod-deploy cancel-in-progress: false env: LIDERRA_HOST: 111.88.246.137 LIDERRA_USER: ubuntu steps: - name: Checkout uses: actions/checkout@v4 with: ref: ${{ github.event.inputs.ref }} - name: Setup Node 22 uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' cache-dependency-path: app/package-lock.json - name: Install frontend deps # --legacy-peer-deps: Histoire 1.0-beta.1 заявляет peerDep vite ^7, # установлено vite 8 — известный квирк проекта (memory feedback_environment.md #74). working-directory: app run: npm ci --legacy-peer-deps - name: Build frontend working-directory: app run: npm run build - name: Verify build artifacts present run: | test -f app/public/build/manifest.json ls app/public/build/assets/ | head -5 du -sh app/public/build/ - name: Create deploy tarball run: | tar czf /tmp/deploy.tgz \ --exclude='app/.env' \ --exclude='app/.env.example' \ --exclude='app/.env.production' \ --exclude='app/storage' \ --exclude='app/vendor' \ --exclude='app/node_modules' \ --exclude='app/bootstrap/cache' \ app db ls -lh /tmp/deploy.tgz - name: Setup SSH key run: | mkdir -p ~/.ssh echo "${{ secrets.LIDERRA_SSH_KEY }}" > ~/.ssh/liderra_deploy chmod 600 ~/.ssh/liderra_deploy ssh-keyscan -H ${{ env.LIDERRA_HOST }} >> ~/.ssh/known_hosts 2>/dev/null - name: Upload tarball to prod run: | scp -i ~/.ssh/liderra_deploy -o StrictHostKeyChecking=accept-new \ /tmp/deploy.tgz ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }}:/tmp/deploy.tgz - name: Extract + run redeploy.sh on prod run: | ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} 'bash -s' <<'REMOTE' set -euo pipefail TS=$(date -u +%Y%m%d-%H%M%S) echo "=== Backup current app ===" sudo tar czf /home/ubuntu/deploy-backups/app-pre-deploy-${TS}.tgz \ --exclude='storage' --exclude='vendor' --exclude='node_modules' --exclude='public/build' \ -C /var/www/liderra app ls -lh /home/ubuntu/deploy-backups/app-pre-deploy-${TS}.tgz echo "=== Extract overlay ===" cd /var/www/liderra sudo tar xzf /tmp/deploy.tgz sudo chown -R www-data:www-data /var/www/liderra/app /var/www/liderra/db echo "=== redeploy.sh (composer + migrate + optimize + restart) ===" sudo bash /var/www/liderra/redeploy.sh rm -f /tmp/deploy.tgz REMOTE - name: Backfill today's snapshot if: ${{ github.event.inputs.backfill_snapshot != 'false' }} run: | ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} 'bash -s' <<'REMOTE' set -e cd /var/www/liderra/app sudo -u www-data php artisan snapshot:backfill --date=$(date +%Y-%m-%d) || \ echo "WARN: backfill returned non-zero — проверь вручную" REMOTE - name: Smoke tests run: | ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} 'bash -s' <<'REMOTE' set -e cd /var/www/liderra/app echo '=== Migrations status (last 5) ===' sudo -u www-data php artisan migrate:status 2>&1 | tail -5 echo '=== Snapshots count (last 3 dates) ===' sudo -u postgres psql -d liderra -c "SELECT snapshot_date, COUNT(*) AS rows FROM project_routing_snapshots GROUP BY 1 ORDER BY 1 DESC LIMIT 3;" || true echo '=== Service status ===' systemctl is-active nginx php8.3-fpm postgresql liderra-queue echo '=== Internal portal health ===' curl -sf -o /dev/null -w 'https=%{http_code} time=%{time_total}s\n' --max-time 8 https://127.0.0.1/ -k || true REMOTE - name: External portal health (from runner) run: | curl -sf -o /dev/null -w 'external https=%{http_code} time=%{time_total}s\n' \ --max-time 15 https://liderra.ru/ || echo "external health returned non-zero" - name: Cleanup SSH key if: always() run: rm -f ~/.ssh/liderra_deploy