Skip to content

feat(plugins): bump eslint to 10, oxlint to 1.x, and prisma to 7 - #2825

Merged
marschattha merged 3 commits into
mainfrom
ma/bump-node-runtime-22
Jul 28, 2026
Merged

feat(plugins): bump eslint to 10, oxlint to 1.x, and prisma to 7#2825
marschattha merged 3 commits into
mainfrom
ma/bump-node-runtime-22

Conversation

@marschattha

@marschattha marschattha commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

Promotes the three plugins unblocked by the node 22 runtime bump that need no code changes. The runtime bump itself landed separately in #2827 (closing #2814), so this PR is now plugin promotions only.

npm silently skips optional dependencies (including native bindings) whose engines exclude the running node, and some tools crash outright — node 21 was excluded by current eslint, knip, oxlint, and prisma engine ranges. The knip 6 bump requires a parser change and follows in a separate stacked PR (#2826).

Updates

Plugin Previous New Published Age Notes
eslint 9.39.4 10.5.0 2026-06-12 39d fixture config no longer imports @eslint/js (not bundled in eslint 10)
oxc 0.11.1 1.70.0 2026-06-15 36d uses the pre-existing version-gated >=1.0.0 driver block
prisma 6.15.0 7.8.0 2026-04-22 90d new basic_7 fixture — prisma 7 forbids datasource url, prisma 5/6 require it

Stability policy

All promoted versions have been published for at least 30 days and checked against GitHub Security Advisories (repo-level and the npm ecosystem database). No unwithdrawn advisories affect any promoted version. Newer releases (eslint 10.7.0, oxlint 1.74.0, prisma 7.9.0) were rejected by the 30-day gate; latest_version fields record them.

Test results

  • Plain-mode jest for touched linters (every fixture at every snapshot version, old and new): all passed
  • eslint's rewritten basic_9 fixture config verified against the existing 9.6.0 / 9.7.0 / 9.39.4 snapshots
  • oxc's new snapshot records proper rule keys (eslint(no-cond-assign)) where 0.11.1's output format offered none
  • cargo test: 1087 passed, 0 failed

Test plan

  • All linter tests pass in CI (including windows-2022)
  • No security advisories affect updated versions

🤖 Generated with Claude Code

@qltysh

qltysh Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Qlty


Coverage Impact - macos-15

This PR will not change total coverage.

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@qltysh

qltysh Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Qlty


Coverage Impact - ubuntu-latest

This PR will not change total coverage.

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Qlty’s managed Node runtime to the current Node 22 LTS line and promotes several Node-based linter plugins whose newer versions were previously blocked by Node 21’s engine incompatibilities.

Changes:

  • Bump managed Node runtime default from 21.7.3 to 22.23.1.
  • Promote eslint, oxc (oxlint), and prisma to newer known_good_versions.
  • Add/update fixtures and Jest snapshots to cover the promoted plugin versions (including Prisma 7 fixture differences and new oxlint 1.x rule keys).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
qlty-check/src/tool/tool_builder.rs Updates the default managed Node runtime version used by runtime-backed plugins.
qlty-plugins/plugins/linters/eslint/plugin.toml Promotes eslint to known_good_version = 10.5.0.
qlty-plugins/plugins/linters/eslint/fixtures/basic_9.in/eslint.config.mjs Adjusts the eslint v10 fixture config (removes @eslint/js usage, sets explicit rules).
qlty-plugins/plugins/linters/eslint/fixtures/snapshots/basic_9_v10.5.0.shot Adds snapshot for eslint 10.5.0 expectations.
qlty-plugins/plugins/linters/oxc/plugin.toml Promotes oxlint to known_good_version = 1.70.0.
qlty-plugins/plugins/linters/oxc/fixtures/snapshots/basic_v1.70.0.shot Adds snapshot for oxlint 1.70.0 output (notably ruleKey values).
qlty-plugins/plugins/linters/prisma/plugin.toml Promotes prisma to known_good_version = 7.8.0 and updates latest_version.
qlty-plugins/plugins/linters/prisma/fixtures/basic_7.in.prisma Adds a Prisma 7-specific fixture input.
qlty-plugins/plugins/linters/prisma/fixtures/snapshots/basic_7_v7.8.0.shot Adds snapshot for prisma 7.8.0 fixture expectations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread qlty-plugins/plugins/linters/oxc/plugin.toml
@marschattha
marschattha marked this pull request as ready for review July 21, 2026 23:04
@marschattha
marschattha requested a review from noahd1 July 21, 2026 23:05
marschattha added a commit that referenced this pull request Jul 22, 2026
## Summary

Bumps the managed Node runtime from 21.7.3 (odd-numbered, EOL, non-LTS)
to 22.23.1 (latest 22 LTS "Jod"). Closes #2814.

Node 21 is a short-lived non-LTS line that the npm ecosystem
deliberately excludes: engine ranges target even LTS lines (`^20.19 ||
^22.12 || >=24`), and npm silently skips optional dependencies —
including native bindings — whose `engines` exclude the running node.
This blocked eslint 10, knip 6, oxlint 1.x, and prisma 7.

The download URLs in `qlty-check/src/tool/node.rs` are
version-templated, so this is a one-line change. The plugin promotions
this unblocks follow in stacked PRs: #2825 (eslint, oxc, prisma) and
#2826 (knip, which also needs a parser change).

## Test results

- Full node-linter jest matrix on node 22.23.1: 11/11 suites, 24 tests,
24 snapshots passed — every fixture at every historical snapshot version
(back to eslint 8.10.0, prettier 2.6.2) runs unmodified on the new
runtime
- `cargo test`: 1087 passed, 0 failed

## Test plan

- [ ] All linter tests pass in CI (including windows-2022)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
marschattha and others added 3 commits July 28, 2026 02:57
eslint 10 no longer bundles @eslint/js, so the basic_9 fixture config
now enables the three exercised rules directly instead of extending
js.configs.recommended. The config works unchanged across eslint 9
and 10, keeping all historical snapshots valid.

10.5.0 is the newest release passing the 30-day stability gate
(published 2026-06-12) with no known security advisories.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Uses the version-gated >=1.0.0 driver block added previously for the
oxlint 1.x --format github output change. The new snapshot records
proper rule keys (e.g. eslint(no-cond-assign)) where the 0.11.1
format offered none.

1.70.0 is the newest release passing the 30-day stability gate
(published 2026-06-15) with no known security advisories.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
prisma 7 no longer allows a url property in schema-file datasource
blocks, while prisma 5/6 require it, so a separate basic_7 fixture
covers 7.x and the original fixture keeps covering the 5.x snapshots.

7.8.0 is the newest release passing the 30-day stability gate
(published 2026-04-22) with no known security advisories.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 27, 2026 22:00
@marschattha
marschattha force-pushed the ma/bump-node-runtime-22 branch from 1c1ebd3 to f631774 Compare July 27, 2026 22:00

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

@marschattha marschattha changed the title feat(check): bump managed node runtime to 22.23.1 LTS and unblock eslint 10, oxlint 1.x, prisma 7 feat(plugins): bump eslint to 10, oxlint to 1.x, and prisma to 7 Jul 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comment thread qlty-plugins/plugins/linters/prisma/plugin.toml
Comment thread qlty-plugins/plugins/linters/oxc/plugin.toml
@marschattha
marschattha merged commit 069b757 into main Jul 28, 2026
20 checks passed
@marschattha
marschattha deleted the ma/bump-node-runtime-22 branch July 28, 2026 20:15
@qlty-releases qlty-releases Bot mentioned this pull request Aug 3, 2026
marschattha pushed a commit that referenced this pull request Aug 3, 2026
Automated PR for release 0.641.0.

Review (and edit, if needed) the changelog entry below, then
merge this pull request to publish the release.

## Draft release notes


### Improved

- Bump the eslint, oxlint, and prisma plugins to eslint 10, oxlint 1.x,
and prisma 7 (#2825)

### Fixed

- Switch Biome >= 2.4 to the stable `rdjson` reporter, restoring lint
results that were dropped when Biome 2.4 changed its unstable `json`
reporter output (#2821)

Co-authored-by: qlty-releases[bot] <181762136+qlty-releases[bot]@users.noreply.github.com>
marschattha added a commit that referenced this pull request Aug 26, 2026
Routine bumps within the majors landed by #2825, each published at least
30 days ago with no advisories:

- eslint 10.5.0 -> 10.8.0
- oxlint 1.70.0 -> 1.76.0
- prisma 7.8.0 -> 7.9.1

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
marschattha added a commit that referenced this pull request Aug 28, 2026
## Summary

Update linter plugin versions with stability and security vetting.
Covers the
gaps the weekly `updateLinterVersions.ts` script leaves behind.

After this PR, **knip is the only linter with `latest_version` ahead of
`known_good_version`** (blocked on #2826), and every script-unreachable
linter
is either current or has a filed reason below.

## Updates

| Linter | Previous | New | Published | Age | Notes |
|--------|----------|-----|-----------|-----|-------|
| redocly | 2.32.2 | **2.41.0** | 2026-07-27 | 30d | ⚠️ security — see
below |
| shfmt | 3.8.0 | **3.13.1** | 2026-04-06 | 142d | ⚠️ also fixes a
silent-pass bug — see below |
| checkstyle | 13.5.0 | 13.9.0 | 2026-07-27 | 30d | |
| pmd | 7.25.0 | 7.26.0 | 2026-06-29 | 58d | |
| trufflehog | 3.95.5 | 3.96.0 | 2026-07-24 | 33d | security-sensitive
linter |
| swiftformat | 0.61.1 | 0.62.1 | 2026-07-07 | 50d | custom-download |
| swiftlint | 0.63.3 | 0.65.0 | 2026-06-27 | 60d | custom-download |
| terraform | 1.15.6 | 1.15.8 | 2026-07-08 | 49d | custom-download |
| eslint | 10.5.0 | 10.8.0 | 2026-07-24 | 33d | within the major from
#2825 |
| oxc (oxlint) | 1.70.0 | 1.76.0 | 2026-07-27 | 30d | within the major
from #2825 |
| prisma | 7.8.0 | 7.9.1 | 2026-07-27 | 30d | within the major from
#2825 |

## Security

**redocly 2.32.2 was vulnerable.** The pinned version falls inside the
range of
two advisories published 2026-07-27:

- **CVE-2026-63325** (high) — arbitrary code execution via Arazzo
`$faker`
  expression using `respect`; patched in 2.33.0.
- **CVE-2026-63225** (medium) — path traversal in the `split` command;
patched
  in 2.33.2.

2.41.0 clears both.

All other candidates were checked against
`/repos/{owner}/{repo}/security-advisories`
and the GitHub Advisory Database, filtering withdrawn advisories. The
only hits
were against versions far older than both current and target (checkstyle
< 8.29,
pmd <= 7.21.0, trufflehog < 3.81.9, terraform < 0.12.17, prisma <
2.20.0).

**trufflehog** is a security-sensitive linter (secret detection,
elevated
trust). Beyond the advisory check, its 3.96.0 release assets were
verified for
expected content types and its release notes reviewed — nothing
suspicious.

## shfmt was reporting unparseable files as clean

The version bump surfaced a live correctness bug, fixed here.

The format driver declared `success_codes = [0, 1]`, but with `-w` shfmt
exits
0 whether or not it rewrites the file — **exit 1 means only a parse or
I/O
error**. Accepting 1 as success meant any shell file shfmt could not
parse
produced no rewrite, no error, and zero issues. Verified across both
versions:

| input | shfmt 3.8.0 | shfmt 3.13.1 |
|-------|-------------|--------------|
| unterminated quote | 1 | 1 |
| unfinished `case` | 1 | 1 |
| unclosed `{` | 1 | 1 |
| `if true; then` / `fi` (empty body) | 0 | 1 |
| valid but misformatted | 0 | 0 |

The exit-code contract is identical across versions, so this is **not**
version-gated — 3.8.0 silently passes an unterminated quote today, and
gating
would preserve that for anyone pinning an old shfmt. shfmt 3.9 only made
the
parser stricter (an `if` with an empty body is now correctly rejected),
which is
what exposed the bug: the old fixture was invalid shell, so 3.13.1
refused it,
the rewrite never ran, and the test went green with zero findings.

The fixture now has a body, so old and new shfmt both parse it and both
still
find it misformatted. Its snapshot is unchanged — `output = "rewrite"`
records
only a generic formatting issue, not file contents. An invalid fixture
cannot be
kept as coverage once exit 1 is honored, since the harness asserts
`success: true` per fixture.

**Behavior change:** shell files that cannot be parsed now surface a
plugin
error instead of silently reporting clean.

Worth a follow-up audit: biome, ktlint, markdownlint, rubocop,
ruby-stree, and
standardrb also declare `[0, 1]` on rewrite-mode drivers. For several of
them
exit 1 legitimately means "issues found" and the config is correct — but
each
should be checked against its tool's actual contract.

## Coverage of script-unreachable linters

The script can only update a linter that declares `releases` or a
`runtime` in
{java, php, ruby, python, node}; anything else hits its `Unknown
runtime` throw.
Because it also cannot write their `latest_version`, these linters never
appear
in the usual "latest != known_good" gap scan either. Full enumeration:

| Linter | Why unreachable | Disposition |
|--------|-----------------|-------------|
| kube-linter | no releases, no runtime | already latest (0.8.3) |
| stringslint | no releases, no runtime | already latest (0.1.10) |
| swiftformat, swiftlint, terraform | no releases, no runtime |
**updated here** |
| shfmt | runtime `go` | **updated here** |
| clippy, rustfmt | runtime `rust` | see below |
| gofmt | runtime `go` | see below |
| hadolint | skip-list | too new (2.15.1 is 26d) |
| tsc | skip-list | no version fields (`hidden = true`) |

**clippy, rustfmt, and gofmt are runtime-coupled, not ordinary
plugins.**
`gofmt` 1.22.0 *is* the managed Go pin (`tool_builder.rs:148`), and
clippy/rustfmt track the Rust toolchain (pinned 1.77.2). Upstream is far
ahead
— Rust 1.98.0, Go 1.27.0 — but bumping them means moving the managed
runtimes,
the same class of work as the node 21→22 bump in #2814/#2825, with much
wider
blast radius. Deliberately out of scope here; worth its own issue.

## Stability policy

Every version here has been published for at least 30 days, no
overrides.
Newer releases rejected by the gate, to pick up next run: redocly
2.48.0,
checkstyle 14.0.0, eslint 10.9.1, oxlint 1.80.0, prisma 7.10.0,
swiftlint 0.65.1, terraform 1.15.9, hadolint 2.15.1 (26d).

Node linters were pre-checked with `npm view {pkg}@{ver} engines`
against the
managed runtime (22.23.1) — all satisfied.

## Also noticed

- The stale comments in `knip/plugin.toml` and `oxc/plugin.toml` still
blame
node 21.7.3. knip's real blocker is #2826; oxc's is simply obsolete.
Left
  untouched here.
- **#2813 (biome parser) looks closeable** — #2821 landed an rdjson
reporter and
  biome is already at 2.5.6 on main.

## Test results

All 11 updated linters pass in **plain mode**, which runs every fixture
at every
historical snapshot version — what CI effectively exercises. Each target
was
additionally run in compare-latest-snapshot mode. Apart from shfmt,
output was
byte-identical everywhere, so no snapshot changes were needed. Snapshots
were
inspected for non-zero findings to rule out vacuous passes (this is what
caught
shfmt).

Two fixtures fail *in compare mode only* — eslint `basic_8` (eslintrc,
ESLint 8
only) and prisma `basic` (prisma 5 schema). Compare mode forces the
target
version onto every fixture regardless of what it supports. Both were
confirmed
to fail identically at the **current** promoted versions (10.5.0 /
7.8.0), so
this is pre-existing harness behaviour, not a regression.

Custom-download URL templates were HEAD-checked at the target version
across
every platform variant (all 200) — no asset-name drift this round.

## Test plan

- [ ] All linter tests pass in CI
- [x] Download URLs verified for custom-download linters (all platforms,
200)
- [x] No security advisories affect updated versions
- [x] Node engines checked against the managed runtime
- [x] Every script-unreachable linter enumerated and dispositioned
- [ ] Watch the windows-2022 job specifically — local runs only cover
macOS

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants