Release Checklist
Every release — including release candidates — walks this list top to bottom. A release is one coherent artifact set: tag, binary, image, chart, CRDs chart (k8s-aibom-crds, same version), install.yaml, SBOM, provenance. If any step fails, fix and restart from the tag step with a new version.
Before tagging
mainis green: all required checks passing on the release commit.CHANGELOG.md: move[Unreleased]into a new version section with today’s date; entries reviewed for accuracy, migration notes included for any behavior change.- Version consistency: chart
version/appVersionare derived at package time and the binary version at build time from the tag — no hand-edited version strings anywhere in the diff. - Dependabot alerts: zero open critical/high.
- Helm version: every workflow pins Helm (
azure/setup-helmversion:), currently v3.22.1, and the weekly version matrix runs one kind leg on Helm 4 on purpose (#260). A release is never packaged or attested with an unpinned Helm; bump the pin in all six workflow files and the Makefile’sHELM_VERSION(whatmake helminstalls) together. - README version strings: the Quickstart’s chart
--versionand install.yaml release URL updated to the new version (they are hardcoded by design so installs are reproducible). Merge all README/docs updates BEFORE tagging so the tagged tree is self-consistent — release URLs briefly pointing at a not-yet-published release is acceptable; a tag whose README contradicts the release is not (v1.0.0 lesson: its tagged README predated the install rewrite). - Downstream consumers: distributions that qualify k8s-aibom (e.g. NVIDIA AICR, per their ADR-019) pin the chart, image, CRDs, and status contract as one versioned set — any release changes their qualification target. Give downstream maintainers a heads-up, especially for unscheduled security patches landing mid-qualification.
Real-cluster verification (GKE)
Run on a GKE cluster on the current stable channel, from the release commit:
- Build and push a candidate image; install via the chart with that image.
- Controller Deployment becomes Available;
AIBOMControllerConfig/defaultreportsReady=True. - Label a test namespace
aibom.k8saibom.dev/enabled=true; deploy a known AI workload fixture; verify an AIBOM is created, carries the expected components/confidence, and its hashes validate. - Deploy a non-AI workload; verify no AIBOM is created for it.
- Remove the fixture; verify the AIBOM is cleaned up (owner reference).
- Uninstall the release; verify no release-owned resources remain (Deployment, RBAC, ServiceAccount, AIBOMControllerConfig). Three retentions are intentional, not orphans: the CRDs (Helm never removes
crds/), the release namespace, and workload-owned AIBOMs whose owners still exist (inventory outlives the collector; GC’d with the workload).
Tag & publish
- Tag the verified commit:
git tag vX.Y.Z && git push origin vX.Y.Z. - The release workflow builds and publishes: multi-arch image (ghcr), Helm chart and CRDs chart (OCI, same version, both attested), install.yaml (digest-pinned), SBOM, provenance attestations, GitHub release with notes.
After publishing
- Verify the image attestation:
gh attestation verify oci://<image>@<digest> --owner GoogleCloudPlatform. Then verify a plugin archive offline from the release assets alone:gh attestation verify kubectl-aibom_<tag>_linux_amd64.tar.gz --owner GoogleCloudPlatform --bundle kubectl-aibom_<tag>.provenance.intoto.jsonl. The five*.intoto.jsonlassets (image provenance, image SBOM, chart provenance, CRDs-chart provenance, plugin provenance) must all be present; the Scorecard Signed-Releases check reads them. helm installthe published CRDs chart, then the main chart, from OCI on a clean kind cluster; confirm the digest-pinned image pulls and the CRDs carryapp.kubernetes.io/managed-by=Helm.kubectl applythe release install.yaml on a clean cluster; confirm readiness.- First release of a new package only: set ghcr package visibility to public and confirm repository linkage. (v1.6.0: the new
charts/k8s-aibom-crdspackage.) - Update the adoption metrics log (image pull baseline for the new version).
Plugin distribution (after publishing)
- Bump every installable version reference to the new tag —
grep -rn 'version 1\.' README.md docs/install-eks-aks.md docs/deck/index.html terraform/variables.tf— install commands, install.yaml URL, terraform chart_version default, deck install slide + title kicker. Historical “since vX.Y” feature attributions stay as-is. - The plugin is live on krew-index (
kubectl krew install aibom, since 2026-09-25); each release updates the existingplugins/aibom.yamlthere rather than adding a new file. - Fill
hack/krew/aibom.yamlversion + sha256 fields fromkubectl-aibom_checksums.txton the release. - Validate locally:
kubectl krew install --manifest=hack/krew/aibom.yaml. - PR the updated manifest over kubernetes-sigs/krew-index
plugins/aibom.yaml(version-bump PRs are lightly reviewed; consider krew-release-bot to automate this step).