The compose file includes a local npm registry for end-to-end publish testing. It lets you run the full publish → install → run loop without touching real registries.
pnpm build and pnpm test catch code errors, but not packaging errors. Things that only break after publishing:
- Missing files in the published tarball (
filesfield in package.json) - Broken
exportsmap (works locally via workspace symlinks, fails after install) workspace:*dependency ranges not rewritten to real versions- Docker image missing runtime dependencies or failing at startup
npx @stripe/sync-enginenot resolving its bin entry
Local registries catch all of these without side effects.
A Verdaccio instance for testing npm publish + npx install.
# Start
docker compose --profile npm-registry up -d npm-registry
# Publish all packages and smoke test
bash tests/e2e-publish.sh
# Stop
docker compose --profile npm-registry downPort: 4873
API: http://localhost:4873
The .npmrc at the repo root points @stripe:registry at $STRIPE_NPM_REGISTRY. Locally this is set to http://localhost:4873 via .envrc (direnv). In CI it points to GitHub Packages.
The publish script (tests/e2e-publish.sh) publishes every workspace package, then verifies npx @stripe/sync-engine --version, --help, and check work from a clean temp directory — exactly as an end-user would experience it.
Docker images are built locally with docker build. In CI, pushes to main and v2 first publish a multi-arch image to ghcr.io, then the same built image is promoted to Docker Hub (stripe/sync-engine) with the branch tag and latest.
# Build and test locally
docker build -t sync-engine:test .
bash tests/docker-test.sh sync-engine:testThe npm registry doesn't start with a bare docker compose up. You must opt in:
docker compose --profile npm-registry up -d npm-registryThis keeps docker compose up fast for everyday development (only starts postgres, stripe-mock, etc.).