Merge pull request #368 from Open-Legal-Products/vercel-ai-sdk-backend #370
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
| # CI: build and test. | |
| # | |
| # Adapted from the amal66/mike fork's .github/workflows/ci.yml (monorepo | |
| # layout) to this repository's backend/ + frontend/ layout. Test steps use | |
| # `npm test --if-present`, and the eval job checks for evals/run.mjs, so this | |
| # workflow is safe to merge before or after the test-harness and evals PRs: | |
| # on a tree without those pieces the test steps no-op and the build still | |
| # gates the merge. Beyond the fork version this also builds the frontend | |
| # (placeholder NEXT_PUBLIC_* env — verified sufficient for `next build`) and | |
| # runs eslint as a blocking gate (the error backlog is at zero). | |
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| backend: | |
| name: Backend build and tests | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: backend | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: backend/package-lock.json | |
| # Git's line-level merge can splice both sides of package(-lock).json | |
| # into invalid JSON without a conflict (bit PR #233). npm's own error | |
| # for an unparseable lockfile is the misleading "npm ci can only | |
| # install with an existing package-lock.json" — fail fast with the real | |
| # reason instead. | |
| - name: Validate package.json and lockfile parse | |
| run: node -e "for (const f of ['package.json','package-lock.json']) JSON.parse(require('fs').readFileSync(f, 'utf8'))" | |
| - run: npm ci | |
| # No-ops on a tree without a "test" script (e.g. before the vitest | |
| # harness PR merges); runs the suite once it exists. | |
| - run: npm test --if-present | |
| - run: npm run build | |
| frontend: | |
| name: Frontend build and tests | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: frontend | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: npm | |
| cache-dependency-path: frontend/package-lock.json | |
| # Same silent-merge-corruption guard as the backend job. | |
| - name: Validate package.json and lockfile parse | |
| run: node -e "for (const f of ['package.json','package-lock.json']) JSON.parse(require('fs').readFileSync(f, 'utf8'))" | |
| - run: npm ci | |
| # Runs the suite with the coverage-ratchet floor check (see | |
| # docs/frontend-testing.md); --if-present keeps the fallback semantics, | |
| # so a tree without the "test:coverage" script still no-ops. | |
| - run: npm run test:coverage --if-present | |
| # Blocking gate: the eslint error backlog was burned down in this PR | |
| # (0 errors; warnings do not fail the step), so any new error fails CI. | |
| - run: npm run lint | |
| # Production build. NEXT_PUBLIC_* values are inlined at build time and | |
| # only need to be well-formed here — nothing is contacted during build. | |
| # This catches type errors (next build runs tsc) and broken routes/imports. | |
| - run: npm run build | |
| env: | |
| NEXT_PUBLIC_SUPABASE_URL: https://placeholder.supabase.co | |
| NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY: sb_publishable_placeholder | |
| NEXT_PUBLIC_API_BASE_URL: http://localhost:3001 | |
| # ----------------------------------------------------------------------- | |
| # Generated-workflows drift check: the committed generated files must be | |
| # exactly what scripts/build-workflows.js produces from the mike-workflows | |
| # commit stamped into backend/src/lib/systemWorkflows.ts. Both repos are | |
| # checked out as siblings inside the workspace because the generator | |
| # resolves the source checkout at <repo-root>/../mike-workflows. The | |
| # generator has no npm dependencies, so no install step is needed. | |
| # mike-workflows is public, so the default token suffices. | |
| # ----------------------------------------------------------------------- | |
| workflows-drift: | |
| name: Generated workflows drift check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| path: mike | |
| - name: Read pinned mike-workflows commit | |
| id: source | |
| working-directory: mike | |
| run: | | |
| commit=$(grep -oE 'SYSTEM_WORKFLOWS_SOURCE_COMMIT = "[0-9a-f]{40}"' backend/src/lib/systemWorkflows.ts | grep -oE '[0-9a-f]{40}') | |
| if [ -z "$commit" ]; then | |
| echo "No SYSTEM_WORKFLOWS_SOURCE_COMMIT found in backend/src/lib/systemWorkflows.ts" >&2 | |
| exit 1 | |
| fi | |
| echo "commit=$commit" >> "$GITHUB_OUTPUT" | |
| - uses: actions/checkout@v4 | |
| with: | |
| repository: Open-Legal-Products/mike-workflows | |
| ref: ${{ steps.source.outputs.commit }} | |
| path: mike-workflows | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: Regenerate workflows | |
| working-directory: mike | |
| run: node scripts/build-workflows.js | |
| - name: Fail on drift against the committed generated files | |
| working-directory: mike | |
| run: git diff --exit-code -- backend/src/lib/systemWorkflows.ts landing/app/generated-workflows.ts | |
| # ----------------------------------------------------------------------- | |
| # Offline eval harness: deterministic scorecard for citation accuracy, | |
| # prompt-injection resistance, and privilege/PII leakage. Runs against | |
| # committed fixtures (no network, no LLM calls, no secrets), so it is cheap | |
| # enough to gate every PR. --threshold 1.0 = every case must pass. | |
| # Skips gracefully until the evals PR merges. | |
| # ----------------------------------------------------------------------- | |
| evals: | |
| name: Eval harness | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: Run eval harness (skips if evals/ not present) | |
| run: | | |
| if [ -f evals/run.mjs ]; then | |
| node evals/run.mjs --threshold 1.0 | |
| else | |
| echo "evals/run.mjs not present on this tree; skipping" | |
| fi |