Skip to content

Build for Lambda, add CI, and release 3.0.0 - #285

Open
ottonomy wants to merge 3 commits into
exchanges-switch-and-limitsfrom
lambda-build-ci-release
Open

ottonomy wants to merge 3 commits into
exchanges-switch-and-limitsfrom
lambda-build-ci-release

Conversation

@ottonomy

Copy link
Copy Markdown
Contributor

Stacked on #284 — review and merge that first. This is the last PR in the stack (#280 ← #281 ← #283 ← #284 ← this), and it makes the stack release 3.0.0.

It adds the Lambda build, CI that proves both the Docker shape and the Lambda shape on every pull request, Playwright without screenshot comparisons, and the docs for the breaking changes.

Please review the breaking-change text closely. It is what Docker self-hosters will read when they upgrade: the CHANGELOG's 3.0.0 "Breaking" section, the README's new "Upgrading from 2.x", .env.example, and both docker-compose.example*.yml files.

Lambda build

  • npm run build:lambda (scripts/build-lambda.sh) writes dist/lambda/: the Next.js standalone server, .next/static, public/, .next/cache linked to /tmp/cache, and an executable run.sh that the Lambda Web Adapter starts. The script fails if any of those is missing or run.sh is not executable. It does not zip; the deployment does.
  • Build on Linux x86_64 for a deployable artifact (native sharp binaries). dist/ is ignored by git, Docker and tsc.

Settings contract

  • settings.contract.json lists every environment variable the app reads: whether it is required, its values and default, its purpose, and who sets it under Docker and on Lambda.
  • app/lib/settings.contract.test.ts checks it both ways: every name app/lib/settings.ts reads is listed and no listed app setting is unread. It also checks that leaving out each always-required setting (CREDENTIAL_STORE, EXCHANGES) makes /health/ready answer 503 naming it.

CI (.github/workflows/ci.yml, on pull requests and pushes to main; actions pinned to commit SHAs)

  • unit: npm test, npx tsc --noEmit.
  • stores: the store tests against mongo:7 and amazon/dynamodb-local:3.3.2.
  • lambda-shape: build:lambda, then Playwright (API, DesktopChrome, Lambda) against dist/lambda/run.sh with the memory store and exchanges off. This does not prove the adapter layer, real DynamoDB or API Gateway; the staging deployment's tests do.
  • docker: the image beside MongoDB with EXCHANGES=on, /api/healthz healthy, then the same Playwright projects.
  • Some Playwright tests fetch fixtures and registries from the internet, as before; the HTML report is uploaded as an artifact.

Playwright

  • The seven toHaveScreenshot() calls and all 40 baselines are gone. The verification-log tests check each line's icon (green checkmark, yellow warning, red x) by its accessible name; the achievement-image tests check that the image loaded.
  • New Lambda project (tests/lambda.spec.ts, no browser, no retries): /health/ready is 200; 20 share-then-read round trips, 10 in parallel; 404 after unshare; 413 for a body over 5 MB to /api/verify and for a shared credential over 350 KB. npm run test:e2e runs it too.
  • The wallet exchange test asks /api/config first and is skipped when exchanges are off.

Also

  • The Dockerfile sets HOSTNAME=0.0.0.0. Docker sets HOSTNAME to the container id, so the server listened only on that interface and /api/healthz could not reach it at localhost.
  • .env.example now uses DB_URI=mongodb://127.0.0.1:27017. The old example set DB_HOST=127.0.0.1 with no user or password, which 3.0.0 reports as a problem.
  • Version 3.0.0.

Validated locally (macOS arm64, Node 24)

  • npm test: 116 passed; npx tsc --noEmit clean, also from a fresh state with no .next.
  • npm run test:stores with docker-compose.test.yml: 142 passed.
  • build:lambda, then run.sh with the memory store: /health/ready 200; Playwright API, DesktopChrome, Lambda: 58 passed, 1 skipped (the exchange test, exchanges off).
  • The image on the MongoDB container's network with -p 3000:3000 and EXCHANGES=on: /api/healthz healthy; the same Playwright projects: 59 passed, the exchange test included.
  • actionlint clean. Breaking the contract file, or expecting the wrong icon for a revoked credential, makes the new tests fail.

Not covered here

  • The Linux x86_64 build is first proven by this PR's lambda-shape job.
  • Tagging v3.0.0 on the merge commit is optional (only v2.0.0 is tagged today).

🤖 Generated with Claude Code

npm run build:lambda builds dist/lambda/: the Next.js standalone server,
its static files and public/, a .next/cache link to /tmp/cache, and
run.sh, the entry the Lambda Web Adapter starts (HOSTNAME=0.0.0.0, PORT
defaulting to 8080). The script fails if run.sh, server.js, the static
files or public/ are missing, or run.sh is not executable. It does not
zip; the deployment does.

settings.contract.json lists every environment variable the app reads,
with whether it is required, its values and default, its purpose, and
who sets it under Docker and on Lambda. A unit test checks that every
name app/lib/settings.ts reads is in the file and nothing stale is, and
that leaving out each always-required setting makes /health/ready
answer 503 naming it.

CI (.github/workflows/ci.yml), on pull requests and pushes to main:
- unit: npm test and tsc --noEmit.
- stores: the store tests against MongoDB 7 and DynamoDB Local.
- lambda-shape: build:lambda, then the end-to-end tests against
  dist/lambda/run.sh with the memory store and exchanges off.
- docker: the image beside MongoDB with exchanges on, /api/healthz
  healthy, then the same end-to-end tests.

Playwright:
- The seven screenshot comparisons are gone, with all 40 baselines.
  The verification log tests check each line's icon (green checkmark,
  yellow warning or red x) by its accessible name; the achievement image
  tests check the image loaded.
- A Lambda project (tests/lambda.spec.ts, no browser, no retries):
  /health/ready is 200; 20 share-then-read round trips, 10 in parallel;
  404 after unshare; 413 for a body over 5 MB to /api/verify and for a
  shared credential over 350 KB. npm run test:e2e runs it too.
- The wallet exchange test asks /api/config first and is skipped when
  exchanges are off.

The Dockerfile sets HOSTNAME=0.0.0.0. Docker sets HOSTNAME to the
container id, so the server listened on that interface only and
/api/healthz could not reach it at localhost.

Docs: the CHANGELOG's 3.0.0 entry states the breaking changes;
the README gains settings, upgrading from 2.x, running with no
database, MongoDB indexes and 2.x records, Docker, AWS Lambda and
testing sections; .env.example and both compose examples set
CREDENTIAL_STORE=mongodb and EXCHANGES=on and show EXCHANGE_SERVER_URL
commented out. Version 3.0.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ottonomy
ottonomy added this pull request to stack #282 November 11, 2026 05:21
ottonomy and others added 2 commits November 10, 2026 21:26
ubuntu-latest is now Ubuntu 26.04, where Playwright 1.56 cannot install
its browsers, so the lambda-shape and docker jobs failed before testing
anything. Pin every job to ubuntu-24.04, which Playwright supports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ubuntu-latest is now Ubuntu 26.04. Playwright 1.56 cannot install its
browsers there; 1.65 can. Upgrading fixes the lambda-shape and docker
jobs without pinning the runner, so this undoes the ubuntu-24.04 pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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