Skip to content

refactor(ui): adopt <Card> on public surfaces (SSOT) + add <Eyebrow> #1481

refactor(ui): adopt <Card> on public surfaces (SSOT) + add <Eyebrow>

refactor(ui): adopt <Card> on public surfaces (SSOT) + add <Eyebrow> #1481

Workflow file for this run

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