Quickstart

Run a real HTTP case against a live API in a few minutes. No credentials, no account.

Terminal recording of a passing flag-proof run

1. Get the CLI

Three ways to run it. Have the .NET 8 SDK? Install the published nuget.org tool — that package is how you install, not how you find ReleaseTwin. New here? See a real case file first (no account).

dotnet tool
dotnet tool install -g releasetwin

Or clone and build from source:

clone and build
git clone https://github.com/ernestoalejowitt22/ReleaseTwin
cd ReleaseTwin
dotnet build ReleaseTwin.sln

Or via the published container image — no .NET SDK required:

docker
docker pull ghcr.io/ernestoalejowitt22/releasetwin/cli:0.4.0

2. Scaffold a case and run it

From an empty directory — no engine checkout, no examples/ mount.init writes cases/ and fixtures/ into the current folder; the next command runs them.

scaffold then run
docker pull ghcr.io/ernestoalejowitt22/releasetwin/cli:0.4.0
docker run --rm -v "$PWD:/workspace" ghcr.io/ernestoalejowitt22/releasetwin/cli:0.4.0 init /workspace
docker run --rm -v "$PWD:/workspace" ghcr.io/ernestoalejowitt22/releasetwin/cli:0.4.0 run /workspace/cases

You'll see pass/fail for the scaffolded cases. A missing adapter reports as a failing case rather than crashing — a non-zero exit code is safe to wire straight into CI.

3. Look at the evidence

A pass/fail line is the verdict; the evidence is the product. Set RELEASETWIN_EVIDENCE_DIR and the CLI writes a redacted record of every case to disk — then view serves it as a browsable report. No account, no sign-up, and no network call.

run with evidence, then view it
docker run --rm -v "$PWD:/workspace" \
  -e RELEASETWIN_EVIDENCE=on \
  -e RELEASETWIN_EVIDENCE_DIR=/workspace/evidence \
  ghcr.io/ernestoalejowitt22/releasetwin/cli:0.4.0 run /workspace/cases

docker run --rm -p 8080:8080 -v "$PWD:/workspace" \
  ghcr.io/ernestoalejowitt22/releasetwin/cli:0.4.0 view /workspace/evidence

The second command prints the URL to open — publishing the port with -p is what makes it reachable from outside the container, and the container has no browser of its own to launch. Running the dotnet tool install instead? releasetwin view ./evidence opens your browser for you.

What you get on disk, one directory per case id:

on disk
evidence/
  CASE-1/
    evidence.json        # the redacted step-by-step record
    <screenshot-id>.png  # one per captured screenshot, best-effort redacted
  • Redaction runs in your CLI as the evidence is produced — auth headers, credential-shaped fields, and resolved ${ENV_VAR} values are stripped before anything is written.
  • Recording UI cases with RELEASETWIN_UI_VIDEO_DIR? Point view at that directory too — --video-dir, or the same environment variable — and each case's session plays alongside its evidence. Recordings live outside the evidence directory, so the viewer has to be told where they are.
  • view --export evidence.html writes one self-contained file instead of serving — handy for attaching a run to a pull request.

This is the same evidence document the hosted platform renders. The difference there is that it is kept, shareable by link, and rolled up across runs — not that it shows you more of any single run.

4. Write a case against your own API

No new adapter code needed — http.request and http.assertJsonPath test any REST API from case-file data alone. Put this in cases/my-case.yaml:

There is no language or framework list to check against: a case file is a pipeline of generic operations, and the CLI itself only cares about the exit code and the --summary-json it writes. If your API speaks HTTP, http.request tests it — whether the service behind it is .NET, Node, Python, Go, Java, or anything else. (UI/journey evidence is the one exception — that path drives a real browser, so it needs a Playwright-drivable target rather than being stack-agnostic.)

cases/my-case.yaml
id: MY-CASE-1
oracle:
  locator: tickets/MY-CASE-1
fixture:
  locator: my-fixture.json       # resolved next to cases/, in a fixtures/ directory
  sha256: <sha256 of the fixture file>
pipeline:
  - operation: http.request
    with:
      method: POST
      url: ${API_BASE_URL}/orders     # ${ENV_VAR} resolved at load time — never commit secrets
      headers:
        Authorization: Bearer ${API_TOKEN}
      body:
        productId: 123
  - operation: http.assertJsonPath
    with:
      path: $.status
      expected: confirmed
  • ${ENV_VAR} references are resolved when the case loads — keep URLs, tokens, and secrets in the environment, not the file.
  • The fixture is resolved locally by whatever machine runs the CLI and verified by hash before the pipeline runs.

Next

  • Case files — every block a case can declare, including flag proof.
  • Examples — see it applied to a real API, against GitHub and Stripe.
  • Hosted platform — upload run history and turn on the evidence viewer.
  • A real case file — the redacted evidence document a stranger sees with no account.