# node 22-alpine, 2026-02-22 FROM node@sha256:e4bf2a82ad0a4037d28035ae71529873c069b13eb0455466ae0bc13363826e34 WORKDIR /app # Makes script/lint run the linter directly rather than building # Dockerfile.lint, which would need a docker daemon here. ENV LINT_IN_CONTAINER=1 # script/bootstrap installs all prerequisites. Manifests are copied # first so that layer stays cached until dependencies change. COPY script/ script/ COPY package.json yarn.lock ./ RUN script/bootstrap COPY . . # CHECK_EPOCH is a per-invocation nonce from script/cibuild and # script/docker; without it an unchanged tree serves this layer from # cache and the build reports a green it never ran. ARG is stage-scoped, # so declare it in every stage that runs checks. The guard fails a bare # `docker build .`, which would otherwise reuse the empty (and therefore # stable) cache key. The value is also expanded into the check command, # so the cache miss does not depend on BuildKit's handling of an # unreferenced ARG; keep both references. ARG CHECK_EPOCH RUN [ -n "$CHECK_EPOCH" ] || exit 1 RUN echo "check epoch: ${CHECK_EPOCH}" && make check