LEAN010 — missing-docker-build-cache¶
Severity: warning (downgraded to info on unrecognized/self-hosted-looking runners — see below) · Category: Lean pipelines
What it checks¶
Flags a docker/build-push-action step with no cache-from and
cache-to inputs set.
Why it matters¶
Docker's build cache lives on the runner's local disk during the job —
which is thrown away the moment the job ends, since GitHub-hosted
runners are ephemeral. Without an explicit cache backend (most commonly
type=gha, which routes through GitHub's own Actions cache, or a
registry-backed cache), every single build starts from zero: every
layer rebuilds from scratch on every run, even if nothing in the
Dockerfile or build context actually changed.
Examples¶
Flagged:
steps:
- uses: docker/build-push-action@ca877d9245402d1537745e0e356eab639262a132 # v6.15.0
with:
push: true
tags: myapp:latest
Fixed — export and import the build cache through GitHub's Actions cache:
steps:
- uses: docker/build-push-action@ca877d9245402d1537745e0e356eab639262a132 # v6.15.0
with:
push: true
tags: myapp:latest
cache-from: type=gha
cache-to: type=gha,mode=max
Self-hosted runners get a lower-confidence version of this finding¶
Like PERF001, the "every build starts from zero" framing assumes the
runner itself is thrown away between jobs. If the job's runs-on:
doesn't look GitHub-hosted or like a known managed-ephemeral runner
service, this still fires but at info instead of warning — Docker's
local build cache may well already be sitting on disk from the previous
job on a persistent self-hosted worker, even with no cache-from/
cache-to configured at all.
Asserting a runner is already cached¶
Same mechanism as PERF001: if a runs-on: label is known for certain
to be a persistent worker with Docker's build cache already on disk,
say so and get silence instead of the info-severity downgrade above:
# .vlotpipe.yml
rules:
LEAN010:
cached_runners: ["gha-hmak-web"] # exact label, or "*" for any runner
Suppressing¶
The finding is reported on the step's line:
- uses: docker/build-push-action@ca877d9245402d1537745e0e356eab639262a132 # vlotpipe: ignore[LEAN010]
with:
push: true
Reasonable for a genuinely one-off or from-scratch-by-design build (a
nightly full-rebuild job meant to catch base-image drift, for example),
where reusing a cache would defeat the point — or for a self-hosted pool
known for certain to be persistent, where the info-severity finding
already reflects that.