# Test and build image: the suite, then the compile. # # Linting deliberately does not happen here. `script/lint` is a build of # Dockerfile.lint, and `script/check` calls `script/lint`, so running # `make check` in this image would mean running `docker build` inside a # container. Lint runs exactly once, in Dockerfile.lint; script/cibuild # builds that first and this second. # node 22.22.0 on Alpine 3.23.3 (node:22-alpine), 2026-08-09 FROM node@sha256:e4bf2a82ad0a4037d28035ae71529873c069b13eb0455466ae0bc13363826e34 AS check WORKDIR /app COPY script/ script/ COPY package.json yarn.lock ./ RUN script/bootstrap COPY . . # CHECK_EPOCH is a cache buster: without it Docker serves the test layer from # cache on an unchanged tree, the suite never executes, and the build still # exits 0. The guard makes an absent argument a hard failure — an unset ARG # is the empty string, which is a perfectly stable cache key, so a plain # `docker build .` would otherwise still get the false green. Fail closed. ARG CHECK_EPOCH RUN [ -n "$CHECK_EPOCH" ] || exit 1 RUN make test ARG CHECK_EPOCH RUN [ -n "$CHECK_EPOCH" ] || exit 1 RUN make build