Skip to content

Deploy an app change

Shipping a change on Ultron Infra is a two-repo dance: code lands in your app repo, the image tag bumps in gitops. You never kubectl applyArgo CD reconciles, and Argo Rollouts runs the canary. This is the platform’s GitOps delivery flow; every app onboarded to the platform ships the same way.

flowchart LR
  A([push app repo]) --> CI[GitHub Actions]
  CI -->|build + push| GHCR[(ghcr.io/<owner>/<app>:sha-<sha>)]
  GHCR -.->|copy the tag| Dev([you])
  Dev -->|bump tag + push| GO[(gitops repo)]
  GO -->|sync| Argo[Argo CD]
  Argo --> RO[Argo Rollouts]
  RO -->|metric-gated canary| K8s[(<app> ns)]

Push to your app repo. GitHub Actions builds the arm64 image and pushes it to GHCR tagged with the commit SHA:

ghcr.io/<owner>/<app>:sha-<sha>

Grab the exact tag from the Actions run (or git rev-parse --short HEAD — CI uses the short SHA, e.g. sha-ed927c2).

Edit workloads/<app>/rollout.yaml and set the new image tag:

spec:
template:
spec:
containers:
- name: <app>
image: ghcr.io/<owner>/<app>:sha-<new-sha>

Commit and push to the gitops repo. That’s the only change required for a normal code deploy.

3. Argo CD syncs, Rollouts runs the canary

Section titled “3. Argo CD syncs, Rollouts runs the canary”

Argo CD detects the new desired state and applies it. Argo Rollouts then steps traffic to the new ReplicaSet while a background AnalysisRun watches the Prometheus success-rate metric:

StepWeightPause
125%60s
250%60s
375%60s
100% (promote)

The gate requires non-5xx / total ≥ 0.95 (result[0] >= 0.95), read every 30s, aborting after 2 sub-threshold reads. If it fails, Rollouts auto-rolls back to the stable ReplicaSet — no manual intervention.

Watch and control it from Operate rollouts.