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_VERSIONandCILIUM_CHART_SHA256pin in the Makefile (the digest comes from the Helm index andmake cilium-chartverifies the download against it);//go:embed chart/cilium-X.tgzinpkg/cni/cilium/render.go;ChartVersioninpkg/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 bymake cilium-goldens(internal/tools/ciliumgolden); the version named inREADME.md,docs/guides/getting-started.md,docs/guides/adopt-and-reclaim.mdand the foreign-cluster hardware tests (test/e2e/foreign,test/internal/foreign); and the tag in the citation above"1.20"inpkg/release/compat.go. It does not touchCHANGELOG.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 sameX.Y; the downloaded chart matches the index digest and itsChart.yamlnames the version;cosign verifyaccepts the three images the chart pins (the same three Ichor verifies at runtime) with issuerhttps://token.actions.githubusercontent.comand identityhttps://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.yamlat the new tag equal those at the old tag, becausecompat.gostates 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, thenmake testandmake lint, and opens or updates the pull request on the branchchore/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_TOKENdoes not start other workflows. The workflow uses the secretCILIUM_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.