Version tags, GHCR images, digest-pinned install.yaml, upgrades, and uninstall.
Release and image versioning
The current public release is v0.1.0-alpha.2. Kontext releases use
SemVer-compatible git tags:
vMAJOR.MINOR.PATCH
vMAJOR.MINOR.PATCH-PRERELEASE
Build metadata suffixes (+...) are not supported because they are not valid
OCI tag characters.
Published images
Each release publishes the same tag for four public GHCR images:
ghcr.io/mfs-code/kontext-operator:<release-tag>
ghcr.io/mfs-code/kontext-echo:<release-tag>
ghcr.io/mfs-code/kontext-reporter:<release-tag>
ghcr.io/mfs-code/kontext-reference:<release-tag>
Every image index includes linux/amd64 and linux/arm64. Releases do not
publish mutable latest or dev tags. The workflow refuses to overwrite an
existing release image tag, verifies anonymous pulls, and attaches an
image-digests.json asset containing immutable image@sha256:... references.
GitHub provides no API to change container package visibility, so each GHCR package must be made public once, manually, in its package settings on GitHub. Visibility persists across pushes. The workflow verifies that every package is public and fails with a link to the settings page if one is not. Publication fails before a GitHub release is created if anonymous access cannot be verified.
Install
Install a tagged release on an existing cluster without cloning the repository or building images:
VERSION=v0.1.0-alpha.2
kubectl apply -f \
"https://github.com/MFS-code/Kontext/releases/download/${VERSION}/install.yaml"
install.yaml contains the CRDs, Namespace, RBAC, controller Deployment,
webhook Service, NetworkPolicy, and narrow admission registration. It contains
no certificate or private key. The controller creates and rotates the
namespaced TLS Secret after installation. Its operator and trusted reporter
references use the immutable digests recorded in image-digests.json, while
app.kubernetes.io/version and kontext.dev/release retain the human-readable
release tag.
The registration matches only sparse referenced AgentRun CREATE requests.
It fails matching requests closed, uses a five-second timeout, and leaves
complete standalone and controller-created runs outside the webhook. Every
controller replica reconciles the shared TLS Secret and registration, reloads
renewed serving certificates, and must agree with the registered CA bundle
before becoming ready.
Webhook permissions are split from controller reconciliation and leader
election. A namespaced Role manages only the TLS Secret. A separate
ClusterRole manages only the named MutatingWebhookConfiguration, except that
Kubernetes RBAC cannot name-scope the create verb. The release NetworkPolicy
is ingress-only and selects controller Pods for webhook port 9443 and health
port 8081. It does not restrict AgentRun workloads or controller egress.
Given a downloaded digest manifest, the release artifact is reproducible from the tagged source:
make release-manifest IMAGE_DIGESTS=image-digests.json
Upgrade between alpha releases
v1alpha1 does not imply compatibility between Kontext distribution versions.
Read the target release notes first, especially any CRD schema, defaulting,
runtime-contract, or status changes. Back up custom resources before upgrading:
kubectl get agents,agentruns --all-namespaces -o yaml \
> kontext-custom-resources-backup.yaml
Apply the new release manifest over the existing installation and wait for the controller rollout:
NEW_VERSION="<target-release-tag>"
kubectl apply -f \
"https://github.com/MFS-code/Kontext/releases/download/${NEW_VERSION}/install.yaml"
# Remove identities used by releases before the kontext- name prefix.
kubectl delete deployment/controller-manager \
-n kontext-system --ignore-not-found=true --wait=true
kubectl delete \
mutatingwebhookconfiguration/task-agentrun-mutator.kontext.dev \
clusterrolebinding/manager-rolebinding \
clusterrolebinding/webhook-registration-manager \
clusterrole/manager-role \
clusterrole/webhook-registration-manager \
--ignore-not-found=true
kubectl delete \
service/webhook-service \
serviceaccount/controller-manager \
rolebinding/leader-election-manager \
rolebinding/webhook-certificate-manager \
role/leader-election-manager \
role/webhook-certificate-manager \
networkpolicy/controller-manager-webhook \
-n kontext-system --ignore-not-found=true
kubectl rollout status deployment/kontext-controller-manager \
--namespace kontext-system \
--timeout=180s
The explicit cleanup is idempotent. It stops an unprefixed controller from retaining the shared leader-election Lease and removes its fail-closed webhook before the old Service disappears. The namespaced TLS Secret remains and is renewed for the prefixed webhook Service.
Kubernetes updates the CRDs and current resources declaratively; existing
Agent and AgentRun resources remain. Downgrades are not supported as an API
compatibility guarantee. Release CI nevertheless migrates in both directions,
applies the previous manifest after the candidate as a rollback safety check,
verifies baseline workloads remain available, and then restores the candidate.
Uninstall
To remove only the Kontext control plane while retaining the CRDs and custom resources in other namespaces:
kubectl delete clusterrolebinding kontext-manager-rolebinding \
--ignore-not-found=true
kubectl delete clusterrole kontext-manager-role \
--ignore-not-found=true
kubectl delete mutatingwebhookconfiguration \
kontext-task-agentrun-mutator.kontext.dev --ignore-not-found=true
kubectl delete clusterrolebinding kontext-webhook-registration-manager \
--ignore-not-found=true
kubectl delete clusterrole kontext-webhook-registration-manager \
--ignore-not-found=true
kubectl delete mutatingwebhookconfiguration \
task-agentrun-mutator.kontext.dev --ignore-not-found=true
kubectl delete clusterrolebinding manager-rolebinding \
webhook-registration-manager --ignore-not-found=true
kubectl delete clusterrole manager-role \
webhook-registration-manager --ignore-not-found=true
kubectl delete namespace kontext-system \
--ignore-not-found=true --wait=true
Deleting kontext-system removes the controller and its ServiceAccount.
Agent and AgentRun resources in other namespaces remain stored and can be
reconciled again by reapplying an install manifest. Any custom resources
created inside kontext-system are deleted with that Namespace.
To remove Kontext completely, including both CRDs:
VERSION=v0.1.0-alpha.2
kubectl delete -f \
"https://github.com/MFS-code/Kontext/releases/download/${VERSION}/install.yaml" \
--ignore-not-found=true --wait=true
Deleting a CRD deletes all custom resources of that kind across the cluster. Back them up first if their history or results must be retained. Release CI verifies both the retention procedure and complete removal.
API relationship
The git tag, GitHub release, and image tags identify one version of the Kontext
distribution. They do not change the Kubernetes API group/version: current
releases serve kontext.dev/v1alpha1, and maintained runtimes emit the
versioned event and result contracts documented in the API specification.
v1alpha1 is intentionally unstable. A new Kontext alpha release may make
breaking CRD, runtime-contract, or status-shape changes while retaining the
same Kubernetes API version. Consumers must read the release notes and follow
the documented upgrade procedure rather than treating matching v1alpha1
labels as compatibility guarantees.