Skip to content

Fix the build cache of the container image workflows - #421

Merged
ericof merged 1 commit into
2.xfrom
fix-container-image-cache
Oct 2, 2026
Merged

ericof merged 1 commit into
2.xfrom
fix-container-image-cache

Conversation

@sneridagh

Copy link
Copy Markdown
Member

Problem

container-image-build.yml and container-image-push.yml never reuse their registry build cache:

  • They write it to <image-cache-suffix>-<base-tag>, for example buildcache-sha-45c6735.
  • They read it from <image-cache-suffix>-<cache-key>, where cache-key defaults to github.ref_name, for example buildcache-main.

Nothing ever writes buildcache-<branch>, so every build starts cold. The log of a kitconcept.intranet run shows it:

importing cache manifest from ghcr.io/kitconcept/kitconcept-intranet-frontend:buildcache-main
ERROR: failed to configure registry cache importer: ghcr.io/kitconcept/kitconcept-intranet-frontend:buildcache-main: not found

As a result, container-image-push rebuilds from scratch too, although the docs say it reuses the cache written by container-image-build. In kitconcept.intranet the frontend image takes ~6.5 minutes in both. Also, every commit pushes a new buildcache-sha-* image to the registry that is never read.

Fix

In both workflows, a new step computes the cache references:

  • Write to <image-cache-suffix>-<cache-key>, with the key normalized to a valid image tag (feature/x → feature-x).
  • Read, in order, from:
    1. <image-cache-suffix>-<base-tag>, so callers that pass cache-key: <base-tag> keep working as before;
    2. <image-cache-suffix>-<cache-key>, the latest build of the branch, including the container-image-build job of the same run, so container-image-push reuses it;
    3. <image-cache-suffix>-<default branch>, as a fallback for the first build of a new branch.

Missing cache images are only logged by buildx, they don't fail the build. Inputs are passed through env, not interpolated into the script.

The registry gets one cache image per branch instead of one per commit.

The reference docs and a news entry are updated. container-image-build-push.yml has no registry cache, so it's unchanged.

Test plan

  • The cache-references script, run locally for main, feature/plate-53, cache-key == base-tag, and an empty default branch, produces the expected references
  • actionlint and zizmor report no new findings (the existing ones are unchanged)
  • Two consecutive runs of kitconcept.intranet pointing at this branch: the second one imports buildcache-<branch> and the image builds are faster

The cache was written to <suffix>-<base-tag> but read from <suffix>-<cache-key>
(the branch name by default), so it was never reused. Write it per cache key
(sanitized branch name), and read it from the base tag, the cache key, and the
default branch.
@sneridagh

Copy link
Copy Markdown
Member Author

Test results in kitconcept.intranet

I tested this branch in kitconcept.intranet on a test branch (test-meta-cache), which points its container-image-build and container-image-push calls at fix-container-image-cache. Two runs on the same branch:

  1. Run 1: first build of the branch, so no cache yet (buildcache-main doesn't exist).
  2. Run 2: a follow-up commit that only changes a comment in a workflow file, so the image contents are unchanged.
Job Before (2.x, recent runs) Run 1 Run 2
Frontend image build 6.4–6.6 min 7.1 min (cold) 0.5 min
Backend image build 2.2–2.3 min 2.2 min (cold) 0.6 min
Acceptance image build 2.3–2.9 min 2.4 min (cold) 0.6 min
Frontend release (container-image-push) 5.5–6.3 min 0.5 min 0.6 min
Backend release (container-image-push) 2.1–2.3 min 0.3 min 0.4 min
Whole CI run ~22 min 20 min 13.7 min
  • Run 1: the release jobs imported buildcache-test-meta-cache, which the build job of the same run had just written. The frontend release went from a full rebuild to 0.5 min.
  • Run 2: the build jobs imported buildcache-test-meta-cache from run 1, with 10 steps CACHED in the frontend build.
  • The cache references that don't exist yet (buildcache-sha-*, buildcache-main) are logged as not found by buildx and skipped, without failing the build.

The remaining time is the acceptance tests (~8–10 min). Builds after a dependency change will be partly cached, depending on how the Dockerfiles order their layers.

@ericof
ericof merged commit 4670519 into 2.x Oct 2, 2026
4 checks passed
@ericof
ericof deleted the fix-container-image-cache branch October 2, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants