From 5fec47ad025a0ff07c16b3320acd71ed5edf0cc3 Mon Sep 17 00:00:00 2001 From: Raphael Maenle Date: Tue, 9 Jun 2026 19:54:32 +0200 Subject: [PATCH] ci: bake secs4j harness into image instead of bind-mounting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second secs4j-interop CI failure: ensuring secs4j-interop image is built... compiling Secs4jHostHarness.java... error: file not found: Secs4jHostHarness.java FAIL: javac The script bind-mounted $PWD/interop/secs4j into /work inside the container so it could javac the harness at runtime. That works locally where docker daemon and script share a filesystem, but fails in CI: the act runner runs the workflow inside a container, the docker socket is mounted from the host, and the daemon interprets bind-mount paths against the host filesystem — where $PWD/interop/secs4j doesn't exist. Result: empty /work, javac errors, job fails. Fix: COPY Secs4jHostHarness.java into the image and javac it at image build time. The script just runs the container — no bind mount, no docker-in-docker mount path translation, works in CI and locally. Verified locally with a fresh image rebuild: 55/55 checks pass. Co-Authored-By: Claude Opus 4.7 --- interop/secs4j/Dockerfile | 15 ++++++++++++--- interop/secs4j_validate.sh | 13 +++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/interop/secs4j/Dockerfile b/interop/secs4j/Dockerfile index 0f13eea..0ba997b 100644 --- a/interop/secs4j/Dockerfile +++ b/interop/secs4j/Dockerfile @@ -27,7 +27,16 @@ WORKDIR /opt/secs4java8 # at image build so the harness can just include the resulting jar. RUN bash compile.sh -# The harness source lives outside this image and is mounted at /work -# when the container runs (so editing the harness doesn't require a -# rebuild). +# Bake the harness into the image and compile it here. +# +# The previous arrangement bind-mounted the harness from the host at +# runtime, which fails when this script runs inside a CI container +# whose docker socket points at a daemon on a different filesystem — +# the host path interop/secs4j doesn't exist on the docker daemon's +# side, so `docker run -v $PWD/interop/secs4j:/work` mounts an empty +# directory and javac reports "file not found." Copying the source +# in at build time avoids the docker-in-docker volume problem +# entirely. WORKDIR /work +COPY Secs4jHostHarness.java /work/ +RUN javac -cp /opt/secs4java8/Export.jar Secs4jHostHarness.java diff --git a/interop/secs4j_validate.sh b/interop/secs4j_validate.sh index 28baa2e..2609b7c 100755 --- a/interop/secs4j_validate.sh +++ b/interop/secs4j_validate.sh @@ -16,17 +16,15 @@ PORT=${PORT:-5099} cd "$(dirname "$0")/.." -# Ensure the secs4j-interop image is built (idempotent). +# Ensure the secs4j-interop image is built (idempotent). The image +# COPYs Secs4jHostHarness.java in and compiles it at build time, so +# no bind mount is needed at run time — important because docker- +# in-docker (CI runners with a mounted /var/run/docker.sock) can't +# bind-mount paths from the container's filesystem to the daemon's. echo "ensuring secs4j-interop image is built..." docker build -t secsgem-secs4j-interop -f interop/secs4j/Dockerfile interop/secs4j \ >/dev/null 2>&1 -# Ensure the harness is compiled. -echo "compiling Secs4jHostHarness.java..." -docker run --rm -v "$PWD/interop/secs4j:/work" secsgem-secs4j-interop \ - bash -c "cd /work && javac -cp /opt/secs4java8/Export.jar Secs4jHostHarness.java" \ - || { echo "FAIL: javac"; exit 2; } - # Start the C++ server in background on the compose bridge network so # the secs4j container can DNS-resolve it. echo "starting secs_server (compose)..." @@ -42,7 +40,6 @@ sleep 1 echo "running Secs4jHostHarness..." docker run --rm \ --network secs-gem_secs \ - -v "$PWD/interop/secs4j:/work" \ secsgem-secs4j-interop \ java -cp /opt/secs4java8/Export.jar:/work Secs4jHostHarness server 5000