# Run TestVibe in CI

URL: https://docs.testvibe.com/testvibe-api/guides/run-in-ci

`testvibe run --all --wait` runs every generated feature and exits non-zero when any of them fails — that's the whole integration. Point it at the environment you just deployed and let the exit code gate the pipeline.

## GitHub Actions example

.github/workflows/e2e.yml

```yaml
e2e:
  runs-on: ubuntu-latest
  needs: deploy-staging
  steps:
    - uses: actions/setup-node@v4
      with: { node-version: 20 }
    - run: npm install -g testvibe   # or, without npm: curl -fsSL "$TESTVIBE_SERVER/api/v1/install.sh" | sh
    - run: testvibe run --all --url "$STAGING_URL" --wait
      env:
        TESTVIBE_SERVER: ${{ vars.TESTVIBE_SERVER }}
        TESTVIBE_API_KEY: ${{ secrets.TESTVIBE_API_KEY }}
        TESTVIBE_PROJECT: ${{ vars.TESTVIBE_PROJECT }}
```

The same shape works anywhere — only the env-var syntax changes.

## Practical notes

- **Use env vars, not `testvibe login`** , in CI — `TESTVIBE_API_KEY` / `TESTVIBE_SERVER` / `TESTVIBE_PROJECT` ( [config precedence](/testvibe-api/cli) ). Create a dedicated key for CI so it can be revoked independently.
- **`--url` targets the deployment under test** (a preview URL, staging) without touching the project's configured URL.
- **`--all` runs the whole suite** (one cloud run per generated feature, summarized at the end); name features instead ( `testvibe run Login Checkout --wait` ) or keep a single broad "smoke" feature when you want a faster gate.
- **Tests run in TestVibe's sandboxes, not your runner** — the CI job is just dispatch + poll, so it's cheap; the target URL must be reachable from TestVibe's cloud, not from the runner.
- **Artifacts on failure:**`testvibe runs artifacts <runId>` prints short-lived trace/screenshot links you can echo into the job log; the run is also waiting in the TestVibe app.
info
Want the run to *create or update* tests too? That's a generation concern, not a CI one — keep `generate` interactive (it consumes credits and takes minutes) and let CI only `run` what's already `generated` .
