How to generate Operator Bundles for Kubernetes
March 16, 2026 · View on GitHub
For Kubernetes Platform (operatorhub.io) release we generate the
bundle using the release-manifest strategy.
Prerequisites
-
Container registry: You can use either Quay.io or ttl.sh (anonymous, no login).
-
Quay.io: Log in first (
docker login quay.io). SetIMAGE_NAMESPACEto a Quay org/namespace you can push to (e.g.your-username/tektoncd/operator). The defaultjkhelil/tektoncd/operatoris only an example and will fail with "unauthorized" unless you have access. -
ttl.sh (instead of Quay): No login. Use ttl.sh so the catalog image is at a public URL like
ttl.sh/<name>/operator-catalog:0.79.0instead ofquay.io/.../operator-catalog:0.79.0. Set:export IMAGE_HOST=ttl.sh export IMAGE_NAMESPACE=tektoncd-operator # or any single path segment, e.g. your-name-operator
You can pass
IMAGE_HOSTandIMAGE_NAMESPACEon the command line (e.g.make operator-bundle-push IMAGE_NAMESPACE=your-username/tektoncd/operator) or editoperatorhub/Makefile. -
-
Kubernetes cluster (for testing with OLM): Steps 5 and 6 (install OLM and run the operator catalog) require a cluster. You do not need Kind specifically—any cluster is fine (Kind, Minikube, k3d, or a cloud cluster). Ensure
kubectlis configured and your current context points to that cluster:kubectl config current-context kubectl cluster-info
Steps to generate bundles from an existing github release.yaml
Generate the operator bundle
Note: The input release.yaml could be a github release or the result of ko resolve config
-
Set minKubeVersion (required by OperatorHub CI). In
operatorhub/kubernetes/config.yamlsetmin-kube-versionto the minimum Kubernetes version your operator supports (e.g."1.28.0"). When you runmake operator-bundle, the bundle tooling (bundle.py) will addspec.minKubeVersionto the generated CSV automatically. Without this, the community-operators CI may fail with "csv.Spec.minKubeVersion is not informed". -
Make sure that we have the release manifest file ready eg:
tektoncd_operator_version=$( curl -sL https://api.github.com/repos/tektoncd/operator/releases | jq -r '.[].tag_name' | sort -Vr | head -n 1 | tr -d 'v') release_file_name=release-v${tektoncd_operator_version}.yaml curl -sL -o ${release_file_name} "https://github.com/tektoncd/operator/releases/download/v${tektoncd_operator_version}/release.notags.yaml" -
From the project root (tektoncd/operator) run (note absolute path for
--release-manifestflag is necessary)export BUNDLE_ARGS="--workspace kubernetes --operator-release-version ${tektoncd_operator_version} --channels stable --default-channel stable --fetch-strategy-release-manifest --release-manifest $(pwd)/${release_file_name} --upgrade-strategy-semver" make operator-bundleCLI flags explained
Flag Description --workspace kubernetesthe working directory (inside operatorhub/) where the operator bundle should be assembled --operator-release-version ${tektoncd_operator_version}version of the release (version of bundle) --channels stabletarget release channel(s) (eg: stable,preview) --default-channel stableset default channel of the operator --fetch-strategy-release-manifestgather input kubernetes resources from a list of yaml manifests instead of using local files --release-manifest $(pwd)/${release_file_name}specify absolute ({release_file_name}) path to release manifest file --upgrade-strategy-semverspecify update strategy (options replacesorsemver)
Note: the generated files are the base bundle files that serve to create a PR in https://github.com/k8s-operatorhub/community-operators/
Test the operator bundle
Version: Set VERSION in operatorhub/Makefile (default 0.79.0) to match the version you use when generating the bundle.
-
Build the operator bundle image using
make operator-bundle-build -
Push the operator bundle image to a container registry.
- Log in first (e.g. for Quay:
docker login quay.io). - Set
IMAGE_HOSTandIMAGE_NAMESPACEto a registry and namespace you can push to (e.g.make operator-bundle-push IMAGE_NAMESPACE=your-username/tektoncd/operatoror edit operatorhub/Makefile). The defaultjkhelil/tektoncd/operatoris only an example.
make operator-bundle-push - Log in first (e.g. for Quay:
-
Build the operator catalog source image
make operator-catalog-build -
Push the operator catalog source image
make operator-catalog-push -
Install OLM (requires a Kubernetes cluster; see Prerequisites)
make install-olm -
Run the operator catalog
make operator-catalog-run -
Verify the installation: TektonConfig should be up and ready at the end of testing. Check that the operator has created and reconciled the config:
kubectl get tektonconfig -AYou should see a
configTektonConfig withREADYTrue and your bundle version (e.g.v0.79.0). If it is not ready, check operator and catalog pods and logs.