This documentation will help you build and publish a new release of the Coraza Kubernetes Operator (CKO).
Note: All releases target tags, and our tags follow semver.
Note: Most of the release process is automated via GitHub Workflow. See the release.yml workflow for details.
Confirm with all other maintainers the plans to cut a release.
This should generally coincide with the completion of one of our milestones for any major or minor releases.
Note: Patch releases may be cut at any time out of
mainor another branch depending on the criticality of the patches included.
Create a tag off the top of the main branch, e.g.:
git tag v0.1.1Push the tag to the repository, e.g.:
git push upstream v0.1.1This will trigger workflows to test and create the release:
build-testrelease
You can follow along on the actions page.
The release workflow will:
- build and tag a container image (e.g.
ghcr.io/networking-incubator/coraza-kubernetes-operator:v0.1.1) - push the tag to GHCR
- cut a
draftrelease from the tag
Stop here and verify that CI has been successful on main where the release
was tagged.
Note: tags that start with
v0or have suffixes includingrc,alpha, orbeta(e.g.v0.1.1,v1.0.0-rc1,v0.1.0-alpha1) will be automatically marked as pre-releases.
Once you've confirmed the CI workflows have succeeded for this tag, review the
draft release for your tag on the releases page. Verify the following are
correct:
- The release name should just be the tag name
- Add the major themes and most important changes to the top of the description
- The remainder of the description should include the auto-generated release notes
- The crds.yaml, operator.yaml, samples.yaml & Helm chart .tgz artifacts are attached
- Check each manifest and the chart package, and verify their correctness
- Make sure the previous release is set correctly
- e.g. for a
v1.0.0release, don't targetrc, patch or other pre-releases. Target the last major/minor.
- e.g. for a
Once you've verified the release, we need to tag the container image appropriately before we publish.
The release workflow pushes the operator image tagged as the git tag
(e.g. v0.1.1). The OLM bundle references the image by its immutable
digest, so the tag does not affect OLM installs.
For stable (non-pre-release) versions, tag the image as latest before
publishing the release:
docker pull ghcr.io/networking-incubator/coraza-kubernetes-operator:v0.1.1
docker tag ghcr.io/networking-incubator/coraza-kubernetes-operator:v0.1.1 ghcr.io/networking-incubator/coraza-kubernetes-operator:latest
docker push ghcr.io/networking-incubator/coraza-kubernetes-operator:latestWarning: Do not push the
latesttag until you are confident the release is correct. Pre-release versions (v0.x.x,-alpha,-beta,-rc) should not be tagged aslatest.
The release workflow builds and pushes three container images. Two of them are specific to OLM:
Operator image (:v0.2.0)
│
│ generate_bundle.py (make bundle)
│ Renders Helm chart, extracts Deployment/RBAC/CRDs,
│ injects into CSV template (image pinned by digest)
▼
Bundle image (:v0.2.0)
┌─────────────────────┐
│ manifests/ │ CSV, CRDs, Service, etc.
│ metadata/ │ OLM annotations
│ tests/scorecard/ │ scorecard config
└─────────────────────┘
│
│ opm render (inside catalog docker build)
│ Pulls bundle image, extracts full content
▼
Catalog image (:v0.2.0)
┌─────────────────────┐
│ catalog.yaml │ olm.package + olm.channel
│ + rendered bundles │ full CSV/CRD content from opm render
└─────────────────────┘
│
│ deployed as CatalogSource CR
▼
OLM / OperatorHub UI
What the release workflow does automatically:
make bundle— generates bundle manifests from the Helm chartmake bundle.build bundle.push— builds and pushes the bundle imagemake catalog.update— adds the new version tocatalog.yamlchannel entries (withreplacespointing to the previous version)make catalog.build catalog.push— builds the catalog image (runsopm renderinside the Docker build to pull each bundle image and embed its full content)
Key files:
| File | Role |
|---|---|
bundle/base/csv-template.yaml |
CSV template — edit to change OLM metadata |
bundle/base/ci.yaml |
OperatorHub PR metadata (reviewers, updateGraph); copied to bundle/ci.yaml by make bundle |
hack/generate_bundle.py |
Generates bundle from Helm chart + CSV template |
catalog/coraza-kubernetes-operator/catalog.yaml |
Package and channel definitions (no bundle content) |
hack/update_catalog.py |
Adds new versions to catalog channel entries |
catalog/Dockerfile |
Multi-stage build: uses opm render to embed bundle content |
What needs manual attention:
-
catalog.yamlmust be committed before tagging the release. The release workflow runscatalog.updatein its working tree but does not commit the result back to the repository. If you skip this step, the next release will start from a stale checkout and the OLM upgrade chain will break — each release's catalog will have noreplaceslink to the previous version, making every version an independent install instead of an upgrade.Before tagging, run:
make catalog.update VERSION=vX.Y.Z git add catalog/coraza-kubernetes-operator/catalog.yaml git commit -m "catalog: add vX.Y.Z to OLM channel"
Automating this commit-back step is tracked in #184.
-
If the CSV template needs changes (description, icon, install modes, etc.), edit
bundle/base/csv-template.yamlbefore the release.
Warning: We enforce immutable releases so be absolutely certain the tests are passing and the release is ready before you publish it.
Publish the release. When publishing, the release page will ask you if you want
to create a discussion to announce the release. Say "Yes" to that and publish an
announcement type discussion for the release that links to the release page, or
go to the discussions page and write up an announcement from there.
Make sure the latest release announcement is pinned, and older release announcements get unpinned.
The operatorhub.yml workflow is disabled (if: false on the job) until
a dedicated bot or service account can hold the PAT and related settings for
pushing to a k8s-operatorhub/community-operators fork and opening PRs.
Re-enabling that automation is tracked in issue #201.
Until then, submit the OLM bundle locally after the GitHub release exists and the operator image is published to GHCR.
-
Check out the release tag (same commit you released).
-
Generate the bundle with the same controller image reference as the release (bare tag in
VERSION, full image ref for the env):export CONTROLLER_MANAGER_CONTAINER_IMAGE=ghcr.io/networking-incubator/coraza-kubernetes-operator:vX.Y.Z make bundle VERSION=vX.Y.Z
-
(Recommended) Run the same bundle test the workflow used:
./hack/operatorhub_opp_test.sh --version X.Y.ZUse the bare semver (
X.Y.Z, nov) for--version. -
Set credentials for commits and GitHub API access. The publish script requires
GIT_USER,GIT_EMAIL, andGITHUB_TOKEN(a PAT withrepoon thenetworking-incubatorfork of community-operators). For HTTPS push, rungh auth setup-gitwith that PAT (or use credentials your environment already provides). -
Open the PR to community-operators:
./hack/publish_operatorhub.sh --version X.Y.Z --fork networking-incubatorUse
./hack/publish_operatorhub.sh --helpfor options (--dry-run,--fork, etc.). The script copiesbundle/ci.yaml(frombundle/base/ci.yamlviamake bundle) intooperators/<name>/ci.yamlon the PR branch so this repo stays the source of truth for reviewers andupdateGraph. -
Watch the PR on
k8s-operatorhub/community-operatorsfor OperatorHub CI feedback until it merges.