Goal: git push deploys to Cloud Run with no human in the loop.

cloudbuild.yaml sketch:
- Step 1: build the image with the docker builder, tag with $SHORT_SHA and latest.
- Step 2: push to Artifact Registry.
- Step 3: deploy with the gcloud builder: `gcloud run deploy [SERVICE] --image [IMAGE]:$SHORT_SHA --region [REGION]`.
- Wire a trigger on push to the main branch.

IAM for the Cloud Build SA:
- artifactregistry.writer on the repo, run.admin (or narrower) on the service, iam.serviceAccountUser on the runtime SA so it can deploy as it.
- Nothing more. The build SA is a juicy target; scope it.

Traps:
- Trigger on the wrong branch deploys feature branches to prod. Scope triggers deliberately; use separate triggers/services per environment.
- $SHORT_SHA tagging is for traceability; also keep a latest or stable tag for rollbacks.
- Build timeouts: default 10 minutes. Big images need --timeout raised on the trigger or build.
- Secrets in builds: use Secret Manager, not env vars in the trigger config. Build logs echo commands; never print secrets.
- The deploy step should pass --no-traffic and shift traffic after a smoke test for anything important, not deploy straight to 100 percent.

Ordering: Artifact Registry repo must exist before the first build pushes. Create it in terraform alongside the trigger.

Verify: push a trivial change, watch the build succeed, confirm the new revision serves traffic, and test rollback by redeploying the previous tag.