name: CI on: push: branches: [main] pull_request: branches: [main] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: NODE_VERSION: "20" PNPM_VERSION: "9.14.2" jobs: # ────────────────────────────────────────────── # Typecheck — ~40s, no services needed # ────────────────────────────────────────────── typecheck: name: Typecheck runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Generate Prisma client run: pnpm --filter @planarchy/db exec prisma generate - name: Cache Turborepo uses: actions/cache@v4 with: path: .turbo key: turbo-typecheck-${{ github.sha }} restore-keys: turbo-typecheck- - name: Run typecheck run: pnpm --filter @planarchy/web exec tsc --noEmit # ────────────────────────────────────────────── # Lint — ~20s, no services needed # ────────────────────────────────────────────── lint: name: Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Generate Prisma client run: pnpm --filter @planarchy/db exec prisma generate - name: Cache Turborepo uses: actions/cache@v4 with: path: .turbo key: turbo-lint-${{ github.sha }} restore-keys: turbo-lint- - name: Run lint run: pnpm lint # ────────────────────────────────────────────── # Unit tests — needs PostgreSQL + Redis # ────────────────────────────────────────────── test: name: Unit Tests runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_DB: planarchy_test POSTGRES_USER: planarchy POSTGRES_PASSWORD: planarchy_test ports: - 5432:5432 options: >- --health-cmd="pg_isready -U planarchy -d planarchy_test" --health-interval=10s --health-timeout=5s --health-retries=5 redis: image: redis:7 ports: - 6379:6379 options: >- --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=5 env: DATABASE_URL: postgresql://planarchy:planarchy_test@localhost:5432/planarchy_test REDIS_URL: redis://localhost:6379 steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Generate Prisma client run: pnpm --filter @planarchy/db exec prisma generate - name: Run unit tests run: pnpm test:unit # ────────────────────────────────────────────── # Build — depends on typecheck passing # ────────────────────────────────────────────── build: name: Build needs: [typecheck] runs-on: ubuntu-latest env: DATABASE_URL: postgresql://placeholder:placeholder@localhost:5432/placeholder steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Generate Prisma client run: pnpm --filter @planarchy/db exec prisma generate - name: Cache Turborepo uses: actions/cache@v4 with: path: .turbo key: turbo-build-${{ github.sha }} restore-keys: turbo-build- - name: Cache Next.js build uses: actions/cache@v4 with: path: apps/web/.next/cache key: nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ github.sha }} restore-keys: nextjs-${{ hashFiles('pnpm-lock.yaml') }}- - name: Build run: pnpm --filter @planarchy/web exec next build # ────────────────────────────────────────────── # E2E — depends on build, needs PostgreSQL + Redis # ────────────────────────────────────────────── e2e: name: E2E Tests needs: [build] runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_DB: planarchy_test POSTGRES_USER: planarchy POSTGRES_PASSWORD: planarchy_test ports: - 5432:5432 options: >- --health-cmd="pg_isready -U planarchy -d planarchy_test" --health-interval=10s --health-timeout=5s --health-retries=5 redis: image: redis:7 ports: - 6379:6379 options: >- --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=5 env: DATABASE_URL: postgresql://planarchy:planarchy_test@localhost:5432/planarchy_test REDIS_URL: redis://localhost:6379 PORT: 3100 steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: ${{ env.PNPM_VERSION }} - uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Generate Prisma client run: pnpm --filter @planarchy/db exec prisma generate - name: Cache Playwright browsers id: playwright-cache uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: playwright-${{ hashFiles('apps/web/package.json') }} restore-keys: playwright- - name: Install Playwright browsers if: steps.playwright-cache.outputs.cache-hit != 'true' run: pnpm --filter @planarchy/web exec playwright install --with-deps chromium - name: Install Playwright system deps if: steps.playwright-cache.outputs.cache-hit == 'true' run: pnpm --filter @planarchy/web exec playwright install-deps chromium - name: Push DB schema & seed run: | pnpm db:push pnpm db:seed - name: Run E2E tests run: pnpm test:e2e - name: Upload Playwright report uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} with: name: playwright-report path: apps/web/playwright-report/ retention-days: 14