This project follows SemVer with the pre-1.0 relaxations documented below, and uses tag-triggered automation to publish every release artifact.
- Minor releases every 2-4 weeks, covering a milestone worth of
features (see
gh milestone list). - Patch releases within 24-72 hours when a critical fix lands.
- Release candidates precede every minor release — tag
vX.Y.Z-rc.Nbefore the finalvX.Y.Z. Soak ≥ 3 days unless the change set is trivial.
Main must stay releasable. Any merged PR should be such that cutting a tag at HEAD would produce a shippable artifact.
- Major stays at 0.
- Minor may carry breaking CRD changes with a migration note in CHANGELOG.
- Patch is backwards-compatible fixes only.
- 1.0 will freeze the v1alpha1 → v1beta1 transition policy and commit to API stability.
Pre-requisites:
- CI green on
main. gh milestone listshows the target milestone has no blocking open issues (paused / aspirational items moved to the next milestone).CHANGELOG.mdhas a dated entry for the new version under the## [X.Y.Z] - YYYY-MM-DDheading.dist/chart/Chart.yaml,dist/chart/values.yaml,bundle/manifests/*.clusterserviceversion.yaml,config/manager/kustomization.yaml, andMakefile VERSIONall reference the new version. (The release workflow double-bumps the chart version from the tag at publish time; source consistency is still required sohelm templateoffmainproduces sensible output.)- The CSV's upgrade-graph metadata is correct for the catalog state:
prefer
spec.replaces: ntn-operators.vX.Y.Z-prevwhen the previous CSV was actually published to an OperatorHub catalog; fall back tospec.skipRange: "<X.Y.Z"when no prior CSV was published (which was the case for v0.4.0-rc.1 — v0.1.0 predated the bundle infrastructure). Do not setreplaces:pointing at a CSV that never existed in a catalog — OLM will reject the bundle.
Steps:
- Open a
release/vX.Y.Zbranch with the version bumps above. - Run
make test lintlocally. Review the bumped CSV underoperator-sdk bundle validateif available. - Open a PR, land it, then:
git tag -a vX.Y.Z-rc.1 -m "vX.Y.Z release candidate 1" git push origin vX.Y.Z-rc.1 - Monitor
.github/workflows/release.yml. It will:- ko build + Trivy scan + push multi-arch image to GHCR
- cosign sign (keyless OIDC)
- generate SPDX SBOM and attest it to the image index
- package + push the Helm chart to
oci://ghcr.io/<owner> - create the GitHub Release (auto-generated notes + chart tarball
- SBOM JSON attached)
- Smoke-test the RC:
- Pull the image and run against a test cluster.
- Install the chart via OCI and verify CRDs apply cleanly.
- If there is a running cluster with the previous version, test OLM upgrade via the bundle image.
- After soak, tag the final version:
git tag -a vX.Y.Z -m "vX.Y.Z" git push origin vX.Y.Z - The GitHub Release is auto-flagged as pre-release whenever the
tag carries any pre-release identifier (the
-rc/-beta/ similar suffix), so nothing further is required on the UI.
While pre-1.0 a minor bump may carry a breaking CRD change. When it does:
- Add an Upgrade notes section to the CHANGELOG entry spelling out what changed and how to migrate.
- Provide a manual migration path (kubectl patch, in-place edit, migration pod) — conversion webhooks are deferred until 1.0.
- Announce the break in the GitHub Release body prominently.
- Git tag, annotated
- GitHub Release with auto-generated notes + chart
.tgz+ SBOM - Multi-arch container image at
ghcr.io/thc1006/ntn-operators:vX.Y.Zplus:latest - cosign signature attached to the image index
- SPDX SBOM attested to the image index
- Helm chart at
oci://ghcr.io/thc1006/ntn-operators, versionX.Y.Z, appVersionX.Y.Z - OLM bundle image at
ghcr.io/thc1006/ntn-operators-bundle:vX.Y.Z(aftermake bundle-build bundle-push VERSION=X.Y.Z)
The project targets CNCF Sandbox and OperatorHub listing. Both value release cadence over single-release novelty — the second release matters as much as the first. Keep cadence tight and the CHANGELOG honest.