Git, CI/CD & GitOpsLXXVI · GitOps Repository ArchitecturePromotion
Promotion models — promote the immutable artifact vs promote the Git ref
What you'll learn
- Distinguish artifact promotion from Git-ref promotion as the two ways to release between environments
- Identify what is promoted in each model and what the audit record looks like
- Choose the right model for a given supply-chain trust posture
- Recognise the rollback shape of each model
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
Promotion is the act of moving a release from one environment to the next. In a GitOps design there are exactly two ways to do this, and the choice between them is the most consequential architectural decision in the promotion chain. The first model promotes the artifact: the same digest, signed once, moves across environments. The second model promotes the Git ref: the same source tree, at a new revision, is re-rendered and signed per environment. The two models have different audit shapes and different rollback profiles.
Promote the immutable artifact
In the artifact promotion model, the CI pipeline produces an artifact once - a container image, a Helm chart, a binary - and the same artifact is deployed to dev, then staging, then production. The environment repos (or overlays) pin the digest, not the tag. The digest is the same across environments.
flowchart LR
A["CI build"] --> IM["Image: sha256:9a3f...e21b"]
IM --> D["dev: pinned"]
IM --> S["staging: pinned"]
IM --> P["prod: pinned"]
The audit record is the digest. “What is running in production?” is answered by a single SHA-256. The same SHA-256 is in the dev audit log and the staging audit log, with timestamps that record the promotion order. The roll-forward is a new digest; the rollback is the previous digest.
The supply-chain trust is straightforward. The artifact is signed once. The signature is verified when the digest is promoted. The same signature covers the same artifact across environments, so the production controller can verify the signature against the same public key the staging controller verified against.
Promote the Git ref
In the Git-ref promotion model, the CI pipeline re-renders the
manifests for each environment. The dev environment is at commit
a3f9d2 of the env repo; staging is at commit b7c1e1; prod is
at commit c4d8f3. The commits are different because each
environment’s rendered manifest includes environment-specific
values.
flowchart LR
A["App repo: commit X"] --> R["Render pipeline"]
R --> D["dev: commit a3f9d2"]
R --> S["staging: commit b7c1e1"]
R --> P["prod: commit c4d8f3"]
The audit record is the Git ref. “What is running in production?”
is answered by the env repo’s commit hash at the time the
controller last reconciled. The roll-forward is a new commit; the
rollback is git revert of the commit.
The supply-chain trust is per-environment. Each environment’s manifest is rendered separately, so each environment’s manifest is signed (or attested) separately. The same source tree produces different rendered outputs, and the trust chain is per output.
Trade-offs
The two models have different trade-offs in five dimensions:
| Dimension | Artifact promotion | Git-ref promotion |
|---|---|---|
| Audit unit | Digest (one SHA across envs) | Git commit (one SHA per env) |
| Rollback | Repin the previous digest | git revert the commit |
| Supply-chain signing | Sign once, verify everywhere | Sign per environment output |
| Promotion speed | One PR per environment, same digest | One PR per environment, different commits |
| Failure investigation | Digest is the lingua franca | Diff is per environment |
The artifact promotion model is the right default for a team that treats the artifact as the unit of release. The image is the release; the manifest is a description of where it runs. The Git-ref promotion model is the right default for a team that treats the rendered manifest as the unit of release. The manifest is the release; the image is an input to the manifest.
When to choose which
The artifact promotion model wins when:
- The artifact is the contract. The same artifact must run in every environment (or, more precisely, the only thing that changes between environments is configuration, not code).
- The supply-chain is signed at the artifact. Sigstore cosign signs the image; the manifest references the digest.
- The audit answer “what is running in production?” must be expressible as a digest.
The Git-ref promotion model wins when:
- The rendered manifest is the contract. The same source tree produces different YAML per environment, and the YAML is what is reviewed and signed.
- The diff between environments is structurally meaningful. A Git diff between the dev and prod manifests is the environment-specific difference.
- The team is comfortable with the per-environment signing and verification flow.
flux create kustomization payment-api \
--source=env-repo \
--path=./overlays/production \
--prune=true \
--interval=10m
The flux command does not care which model the team uses. The Kustomization imports the same source repository either way; the difference is what the overlay says.
Under the hood
The two promotion models are not always orthogonal. The artifact promotion model can be implemented with a Git-ref promotion underneath: the environment repo’s commit changes, but the digest it pins does not. The Git-ref promotion model can be implemented with an artifact promotion underneath: the source tree is the same across environments, but the rendered outputs are different.
The architectural decision is what the team treats as the unit of release. If the team treats the artifact as the unit of release, the digest is the audit record and the manifest is a description. If the team treats the manifest as the unit of release, the Git commit is the audit record and the artifact is an input.
Production discipline
The production rules for promotion:
- Pick one model and document it. The promotion model is the team’s contract with itself. A team that mixes artifact promotion in one service and Git-ref promotion in another has two audit stories, two rollback stories, and two training stories.
- The model’s audit record is the answer to the regulator’s question. “What is running in production?” is answered by the digest (artifact promotion) or by the commit (Git-ref promotion). The audit record retention must match that answer.
- The rollback path is rehearsed. The rollback is the
inverse of the promotion. If the promotion is a digest
change, the rollback is a digest change. If the promotion is
a commit, the rollback is a
git revert. The rehearsal is a tabletop exercise, not a guess.
Cross-course references
- Git, CI/CD & GitOps for Infrastructure Engineers - Part LXXVI-01 (Application vs Environment repos) is the model that the artifact promotion model fits; Part LXXVI-02 (Monorepo with overlays) is the model that the Git-ref promotion model fits.
- Kubernetes for Production Sysadmins - Part XX (Supply Chain) covers the artifact signing chain that the artifact promotion model depends on.
- Terraform for Production Sysadmins - Part XXII (Plan Files) covers the analogous decision in Terraform: the plan file is the unit of release, and the choice between re-planning per environment and reusing the plan file mirrors the Git-ref / artifact promotion trade-off.
Quiz
Knowledge check · 4 questions
Q1. In the artifact promotion model, what is the unit of release?
Q2. Promoting an artifact by tag is functionally equivalent to promoting it by digest.
Q3. Name the two promotion models and identify the rollback shape of each.
Q4. Diagnose what audit shape the team needs and recommend the promotion model.
A regulated team must answer the regulator's question 'what exact bytes were running in production at 14:00 on Tuesday?' with a single identifier. The team currently uses Git-ref promotion: each environment's manifest is rendered separately and signed separately. The audit answer requires cross-referencing the env repo's commit with the rendered manifest with the image tag and the registry's tag-mutation log.
Passing score: 75%. Answers are checked in this browser.