Skip to content

Transport routes

A transport route is the directed edge between two runtimes — “this environment promotes to that one”. The designer renders the chain on the Environments page under the “Transport routes” card.

Each Runtime record has an optional promotesTo field pointing at another runtime’s id. That’s the entire model:

dev.promotesTo = test
test.promotesTo = staging
staging.promotesTo = prod
prod.promotesTo = null (terminal)

This forms a tree (or DAG with branches). Pipebase uses it to:

  1. Order the env-track under each flow row in the FlowList
  2. Show “Promote to buttons on the flow detail page
  3. Validate promotions — you can only promote from a runtime that has promotesTo: <target> set, AND has the flow in-sync

If you try to set prod.promotesTo = dev when dev → test → staging → prod already exists, Pipebase rejects it with a clear error message naming the chain that would form a cycle. The check walks up to 16 hops as a safety net.

The “Promote” button on the flow detail page is the same code path as a regular Deploy — it just targets a different runtime. Specifically:

  1. Read the YAML from the designer’s disk (single source of truth — the YAML on the upstream runtime might be older / mutated by a curl directly to it)
  2. Apply parameter substitution using the target runtime’s per-runtime overrides
  3. PUT to the target runtime’s /_api/flows/:id
  4. Stamp a new lastDeployedAt on the designer’s index entry

So promote ≠ copy. Each environment can have different param values; the YAML body is the same.

  • Single linear chain at a time per branch — no fanout (one source can only promote to one target)
  • No automatic promotion (e.g. “promote on green tests”). Trigger is always manual.
  • No rollback link — if you want to undo a promote, you redeploy from the upstream environment