Pipelines, Promotion & Rollback
A Project is a pipeline: its Environments are stages, ordered development → staging → production. Promotion moves the image an app already built in one stage into the next stage, without rebuilding it. This page explains how a stage gets its images, how to promote and roll back, and what the platform refuses and why.
Build stages and promote-only stages
Every Environment has a release source:
| Release source | How apps in the Environment get their image |
|---|---|
| Builds from source (default) | The platform watches the Environment’s git branch, builds a new image on every push, and deploys it (subject to Automatic deployment). |
| Promote-only | Nothing is built here. An app’s image is whatever was last promoted into it (or rolled back to). Pushes to this Environment’s git remote are refused, and so is a manual deployment. |
New Environments always start as Builds from source. Switch an Environment to promote-only in the dashboard under the Environment’s Settings → General → Release source, or from the CLI:
paas envs update production -o acme -p shop --release-source promote
A stage is either one or the other, never both. The usual shape is one build stage (development) feeding one or more promote-only stages (staging, production).
What the switch does
Switching to promote-only removes the Environment’s build machinery. It is refused with UNPINNED_APPS if any app in the Environment has never been built or promoted — such an app would have no image to run. Build or promote it first, then switch.
Switching back to builds from source recreates the build machinery: the platform rebuilds every app from the branch and deploys the new builds, replacing whatever had been promoted. The dashboard asks you to confirm before it does this.
Creating an app in a promote-only stage
You can create an app in a promote-only Environment as long as an app with the same name exists in the stage upstream. The new app starts with the upstream app’s current image. If there is no upstream image yet, the app is created but nothing runs until the first promotion; the pipeline board shows it as awaiting first promotion.
The pipeline board
Open a Project’s Pipeline tab. The Project Overview lists its environments. Application cards line up across environments; a placeholder shows when an application is missing.
Databases and Object storage have separate sections with their status and configured size, version or storage tier. They link to resource details and are not promoted. Build stages show Built here or Awaiting first build instead of comparing themselves with an upstream stage.
The Pipeline page shows one column per stage. Each app card shows the running image’s short digest and, where the platform knows it, the commit it was built from, plus one of:
| Card says | Meaning |
|---|---|
| not built yet | A build stage whose app has not produced an image yet. |
| awaiting first promotion | A promote-only stage whose app has never received an image. |
| not in upstream | No app with this name exists in the stage before this one, so there is nothing to promote from. |
| in sync with upstream | Running the same image as the same-named app upstream. |
| differs from upstream | Upstream has moved on (or this stage was rolled back). |
Promoting
Promotion copies the image digest from the same-named app in the source stage into the target stage. Databases, buckets, secrets and environment variables are per-Environment and are never copied.
You need the Promote & roll back capability on the target Environment and View on the source. The target must be promote-only; promoting into a build stage is refused with BUILD_ENV.
From the dashboard: each stage column has a Promote all apps to next button that promotes every app present in both stages. For one app, open its card’s actions menu and choose Promote to next. If the stage’s button is disabled, the reason shows under it (“production builds from source — set its release source to promote-only first”, or “Requires promote on production”), and the per-card buttons are hidden.
From the CLI:
# one app
paas promote web --from staging --to production -o acme -p shop
# every app that exists in both stages
paas promote --all --from staging --to production -o acme -p shop
The result is a table with one row per app:
| Outcome | Codes | Meaning |
|---|---|---|
| promoted | — | The image was copied. A HISTORY_WRITE_FAILED code on a promoted row means the image shipped but its history entry could not be written. |
| skipped | ALREADY_CURRENT | The target already runs this image. |
| skipped | NOT_IN_TARGET, NO_UPSTREAM_IMAGE | No same-named app in the target, or the source app has no image yet. |
| error | VALUES_MISSING, PROMOTE_FAILED | The target app cannot be promoted (its framework produces nothing deployable) or the write failed; the row’s message says more. |
The CLI exits 1 when any row errored, or when you named a single app and it was skipped for any reason other than ALREADY_CURRENT. paas promote --all with everything already current exits 0.
Protected targets
Promoting into a protected Environment asks you to type the Environment’s name to confirm. The CLI does the same, or skips the prompt with --yes; without a terminal and without --yes it refuses before sending anything. Every promotion is recorded in the Organization’s audit log.
Rolling back
On a promote-only stage you can re-pin an app to any earlier image it has run in that Environment. Rolling back needs the Promote & roll back capability on that Environment.
From the dashboard: open the app and click Rollback… in its header. The picker lists this app’s earlier releases, newest first, from its last 100 deployments, excluding the one currently running.
From the CLI: find the deployment id (id) with paas releases --json -a web, then:
paas releases --json -a web -e production -o acme -p shop
paas rollback web --to 6f1b2c3d-4e5f-4a6b-8c9d-0e1f2a3b4c00 -e production -o acme -p shop
Rollback is refused with BUILD_ENV on a build stage (push a fix or re-deploy instead), with ALREADY_CURRENT when the app already runs that image, and with a 404 when the id belongs to another app.
This re-pins to any earlier version this app has run, healthy or not. To roll back a deployment that failed its health check, in any Environment, use paas deploys rollback instead — see Deployments, Health Checks & Rollback.
What a promote-only stage refuses
| Action | Response |
|---|---|
git push to the Environment’s remote (SSH or HTTPS) | Rejected with a message naming the upstream stage to push to and promote from. |
paas deploy / resource sync | 409 PROMOTE_ONLY_ENV. Re-syncing the whole Environment is still allowed. |
| Asking for the Environment’s git remote | 409 PROMOTE_ONLY_ENV. |
| Promote or rollback into a build stage | 409 BUILD_ENV. |
Reading the history
Deployment history marks each entry as a build, a promote or a rollback — promote entries read “promoted from source by name”. paas deploys list --json includes the same kind and each deployment’s id, which is the argument paas rollback --to takes.
Next steps
- Deployments, Health Checks & Rollback
- Organizations, Projects & Environments
- Access Control
- CLI Command Reference
Checking dependencies before promotion
Before promotion, d2o checks the selected applications’ database and object-storage attachments and known connections to other applications. A target service can have a different name if the application has the same compatible binding there.
If dependencies are missing, review the warning and explicitly confirm before continuing. A protected environment also requires its name in the same confirmation. If the dependency warnings change before the request is applied, you must review them again.
If the CLI reports missing dependencies, attach the required services first or review and confirm the promotion in the dashboard.
This check covers known attachments and application connections; it cannot infer dependencies hidden in secrets or external services. Promotion only moves application images. It does not create dependent services or copy databases, objects, secrets or environment-variable values.