Skip to content

Commit 84121e2

Browse files
authored
docker: produce linera-tests image with remote-net test binary (#6349)
## Summary - New Dockerfile stages: `tests-builder` runs `cargo test --no-run -p linera-service --features remote-net --test linera_net_tests` and extracts the executable from cargo's JSON output; `tests` is built `FROM runtime` and bundles the test binary alongside the CLI (symlinked into PATH so `Command::new("linera")` resolves). - Workflow `docker_image.yml` builds and pushes `linera-tests:{branch,sha_short,sha_long}` in parallel via `--target tests`. BuildKit dedups the shared chef/planner/builder_src stages between the two builds. - Production `linera:<tag>` image (target=runtime) is unchanged. Refs: linera-io/linera-infra#1188 ## Test plan - `docker buildx build --check --target tests`: clean (no warnings). - Verified the existing `runtime` stage is byte-identical: only new stages added after it, no edits to its COPY/RUN steps. - The added `jq` apt package in the chef stage is the only delta to the production build path; chef cache key is still cargo-chef's `recipe.json`, so unchanged. - End-to-end validation (image pushed by this workflow → consumed by the linera-infra CronJob) happens when this lands and triggers the `Docker Image` workflow.
1 parent 9a7407e commit 84121e2

2 files changed

Lines changed: 49 additions & 9 deletions

File tree

.github/workflows/docker_image.yml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,20 @@ jobs:
8686
local IMAGE_SHORT=$3
8787
local IMAGE_LONG=$4
8888
local BUILD_NAME=$5
89+
local TARGET=$6
8990
local LOG_FILE="/tmp/${BUILD_NAME}.log"
9091
9192
{
9293
echo "========================================"
93-
echo "Building ${BUILD_NAME} (${DOCKERFILE})"
94+
echo "Building ${BUILD_NAME} (${DOCKERFILE}${TARGET:+ target=$TARGET})"
9495
echo "========================================"
9596
9697
DOCKER_BUILDKIT=1 docker build \
9798
-t "${IMAGE_BRANCH}" \
9899
-t "${IMAGE_SHORT}" \
99100
-t "${IMAGE_LONG}" \
100101
-f "${DOCKERFILE}" \
102+
${TARGET:+--target "${TARGET}"} \
101103
--build-arg "git_commit=${GIT_COMMIT_LONG}" \
102104
--build-arg "build_date=${BUILD_DATE}" \
103105
--build-arg "build_flag=--release" \
@@ -116,28 +118,35 @@ jobs:
116118
echo "Starting parallel builds..."
117119
118120
build_and_push "docker/Dockerfile" \
119-
"${LINERA_IMAGE_BRANCH}" "${LINERA_IMAGE_SHORT}" "${LINERA_IMAGE_LONG}" "Linera" &
121+
"${LINERA_IMAGE_BRANCH}" "${LINERA_IMAGE_SHORT}" "${LINERA_IMAGE_LONG}" "Linera" "runtime" &
120122
PID_LINERA=$!
121123
124+
# linera-tests shares the Dockerfile and chef cache mounts with
125+
# linera; --target tests builds the overlay stage that bundles
126+
# the remote-net integration test binary on top of the runtime.
127+
build_and_push "docker/Dockerfile" \
128+
"${LINERA_TESTS_IMAGE_BRANCH}" "${LINERA_TESTS_IMAGE_SHORT}" "${LINERA_TESTS_IMAGE_LONG}" "LineraTests" "tests" &
129+
PID_LINERA_TESTS=$!
130+
122131
build_and_push "docker/Dockerfile.indexer" \
123-
"${INDEXER_IMAGE_BRANCH}" "${INDEXER_IMAGE_SHORT}" "${INDEXER_IMAGE_LONG}" "Indexer" &
132+
"${INDEXER_IMAGE_BRANCH}" "${INDEXER_IMAGE_SHORT}" "${INDEXER_IMAGE_LONG}" "Indexer" "" &
124133
PID_INDEXER=$!
125134
126135
build_and_push "docker/Dockerfile.explorer" \
127-
"${EXPLORER_IMAGE_BRANCH}" "${EXPLORER_IMAGE_SHORT}" "${EXPLORER_IMAGE_LONG}" "Explorer" &
136+
"${EXPLORER_IMAGE_BRANCH}" "${EXPLORER_IMAGE_SHORT}" "${EXPLORER_IMAGE_LONG}" "Explorer" "" &
128137
PID_EXPLORER=$!
129138
130139
build_and_push "docker/Dockerfile.exporter" \
131-
"${EXPORTER_IMAGE_BRANCH}" "${EXPORTER_IMAGE_SHORT}" "${EXPORTER_IMAGE_LONG}" "Exporter" &
140+
"${EXPORTER_IMAGE_BRANCH}" "${EXPORTER_IMAGE_SHORT}" "${EXPORTER_IMAGE_LONG}" "Exporter" "" &
132141
PID_EXPORTER=$!
133142
134143
build_and_push "docker/Dockerfile.bridge" \
135-
"${BRIDGE_IMAGE_BRANCH}" "${BRIDGE_IMAGE_SHORT}" "${BRIDGE_IMAGE_LONG}" "Bridge" &
144+
"${BRIDGE_IMAGE_BRANCH}" "${BRIDGE_IMAGE_SHORT}" "${BRIDGE_IMAGE_LONG}" "Bridge" "" &
136145
PID_BRIDGE=$!
137146
138147
SUCCESS_NAMES=""
139148
FAILED_NAMES=""
140-
for NAME_PID in Linera:$PID_LINERA Indexer:$PID_INDEXER Explorer:$PID_EXPLORER Exporter:$PID_EXPORTER Bridge:$PID_BRIDGE; do
149+
for NAME_PID in Linera:$PID_LINERA LineraTests:$PID_LINERA_TESTS Indexer:$PID_INDEXER Explorer:$PID_EXPLORER Exporter:$PID_EXPORTER Bridge:$PID_BRIDGE; do
141150
NAME="${NAME_PID%%:*}"
142151
PID="${NAME_PID##*:}"
143152
if wait "$PID"; then

docker/Dockerfile

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
4141
libprotobuf-dev \
4242
clang \
4343
make \
44-
libunwind-dev
44+
libunwind-dev \
45+
jq
4546

4647
WORKDIR /app
4748

@@ -150,7 +151,7 @@ COPY \
150151
FROM builder_src$copy AS binaries
151152

152153
# ── Stage 3: runtime ──
153-
FROM debian:bookworm-slim
154+
FROM debian:bookworm-slim AS runtime
154155

155156
ARG git_commit
156157
LABEL git_commit=$git_commit
@@ -170,3 +171,33 @@ COPY --from=binaries \
170171
/linera-server \
171172
/linera-proxy \
172173
./
174+
175+
# ── Stage 4: tests-builder — compile the remote-net integration test ──
176+
# Builds /linera_net_tests by parsing cargo's JSON output for the executable
177+
# path; the underlying binary lives in /app/target/release/deps/ which is a
178+
# cache mount and won't persist past this RUN, hence the explicit cp.
179+
180+
FROM builder_src AS tests-builder
181+
ARG build_flag
182+
183+
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
184+
--mount=type=cache,target=/usr/local/cargo/git,sharing=locked \
185+
--mount=type=cache,target=/app/target,sharing=locked \
186+
cargo test --no-run ${build_flag:+"$build_flag"} \
187+
-p linera-service \
188+
--features remote-net \
189+
--test linera_net_tests \
190+
--message-format=json-render-diagnostics > /tmp/cargo-tests.json \
191+
&& jq -r 'select(.executable != null) | .executable' /tmp/cargo-tests.json \
192+
| grep '/linera_net_tests-' \
193+
| head -1 \
194+
| xargs -I{} cp {} /linera_net_tests
195+
196+
# ── Stage 5: tests runtime — runtime image + remote-net test binary ──
197+
# Used by linera-infra's network-health-check CronJob; production image
198+
# `linera:<tag>` (target=runtime) is unchanged. The test binary spawns
199+
# the linera CLI via PATH, so /linera is symlinked into /usr/local/bin.
200+
201+
FROM runtime AS tests
202+
RUN ln -s /linera /usr/local/bin/linera
203+
COPY --from=tests-builder /linera_net_tests /usr/local/bin/linera-net-tests

0 commit comments

Comments
 (0)