Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXXXIV · Environment PromotionPromotion models

Promotion by environment repo — each environment has its own Git state

Advanced⏱ ~24 mingit

What you'll learn

  • Define promotion by environment repo as the per-environment repository model
  • Trace a cross-repo promotion: a PR opens in the next repo when the previous repo merges
  • Recognise the access-control implications of dedicated env repos
  • Identify the audit shape and rollback path of per-repo promotion

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

Not yet marked complete on this device.

Promotion by environment repo is the model in which the repository boundary coincides with the environment boundary. The dev repo records dev’s desired state, the staging repo records staging’s, the production repo records production’s. There is no shared branch, no shared overlay, no shared pull request. Promotion is the act of carrying a change from one repository to the next, usually through a controlled promotion pipeline that opens a pull request in the next repo when the previous repo merges.

The promotion shape

The diagram captures the cross-repo flow. A change starts in the application repo and is rendered into the dev repo. When the dev repo merges, the promotion pipeline opens a PR against the staging repo with the same rendered output. When staging merges, a PR opens against the production repo. Each repo has its own branch protection, its own reviewers, its own CI.

flowchart LR
    A["App repo: commit X"] --> R["Render pipeline"]
    R --> D["dev repo: merged"]
    D --> P1["Promotion bot: opens PR in staging"]
    P1 --> S["staging repo: merged"]
    S --> P2["Promotion bot: opens PR in production"]
    P2 --> PR["production repo: merged"]
    D --> AD["Argo CD: dev Application"]
    S --> AS["Argo CD: staging Application"]
    PR --> AP["Argo CD: prod Application"]

Each repository has its own Argo CD Application that tracks its default branch. The reconcile in each cluster is against the repo’s HEAD. The promotion bot is the cross-repo courier; it is a CI job that reads the merged commit from the previous repo and opens a PR in the next repo with the same rendered content.

The access-control boundary is the repo

A dedicated environment repository gives the operations team a place to enforce per-environment policy. The dev repo may allow direct commits from any developer; the staging repo requires one reviewer; the production repo requires two reviewers plus a successful CI run plus a change-window check. The policy is enforced by the repository host — GitHub branch protection, GitLab protected branches, Gerrit access controls — rather than by a custom tool the team has to maintain.

The audit shape per environment is the per-repo commit history. “What is running in production?” is answered by the production repo’s HEAD at the moment of last sync, joined to the controller’s reconcile event, joined to the promotion bot’s PR records in the previous repos. The chain is longer than the single-repo Git-ref model, but each link is enforced by a different primitive — repo permissions, branch protection, PR review — which means the chain has more independent checkpoints.

Reconcile by repo

The Argo CD Application’s source is the repo URL plus the path plus the branch. Promotion by environment repo means each Application points at a different repo URL.

argocd app set payment-api-dev --repo "$DEV_REPO_URL" --path overlays/dev --revision main
argocd app set payment-api-staging --repo "$STAGING_REPO_URL" --path overlays/staging --revision main
argocd app set payment-api-prod --repo "$PROD_REPO_URL" --path overlays/prod --revision main
argocd app sync payment-api-prod --revision main

The sync is the same shape as the Git-ref model: the Application is pinned to a ref, and the controller reconciles against that ref’s commit. The difference is that the ref lives in a different repository, which means the access control and the audit trail are also per-repository.

The rollback shape

The rollback is a git revert in the environment repo that introduced the bad change. The production repo records the bad commit and the revert; the staging repo records the bad commit and the revert; the dev repo may still hold the bad commit if it has not been reverted there yet. The cluster reconciles to the reverted commit on the next sync. The audit trail spans three repositories, but each repository’s history is intact and the rollback is a Git operation in each repo that needs it.

Production discipline

The production rules for promotion by environment repo:

  1. Each repo has a single purpose. The dev repo is for dev, the staging repo for staging, the production repo for production. A repo that mixes environments defeats the boundary.
  2. Branch protection matches the environment. Dev allows direct pushes; staging requires one reviewer; production requires two reviewers and a green CI. The Git host enforces it.
  3. The promotion bot is the only writer across boundaries. No human opens a cross-repo promotion PR by hand; the bot opens the PR and the humans review it. The bot’s commits are signed and traceable.

Cross-course references

  • Git, CI/CD & GitOps — Part LXXVI-01 (Application vs Environment repos) establishes the architectural split this lesson applies to promotion.
  • Git, CI/CD & GitOps — Part XLV-03 (Promotion across environments) is the contrast: one repo with branches versus one repo per environment.
  • Kubernetes for Production Sysadmins — Part XXX (Multi- tenancy) covers the per-namespace boundary that the per-environment-repo boundary mirrors at the Git layer.

Quiz

Knowledge check · 4 questions

  1. Q1. In the promotion-by-environment-repo model, where does the access-control boundary live?

  2. Q2. Promotion by environment repo requires a cross-repo promotion mechanism — usually a CI job — to open a pull request in the next repo when the previous repo merges.

  3. Q3. Name three primitives a team can use to enforce per-environment policy when each environment has its own Git repo.

  4. Q4. Diagnose why the production environment has a stale manifest and recommend the fix.

    Team T uses promotion by environment repo. The dev, staging, and production repos each hold the rendered manifest for their environment. A new release is rendered into the dev repo and merged; the promotion bot opens a PR in the staging repo. An engineer reviews and merges the staging PR. The promotion bot then opens a PR in the production repo. A second engineer reviews the production PR, requests a change, and the PR sits for a week. Meanwhile, a hotfix is needed in production.

Passing score: 75%. Answers are checked in this browser.