Releases
One version across every repository, cut by tag from the orchestrator, deploying nothing.
A release is a compatibility record: the same vX.Y.Z tag and a GitHub release in every tagged repository, plus a manifest in the orchestrator. It moves no environment. Which version an environment runs is a separate decision, made in cvhome-platform by PR (pipeline and promotion).
The model
- One version everywhere. SemVer
X.Y.Z. Every repository withtag: truein the orchestrator'srepos.yamlgets the same tagvX.Y.Zonmainon the same day, whether or not it changed. Compatibility is then a tautology: version X of anything works with version X of everything else. - The tag is the version; no file carries it. cvhome's
gradle.propertiesstays0.0.0-SNAPSHOT; the platform's CodeBuild checks cvhome out atvX.Y.Zand passes-Pversion=X.Y.Z, and Gradle tags the imagesX.Y.Z,X.Yandlatest. A snapshot build tags onlylatest, so a branch build can never overwrite a release. cvhome-platform has no version file either. - A release is one button in the orchestrator's
Releaseworkflow (release-product.yml). - Releases do not deploy. The orchestrator only records which released version each environment names.
- Nothing publishes from GitHub Actions in cvhome.
saas-gatewayandaws-otel-collectorkeep pushingsha-<short>onmain; on avX.Y.Ztag their workflows also pushX.Y.Z.public-dkrmirrors the releasedX.Y.Zto public ECR; cvhome pinssaas-gateway:X.Y.Z. - The first aligned version was 2.0.0, cut 2026-09-07.
Tagged (tag: true) | Rolling (main is the release) |
|---|---|
cvhome, cvhome-platform, lcl, saas-gateway, caddy-domainlookup, certmagic-s3, aws-otel-collector | load-testing, e2e-testing, public-dkr, assets, cvhome-saas.github.io, .github, ideation, orchestrator |
Cutting a release
gh workflow run release-product.yml -R cvhome-saas/orchestrator -f bump=auto # or patch|minor|major
gh workflow run release-product.yml -R cvhome-saas/orchestrator -f version=2.1.0 # explicit
gh run watch -R cvhome-saas/orchestratorWhat the workflow does, in order:
- Decides the version from cvhome's merged PR labels since the last tag (
warn/*gives a major,type/enhancementorfeat:a minor, anything else a patch), or takes the one given. Nothing to release (onlyignore-changelogPRs) stops the run. - Checks that every tagged repository is green on
mainand does not already carry the tag. - Runs the cross-repo contract check.
- Creates the
vX.Y.Ztag and a GitHub release with generated notes in every repository listed byscripts/release.py tagged-repos, through a GitHub App, not a personal token. - Commits
releases/vX.Y.Z.yamlto the orchestrator.
Dry run: scripts/release.py next-version --json shows the last tag, the PRs and the bump it would pick. A hotfix is the fix merged to main and the workflow run with bump=patch.
Never push a v* tag or bump a version file by hand. Every repository's push guard refuses a push to main, and the tags exist only as the workflow's output. cvhome-platform's release-guard CI job runs on every v* tag and fails if a protected environment's tfvars still names latest.
The manifest
releases/vX.Y.Z.yaml records the commit each tagged repository was at and which load-testing and e2e-testing commits the version was validated with:
version: 2.0.0
date: 2026-09-07
repos:
cvhome: <sha>
cvhome-platform: <sha>
lcl: <sha>
saas-gateway: <sha>
caddy-domainlookup: <sha>
certmagic-s3: <sha>
aws-otel-collector: <sha>
validated_by:
load-testing: { commit: <sha>, result: pending }
e2e-testing: { commit: <sha>, result: pending }Changelog from labels
Every repository carries the same .github/release.yml, so the generated notes look alike. PR labels sort into sections, and the same labels drive the version bump:
| Section | Labels |
|---|---|
| Update considerations and deprecations | warn/api-change, warn/behavior-change, warn/blocker, warn/deprecation, warn/regression |
| New features and improvements | type/enhancement |
| Documentation | type/documentation |
| Bug fixes | type/bug |
| Other changes | everything else |
| Excluded | ignore-changelog, type/test, type/chore, type/dependency-upgrade |
Deploying a version
Not here. Deploying X.Y.Z to an environment is a PR in cvhome-platform changing image_tag in envs/<env>.tfvars, then a run of that environment's 3-apply project. A new environment gets its version from the bootstrap stack's ImageTag parameter instead. Both are described on pipeline and promotion and the deployment guide.
Source of truth: orchestrator docs/releasing.md, docs/release-plan.md, repos.yaml, releases/v2.0.0.yaml; cvhome-platform .github/release.yml, README.md.
