From 453fd71c5752f093cf396f4c50692bdd084878b8 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 21 May 2026 10:05:56 -0600 Subject: [PATCH 1/4] feat: enable unit tests in CI and renovate auto-merge - Add unitTests/unitTestSetup.cjs to bootstrap the minimum Harper environment (STORAGE_PATH, _DISABLE_NATS) required before ESM modules with module-level side effects can be loaded - Wire setup file into .mocharc.json via "require" so it runs before any test file is evaluated - Add test:unit script (mocha 'unitTests/**/*.test.mjs') to package.json - Add .github/workflows/unit-tests.yaml running on Node 22 + 24 for push/PR, mirroring the build-then-test pattern used by integration tests - Enable automerge on renovate's digest-pin and non-major update rules Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/unit-tests.yaml | 37 +++++++++++++++++++++++++++++++ .mocharc.json | 1 + package.json | 1 + renovate.json | 6 +++-- unitTests/unitTestSetup.cjs | 14 ++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/unit-tests.yaml create mode 100644 unitTests/unitTestSetup.cjs diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml new file mode 100644 index 000000000..0cdf71b27 --- /dev/null +++ b/.github/workflows/unit-tests.yaml @@ -0,0 +1,37 @@ +name: Unit Tests + +on: + push: + branches: [main, 'v[0-9]+.[0-9]+'] + pull_request: + workflow_dispatch: + +jobs: + unit-tests: + name: Unit Tests (Node.js v${{ matrix.node-version }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: [22, 24] + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + submodules: 'recursive' + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ matrix.node-version }} + package-manager-cache: false + + - name: Install dependencies + run: npm install + + - name: Build + run: npm run build || true + + - name: Run unit tests + run: npm run test:unit diff --git a/.mocharc.json b/.mocharc.json index 4edecfbaf..a4deac876 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -4,6 +4,7 @@ "extension": ["js", "mjs"], "recursive": true, "enable-source-maps": true, + "require": ["unitTests/unitTestSetup.cjs"], "exclude": ["unitTests/testApp/**"], "node-option": ["expose-internals", "enable-source-maps", "experimental-vm-modules"], "exit": true diff --git a/package.json b/package.json index f2238d46f..896853cf5 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "lint": "oxlint --deny-warnings .", "lint:fix": "npm run lint -- --fix", "lint:required": "oxlint --quiet .", + "test:unit": "mocha 'unitTests/**/*.test.mjs'", "test:integration": "HARPER_INTEGRATION_TEST_INSTALL_SCRIPT=dist/bin/harper.js harper-integration-test-run", "test:integration:all": "npm run test:integration -- integrationTests/**/*.test.*s", "cluster:ip:local": "pushd utility/dev && docker compose -f docker-compose.ip.yml --project-directory ../.. build && docker compose -f docker-compose.ip.yml --project-directory ../.. up; popd", diff --git a/renovate.json b/renovate.json index 8c541fd2f..fd1281b7d 100644 --- a/renovate.json +++ b/renovate.json @@ -18,13 +18,15 @@ "groupName": "pin digests", "groupSlug": "all-digests", "matchDepTypes": ["action"], - "pinDigests": true + "pinDigests": true, + "automerge": true }, { "groupName": "all non-major dependencies", "groupSlug": "all-minor-patch", "matchUpdateTypes": ["minor", "patch"], - "matchCurrentVersion": "!/^0/" + "matchCurrentVersion": "!/^0/", + "automerge": true } ] } diff --git a/unitTests/unitTestSetup.cjs b/unitTests/unitTestSetup.cjs new file mode 100644 index 000000000..dab23b09e --- /dev/null +++ b/unitTests/unitTestSetup.cjs @@ -0,0 +1,14 @@ +'use strict'; +const os = require('os'); +const path = require('path'); +const fs = require('fs'); + +// Minimal environment setup required before Harper modules are loaded. +// Harper's auth and database modules initialize storage at import time, +// so these env vars must be set before the ESM test files are evaluated. +const testDir = path.join(os.tmpdir(), `harper-unit-tests-${process.pid}`); +fs.mkdirSync(testDir, { recursive: true }); + +process.env.STORAGE_PATH = testDir; +process.env._DISABLE_NATS = 'true'; +process.env.LOGGING_STDSTREAMS = 'false'; From 9fe234d7af0a587c96c31db22eff22cb93ea0a08 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 21 May 2026 11:54:31 -0600 Subject: [PATCH 2/4] fixup: address cross-model review findings - Add Node 20 to unit test CI matrix - Add temp dir cleanup on process exit in unitTestSetup.cjs - Update AGENTS.md to reflect that test:unit now exists in Pro Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/unit-tests.yaml | 2 +- AGENTS.md | 2 +- unitTests/unitTestSetup.cjs | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 0cdf71b27..70aedec5f 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [22, 24] + node-version: [20, 22, 24] steps: - name: Checkout code diff --git a/AGENTS.md b/AGENTS.md index 5ae5695ba..52cac8cec 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -35,6 +35,6 @@ inside `.git/modules/core/`, remove them immediately — they are corrupting the ## Pro-specific notes - **Linter**: oxlint with `--deny-warnings` (`npm run lint`), same as core. -- **Tests**: only `npm run test:integration` exists here. There is no `test:unit` split — Pro relies on core for unit-test coverage of the substrate it inherits. `test:integration` is slow; run only when the change plausibly affects integration behavior. +- **Tests**: `npm run test:unit` runs `unitTests/**/*.test.mjs` via mocha (fast, no server required — requires a built `dist/`, run `npm run build` first). `npm run test:integration` is slow; run only when the change plausibly affects integration behavior. - **Storage substrate**: same as core — RocksDB primary, LMDB available via `HARPER_STORAGE_ENGINE=lmdb`. - **Documentation scope**: https://docs.harperdb.io is authoritative for Harper mechanics. Pro docs describe Pro-only surface, not core behavior. diff --git a/unitTests/unitTestSetup.cjs b/unitTests/unitTestSetup.cjs index dab23b09e..d732c09dc 100644 --- a/unitTests/unitTestSetup.cjs +++ b/unitTests/unitTestSetup.cjs @@ -12,3 +12,5 @@ fs.mkdirSync(testDir, { recursive: true }); process.env.STORAGE_PATH = testDir; process.env._DISABLE_NATS = 'true'; process.env.LOGGING_STDSTREAMS = 'false'; + +process.on('exit', () => fs.rmSync(testDir, { recursive: true, force: true })); From 05abbbac6371201178c94883ec093d58da10f5b6 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Thu, 21 May 2026 11:56:25 -0600 Subject: [PATCH 3/4] fix: scope unit test env setup to test:unit script only Move --require unitTests/unitTestSetup.cjs from .mocharc.json onto the test:unit npm script so the env overrides (_DISABLE_NATS, STORAGE_PATH) don't bleed into other mocha invocations. Co-Authored-By: Claude Sonnet 4.6 --- .mocharc.json | 1 - package.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.mocharc.json b/.mocharc.json index a4deac876..4edecfbaf 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -4,7 +4,6 @@ "extension": ["js", "mjs"], "recursive": true, "enable-source-maps": true, - "require": ["unitTests/unitTestSetup.cjs"], "exclude": ["unitTests/testApp/**"], "node-option": ["expose-internals", "enable-source-maps", "experimental-vm-modules"], "exit": true diff --git a/package.json b/package.json index 896853cf5..d32a6687a 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "lint": "oxlint --deny-warnings .", "lint:fix": "npm run lint -- --fix", "lint:required": "oxlint --quiet .", - "test:unit": "mocha 'unitTests/**/*.test.mjs'", + "test:unit": "mocha --require unitTests/unitTestSetup.cjs 'unitTests/**/*.test.mjs'", "test:integration": "HARPER_INTEGRATION_TEST_INSTALL_SCRIPT=dist/bin/harper.js harper-integration-test-run", "test:integration:all": "npm run test:integration -- integrationTests/**/*.test.*s", "cluster:ip:local": "pushd utility/dev && docker compose -f docker-compose.ip.yml --project-directory ../.. build && docker compose -f docker-compose.ip.yml --project-directory ../.. up; popd", From 8aaf0b15667e9beb101c7c0fc90ef54973365b52 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Fri, 22 May 2026 15:57:02 -0600 Subject: [PATCH 4/4] fix: use --ignore-scripts on npm install in unit test CI Consistent with harper repo practice. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/unit-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 70aedec5f..fb935008c 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -28,7 +28,7 @@ jobs: package-manager-cache: false - name: Install dependencies - run: npm install + run: npm install --ignore-scripts - name: Build run: npm run build || true