ci-build.yml resolves the Dockerfile only as <context>/Dockerfile (then <context>/Containerfile) and exposes no file: input. That makes a repo unbuildable when its Dockerfile is not at the root of the context it needs — which is the normal shape for a Go repo with more than one image.
The assumption that does not hold
The current comment explains the cut as:
There is no file: override branch any more: resolution is by convention or it is a loud failure. A repo whose Dockerfile is elsewhere moves its context:, which is the input that was kept.
That works only when the Dockerfile and the build context can be the same directory. They cannot be when the Dockerfile needs to copy source from the repo root.
Concrete case
jacaudi/wireguard-operator publishes two images, images/manager/Dockerfile and images/agent/Dockerfile. Both contain:
COPY go.mod go.sum ./
COPY cmd cmd/
COPY api api/
COPY internal internal/
So both require the repo root as context, and neither sits at it:
build_context |
result |
. |
::error::no Dockerfile or Containerfile in . |
images/manager |
resolves the Dockerfile, then fails at the COPY — no Go source in that context |
There is no answer to the build_context question that builds either image. Note this is not only about the second image: the primary one is equally unbuildable.
extra_build_contexts is not an escape hatch either — ci.yaml's build-check matrix passes only context:, so it carries the identical constraint, and ci-build-check.yml never pushes.
The fix already exists in this repo
ci-build-check.yml ships exactly the needed input, for exactly this reason:
file:
description: >-
Dockerfile path. Empty auto-resolves <context>/Dockerfile then
<context>/Containerfile, and fails loudly if neither exists.
required: false
default: ''
type: string
...with the matching resolution block. So this is not a new pattern to invent — it is the template's own, merely absent from the stage that publishes. Porting those ~12 lines into ci-build.yml keeps the convention-by-default behaviour and the loud failure, and adds an override for the case convention cannot express.
Two callers would want it: the build job in ci.yaml, and release-republish.yml's rebuild job — the latter matters because it is the repair path, so its failure surfaces during an incident.
Current downstream workaround
jacaudi/wireguard-operator (jacaudi/wireguard-operator#43) carries the input as a local edit to its copied ci-build.yml. It works, but it is the one file in that repo where copier update will conflict permanently. Landing it here would let that deviation be dropped.
ci-build.ymlresolves the Dockerfile only as<context>/Dockerfile(then<context>/Containerfile) and exposes nofile:input. That makes a repo unbuildable when its Dockerfile is not at the root of the context it needs — which is the normal shape for a Go repo with more than one image.The assumption that does not hold
The current comment explains the cut as:
That works only when the Dockerfile and the build context can be the same directory. They cannot be when the Dockerfile needs to copy source from the repo root.
Concrete case
jacaudi/wireguard-operatorpublishes two images,images/manager/Dockerfileandimages/agent/Dockerfile. Both contain:So both require the repo root as context, and neither sits at it:
build_context.::error::no Dockerfile or Containerfile in .images/managerCOPY— no Go source in that contextThere is no answer to the
build_contextquestion that builds either image. Note this is not only about the second image: the primary one is equally unbuildable.extra_build_contextsis not an escape hatch either —ci.yaml'sbuild-checkmatrix passes onlycontext:, so it carries the identical constraint, andci-build-check.ymlnever pushes.The fix already exists in this repo
ci-build-check.ymlships exactly the needed input, for exactly this reason:...with the matching resolution block. So this is not a new pattern to invent — it is the template's own, merely absent from the stage that publishes. Porting those ~12 lines into
ci-build.ymlkeeps the convention-by-default behaviour and the loud failure, and adds an override for the case convention cannot express.Two callers would want it: the
buildjob inci.yaml, andrelease-republish.yml'srebuildjob — the latter matters because it is the repair path, so its failure surfaces during an incident.Current downstream workaround
jacaudi/wireguard-operator(jacaudi/wireguard-operator#43) carries the input as a local edit to its copiedci-build.yml. It works, but it is the one file in that repo wherecopier updatewill conflict permanently. Landing it here would let that deviation be dropped.