Skip to content

chore: migrate BoringStack to monorepo (apps + infra) #1

chore: migrate BoringStack to monorepo (apps + infra)

chore: migrate BoringStack to monorepo (apps + infra) #1

name: openapi-drift
# Catch ui-template schema drift in the api-template PR that introduced it.
# Before this job, drift only surfaced in infra-docker-compose-template's
# full-stack-smoke workflow — which runs only on infra pushes, so drift
# would sit on api-template main until someone touched infra.
on:
push:
branches: [main]
paths:
- "apps/api/src/**"
- "apps/api/package.json"
- "apps/api/bun.lock"
- ".github/workflows/apps-api-openapi-drift.yml"
pull_request:
paths:
- "apps/api/src/**"
- "apps/api/package.json"
- "apps/api/bun.lock"
- ".github/workflows/apps-api-openapi-drift.yml"
concurrency:
group: apps-api-openapi-drift-${{ github.ref }}
permissions:
contents: read
jobs:
drift:
name: ui-template OpenAPI schema is fresh
runs-on: ubuntu-latest
timeout-minutes: 8
services:
postgres:
image: postgres:17-alpine
env:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: app_dev_password
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U app -d app"
--health-interval 5s
--health-timeout 5s
--health-retries 10
valkey:
image: valkey/valkey:8-alpine
ports:
- 6379:6379
options: >-
--health-cmd "valkey-cli ping"
--health-interval 5s
--health-timeout 5s
--health-retries 10
env:
NODE_ENV: development
DATABASE_URL: postgresql://app:app_dev_password@localhost:5432/app
JWT_SECRET: ci-only-jwt-secret-padded-to-thirty-two-chars
FRONTEND_URL: http://localhost:3001
ALLOWED_ORIGINS: http://localhost:3001
APP_NAME: API Template
LOG_LEVEL: warn
EMAIL_PROVIDER: resend
RESEND_API_KEY: ""
EMAIL_FROM: noreply@example.com
VALKEY_HOST: localhost
VALKEY_PORT: "6379"
steps:
- name: Checkout monorepo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.13
- name: Install api-template deps
working-directory: apps/api
run: bun install --frozen-lockfile
- name: Apply DB migrations
working-directory: apps/api
run: bun run db:migrate
- name: Build email templates
working-directory: apps/api
run: bun run build:templates
- name: Boot API
working-directory: apps/api
run: |
bun run src/index.ts &
echo "API_PID=$!" >> "$GITHUB_ENV"
for i in {1..30}; do
if curl -fsS http://localhost:3000/swagger/json > /dev/null 2>&1; then
echo "✓ api ready after ${i}s"
exit 0
fi
sleep 1
done
echo "✗ api did not become reachable in 30s" >&2
exit 1
- name: Setup pnpm
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
with:
version: 11.1.2
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: apps/ui/.nvmrc
- name: Install ui-template deps
working-directory: apps/ui
run: pnpm install --frozen-lockfile
- name: Check ui-template schema is up-to-date
working-directory: apps/ui
env:
OPENAPI_URL: http://localhost:3000/swagger/json
run: |
if ! pnpm generate:api:check; then
echo "::error::apps/ui/src/lib/api/schema.d.ts is stale against this API change."
echo "::error::To fix: boot api on :3000, then from repo root run 'pnpm regen' and commit apps/ui in the same PR."
exit 1
fi
- name: Stop API
if: always()
working-directory: ${{ github.workspace }}
run: |
if [ -n "${API_PID:-}" ]; then
kill "$API_PID" 2>/dev/null || true
fi