Install ESLint and prettier with yarn 4 through corepack (closes #493)
check / check (push) Waiting to run

The `js-deps` stage installed ESLint and prettier with yarn 1, which is no longer developed and made node print a `url.parse()` deprecation warning on every install. `package.json` now pins yarn 4 by version and hash in its `packageManager` field; the stage enables it through the node image's own corepack and installs with `yarn install --immutable`. `yarn.lock` is regenerated in yarn 4's format with every package at its previously locked version, and `.yarnrc.yml` keeps the install in `node_modules/`, where the lint and Markdown stages run the tools from. The install prints no warning and stays cached until the manifests change.

Model: opus-5-5
This commit was merged in pull request #496.
This commit is contained in:
2026-10-03 07:03:31 +02:00
parent 9ccaa8ce01
commit fe5e0d4173
5 changed files with 638 additions and 433 deletions
+3
View File
@@ -0,0 +1,3 @@
# Install into node_modules/: the Dockerfile's lint and Markdown stages run
# ESLint and prettier from node_modules/.bin.
nodeLinker: node-modules
+12 -7
View File
@@ -67,15 +67,20 @@ RUN sed 's/}/}\n/g' static/css/tailwind.css > /tmp/committed.css \
# JavaScript lint stages: ESLint, at the version package.json and yarn.lock
# pin, checks static/js/ against eslint.config.mjs. js-deps installs it, and
# prettier for the Markdown stages below, and stays cached until those two
# files change. script/lint forces only js-lint to re-run, and the build stage
# below runs it too. COPY . . brings in the CI cache barrier described in the
# lint stage above.
# node:24.21.0-alpine (LTS, with yarn 1.22.22), 2026-09-18
# prettier for the Markdown stages below, and stays cached until package.json,
# yarn.lock or .yarnrc.yml changes. script/lint forces only js-lint to re-run,
# and the build stage below runs it too. COPY . . brings in the CI cache
# barrier described in the lint stage above.
#
# The image's own corepack runs the yarn that package.json's packageManager
# field names, yarn 4.18.1 (released 2026-09-24), and checks it against the
# hash there. The image also ships yarn 1, which `corepack enable yarn`
# replaces.
# node:24.21.0-alpine (LTS), 2026-09-18
FROM node:24.21.0-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1 AS js-deps
WORKDIR /src
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --ignore-scripts
COPY package.json yarn.lock .yarnrc.yml ./
RUN corepack enable yarn && yarn install --immutable --mode=skip-build
FROM js-deps AS js-lint
COPY . .
+16 -10
View File
@@ -3064,7 +3064,8 @@ webhooker/
├── Dockerfile.browser # Browser test image built by script/test-browser
├── Makefile # 13 of 19 targets shim script/; 6 are inline
├── go.mod / go.sum
├── package.json / yarn.lock # ESLint and prettier, pinned, for the JavaScript lint and Markdown stages
├── package.json / yarn.lock # ESLint, prettier and yarn, pinned, for the JavaScript lint and Markdown stages
├── .yarnrc.yml # yarn settings: install into node_modules/
├── eslint.config.mjs # ESLint configuration for static/js/
├── .prettierrc # prettier settings for the Markdown
└── .golangci.yml # golangci-lint configuration
@@ -3352,13 +3353,17 @@ ESLint never runs on the host either. It lints `static/js/` (not the extracted
Alpine.js) in the Dockerfile's `js-lint` stage, which `script/lint` builds after
`Dockerfile.lint` and the image build runs before the builder stage. Its version
is pinned in `package.json` and every package's hash in `yarn.lock`. The
`js-deps` stage before it installs ESLint and stays cached until either file
changes, so only the lint step re-runs and ESLint is not downloaded again.
`eslint.config.mjs` turns on the rules of the JavaScript styleguide
`REPO_POLICIES.md` links to that a linter can check: `no-var` and
`prefer-const`. ESLint prints nothing on a pass, so `script/lint` has no summary
line to look for; it names the stage once for both `--target` and
`--no-cache-filter`, and `--target` fails on a name that matches no stage.
`js-deps` stage before it installs ESLint with `yarn install --immutable`, which
fails rather than change `yarn.lock`. The yarn it runs is the one the
`packageManager` field in `package.json` pins by version and hash, which the
node image's own corepack fetches and checks. The stage stays cached until
`package.json`, `yarn.lock` or `.yarnrc.yml` changes, so only the lint step
re-runs and ESLint is not downloaded again. `eslint.config.mjs` turns on the
rules of the JavaScript styleguide `REPO_POLICIES.md` links to that a linter can
check: `no-var` and `prefer-const`. ESLint prints nothing on a pass, so
`script/lint` has no summary line to look for; it names the stage once for both
`--target` and `--no-cache-filter`, and `--target` fails on a name that matches
no stage.
prettier formats the Markdown, and it never runs on the host either. It is
pinned in `package.json` and `yarn.lock` beside ESLint, installed by the same
@@ -3384,8 +3389,9 @@ independently of the compiler's:
`@source` lines name. `css-check` fails when the committed file differs from
the generated one, and `make css` writes the generated file out from
`css-output` (see [Stylesheet](#stylesheet)).
3. **JavaScript lint stages** (`node:24.21.0-alpine`, with yarn) — `js-deps`
installs ESLint and prettier from `yarn.lock` and `js-lint` runs ESLint over
3. **JavaScript lint stages** (`node:24.21.0-alpine`, with the yarn
`package.json` pins, run through the image's corepack) — `js-deps` installs
ESLint and prettier from `yarn.lock` and `js-lint` runs ESLint over
`static/js/` (see [Linting](#linting)).
4. **Markdown stages** (on `js-deps`) — `markdown-check` runs prettier over the
Markdown and fails on any file it would change, and `make fmt` writes the
+2 -1
View File
@@ -3,5 +3,6 @@
"devDependencies": {
"eslint": "10.11.0",
"prettier": "3.9.9"
}
},
"packageManager": "yarn@4.18.1+sha512.b2e1e7524f654f2749d32b4ebcb4622473cb5bcbc485df2007e12a154e50162a4d795526768bc5f5b8f81717bfd79deb2472813d86fb5ae2eb551fa9c872b08f"
}
+605 -415
View File
File diff suppressed because it is too large Load Diff