ci(graph-ui): pin D1 persist dir and make readiness prove the data #3
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
| # Browser coverage for the graph UI. | |
| # | |
| # Why: four user-visible defects shipped in a single day — a render loop that never | |
| # idled (~227% CPU on a still page), a database missing from one view's selector, a | |
| # top bar painted over by the drawers, and drawer widths that had no coverage at all. | |
| # Every one was caught by a hand-written probe, never by a gate, so nothing stopped | |
| # them recurring. The Python CI (clean-install.yml) does not touch any of this. | |
| # | |
| # Each assertion in test_ui.mjs maps to one of those defects. All three have been | |
| # mutation-tested: breaking the shipped code turns exactly the matching assertion red. | |
| name: graph-ui | |
| on: | |
| push: | |
| branches: [main, dev] | |
| tags: ["v*"] | |
| paths: | |
| - "memora-graph/**" | |
| - "memora/graph/**" # index.html lives here; public/ symlinks to it | |
| - ".github/workflows/graph-ui.yml" | |
| pull_request: | |
| paths: | |
| - "memora-graph/**" | |
| - "memora/graph/**" | |
| - ".github/workflows/graph-ui.yml" | |
| workflow_dispatch: | |
| jobs: | |
| graph-ui: | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: memora-graph | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| # 22.x for --experimental-strip-types, which test_lineage.mjs needs to | |
| # import the shipped _lineage.ts directly instead of reimplementing it. | |
| node-version: "22" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Install Chromium for Playwright | |
| run: npx playwright install --with-deps chromium | |
| - name: Seed local D1 from the fixture | |
| # Supersession chain, non-lineage typed edges, and a mirror-only drift row. | |
| # | |
| # --persist-to is passed to BOTH this and `pages dev` below and must match. | |
| # Relying on each command's default landed the seed in one state directory | |
| # and served from another: the seed reported success, the server started | |
| # fine, and every query failed with "no such table: memories". | |
| run: npx wrangler d1 execute memora-graph --local --persist-to=.wrangler/state --file=tests/fixture.sql | |
| - name: Resolve the index.html symlink | |
| # public/index.html is a symlink to memora/graph/index.html. `wrangler pages | |
| # dev` does NOT serve symlinked assets (the page 404s), while deploys DO | |
| # follow it. Swapping in a resolved copy serves identical bytes. | |
| run: | | |
| cp -L public/index.html /tmp/index.real.html | |
| rm public/index.html | |
| cp /tmp/index.real.html public/index.html | |
| test -f public/index.html && ! test -L public/index.html | |
| - name: Start wrangler pages dev | |
| run: | | |
| npx wrangler pages dev ./public --local --persist-to=.wrangler/state \ | |
| --port 8788 --log-level warn > /tmp/wrangler.log 2>&1 & | |
| # Readiness must prove the DATA is reachable, not just that a port is open. | |
| # This previously polled /api/databases, which reports the binding catalog | |
| # from env and answers 200 with an empty database — so an unseeded server | |
| # looked healthy and the run failed 60s later as an opaque browser timeout, | |
| # diagnosable only from a buried server log. /api/graph hits the tables. | |
| for i in $(seq 1 60); do | |
| NODES=$(curl -sf http://localhost:8788/api/graph 2>/dev/null \ | |
| | python3 -c "import json,sys; print(len(json.load(sys.stdin).get('nodes',[])))" 2>/dev/null || echo 0) | |
| if [ "${NODES:-0}" -gt 0 ]; then | |
| echo "server up after ${i}s with ${NODES} seeded nodes"; exit 0 | |
| fi | |
| sleep 1 | |
| done | |
| echo "server never served seeded data. wrangler log:"; cat /tmp/wrangler.log | |
| echo "--- state dirs present ---"; find .wrangler -name '*.sqlite' 2>/dev/null | |
| exit 1 | |
| - name: Lineage logic tests | |
| # Pure-logic suite that imports the shipped modules. It existed before this | |
| # workflow and ran nowhere. | |
| run: node --experimental-strip-types scripts/test_lineage.mjs | |
| - name: Browser tests | |
| run: node scripts/test_ui.mjs http://localhost:8788 | |
| - name: Server log on failure | |
| if: failure() | |
| run: cat /tmp/wrangler.log || true |