check / check (push) Waiting to run
A plain `docker build .` now stamps the version from git rather than `dev`/`0.0.0`. After `tsc`, `script/build` writes into `dist/package.json` the version `script/version` decides: `VERSION` when given, otherwise `git describe --tags --always` (the tag; or tag, commits since and short commit; or the short commit), otherwise `package.json`'s. A checkout with `.git` that yields an empty, `dev` or `unknown` version fails the build. `.dockerignore` sends `.git` but not `.git/config`, so no remote URL or credential reaches the image. `ARG VERSION` has no default, and the host scripts' version still wins. Not changed: `REPO_POLICIES.md` still says `ARG VERSION=dev` until the shared policy changes. Model: opus-5-5 Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
73 lines
2.4 KiB
Docker
73 lines
2.4 KiB
Docker
# Lint phase. The linters are invoked directly rather than through `make
|
|
# lint` or `script/lint`, which are themselves a docker build and would
|
|
# recurse into a daemon that does not exist in a build step.
|
|
#
|
|
# node 22.22.0 on Alpine 3.23.3 (node:22-alpine), 2026-08-09
|
|
FROM node@sha256:e4bf2a82ad0a4037d28035ae71529873c069b13eb0455466ae0bc13363826e34 AS lint
|
|
|
|
WORKDIR /app
|
|
|
|
COPY script/ script/
|
|
COPY package.json yarn.lock ./
|
|
RUN script/bootstrap
|
|
|
|
COPY . .
|
|
|
|
RUN yarn run eslint .
|
|
RUN yarn run prettier --check .
|
|
|
|
# Test phase, same shape and for the same reason. The suite runs without
|
|
# verbose output first and is rerun verbosely only if it fails; the timeout
|
|
# catches a hung test.
|
|
#
|
|
# node 22.22.0 on Alpine 3.23.3 (node:22-alpine), 2026-08-09
|
|
FROM node@sha256:e4bf2a82ad0a4037d28035ae71529873c069b13eb0455466ae0bc13363826e34 AS test
|
|
|
|
WORKDIR /app
|
|
|
|
COPY script/ script/
|
|
COPY package.json yarn.lock ./
|
|
RUN script/bootstrap
|
|
|
|
COPY . .
|
|
|
|
# Unlike the template, the suite runs as the image's non-root `node` user:
|
|
# root ignores directory permissions, so the tests of a destination that is
|
|
# not writable would otherwise fail. vitest writes into /app.
|
|
RUN chown -R node:node /app
|
|
USER node
|
|
|
|
RUN timeout 90 yarn run vitest run --reporter=dot || \
|
|
{ echo "--- Rerunning with verbose for details ---"; \
|
|
timeout 90 yarn run vitest run --reporter=verbose; exit 1; }
|
|
|
|
# Build stage, and the last stage: a plain `docker build .` names no target
|
|
# and so builds this one. Nothing is wanted from the two phases above; the
|
|
# copies are what make BuildKit build them first, so this image cannot be
|
|
# produced unless lint and test passed. A stage appended after this one
|
|
# would drop all three out of a plain build.
|
|
#
|
|
# node 22.22.0 on Alpine 3.23.3 (node:22-alpine), 2026-08-09
|
|
FROM node@sha256:e4bf2a82ad0a4037d28035ae71529873c069b13eb0455466ae0bc13363826e34
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=lint /app/package.json /dev/null
|
|
COPY --from=test /app/package.json /dev/null
|
|
|
|
COPY script/ script/
|
|
COPY package.json yarn.lock ./
|
|
RUN script/bootstrap
|
|
|
|
COPY . .
|
|
|
|
# Version stamped into the build: the VERSION build arg when one is given,
|
|
# otherwise what script/version derives from the .git the build context
|
|
# carries (script/bootstrap installed git), so any `docker build .` of a
|
|
# clone stamps its commit. The label can only carry the build arg, and is
|
|
# empty without one.
|
|
ARG VERSION
|
|
LABEL org.opencontainers.image.version="${VERSION}"
|
|
|
|
RUN make build
|