Deploy an app change
Two repos: code in the app repo, image tag in loom. You do not kubectl apply. Staging and prod are overlays on the
same cluster. Every app ships this way — Penvoice is only an example.
The pipeline
Section titled “The pipeline”flowchart LR A([merge app main]) --> CI[CI builds sha] CI --> Stg[overlays/staging newTag] Stg --> ArgoS[Argo syncs staging] ArgoS --> Promo[Promote Action] Promo --> Prod[overlays/prod same digest] Prod --> Canary[timed canary 25-50-75]
1. Merge the code
Section titled “1. Merge the code”CI builds linux/arm64 and pushes ghcr.io/<owner>/<app>:sha-<sha>. Copy that tag from the Actions run.
The GHCR package must be public, or the pod needs an imagePullSecret.
2. Staging first
Section titled “2. Staging first”Set images.newTag in workloads/<app>/overlays/staging/kustomization.yaml (not a raw image line in
base/rollout.yaml
if the overlay already pins the tag). Push. Argo syncs staging only.
Config-only: bump the *.app/redeploy annotation on the pod template so Rollouts sees a new revision.
3. Promote the same digest
Section titled “3. Promote the same digest”GitHub Action Promote (workflow_dispatch, pick the app) copies staging newTag into the prod overlay and opens a
PR — or you copy it by hand. Do not rebuild for prod.
4. Prod canary
Section titled “4. Prod canary”Prod walks 25% → 50% → 75% with a 60s pause. Time only — no Prometheus gate. Staging is one replica and jumps to 100%.
Watch from Operate rollouts.