Command Reference
Previewops is driven by comments on GitHub pull requests. This page covers every available command and its options.
/deploy-previewops
Builds a Docker image from the PR branch and deploys a preview environment.
/deploy-previewops [options]
Options
| Option | Type | Example | Description |
|---|---|---|---|
--ttl |
number (hours) | --ttl=48 |
Override the TTL for this specific deploy. Must be within your plan's TTL maximum. |
--resources |
small | medium | large |
--resources=medium |
Override the container resource preset for this deploy. small = 128Mi / 0.1 CPU, medium = 256Mi / 0.5 CPU, large = 512Mi / 1 CPU. |
--dockerfile |
string | --dockerfile=apps/web/Dockerfile |
Path to the Dockerfile relative to the repo root. Overrides dockerfilePath in .previewops.yaml. |
--provider |
string | --provider=fly |
Override the deployment provider for this deploy. Overrides provider in .previewops.yaml. |
--name |
string | --name=gcp-eu |
Deploy using a named credential profile. Previewops resolves the provider from the stored credential — --provider is not required when --name is given. If both are supplied and their providers differ, an error is posted. Available on Premium BYOC and Custom plans. |
--perf |
flag | --perf |
Immediately run a load test against the preview after deploy completes. Equivalent to having performance.enabled: true in .previewops.yaml but scoped to this single deploy. |
--commit |
SHA (7–40 hex chars) | --commit=abc1234 |
Deploy a specific commit from this PR's history instead of the PR head. Combine with --provider= to run A/B comparisons — each provider gets its own preview slot. The SHA is validated against this PR's commit history before any build starts. |
--database |
preview | env |
--database=env |
Control Preview DB provisioning for this deploy. preview (default when the add-on is active) provisions or reuses a Preview DB branch. env skips provisioning entirely and uses the DATABASE_URL from your .previewops.yaml env: block instead. Only has an effect when the Preview DB add-on is active. |
--db-branch |
string | --db-branch=seed-v2 |
Deploy using a named Preview DB branch. Previewops reuses an existing branch with this alias on the PR, or forks a new one if none exists. Requires the Preview DB add-on. Alias must be lowercase alphanumeric and hyphens, 1–50 characters, starting with a letter or digit. If the add-on is not active, a ⚠️ notice is posted and the flag is ignored. See databases.md for details. |
Examples
/deploy-previewops
/deploy-previewops --ttl=24
/deploy-previewops --resources=medium
/deploy-previewops --provider=hetzner --ttl=48
/deploy-previewops --perf
/deploy-previewops --ttl=48 --perf
/deploy-previewops --name=gcp-eu
/deploy-previewops --name=fly-staging --ttl=24
# A/B test: compare two commits across providers
/deploy-previewops --provider=render --commit=abc1234
/deploy-previewops --provider=fly --commit=def5678
/deploy-previewops --provider=cloud-run # deploys the PR head (no --commit=)
# Preview DB: skip provisioning for this deploy (use env: DATABASE_URL instead)
/deploy-previewops --database=env
# Preview DB: deploy with a named branch alias
/deploy-previewops --db-branch=seed-v2
/deploy-previewops --provider=fly --db-branch=empty
/deploy-previewops --provider=cloud-run --db-branch=seeded
A/B testing constraint: Deploying two different SHAs to the same provider on the same PR is sequential — the second replaces the first. To run multiple commits simultaneously, use different
--provider=values or different--env=names.
What happens
- Previewops checks capacity — if the concurrency limit is reached, the oldest preview is evicted.
- Credentials are validated against your provider before the build starts. If validation fails, a clear error is posted — no build quota is consumed.
- A Docker image is built using your provider's build system (Cloud Build for Cloud Run, SSH-based build on the remote host for Hetzner / DigitalOcean / Lightsail / docker-ssh, the provider's native builder for Fly / Render / Railway).
- The image is deployed to the configured provider.
- A PR comment (the preview dashboard) is posted with the preview URL and TTL expiry time. On re-deploys, the existing dashboard comment is deleted and a fresh one is posted at the bottom of the PR thread, keeping the latest status visible next to recent activity.
Notices shown in the dashboard:
- TTL clamped — if the requested
--ttlvalue exceeds your plan's TTL maximum, the TTL is automatically reduced and a notice is shown in the dashboard. - Overage — if your monthly deploy cap has been reached but your plan allows overage, a billing notice is shown.
- Build already in progress — if you run
/deploy-previewopswhile a build is already active for this PR (e.g. a second provider deploy issued before the first finishes), Previewops replies with a notice asking you to wait and rerun. Once the first build completes, rerun your command. - Commit column — when
--commit=is used and the deployed SHA differs from the PR head, the dashboard table shows a linked short SHA (e.g.abc1234) in a Commit column for that row. Rows deployed from the PR head have no Commit column entry.
Build failures:
If the build or deploy fails, the dashboard shows a ❌ Failed row. Expand the collapsible Show build logs section to see the error message along with AI debug links:
- Ask Claude ↗ — opens the error in Claude for debugging help.
- Ask ChatGPT ↗ — opens the error in ChatGPT.
- Open in Cursor ↗ — opens the error in Cursor (AI-assisted IDE).
/delete-previewops
Immediately deletes the preview environment for the current PR.
/delete-previewops [options]
Options
| Option | Type | Example | Description |
|---|---|---|---|
--env |
string | --env=staging |
Delete only the named environment suffix. Useful when a repo deploys multiple named environments per PR. |
--provider |
string | --provider=fly |
Delete only the deployment for the specified provider. |
All options are optional. With no options, all active previews for the current PR are deleted.
Edge cases:
- Build in progress — if a build is currently active for the PR, Previewops will post a warning and ask you to wait until it completes before retrying
/delete-previewops. This prevents a race condition where the delete runs against a half-deployed resource. - Nothing deployed — if no active previews are found for the PR, Previewops posts an informational comment rather than a false "Deleted" confirmation. If a
--provideror--envfilter was specified, the message will name the filter and suggest running/list-previewopsto see what is actually active. If no filter was given, the message includes a prompt to deploy with/deploy-previewops. - New comment on delete — when deleting a preview, Previewops posts a fresh dashboard comment at the bottom of the PR thread showing the updated status. This keeps the result visible right next to your
/delete-previewopscommand rather than silently editing a buried earlier comment. - PR closed — when a PR is closed, Previewops automatically attempts cleanup. If a build was in progress at the time of closing, cleanup proceeds on a best-effort basis.
- Preview DB add-on — multi-env — if the Preview DB add-on is active and a PR has multiple environments deployed (e.g.
--env=stagingand--env=production), the database branch is preserved until the last environment for that PR is deleted. Removing one environment with--env=stagingwill delete that cloud service but leave the database branch intact so the remaining environment continues to work.
/list-previewops
Lists the currently active preview environments for the current PR.
/list-previewops
No options. Previewops queries your cloud provider for active previews scoped to this PR and replies with a table of live URLs and expiry times. Returns a "no active previews" message if nothing is deployed yet.
/validate-previewops
Shows a status dashboard of your stored credentials and .previewops.yaml configuration without deploying anything. Useful for confirming that credentials are stored correctly before your first deploy.
/validate-previewops [options]
Options
| Option | Type | Example | Description |
|---|---|---|---|
--provider |
provider key | --provider=aws-lightsail |
Filter both tables to a single provider. |
Examples
/validate-previewops
/validate-previewops --provider=aws-lightsail
/validate-previewops --provider=render
What happens
Previewops posts a comment with two tables:
- BYOC Credentials — the provider keys you have stored, along with the date each was last updated. If no credentials are found, a link to add them is shown.
.previewops.yaml— theproviderfield and anyproviderConfigkeys present in your config file. If no file is found, a note is shown andcloud-rundefaults apply.
No live API calls are made — this is a read-only status view.
/qa-previewops
Runs a QA analysis on the current PR. What you get depends on your plan:
- All plans: a test coverage map showing which changed source files have an existing test file.
- Pro, Enterprise, Custom: full AI-powered analysis including a code review, generated HTTP test scenarios (executed against the preview if available), and regression risk assessment.
- Premium BYOC: same AI analysis as above, but requires the Custom LLM add-on to be activated. Without it, only the test coverage map is returned and an add-on activation prompt is shown.
/qa-previewops [options]
Options
| Option | Type | Example | Description |
|---|---|---|---|
--url |
string (https://) | --url=https://preview-pr42.example.com |
Explicitly provide the preview URL to test against. When omitted, Previewops looks up the active preview for this PR automatically. Private/internal IP addresses are always rejected. |
--provider |
string | --provider=render |
Target the preview deployed to this provider. Useful when multiple active previews exist for the same PR. Aliases are supported: lightsail → aws-lightsail, ecs → aws-ecs, azure → azure-container-apps. If no matching preview is found, the AI analysis still runs but HTTP smoke tests are skipped. |
--env |
string | --env=staging |
Target the preview with this environment name (set via --env when originally deployed). Lowercase alphanumeric and hyphens, max 20 characters. |
--generate-drafts |
flag | --generate-drafts |
Generate Playwright draft test scripts for the repo's active QA scenarios and save them in the QA Hub. Requires the QA Hub add-on and at least one active scenario. |
--draft-scope |
repo | all |
--draft-scope=all |
Scenario scope for draft generation. repo (default) = current repo + global scenarios. all = all repos under the org. |
--draft-max |
integer (1–25) | --draft-max=10 |
Maximum drafts to generate per run. Default: 5. |
--draft-scenario-ids |
comma-separated IDs | --draft-scenario-ids=id1,id2 |
Restrict draft generation to specific scenario IDs. |
--draft-categories |
comma-separated | --draft-categories=smoke,e2e |
Restrict to scenarios matching these categories (smoke, regression, e2e, accessibility, visual). |
--draft-priorities |
comma-separated | --draft-priorities=P0,P1 |
Restrict to scenarios with these priorities (P0, P1, P2). |
--draft-no-preview |
flag | --draft-no-preview |
Allow draft generation without a live preview URL. Generated scripts contain PREVIEW_URL_PLACEHOLDER instead of a real URL. |
Examples
/qa-previewops
/qa-previewops --url=https://pr-42-preview.fly.dev
/qa-previewops --provider=render
/qa-previewops --provider=fly --env=staging
/qa-previewops --generate-drafts --draft-priorities=P0 --draft-categories=smoke
/qa-previewops --generate-drafts --draft-no-preview --draft-max=3
What happens
- Previewops posts a placeholder comment while analysis runs.
- Up to 300 changed files are fetched from the GitHub API (paginated).
- Each changed source file is mapped to its expected test file. Supported languages: TypeScript/JavaScript (
src/X/Y.ts → src/__tests__/X/Y.test.ts), Python (test_X.py/X_test.py), Go (X_test.goin the same directory), Ruby (X_spec.rb/X_test.rb), and Java (XTest.java). Playwright (.spec.ts) and Cypress (.cy.ts) test files are also recognised. A fuzzy fallback handles provider subdirectories and cross-root test layouts. - Eligible plans only: an AI model reviews the diff and produces: a summary with flagged issues, 3–6 HTTP smoke test scenarios, and regression risk areas.
- Eligible plans only: if a preview URL is available (via
--url,--provider/--envfilter, or the most recently deployed active preview for this PR), the generated HTTP scenarios are executed against it. - The placeholder comment is updated with the final report.
On the Free plan, steps 4–5 are skipped and an upgrade prompt is included in the report. On Premium BYOC without the Custom LLM add-on, steps 4–5 are also skipped and a prompt to activate the add-on is shown instead.
See qa-testing.md for the full guide including language support, the report format, and FAQs.
alwaysOn — automatic deploys on push
Certain branches can be configured to deploy automatically whenever a push arrives and an open PR exists — no comment needed.
Add the branch names to .previewops.yaml:
alwaysOn:
- staging
- preview
When a push to a listed branch is received and a PR is open for that branch, Previewops automatically runs the equivalent of /deploy-previewops.
/perf-previewops
Runs a k6 load test against the active preview for this PR and posts a full results comment with latency percentiles, throughput, and SLO pass/fail. On eligible plans, AI-generated scenarios and post-run insights are included.
/perf-previewops [options]
Options
| Option | Type | Example | Description |
|---|---|---|---|
--vus=N |
int | --vus=50 |
Virtual users. Capped by your plan: Premium BYOC = 10, Pro = 50, Enterprise = 100, Custom = 150. |
--duration=<time> |
string | --duration=2m |
Test duration. Accepts 30s, 2m, 30m. Capped at 30 min (60 min with the Advanced Perf add-on). |
--target-tps=N |
int | --target-tps=100 |
Target requests per second. |
--set-baseline |
flag | --set-baseline |
Save this run as the baseline for future delta comparisons. Requires the Advanced Perf add-on (Pro / Enterprise / Premium BYOC). |
--provider |
string | --provider=render |
Target the preview deployed to this provider. Useful when multiple active previews exist for the same PR. Aliases are supported: lightsail → aws-lightsail, ecs → aws-ecs, azure → azure-container-apps. If no matching preview is found, a clear error is posted and the test does not run. |
--env |
string | --env=staging |
Target the preview with this environment name (set via --env when originally deployed). Lowercase alphanumeric and hyphens, max 20 characters. |
Examples
/perf-previewops
/perf-previewops --vus=20 --duration=1m
/perf-previewops --set-baseline
/perf-previewops --vus=50 --duration=5m --target-tps=200
/perf-previewops --provider=render
/perf-previewops --provider=fly --env=staging
What happens
- Previewops looks up the active preview URL for this PR. When
--provideror--envis specified, only the most recently deployed preview matching that filter is used — if no match is found, a clear error is posted and suggested next steps are shown. When no filter is given, the most recently deployed active preview is used. - The plan VU and duration caps are applied — if the requested values exceed the plan limit, the test runs at the plan cap and a notice is shown.
- Endpoints are detected from the PR diff (all plans: regex; paid plans with LLM: AI-generated).
- A placeholder "running…" comment is posted immediately, then automatically updated with a live progress bar at 10 / 30 / 50 / 75 / 95 % milestones.
- A k6 load test runs against the preview URL and results are collected.
- When the load test finishes, the comment updates to "Analyzing results…" while AI analysis and database writes run.
- SLO thresholds from
.previewops.yamlare evaluated (warnings only — never blocks the deploy). - Paid plans with history enabled: the result is persisted and compared against the baseline (if one exists).
- Paid plans with LLM: AI analysis is generated and included in the results.
- The comment is updated with the full results including latency table, SLO status, baseline delta, and AI insights.
See performance-testing.md for the full guide including .previewops.yaml configuration and baseline tracking.
Who can trigger commands
Commands in PR comments are only processed from users with Write, Maintain, or Admin permission on the repository. Comments from users with Read-only access or no access are silently ignored.
Organisation owners and repository administrators always have permission.