0119. A daily CI run turns a new Cilium patch into a pull request

Status: Accepted; built · Date: 2026-11-04 · Design section: Upgrades, Cilium · Touches: 0098, 0108, 0113, 0115

Decided: Ichor pins the Cilium version, and the pin moves to a new upstream patch of the same minor through a pull request that CI opens: .github/workflows/cilium-patch.yml runs daily (and on demand) hack/bump-cilium-patch.sh (make bump-cilium-patch), which takes the newest final patch of the pinned minor from the Cilium Helm index, verifies the cosign signatures of the agent, operator-generic and hubble-relay images that chart pins against the Cilium release workflow of that tag (the identity internal/imagesig uses), checks that Cilium tests the minor with the same Kubernetes versions, and only then moves the pins (Makefile version and SHA-256, the go:embed line, ChartVersion, the chart archive, the bootstrap goldens, the version named in the README, the guides and the foreign hardware tests, the compat.go citation); the workflow runs make test and make lint and opens the pull request chore(cni): bump the embedded Cilium chart to X.Y.Z with peter-evans/create-pull-request. A merged bump reaches clusters only with the next Ichor release. The script never crosses a minor; a new minor is a person's decision.

Context

On 2026-11-04 the user decided that a cluster's Cilium only moves to the chart embedded in the running Ichor, and that Cilium patches reach users through Ichor releases (ADR 0115, amendment of the same day, removes the path that ran a patch's images without a new chart). That makes the delay between an upstream patch and an Ichor change the only lag users feel, so the user asked for CI to make the change quickly. A Cilium patch carries security and datapath fixes; ADR 0113's bump of the chart to 1.20.4 was done by hand and needed the same steps each time: fetch the chart and verify its digest, move the pin in four places, regenerate the goldens, check the signatures.

Decision

  • What the script moves. The CILIUM_CHART_VERSION and CILIUM_CHART_SHA256 pin in the Makefile (the digest comes from the Helm index and make cilium-chart verifies the download against it); //go:embed chart/cilium-X.tgz in pkg/cni/cilium/render.go; ChartVersion in pkg/cni/cilium/values.go; the chart archive (the old one is removed, unless it is the foreign-cluster chart); pkg/cni/cilium/testdata/bootstrap-*.golden.yaml, regenerated by make cilium-goldens (internal/tools/ciliumgolden); the version named in README.md, docs/guides/getting-started.md, docs/guides/adopt-and-reclaim.md and the foreign-cluster hardware tests (test/e2e/foreign, test/internal/foreign); and the tag in the citation above "1.20" in pkg/release/compat.go. It does not touch CHANGELOG.md (a release section is written when the release is cut), ADRs, or tests that use a Cilium version as a fixture.
  • What it checks before writing. The new version is a final release (no -rc, -pre) of the same X.Y; the downloaded chart matches the index digest and its Chart.yaml names the version; cosign verify accepts the three images the chart pins (the same three Ichor verifies at runtime) with issuer https://token.actions.githubusercontent.com and identity https://github.com/cilium/cilium/.github/workflows/build-images-releases.yaml@refs/tags/vX.Y.Z; and the Kubernetes versions in .github/actions/ginkgo/main-k8s-versions.yaml at the new tag equal those at the old tag, because compat.go states the range from that file. A failed check exits non-zero and changes nothing. "No newer patch" exits 0.
  • What the workflow does. It runs the script in nix develop, then make test and make lint, and opens or updates the pull request on the branch chore/cilium-patch. A red run, whether from a signature, a changed Kubernetes matrix or a test that pinned the old patch, means the patch needs a person; no pull request is opened for it. The commit is signed through the API (sign-commits). The pull request body names the upstream release notes (https://github.com/cilium/cilium/releases/tag/vX.Y.Z).
  • Merging is not releasing. The pull request changes what a first install gets and what the next Ichor build offers an existing cluster; nothing moves a cluster until the user installs that Ichor and runs ichor cni upgrade (ADR 0098). A Cilium security patch is shipped by cutting a patch release of Ichor after the merge.
  • Token. A pull request opened with GITHUB_TOKEN does not start other workflows. The workflow uses the secret CILIUM_PATCH_PR_TOKEN (a fine-grained token with contents and pull requests write) when it exists, so that Tests, Lint and PR Title also run on the pull request.

Rejected

  • Merging the bump automatically. A patch changes a CNI that runs on every node; a person reads the release notes and merges.
  • Following a new minor. A minor changes values and removes options (ADR 0113's review of the 1.19 and 1.20 removals), and Cilium upgrades one minor at a time.
  • Verifying only the agent image. Ichor runs and verifies three images, so the script verifies those three.

Test

hack/bump-cilium-patch.sh run on the current tree reports "no newer patch". Run on a copy whose pins were lowered to 1.20.3 it verified the three signatures, moved every pin to 1.20.4, fetched the chart with its digest checked, and left a tree byte-identical to the tree that ADR 0113's manual bump produced.

Search the docs

Search pages and headings