Deployments · Pull request previews
Pull request previews
See a pull request running before you merge it. With previews on, each pull request against a branch your service tracks gets its own temporary environment, built from the pull request's code, with its own URL.
What happens to a pull request
| Pull request event | What the preview does |
|---|---|
| Opened | A preview environment is created in the project, and each previewed service builds the pull request's head commit into it. The pull request gets a check, and a comment with each service's preview URL and when the preview expires. |
| New commits pushed | The preview rebuilds at the new head commit. Its expiry resets. |
| No push for 7 days | The preview is deleted. |
| Closed or merged | The preview is deleted. |
A pull request gets one preview per project, however many of the project's services it touches. A service is previewed when it is connected to the pull request's repository and tracks the pull request's base branch. If more than one environment tracks that branch (for example production and staging both on main), the preview is cut from the oldest of them.
A pull request from a fork never gets a preview. It gets a check that says why.
Turn previews on or off
Previews are off by default for new projects. The setting lives on the project, and a service can override it:
| Setting | Values | Effect |
|---|---|---|
Project pull_request_previews | on, off | The default for every Git-connected service in the project. Turning it off deletes the project's open previews. |
Service pull_request_previews | on, off, inherit | This service's own choice. inherit (the default) follows the project. |
Open a Git-connected service, go to Settings, and find Pull request previews on the Deploy card. Choose Inherit from project, On or Off.
What a preview is given
A preview runs the pull request's code, so it gets only what you choose to give it.
| From the base environment | What the preview gets |
|---|---|
| Secrets (environment and service) | Names only, with empty values. Never a value. |
| Plain variables (environment and service) | Names only, unless the variable is on the preview_copy list. |
Plain variables on the preview_copy list | The value, for a pull request from the repository by someone who can write to it. |
The preview records the names it wasn't given (preview.withheld_variables, and per service for project admins), so you can see what a preview is missing without seeing any value.
Choose which plain variables a preview copies
preview_copy is a list of plain variable names whose values a pull request's preview may copy. Everything else is withheld. Set it with the variables, on the environment or on a service:
# environment variables: copy LOG_LEVEL and FEATURE_FLAGS into previews
curl -X PUT https://api.computesphere.com/v2/environments/$ENV_ID/variables \
-H "Authorization: Bearer $CSPH_TOKEN" -H "Content-Type: application/json" \
-d '{"variables": {"LOG_LEVEL": "debug", "FEATURE_FLAGS": "new-checkout"}, "preview_copy": ["LOG_LEVEL", "FEATURE_FLAGS"]}'
For a service's own variables, send preview_copy with PUT /v2/deployments/{id}/env-vars. Leave preview_copy out to keep the current list. [] clears it.
Rules for the list:
- Only plain variables. A name that is a secret is refused (
422, fieldpreview_copy.NAME), and nothing changes. - No credentials. A value that looks like a credential is refused the same way. Keep credentials as secrets.
- No addresses of the base environment's own services. A value that points at them is refused, so a preview can't reach your production services through a copied URL.
- Who can set it. Only project admins can set a service's list. For an environment's list, only a project admin can send it when the environment, or one of its services, requires deploy approval.
- Who gets the values. Listed values go to every pull request from the repository whose author can write to it, bots included. A pull request from someone without write access gets none of them.
- When it applies. A change to the list reaches new previews. Previews that already exist keep what they were given.
When the preview is made, each listed value is checked again. A value that now looks like a credential, or points at the base environment's own services, is withheld. preview.withheld_listed names it, with the reason: credential, base_address or untrusted.
Existing projects
Previews used to be on by default.
- New projects start with previews off.
- On November 8, 2026, previews were switched off on existing projects with at most one environment whose setting had never been changed. Turn previews back on at any time with the steps above.
- These projects were left as they were: projects with two or more environments, projects where someone had already chosen a setting for the project or one of its services, and projects with an open preview.
Limits
- GitHub only. Previews are opened by pull requests on repositories connected through GitHub.
- No preview for a fork. A pull request from a fork never builds in your account.
preview_copyis in the API only. The console and the CLI don't edit the list yet.- No secret values. A service that needs a secret to start, such as a database URL, starts in a preview without it.
- One preview per pull request per project. Two projects that track the same repository and branch each get their own preview.
What's next
- Environment: variables, secrets and environment settings.
- Promote: ship a tested image to another environment without rebuilding.
- Secret managers: keep credentials out of plain variables.
- Deploy actions: redeploy, stop and roll back.