skip to content

In a build-once pipeline, promoting a release from staging to production never changes the artifact's bytes. What does promotion actually change, and what must the production deployment reference for that promotion to mean anything?

level: seniorimportance: should knowfreq 40%

answer

  1. the bytes never move, the pointer does
  2. a record, not a rebuild
  3. moving labels give split-brain versions
  4. deploy a digest, not a channel name
  5. records answer what ran, and when

basics

~20 s

Promotion changes a reference, not the artifact — the record of which build production is declared to run. For it to mean anything, production must deploy an immutable identity such as a content digest, never a tag that promotion moves.

solid answer

~40 s

Promotion is a bookkeeping event: the delivery system records that a specific, already-built artifact is now the one production should run, and the deployment that follows resolves that record. The artifact is inert throughout — no rebuild, no repackaging, no re-signing of different bytes. The critical detail is what the record points at. If production deploys a moving label like `myapp:prod` and promotion means repointing that label, the reference is mutable: two instances that pull at different moments can end up on different builds, you cannot answer "what is running" from the record alone, and rollback becomes ambiguous. Point the deployment at an immutable identity — a content digest, or a version that is never republished — and keep the human-readable channel as a convenience for lookup, not as the thing the deploy resolves.

go deeper

for a junior

Understand that promoting a build does not rebuild or modify it — the same artifact is deployed to another environment, and something records that decision.

for a middle

Explain the forms a promotion record takes and why a deployment should resolve an immutable identity rather than a name that can be repointed later.

for a senior

Demonstrate the failure you have seen: a moved tag leaving mixed versions across instances, and an incident where nobody could say what was actually running.

for a principal

Own where promotion records live, what they must capture for audit, and how the deploy path is constrained so production cannot run an artifact no record describes.

## Promotion is a change of reference Once a pipeline builds once, "promote to production" cannot mean anything about the artifact — it already exists and is immutable. What changes is a **record**: some system now says *this specific artifact is what production runs*. Every real promotion mechanism is a variation on writing that record: - a version or identity written into a deployment definition that the environment reads; - a release or deployment record inside the delivery system, carrying which artifact, which environment, when, and on whose authority; - a **channel or view** — a named stream such as *stable* — that consumers resolve, with promotion adding the artifact to it; - **metadata attached to the artifact** — a label recording that it passed the staging soak — which downstream steps require before deploying. In a pull-based delivery model the record is the committed desired state that the cluster-side agent reconciles; the same principle applies, only the writer and reader differ. ## Why the reference must be immutable The common shortcut is a moving tag: production deploys `myapp:prod`, and promotion repoints that tag at the newly approved build. It looks elegant and it fails in specific ways. **Split-brain versions.** Nothing resolves the label once, globally. An instance started before the move runs the old build; one started after — an autoscaling event, a node replacement, a crashed process restarting — pulls the new one. You now have two versions serving under one name, with no deployment event to explain it. **Unanswerable provenance.** "What is production running?" resolves to "whatever `prod` points at right now", which is not a historical record. Ten minutes after an incident you cannot reconstruct what was live during it. **Ambiguous rollback.** Rolling back means repointing the label at the previous build — which requires knowing what it was, and requires that artifact still to exist and still to be reachable under some identity. **A weaker control surface.** Anyone able to write that label can change what production runs, without going through the promotion path at all. The fix is to make the deployed reference **content-addressed or otherwise non-reassignable**: production runs `myapp@sha256:...`, or a version string that is never republished. Human-friendly channels remain useful for humans — resolve them once, at promotion time, and record the immutable identity they resolved to. ## What a good promotion record contains At minimum: the artifact's immutable identity; the source commit it was built from; the target environment; the timestamp; and the authority for the decision (which automated gate passed, which person approved). That record is what turns "deployed" into "deployed on purpose" and what makes an audit trail possible after the fact. It is also the input to sensible retention — a store can only protect what a record says was deployed. ## Two anti-patterns dressed up as promotion **Promotion that triggers a build.** A "promote to production" button that re-runs the pipeline against the release branch is not promotion; it produces a new artifact and discards everything pre-production testing established. The tell is that promotion takes as long as a build. **Promotion that produces a variant.** Rebuilding "the same" artifact with production configuration compiled in has the same defect, plus the illusion of continuity because the version number was preserved. ## Making the record authoritative A promotion record only matters if the deploy path cannot be bypassed. That means the production deploy resolves its artifact from the record rather than from a parameter someone types, and the deployment reports back the identity it actually ran so drift between "declared" and "running" is visible. Whether an additional check refuses artifacts lacking a promotion record is an enforcement decision layered on top — but the foundation is the same in every case: one immutable identity, recorded, referenced, and reported. ## The payoff With immutable references and promotion records, three previously fuzzy questions get exact answers: what is running (the identity in the current record), what was running at 03:14 last Tuesday (the record active then), and how do we go back (redeploy the previous record's identity — no build, no ambiguity, seconds rather than minutes).

  • How can a moving tag leave two different builds running under one name at the same time?
    Because the label is resolved at pull time, not once globally. Instances that started before the tag moved keep the old build, while anything that starts afterwards — an autoscaling event, a node replacement, a restart — pulls the new one. Nothing generated a deployment event, so the split is invisible until the two versions behave differently.
  • If a team wants a friendly name like "stable" for the current production build, how do you keep that safe?
    Resolve it once, at promotion time, and record the immutable identity it resolved to; deployments then reference that identity. The friendly name stays a lookup aid for humans and dashboards rather than the value the deploy path dereferences, so no later repointing can silently change what production runs.
  • What belongs in a promotion record beyond the artifact identity?
    The source commit it was built from, the target environment, the timestamp, and the authority for the decision — which gate passed or which person approved. That combination lets you reconstruct what was live at any past moment, feeds retention rules that protect deployed artifacts, and turns a deployment from an event into an accountable one.

saying these in an interview costs you the question

  • Promotion means rebuilding with production settings
  • Moving a shared tag is a clean promotion mechanism
  • The running version is whatever the label points at now
  • Promotion has to change something inside the artifact
  • A version number in the record is as good as a digest

context