Skip to content

ci(github-actions): install SurrealDB from a pinned release tarball, … #3

ci(github-actions): install SurrealDB from a pinned release tarball, …

ci(github-actions): install SurrealDB from a pinned release tarball, … #3

Workflow file for this run

# CI — build every container image, run every unit-test group.
#
# WHY THIS EXISTS. On 2026-08-15 we found that every frontend Docker build had
# been failing since 2026-08-03 on a single missing `COPY tsconfig.base.json`,
# and nobody noticed for twelve days. Two properties conspired:
#
# 1. `pnpm build` on a laptop passes regardless, because tsconfig.base.json is
# sitting right there on disk. The bug only exists inside the image.
# 2. A failed Railway deploy is SILENT — the previous container keeps serving
# and the health check keeps passing.
#
# So the Docker build only ever ran in production, and production only ever
# whispered when it broke. This workflow moves that build to the one place that
# fails loudly and early: the pull request.
#
# See changelog/2026-08-15_01_Every-Frontend-Deploy-Had-Been-Failing-For-Twelve-Days-On-One-Missing-COPY.md
name: CI
on:
pull_request:
push:
# The trunk is rebuild/turbo-rsbuild, NOT main — see the branch-tier model.
branches: [rebuild/turbo-rsbuild]
# A newer push to the same branch makes the in-flight run irrelevant.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
images:
name: image · ${{ matrix.name }}
runs-on: ubuntu-latest
strategy:
# One broken image should not hide the state of the other fifteen —
# that is precisely the failure mode this workflow exists to prevent.
fail-fast: false
matrix:
include:
# Frontends build from the REPO ROOT: they need the pnpm workspace,
# packages/, and tsconfig.base.json. This is the group that broke.
- { name: shell, dockerfile: shell/Dockerfile, context: . }
- { name: chat, dockerfile: apps/chat/Dockerfile, context: . }
- { name: corpora-curator, dockerfile: apps/corpora-curator/Dockerfile, context: . }
- { name: org-workbench, dockerfile: apps/org-workbench/Dockerfile, context: . }
- { name: search-and-add, dockerfile: apps/search-and-add/Dockerfile, context: . }
- { name: search-results, dockerfile: apps/search-results/Dockerfile, context: . }
# Services build from their OWN directory — self-contained tsconfig,
# npm install rather than the workspace. Different shape, same gate.
- { name: content-ingest, dockerfile: services/content-ingest/Dockerfile, context: services/content-ingest }
- { name: ingest, dockerfile: services/ingest/Dockerfile, context: services/ingest }
- { name: prompt-runner, dockerfile: services/prompt-runner/Dockerfile, context: services/prompt-runner }
- { name: prompt-store, dockerfile: services/prompt-store/Dockerfile, context: services/prompt-store }
- { name: record-surrealdb-resolver, dockerfile: services/record-surrealdb-resolver/Dockerfile, context: services/record-surrealdb-resolver }
- { name: response-store, dockerfile: services/response-store/Dockerfile, context: services/response-store }
- { name: row-store, dockerfile: services/row-store/Dockerfile, context: services/row-store }
- { name: social-search, dockerfile: services/social-search/Dockerfile, context: services/social-search }
- { name: workspace, dockerfile: services/workspace/Dockerfile, context: services/workspace }
- { name: xlsx-ingest, dockerfile: services/xlsx-ingest/Dockerfile, context: services/xlsx-ingest }
steps:
# No submodules. The client repos are gitignored out of the Railway build
# context (.railwayignore) and no Dockerfile COPYs clients/, so fetching
# them here would only buy us a credentials problem.
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Build ${{ matrix.name }}
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
file: ${{ matrix.dockerfile }}
# Never push. The artifact is the exit code — proof it builds at all.
push: false
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
tests:
name: unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
# --frozen-lockfile is itself a check: it fails when a package.json and
# the lockfile have drifted, which a split-across-commits change can do.
- run: pnpm install --frozen-lockfile
# Groups E/J are not pure unit tests: test/domains.test.ts spawns a real
# `surreal start … memory` as a child process. On a developer machine that
# binary is already on PATH, so the suite passes locally and fails here
# with `spawn surreal ENOENT` — the same laptop-vs-clean-machine asymmetry
# that hid the tsconfig bug for twelve days. Install it explicitly.
# Pinned rather than `latest`, deliberately: an upstream release that
# breaks this job would look like a broken PR, and a gate that cries wolf
# stops being read. Bump the version here on purpose.
# (install.surrealdb.com's script is not used — it rejects --yes and
# prompts, which hangs or exits 2 on a runner.)
- name: Install SurrealDB CLI (Groups E/J spawn it)
env:
SURREAL_VERSION: v3.2.0
run: |
curl -sSfL "https://github.com/surrealdb/surrealdb/releases/download/${SURREAL_VERSION}/surreal-${SURREAL_VERSION}.linux-amd64.tgz" \
| sudo tar -xz -C /usr/local/bin
- name: Verify surreal is on PATH
run: surreal version
# Mirrors scripts/test-all.sh minus Group I. The e2e group drives a real
# backend chain over a live WebSocket (e2e/harness.mjs wants NATS and
# SurrealDB), so it needs service containers before it can run here.
# Running it without them would produce a red badge that means nothing,
# which is worse than no badge. Tracked as follow-up.
- name: Group C — transport
run: pnpm --filter @augment-it/workspace test
- name: Groups B/D/H — workspace-service
run: pnpm --dir services/workspace test
- name: Groups E/J — resolver
run: pnpm --dir services/record-surrealdb-resolver test
- name: Group F — content-ingest
run: pnpm --dir services/content-ingest test
- name: Group G — corpora-curator
run: pnpm --dir apps/corpora-curator test
design-drift:
name: design drift
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
# Reports 99 known failures today, so it cannot gate yet — it runs to keep
# the number visible and to catch the contrast checks, which DO pass 30/30.
# Turn `|| true` off once the F6/F8 debt is burned down.
- name: pnpm design:drift
run: pnpm design:drift || true