Skip to main content
Version: 0.4.x

Golden-Path Scaffolding

The Scaffold wizard creates everything a new service needs in one flow — no platform ticket, no YAML hand-editing.

What Gets Created

After the PR is merged:

  • ArgoCD syncs the new overlay
  • Crossplane creates the XTenantApp and XTenantDatabase CRs
  • The app is alive in the dev environment

Scaffold Wizard Steps

StepFieldsNotes
1 — App detailsApp name, description, teamApp name is slugified to lowercase-hyphen
2 — TemplateTemplate selectorShows templates from scaffold-templates repo
3 — FeaturesDatabase, external secrets, ingressFeature toggles
4 — PreviewYAML previewLive render of all generated manifests
5 — CreateConfirmRuns the creation flow

Scaffold wizard is a feature toggles + extensions wizard. Fields like DB name, tier, cluster assignment, ingress host, and resource limits go into the separate Promote overlay wizard when advancing lifecycle stages.

Generated Directory Structure

tenants-apps/{team}/{appName}/
├── base/
│ ├── kustomization.yaml ← lists all base resources
│ ├── xtenant-app.yaml ← identity, image, wiring (env-agnostic)
│ ├── xtenant-database.yaml ← (if database enabled)
│ ├── external-secret-app.yaml ← (if secrets enabled)
│ └── catalog-component.yaml ← catalog entity
└── overlays/
└── dev/
├── kustomization.yaml ← references ../../base
├── image-transformer.yaml ← teaches Kustomize where spec/parameters/image is
└── patch-xtenant-app.yaml ← env-specific: replicas, resources, ingress, secretsFrom

tenants/{team}/
└── {appName}-image-updater.yaml ← ArgoCD Image Updater CR (NOT inside tenants-apps/)

Why image-transformer.yaml Exists

Kustomize knows how to substitute images in standard Deployment / StatefulSet specs. XTenantApp is a Crossplane XR — the image lives at spec/parameters/image. The transformer file registers this non-standard path so kustomize build can reach it:

apiVersion: builtin
kind: ImageTagTransformer
metadata:
name: image-tag-transformer
imageTag:
name: my-app
newTag: latest
fieldSpecs:
- path: spec/parameters/image
kind: XTenantApp

Why images: Is NOT in the Overlay kustomization.yaml

ArgoCD Image Updater writes the images: section back after every CI build. If you add a static images: block, the Image Updater's write sets it to latest on every reconcile, overwriting your pin. Leave that section empty — the Image Updater owns it.

ArgoCD Image Updater CR

Location: tenants/{team}/{appName}-image-updater.yaml (not in tenants-apps/)

apiVersion: image.argoproj.io/v1alpha1
kind: ImageUpdateAutomation
metadata:
name: {team}-{appName} # unique across teams in shared argocd namespace
namespace: argocd
spec:
sourceType: Kustomize
applicationSelector:
matchExpressions:
- key: argocd.argoproj.io/app-name
operator: In
values:
- {team}-{appName}-dev
- {team}-{appName}-staging
- {team}-{appName}-production

Image tag conventions

BranchTag formatHow
developdev-{YYYY-MM-DD_HH-MM-SS}-{sha7}CI build
staging mergevX.Y.Z-rcNcrane re-tag
production releasevX.Y.Zcrane re-tag

Scaffold Templates

Templates live in the scaffold-templates Gitea repository. Each template has a template.yaml at its root:

apiVersion: wxops.cloud/v1alpha1
kind: Template
metadata:
name: go-http-service
description: "Go HTTP service with health checks and structured logging."
tags:
- go
- http
spec:
defaults:
replicas: 1
resources:
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "500m", memory: "512Mi" }
recommends:
- feature: database
when: "data persistence required"
- feature: external-secrets
when: "third-party API keys needed"

Platform teams add templates by pushing a new directory to scaffold-templates. The portal discovers them via Gitea API — no config change needed.