@reprova/cli
v0.6.1
Published
Reprova CLI (repro): rebuild a production error's exact database state in a disposable local database (Postgres or MySQL) and replay the captured request
Maintainers
Readme
@reprova/cli
TypeScript, npx-runnable CLI (repro): downloads and decrypts a built package,
rebuilds the exact state in a disposable local Postgres, replays the captured request
against your app, and reports whether the production error reproduced.
Install
npm install -g @reprova/cli # or run ad hoc: npx @reprova/cli <command>Commands
repro login --url <control-plane> --key <api-key> --age-key <path> [--package-token <token>]
repro run <ISSUE_ID> --app-cmd "npm run start" --cwd <path-to-your-app>
repro replay <ISSUE_ID> # re-fire the captured request against the still-running env
repro db <ISSUE_ID> # psql into the seeded database
repro down <ISSUE_ID> # tear down the environment
repro test <ISSUE_ID> --out <path> --cwd <path-to-your-app> # generate a self-contained regression testrepro run exits 0 on an exact match, 2 on a different failure, 3 on
no_reproduction (the row that caused the crash no longer exists — see the repo root
README's limitations section).
Docker
The CLI itself isn't something you containerize as a service (unlike the data-plane
agent — see the dashboard's Agents page). It's a dev-machine/CI tool that shells out to
Docker on its own, to build the disposable Postgres/MySQL/SQL Server it replays into
(src/lib/engines), and runs your app as a co-located process via --app-cmd. Wrapping
that in another container just adds Docker-in-Docker for no benefit in the common case.
On a normal CI runner (GitHub Actions runs-on: ubuntu-latest, a GitLab shared
runner using the shell/VM executor, etc.) Docker is already on the host — install the
CLI and run it directly, nothing special needed. This repo's own .github/workflows/
ci.yml relies on exactly this: the CLI's tests shell out to Docker directly on
ubuntu-latest, no service containers required.
# GitHub Actions — job runs directly on the runner VM
jobs:
reproduce:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install -g @reprova/cli
- run: |
repro login --url "$REPROVA_URL" --key "$REPROVA_CLI_KEY"
repro test "$ISSUE_ID" --out ./repro-tests --cwd .
env:
REPROVA_URL: ${{ vars.REPROVA_URL }}
REPROVA_CLI_KEY: ${{ secrets.REPROVA_CLI_KEY }}
REPROVA_AGENT_URL: ${{ vars.REPROVA_AGENT_URL }}
REPROVA_PACKAGE_TOKEN: ${{ secrets.REPROVA_PACKAGE_TOKEN }}
REPROVA_AGE_KEY: ${{ secrets.REPROVA_AGE_KEY }}REPROVA_AGENT_URL/REPROVA_PACKAGE_TOKEN/REPROVA_AGE_KEY are read directly from
env by every command (checked before the logged-in config) — no need to pass them as
login flags.
Only if your CI job itself runs inside a container image (GitLab's image:, a
GitHub Actions container: key) is there no Docker available by default — that needs a
Docker-in-Docker service:
# GitLab CI — job runs INSIDE the `image:` container, so Docker itself is DinD
reproduce:
image: node:20
services:
- docker:24-dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
script:
- npm install -g @reprova/cli
- repro login --url "$REPROVA_URL" --key "$REPROVA_CLI_KEY"
- repro test "$ISSUE_ID" --out ./repro-tests --cwd .
# REPROVA_AGENT_URL, REPROVA_PACKAGE_TOKEN, REPROVA_AGE_KEY, REPROVA_CLI_KEY as
# masked/protected CI variables (all read directly from env — no need to pass them
# as login flags at all, see cli/src/lib/config.ts's resolveAgentUrl/PackageToken)Layout
src/bin.ts— yargs command wiringsrc/commands/— one file per subcommandsrc/lib/— package fetch/decrypt, migration subsetting, disposable Postgres, DB seeding, the mock server for recorded outbound calls, JWT re-signing, verdict comparison, env-state persistencesrc/shims/—--requirepreload shims (pinned clock, outbound-call proxying) — plain CommonJS, not compiled
Commands
npm run build
npm run lint
npm test