From 1260ca1cd4593257b4911d6c2cab0731593a1bca Mon Sep 17 00:00:00 2001 From: Jeff Cameron <32875696+jcameronjeff@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:03:37 -0400 Subject: [PATCH 1/2] ci: add Phase 1 CI workflow --- .github/workflows/ci.yml | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ae3d869 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +name: CI + +# Bespoke (not the reusable ci-node.yml) because this repo has two quirks the +# generic caller does not handle: +# 1. better-sqlite3 is a NATIVE addon — `npm ci` compiles it from source, so we +# verify the binding actually loads, not just that install succeeded. +# 2. The MCP server is a long-running stdio process that never exits on its own +# (server.connect(transport) blocks forever). A plain `node dist/server.js` +# would hang CI, so we boot it, confirm it survives a few seconds without +# crashing, then kill it — pointed at a throwaway VAULT_DB_PATH. + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # Node 22 matches @types/node ^22 and the native ABI better-sqlite3 builds against. + - uses: actions/setup-node@v4 + with: + node-version: "22" + cache: npm + + # npm ci compiles better-sqlite3 from source against this Node's ABI. + - name: Install dependencies (rebuilds native better-sqlite3) + run: npm ci + + # Fail fast if the native binding can't be loaded after the rebuild. + - name: Verify native better-sqlite3 binding loads + run: node -e "const D=require('better-sqlite3'); const db=new D(':memory:'); db.exec('create table t(x)'); db.close(); console.log('better-sqlite3 OK');" + + - name: Typecheck + run: npx tsc --noEmit + + - name: Build + run: npm run build + + # Boot the stdio MCP server against a temp DB. It never exits on its own, + # so we run it in the background, give it time to construct the SQLite vault + # and connect the transport, then assert it's still alive (didn't crash on + # boot) before tearing it down. + - name: Smoke-boot MCP server + run: | + set -euo pipefail + export VAULT_DB_PATH="$(mktemp -d)/vault.db" + echo "Booting with VAULT_DB_PATH=$VAULT_DB_PATH" + node dist/server.js & + SERVER_PID=$! + sleep 3 + if ! kill -0 "$SERVER_PID" 2>/dev/null; then + echo "::error::MCP server exited during boot (crash)" + wait "$SERVER_PID" || true + exit 1 + fi + echo "Server still alive after boot — OK" + if [ ! -f "$VAULT_DB_PATH" ]; then + echo "::error::Vault DB was not created at $VAULT_DB_PATH" + kill "$SERVER_PID" 2>/dev/null || true + exit 1 + fi + echo "Vault DB created — OK" + kill "$SERVER_PID" 2>/dev/null || true + wait "$SERVER_PID" 2>/dev/null || true + From 0ee436bfd0473a070ce1e68424018785c2592319 Mon Sep 17 00:00:00 2001 From: Jeff Cameron <32875696+jcameronjeff@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:09:46 -0400 Subject: [PATCH 2/2] ci: fix Phase 1 workflow (token-5-0) --- .github/workflows/ci.yml | 42 ++++++---------------------------------- 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae3d869..6219140 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,13 +1,11 @@ name: CI -# Bespoke (not the reusable ci-node.yml) because this repo has two quirks the -# generic caller does not handle: -# 1. better-sqlite3 is a NATIVE addon — `npm ci` compiles it from source, so we -# verify the binding actually loads, not just that install succeeded. -# 2. The MCP server is a long-running stdio process that never exits on its own -# (server.connect(transport) blocks forever). A plain `node dist/server.js` -# would hang CI, so we boot it, confirm it survives a few seconds without -# crashing, then kill it — pointed at a throwaway VAULT_DB_PATH. +# Bespoke (not the reusable ci-node.yml) because better-sqlite3 is a NATIVE +# addon: `npm ci` compiles it from source, so we verify the binding actually +# loads, not just that install succeeded. The server is a stdio MCP process +# (it exits on stdin EOF — there is no long-running daemon to smoke-boot in CI), +# so the gates are install + native-binding load + typecheck + build. A real +# MCP-handshake smoke test is a follow-up. on: push: @@ -47,31 +45,3 @@ jobs: - name: Build run: npm run build - - # Boot the stdio MCP server against a temp DB. It never exits on its own, - # so we run it in the background, give it time to construct the SQLite vault - # and connect the transport, then assert it's still alive (didn't crash on - # boot) before tearing it down. - - name: Smoke-boot MCP server - run: | - set -euo pipefail - export VAULT_DB_PATH="$(mktemp -d)/vault.db" - echo "Booting with VAULT_DB_PATH=$VAULT_DB_PATH" - node dist/server.js & - SERVER_PID=$! - sleep 3 - if ! kill -0 "$SERVER_PID" 2>/dev/null; then - echo "::error::MCP server exited during boot (crash)" - wait "$SERVER_PID" || true - exit 1 - fi - echo "Server still alive after boot — OK" - if [ ! -f "$VAULT_DB_PATH" ]; then - echo "::error::Vault DB was not created at $VAULT_DB_PATH" - kill "$SERVER_PID" 2>/dev/null || true - exit 1 - fi - echo "Vault DB created — OK" - kill "$SERVER_PID" 2>/dev/null || true - wait "$SERVER_PID" 2>/dev/null || true -