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.
This page is the manual flow: the default for any app until its CI and merge settings are updated to match the fast-forward-only, auto-promoting version documented at Staging-to-prod promotion. Both Penvoice and Talon have made that switch, so this page is what a new app starts on before migrating.
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: on its own poll timer, or immediately with
Access & consoles → Skip the poll wait.
Config-only: bump the *.app/redeploy annotation on the pod template. See
Operate rollouts → Force a restart.
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.