Skip to content

Merge pull request #368 from Open-Legal-Products/vercel-ai-sdk-backend #370

Merge pull request #368 from Open-Legal-Products/vercel-ai-sdk-backend

Merge pull request #368 from Open-Legal-Products/vercel-ai-sdk-backend #370

Workflow file for this run

# 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