`make lint` passed locally but failed in Gitea Actions with every Dockerfile
reported as missing:
hadolint: images/node-agent/Dockerfile: withBinaryFile: does not exist
The job itself runs in a container, and the checkout lives in a docker volume
rather than on the host filesystem. Starting hadolint as a sibling container
through the host's docker socket meant `-v "$(CURDIR)":/repo` was resolved
against the HOST, where /workspace/... does not exist — so Docker created an
empty directory and mounted that.
Stream each file in on stdin instead. No shared filesystem is involved, so the
same command works locally and in CI. The linters then only ever see "-" as the
filename, so hack/lint.sh prints the real path itself, and only on failure.
Reproduced the original error and verified the fix against a faithful local
simulation: the repo in a docker volume at a path absent from the host, with
the socket mounted, running the real runner image.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Set up this repo as a base image registry. Each image is self-contained in
its own directory under images/ (Dockerfile + README.md + optional test.sh);
CI discovers them by glob, so adding an image needs no workflow changes.
template/ is the skeleton to copy.
The Makefile is the single entry point for both local work and CI, so a green
`make all` locally means a green pipeline.
Workflows:
* lint.yaml — layout check, hadolint, shellcheck
* build.yaml — diffs against the base commit to build only the images that
changed, smoke-tests each one before anything is published, then pushes.
Releases are per-image tags (<image>/vX.Y.Z); main publishes :edge.
First image, node-agent: node:22-alpine plus a GNU userland (Alpine ships
BusyBox, whose applets take narrower flags than scripts and models expect),
helm, kubectl, jq, yq, bind-tools, curl, git, ripgrep, fd and friends.
Nothing is version-pinned — rebuilding is how upstream updates land, and the
published tag is what pins things for consumers.
Its smoke test asserts the deployment contract as well as tool presence: the
image must work non-root, with a read-only root filesystem and all
capabilities dropped, which is how ToolHive runs it.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>