diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ed923a..ec3ef16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,17 +13,25 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: npm + - name: Install dependencies run: npm ci + - name: Generate Prisma Client run: npx prisma generate --schema=workers/data-sync/prisma/schema.prisma - - name: Type-check + + - name: Type-check (backend + shared) run: npx tsc --noEmit + + - name: Build frontend (catches tsc -b errors missed by root tsconfig) + run: cd apps/web && npm run build + - name: Run tests run: npx vitest run @@ -31,7 +39,6 @@ jobs: name: Deploy to production runs-on: ubuntu-latest needs: ci - # Only deploy when a sprint PR is merged into main if: github.ref == 'refs/heads/main' && github.event_name == 'push' environment: name: production @@ -47,23 +54,62 @@ jobs: set -e cd /var/opt/riftline/app + # ── Save current commit for rollback ──────────────────────────── + PREVIOUS_COMMIT=$(git rev-parse HEAD) + echo "→ Current commit: $PREVIOUS_COMMIT" + + # ── Pull latest code ──────────────────────────────────────────── echo "→ Pulling latest code..." git fetch origin git reset --hard origin/main + NEW_COMMIT=$(git rev-parse HEAD) + echo "→ New commit: $NEW_COMMIT" + # ── Install dependencies ──────────────────────────────────────── echo "→ Installing dependencies..." npm install --prefer-offline + # ── Prisma ────────────────────────────────────────────────────── echo "→ Generating Prisma client..." npx prisma generate --schema=workers/data-sync/prisma/schema.prisma + # ── Build frontend (fail fast) ────────────────────────────────── echo "→ Building frontend..." - cd apps/web && npm run build && cd ../.. + cd apps/web + if ! npm run build; then + echo "✗ Frontend build failed — rolling back to $PREVIOUS_COMMIT" + cd /var/opt/riftline/app + git reset --hard "$PREVIOUS_COMMIT" + exit 1 + fi + cd /var/opt/riftline/app - echo "→ Clearing tsx cache..." + # ── Restart API ───────────────────────────────────────────────── + echo "→ Clearing tsx cache and restarting API..." rm -rf ~/.cache/tsx - - echo "→ Restarting API..." pm2 restart riftline-api --update-env - echo "✓ Deploy complete — https://riftline.app" + # ── Health check ──────────────────────────────────────────────── + echo "→ Health check..." + sleep 5 + MAX_RETRIES=6 + for i in $(seq 1 $MAX_RETRIES); do + STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3001/health || echo "000") + if [ "$STATUS" = "200" ]; then + echo "✓ Health check passed (attempt $i) — https://riftline.app" + exit 0 + fi + echo " Attempt $i/$MAX_RETRIES: status $STATUS — retrying in 5s..." + sleep 5 + done + + # ── Rollback if health check failed ──────────────────────────── + echo "✗ Health check failed after $MAX_RETRIES attempts — rolling back to $PREVIOUS_COMMIT" + git reset --hard "$PREVIOUS_COMMIT" + npm install --prefer-offline + npx prisma generate --schema=workers/data-sync/prisma/schema.prisma + cd apps/web && npm run build && cd /var/opt/riftline/app + rm -rf ~/.cache/tsx + pm2 restart riftline-api --update-env + echo "✓ Rollback complete" + exit 1 diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index e59b7a3..d94dbc8 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -311,7 +311,7 @@ function useSections(t: (key: string) => string): SidebarSection[] { icon: , items: [ { to: '/admin/users', label: t('nav.users') }, - { to: '/admin/invitations', label: t('nav.invitations', { defaultValue: 'Invitaciones' }) }, + { to: '/admin/invitations', label: t('nav.invitations') }, { to: '/admin/data-quality', label: t('nav.dataQuality') }, { to: '/management/roles', label: t('nav.rolesPermissions') }, { to: '/admin/api-status', label: t('nav.apiStatus') },