Provide inert Supabase env for CI builds #149
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 | |
| # Trigger on pushes, gate/version pull requests, main promotion pull requests, and manual dispatch. | |
| on: | |
| push: # Run CI on every commit push to any branch | |
| pull_request: | |
| branches: | |
| - main | |
| - "version/**" | |
| workflow_dispatch: | |
| # Cancel any in-progress runs when a newer commit is pushed to the same ref | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # -------------------------------------------------------------------------- | |
| # 1. Static analysis & build verification | |
| # -------------------------------------------------------------------------- | |
| lint-build: | |
| name: Lint, Type-Check & Build | |
| runs-on: ubuntu-latest | |
| env: | |
| NEXT_PUBLIC_SUPABASE_URL: http://127.0.0.1:54321 | |
| NEXT_PUBLIC_SUPABASE_ANON_KEY: ci-placeholder-anon-key | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "24" | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build local ESLint plugin | |
| run: pnpm run build:eslint-plugin | |
| - name: Run ESLint | |
| run: pnpm -C uapi run lint | |
| - name: Type-check with TypeScript | |
| run: pnpm -C uapi exec tsc --noEmit | |
| - name: Dependency audit advisory report | |
| continue-on-error: true | |
| run: pnpm -C uapi audit --audit-level=moderate | |
| - name: Build Next.js application | |
| run: pnpm -C uapi run build | |
| - name: Build Storybook | |
| if: ${{ vars.ENABLE_STORYBOOK_BUILD == '1' }} | |
| run: pnpm -C uapi run build-storybook | |
| - name: Upload Storybook static build | |
| if: ${{ vars.ENABLE_STORYBOOK_BUILD == '1' }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: storybook-static | |
| path: uapi/storybook-static | |
| # -------------------------------------------------------------------------- | |
| # 2. Jest unit & integration tests using mocks (fast feedback) | |
| # -------------------------------------------------------------------------- | |
| test-mocks: | |
| name: Unit & Integration Tests (mocks) | |
| needs: lint-build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "24" | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run tests (mocked) & collect coverage | |
| run: pnpm -C uapi exec jest --coverage | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: uapi/coverage | |
| - name: Upload coverage to Codecov (mocks) | |
| continue-on-error: true | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| flags: mocks | |
| directory: ./uapi/coverage | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # -------------------------------------------------------------------------- | |
| # 3. Full end-to-end, visual & DB-integrated tests | |
| # -------------------------------------------------------------------------- | |
| test-real-db: | |
| name: E2E, Visual & DB Tests | |
| if: ${{ vars.ENABLE_FULL_DB_E2E == '1' || github.event_name == 'workflow_dispatch' }} | |
| needs: test-mocks | |
| runs-on: ubuntu-latest | |
| env: | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| services: | |
| # Use official Postgres image for Playwright reporters that may read DB | |
| # (We still spin Supabase locally via CLI) | |
| # This just guarantees port availability in the matrix | |
| postgres: | |
| image: postgres:15 | |
| options: >- | |
| --health-cmd "pg_isready -U postgres" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: ["5432:5432"] | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "24" | |
| cache: pnpm | |
| # ------------------------------------------------------------------ | |
| # Supabase local stack to replicate production | |
| # ------------------------------------------------------------------ | |
| - name: Install Supabase CLI | |
| run: npm install -g supabase | |
| - name: Start Supabase | |
| run: supabase start --non-interactive | |
| - name: Wait for Supabase to become healthy | |
| run: | | |
| echo "Waiting for Supabase API..." | |
| for i in {1..30}; do | |
| if curl -sSf http://localhost:54321 > /dev/null; then | |
| echo "Supabase is up ✅"; break; | |
| fi | |
| echo "Still not up – retry $i/30" | |
| sleep 2 | |
| done | |
| - name: Reset database & apply migrations | |
| run: supabase db reset --yes | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| # If embeddings are required for tests we sync them now (needs OpenAI key) | |
| - name: Sync upgrade template embeddings | |
| # Only sync embeddings when an OpenAI key is available. GitHub does not | |
| # expose the `secrets` context for use in step-level `if:` expressions | |
| # at workflow validation time, which causes the "Unrecognized named-value: | |
| # 'secrets'" error. Instead, rely on the job-level environment variable | |
| # we already populate from the secret. | |
| if: ${{ env.OPENAI_API_KEY != '' }} | |
| env: | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| run: pnpm -C uapi run sync-asset-pack-evidence-embeddings | |
| # ------------------------------------------------------------------ | |
| # Run the test suites | |
| # ------------------------------------------------------------------ | |
| - name: Run Jest integration tests (real DB) | |
| env: | |
| USE_REAL_DB: "true" | |
| SUPABASE_URL: "http://localhost:54321" | |
| NEXT_PUBLIC_SUPABASE_URL: "http://localhost:54321" | |
| NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }} | |
| SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} | |
| run: pnpm -C uapi exec jest --runInBand | |
| - name: Install Playwright browsers | |
| run: pnpm -C uapi exec playwright install --with-deps | |
| - name: Run Playwright E2E (UI + visual) | |
| env: | |
| START_STORYBOOK: "false" | |
| USE_REAL_DB: "true" | |
| SUPABASE_URL: "http://localhost:54321" | |
| NEXT_PUBLIC_SUPABASE_URL: "http://localhost:54321" | |
| NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }} | |
| SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} | |
| run: pnpm -C uapi run test:e2e:ui | |
| # ------------------------------------------------------------------ | |
| # Upload artifacts so that PR authors/reviewers can inspect results | |
| # ------------------------------------------------------------------ | |
| - name: Upload Playwright HTML Report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-html-report | |
| path: uapi/playwright-report | |
| - name: Upload Playwright Artifacts (screenshots, traces, videos) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-artifacts | |
| path: uapi/test-results | |
| # Jest coverage from this job (real DB) can override/merge with mocks if desired | |
| - name: Upload coverage (real-db) report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report-real-db | |
| path: uapi/coverage | |
| - name: Upload coverage to Codecov (real-db) | |
| continue-on-error: true | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| flags: real-db | |
| directory: ./uapi/coverage | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # -------------------------------------------------------------------------- | |
| # 4. Validate workflow files themselves with actionlint | |
| # -------------------------------------------------------------------------- | |
| actionlint: | |
| name: Validate GitHub Actions workflows | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: reviewdog/action-actionlint@v1 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| # -------------------------------------------------------------------------- | |
| # 5. CodeQL static security analysis (JavaScript/TypeScript) | |
| # -------------------------------------------------------------------------- | |
| codeql-analysis: | |
| name: CodeQL Analysis | |
| if: ${{ vars.ENABLE_ADVANCED_CODEQL == '1' }} | |
| permissions: | |
| actions: read | |
| security-events: write | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| language: [ 'javascript-typescript' ] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@v4 | |
| with: | |
| languages: ${{ matrix.language }} | |
| - name: Autobuild | |
| uses: github/codeql-action/autobuild@v4 | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v4 | |
| # -------------------------------------------------------------------------- | |
| # 6. GitHub Super-Linter (Markdown, YAML, Shell, etc.) | |
| # -------------------------------------------------------------------------- | |
| super-linter: | |
| name: Super Linter (misc files) | |
| if: ${{ vars.ENABLE_SUPER_LINTER == '1' }} | |
| runs-on: ubuntu-latest | |
| needs: lint-build | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Super-Linter | |
| uses: github/super-linter/slim@v5 | |
| env: | |
| DEFAULT_BRANCH: main | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |