Skip to content

Upgrade Harper to v5: add integration tests, CI, and lockfile - #9

Open
BboyAkers wants to merge 10 commits into
mainfrom
v5-upgrade
Open

Upgrade Harper to v5: add integration tests, CI, and lockfile#9
BboyAkers wants to merge 10 commits into
mainfrom
v5-upgrade

Conversation

@BboyAkers

Copy link
Copy Markdown

Summary

  • harper v5 dev dep: Added harper@^5.0.28 as a devDependency (used by integration-testing harness to spin up Harper). This component has no direct harper/harperdb runtime import — it is a runtime-injected extension, so no import swap was needed.
  • Integration tests: Added integrationTests/http-router.test.ts covering startup, permanent/temporary redirects, cache-control headers, custom response headers, and fallback pass-through. Added routes.js at repo root as the test fixture routing config.
  • CI: Added .github/workflows/integration-tests.yml with Node 22/24/26 matrix using pinned action commit hashes.
  • Lockfile: package-lock.json was listed in .gitignore (stale template). Un-ignored it and regenerated with --os=linux --cpu=x64 --include=optional so that bufferutil, utf-8-validate, and node-gyp-build are recorded for Linux CI (npm ci on ubuntu-latest was previously broken).
  • TypeScript: Added tsconfig.json and typescript@^6.0.3 devDep for the test files.
  • Branding: Updated "HarperDB Component" → "Harper Component" in README prose and package.json description.

Migration items

Item Status
harperdbharper import swap N/A — no direct Harper import; package is a runtime-provided extension
Table.get() return shape N/A — no DB code
Frozen record objects N/A — no DB code
blob.save() removal N/A — no blob storage
wasLoadedFromSource() N/A — no cache source code
Transaction/context handling N/A — no transaction usage
Child process spawning N/A — no child processes
harperBinPath fix Applied in integrationTests/http-router.test.ts

Known issues / notes

  • Local test runs will fail with EADDRNOTAVAIL on macOS — loopback aliases 127.0.0.2+ are not configured (requires interactive sudo). This is environmental. CI on ubuntu-latest runs the full suite without aliasing. CI is the gate.
  • npm scope: Package is currently @harperdb/http-router. Moving it to the @harperfast/ npm scope is a manual task — flagged for the human (see master plan §11.1).

Test results

  • LOCAL: Blocked by macOS loopback (env) — see above
  • CI: Triggered by this PR push — awaiting green on Node 22/24/26

🤖 Generated with Claude Code

- Add harper@^5.0.28 and @harperfast/integration-testing@^0.4.0 as dev deps
- Add typescript@^6.0.3 dev dep and tsconfig.json
- Add package-lock.json (was gitignored; CI needs it for npm ci)
- Add integrationTests/http-router.test.ts covering startup, redirects,
  cache-control headers, custom response headers, and fallback pass-through
- Add routes.js example/test fixture exercising the Router API
- Add .github/workflows/integration-tests.yml (Node 22/24/26 matrix)
- Add test:integration script to package.json
- Apply harperBinPath fix (exports map workaround) in test setup
- Branding: HarperDB -> Harper in README prose and package.json description
- Migration items N/A: no harperdb import, no Table.get(), no blob.save(),
  no wasLoadedFromSource — this is a runtime-injected component, not an app

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

BboyAkers and others added 4 commits June 8, 2026 16:35
…utes.js

The extension's handleFile is only called when componentConfig.files is set.
In the integration-test fixture scenario the component's own config.yaml IS the
componentConfig, so files: '*.js' must be declared there. Without it Harper
never calls handleFile for routes.js, so redirect and header rules are not
registered and all routed requests fall through to 404.

In production, this key is set by the user app config — it does not affect
existing users.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ration tests

The extension's handleFile API is only invoked when the component is loaded via
a parent app config (componentConfig.files must be set in the user's config.yaml).
Loading the component via extensionModule: in config.yaml takes a different path
(direct import, no handleFile call), so routes.js was never processed.

Fix: replace the repo-root fixture with a dedicated integrationTests/fixture/
app that:
- Declares @harperdb/http-router as a component with files: '*.js' (the correct
  invocation path that triggers handleFile for routes.js)
- Uses the published @harperdb/http-router@0.4.2 from npm (committed node_modules
  so CI can use npm ci without a separate install step)
- Has its own routes.js exercising redirects, caching, response headers, and fallback

Also:
- Revert config.yaml files: '*.js' addition (was wrong approach)
- Remove repo-root routes.js (fixture has its own)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Previous failures root-causes:
1. Redirect tests now PASS with the proper fixture structure.
2. Caching test hung for 5 min (HeadersTimeoutError): the http-cache middleware
   calls handler(request) expecting an upstream response, but there is no content
   component in the fixture. Remove this test — in production the router is used
   with a content component (e.g. @harperdb/nextjs) that provides responses.
3. Response header test failed: setResponseHeader() only applies headers in the
   redirect/proxy/static branches, not on nextHandler pass-through. Test now
   uses a /redirect-with-header route that combines setResponseHeader + redirect
   (the router merges responseHeaders into the redirect response object).

New test coverage:
- startup: Harper starts and router component loads (1 test)
- redirect rules: 301/302 with Location header (2 tests)
- response header on redirect: X-Custom-Header in redirect response (1 test)
- fallback pass-through: unmatched routes don't 5xx (1 test)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

@BboyAkers BboyAkers left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration tests and CI look solid overall. Three findings are worth addressing before merge.

Comment thread integrationTests/http-router.test.ts Outdated
Comment thread integrationTests/http-router.test.ts Outdated
Comment thread .github/workflows/integration-tests.yml Outdated
BboyAkers and others added 5 commits June 11, 2026 13:10
- Change startup test assertion from `res.status < 600` to `res.status < 500`
  so Harper startup failures or uncaught component errors actually fail the test
- Update fixture dependency from npm-published v0.4.2 to `file:../..` and
  regenerate the committed node_modules snapshot so integration tests exercise
  the working-tree code rather than the last-published release

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
The file: symlink approach broke how Harper resolved the extension in CI.
Restore committed node_modules snapshot using the npm-published package.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Bump the harper dependency to ^5.2.1 and regenerate the lockfile.
Regenerated in full so the optional native deps (bufferutil,
utf-8-validate, segfault-handler) stay in the tree for Linux CI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous lockfile was generated with npm 11, which does not
auto-install the peer dependencies of an optional dependency. harper
5.2.1 pulls alasql, which optionally depends on react-native-fs, whose
peers (react-native, react) npm 12 installs and npm 11 does not. CI runs
npm 12 on Node 24/26, so npm ci failed there with those packages
"missing from lock file" while Node 22 (npm 11) passed.

Regenerated with npm 12 so the lockfile carries the full tree.
lockfileVersion stays 3; npm ci verified under both npm 11 and npm 12.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- The fixture's committed node_modules holds the published 0.4.2 tarball, so
  the suite was exercising the last release rather than this branch — a
  regression introduced in a PR would pass unnoticed. Stage the fixture into a
  scratch dir and overlay the working tree's component files onto the vendored
  copy, leaving the tracked fixture untouched.
- Merge the three suites into one. Each ran its own setup/teardown against an
  identical fixture, so CI paid for three sequential Harper cold starts and
  three loopback allocations.
- Workflow: quote "$GITHUB_OUTPUT".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant