refactor(ui): adopt <Card> on public surfaces (SSOT) + add <Eyebrow> #1481
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI Pipeline | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| env: | |
| NODE_VERSION: '20' | |
| jobs: | |
| # Quality checks - runs on all branches and PRs | |
| # Self-host deploy: .github/workflows/deploy-selfhost.yml on push to main | |
| quality: | |
| name: Code Quality Checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| # SSOT: lint + umlauts + typecheck + build are bundled in the `verify` npm | |
| # script (package.json). CI calls it verbatim so the gating chain can't | |
| # drift from what runs locally. Do not re-inline these checks here — the | |
| # umlaut gate (Swiss ä/ö/ü convention) lives inside `verify` too. | |
| - name: Verify (lint + umlauts + typecheck + build) | |
| run: npm run verify | |
| env: | |
| # Build-time placeholders so strict env validation doesn't fail during CI compile. | |
| AUTH_SECRET: ci-build-placeholder-secret-32chars | |
| DB_HOST: localhost | |
| DB_NAME: revampit_ci | |
| DB_USER: ci | |
| DB_PASSWORD: ci | |
| # Auth smoke gate: verifies prod login when E2E secrets are present. | |
| # Prefers dual-persona admin credentials; falls back to legacy AUTH_TEST_*. | |
| auth-smoke: | |
| name: Auth Smoke Test | |
| runs-on: ubuntu-latest | |
| needs: quality | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Install Playwright browser | |
| run: npx playwright install --with-deps chromium | |
| - name: Run auth smoke (if credentials configured) | |
| env: | |
| AUTH_TEST_EMAIL: ${{ secrets.AUTH_TEST_EMAIL }} | |
| AUTH_TEST_PASSWORD: ${{ secrets.AUTH_TEST_PASSWORD }} | |
| AUTH_TEST_ADMIN_EMAIL: ${{ secrets.AUTH_TEST_ADMIN_EMAIL }} | |
| AUTH_TEST_ADMIN_PASSWORD: ${{ secrets.AUTH_TEST_ADMIN_PASSWORD }} | |
| run: | | |
| EMAIL="${AUTH_TEST_EMAIL:-${AUTH_TEST_ADMIN_EMAIL:-}}" | |
| PASSWORD="${AUTH_TEST_PASSWORD:-${AUTH_TEST_ADMIN_PASSWORD:-}}" | |
| if [ -z "$EMAIL" ] || [ -z "$PASSWORD" ]; then | |
| echo "No AUTH_TEST_* or AUTH_TEST_ADMIN_* secrets — skipping auth smoke." | |
| exit 0 | |
| fi | |
| export AUTH_TEST_EMAIL="$EMAIL" | |
| export AUTH_TEST_PASSWORD="$PASSWORD" | |
| PLAYWRIGHT_BASE_URL="${PLAYWRIGHT_BASE_URL:-https://revampit.orangecat.ch}" \ | |
| npx playwright test tests/e2e/auth-smoke.spec.ts --project=chromium --reporter=line | |
| # Prod health gate: full dual-persona route inventory (186 routes) when passwords set. | |
| # Primary gate is post-deploy in deploy-selfhost.yml; this catches prod regressions on PRs too. | |
| inventory-smoke: | |
| name: Dual-Persona Inventory Smoke | |
| runs-on: ubuntu-latest | |
| needs: quality | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Install Playwright browser | |
| run: npx playwright install --with-deps chromium | |
| - name: Run inventory smoke (if dual-persona secrets configured) | |
| env: | |
| AUTH_TEST_USER_PASSWORD: ${{ secrets.AUTH_TEST_USER_PASSWORD }} | |
| AUTH_TEST_ADMIN_PASSWORD: ${{ secrets.AUTH_TEST_ADMIN_PASSWORD }} | |
| AUTH_TEST_USER_EMAIL: ${{ secrets.AUTH_TEST_USER_EMAIL }} | |
| AUTH_TEST_ADMIN_EMAIL: ${{ secrets.AUTH_TEST_ADMIN_EMAIL }} | |
| run: bash scripts/e2e-inventory-prod.sh | |
| # Migration drift check — applies every SQL migration in scripts/db/migrations/ | |
| # to a throwaway Postgres container. Uses pgvector image so 005-hirn-ai-rag.sql | |
| # can CREATE EXTENSION vector. Runs on PRs and main pushes. | |
| migrations: | |
| name: Migration Drift Check | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main' | |
| services: | |
| postgres: | |
| image: pgvector/pgvector:pg17 | |
| env: | |
| POSTGRES_PASSWORD: ci | |
| POSTGRES_DB: revampit_drift | |
| options: >- | |
| --health-cmd "pg_isready -U postgres" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Apply migrations in order | |
| env: | |
| PGHOST: localhost | |
| PGPORT: 5432 | |
| PGUSER: postgres | |
| PGPASSWORD: ci | |
| PGDATABASE: revampit_drift | |
| run: bash scripts/db/apply-migrations-ci.sh | |
| e2e-local: | |
| name: Local E2E Journeys | |
| runs-on: ubuntu-latest | |
| needs: [quality, migrations] | |
| services: | |
| postgres: | |
| image: pgvector/pgvector:pg17 | |
| env: | |
| POSTGRES_PASSWORD: ci | |
| POSTGRES_DB: revampit_e2e | |
| options: >- | |
| --health-cmd "pg_isready -U postgres" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| env: | |
| AUTH_SECRET: ci-e2e-placeholder-secret-32chars | |
| NEXTAUTH_URL: http://localhost:3001 | |
| AUTH_URL: http://localhost:3001 | |
| PLAYWRIGHT_BASE_URL: http://localhost:3001 | |
| DB_HOST: localhost | |
| DB_PORT: 5432 | |
| DB_NAME: revampit_e2e | |
| DB_USER: postgres | |
| DB_PASSWORD: ci | |
| DB_SSL: false | |
| PGHOST: localhost | |
| PGPORT: 5432 | |
| PGUSER: postgres | |
| PGPASSWORD: ci | |
| PGDATABASE: revampit_e2e | |
| AUTH_TEST_EMAIL: e2e-admin@revampit.test | |
| AUTH_TEST_PASSWORD: E2EAdmin123! | |
| AUTH_TEST_ADMIN_EMAIL: e2e-admin@revampit.test | |
| AUTH_TEST_ADMIN_PASSWORD: E2EAdmin123! | |
| AUTH_TEST_SECOND_ADMIN_EMAIL: e2e-admin2@revampit.test | |
| AUTH_TEST_SECOND_ADMIN_PASSWORD: E2EAdmin123! | |
| AUTH_TEST_USER_EMAIL: e2e-user@revampit.test | |
| AUTH_TEST_USER_PASSWORD: E2EUser123! | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Install Playwright browser | |
| run: npx playwright install --with-deps chromium | |
| - name: Apply migrations | |
| run: bash scripts/db/apply-migrations-ci.sh | |
| - name: Seed E2E data | |
| run: npm run e2e:seed | |
| - name: Build app | |
| run: npm run build | |
| - name: Start app | |
| run: | | |
| npm run start -- -p 3001 > revampit-e2e.log 2>&1 & | |
| for i in {1..90}; do | |
| if curl -fsS http://localhost:3001/api/health >/dev/null; then | |
| exit 0 | |
| fi | |
| sleep 2 | |
| done | |
| cat revampit-e2e.log | |
| exit 1 | |
| - name: Run Playwright E2E journeys | |
| run: npm run test:e2e:journeys -- --project=chromium --reporter=line | |
| - name: Upload E2E artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: e2e-local-artifacts | |
| path: | | |
| playwright-report/ | |
| test-results/ | |
| revampit-e2e.log | |
| if-no-files-found: ignore | |
| # Unit tests (still non-blocking while suite matures) | |
| test: | |
| name: Run Tests | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run tests | |
| run: npm run test | |
| continue-on-error: true |