From 0752f666fb77a4b78df8975bd029b8634739011e Mon Sep 17 00:00:00 2001 From: dtzp555-max Date: Tue, 5 May 2026 09:44:25 +1000 Subject: [PATCH] test: wire test-features.mjs to npm test + add minimal CI smoke workflow (#60) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `test-features.mjs` shipped at v3.8.0 (per CHANGELOG of the keys.mjs quota+cache work) and is referenced from AGENTS.md as the project's only test artifact, but until now nothing actually ran it — no `npm test` script, no CI step. Wiring it up so it runs on every push and PR. ### Changes - `package.json`: add `"test": "node test-features.mjs"` to scripts. - `.github/workflows/test.yml` (new): single-job workflow that runs `npm test` on push to main and on every PR. Uses Node 24 because `keys.mjs` imports `node:sqlite`, which is stable in Node 23+ (Node 24 is the current LTS; Node 22 would need `--experimental-sqlite`). No `npm install` step — OCP has zero external runtime dependencies per `package-lock.json`. - `AGENTS.md`: note that `test-features.mjs` runs via `npm test` and is enforced by `.github/workflows/test.yml`. ### Why this is a hard check, not a soft check `test-features.mjs` is self-contained — it imports `keys.mjs` and exercises the SQLite-backed key/quota/cache code paths against a throwaway test DB at `~/.ocp/ocp-test.db`. It does NOT require: - a live claude CLI binary - a running OCP server - any network access So CI can run it as a real check; no `continue-on-error` needed. ### Local verification ``` $ npm test [...] === Results: 24 passed, 0 failed === ``` 24 assertions cover createKey / listKeys / quota math / cache hash determinism / cache TTL / clearCache. Exit code is 1 on any failure (`process.exit(failed > 0 ? 1 : 0)` at the bottom of test-features.mjs). ### Future expansion If the suite later grows to include tests that DO require a live claude CLI or a running OCP, mark those steps `continue-on-error: true` (or split them into a separate job). The comment in `test.yml` documents this contract. Refs: audit (test-features.mjs orphan / unrunnable in CI). Co-authored-by: dtzp555 --- .github/workflows/test.yml | 41 ++++++++++++++++++++++++++++++++++++++ AGENTS.md | 2 +- package.json | 3 ++- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..997aedc --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,41 @@ +name: Tests + +on: + push: + branches: [main] + pull_request: + +jobs: + test-features: + name: test-features.mjs (smoke) + runs-on: ubuntu-latest + + # `test-features.mjs` is self-contained — it runs assertions against the + # `keys.mjs` DB layer using a throwaway test database. It does NOT need a + # live claude CLI or a running OCP server. So this job runs as a hard + # check on every push / PR. + # + # If a future expansion of the suite adds tests that DO require a live + # claude CLI or a running OCP server, mark those steps `continue-on-error: + # true` (or split them into a separate job) — CI must not be flaky on + # things outside the contributor's machine. + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + # Node 24 ships `node:sqlite` as stable. The test imports keys.mjs, + # which uses `import { DatabaseSync } from "node:sqlite"`. + # Node 22 also works with `--experimental-sqlite`, but we run on 24 + # to keep the CI step simple and to match what released OCP runs on. + node-version: '24' + + # OCP has zero runtime npm dependencies (package-lock.json shows only + # the project's own package and zero external entries). No install + # step needed — `node:*` modules are built into Node 24. + + - name: Run test-features.mjs + run: npm test diff --git a/AGENTS.md b/AGENTS.md index 3eae2df..93f751e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,7 +22,7 @@ Runtime: Node.js (ESM, `.mjs` throughout). No build step. No bundler. `server.mj - `models.json` as the single source of truth for model metadata - GitHub Actions for CI (`alignment.yml`, `release.yml`) - `gh` CLI assumed for PR creation and release automation -- No TypeScript. No test framework beyond `test-features.mjs`. Keep dependencies minimal. +- No TypeScript. No test framework beyond `test-features.mjs` (run via `npm test`; CI workflow `.github/workflows/test.yml`). Keep dependencies minimal. --- diff --git a/package.json b/package.json index 877a90c..d3c2224 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ }, "scripts": { "start": "node server.mjs", - "setup": "node setup.mjs" + "setup": "node setup.mjs", + "test": "node test-features.mjs" }, "keywords": [ "openclaw",