Skip to content

Upgrade ESLint to 9.39.4 and update configurations across descriptors - #7780

Merged
nvuillam merged 18 commits into
oxsecurity:mainfrom
opravil-jan:feat/eslint-9-upgrade
May 15, 2026
Merged

Upgrade ESLint to 9.39.4 and update configurations across descriptors#7780
nvuillam merged 18 commits into
oxsecurity:mainfrom
opravil-jan:feat/eslint-9-upgrade

Conversation

@opravil-jan

Copy link
Copy Markdown
Contributor

Proposed Changes

  1. ESLint upgraded 8.57.19.39.4 in JAVASCRIPT_ES, TYPESCRIPT_ES, JSX_ESLINT, TSX_ESLINT, and JSON_ESLINT_PLUGIN_JSONC. Added @eslint/eslintrc@3.3.5 to bridge legacy .eslintrc.* configs via FlatCompat. Detects eslint.config.{js,mjs,cjs,ts} first in active_only_if_file_found, with legacy .eslintrc.* filenames preserved for fallback. Removed the --no-eslintrc and --ignore-path CLI
    flags (deleted in ESLint 9) from both descriptors and EslintLinter.build_lint_command.
  2. Replaced abandoned configs with v9-compatible successors: eslint-config-airbnb@19.0.4eslint-config-airbnb-extended@3.1.0, eslint-config-standard@17.1.0neostandard@0.13.0. Neither original package ever shipped ESLint 9 support; the successors are the community-maintained continuations. End-users extending the legacy names must rename extends: ["airbnb"]extends: ["airbnb-extended"] and
    extends: ["standard"]extends: ["neostandard"].
  3. Plugin bumps required for v9: eslint-plugin-n 16.6.218.0.1, eslint-plugin-promise 6.6.07.3.0.
  4. Fixes latent peer-dep conflict in JSON_ESLINT_PLUGIN_JSONC: eslint-plugin-jsonc@3.1.2 declares peer eslint>=9.38.0 while the image shipped eslint@8.57.1. The upgrade resolves the mismatch; the linter itself remains default-disabled per the existing disabled_reason (upstream eslint-plugin-jsonc issue Build errors: Python invocation, YAML version #328).
  5. Test fixtures migrated to flat config (.automation/test/{javascript,typescript,tsx}/eslint.config.js) using @eslint/eslintrc's FlatCompat bridge to the existing .eslintrc.json files — exercises the same backward-compat code path end-users will rely on, while keeping the legacy fixtures intact. Required passing recommendedConfig/allConfig from @eslint/js (transitive dep of eslint@9, available via
    NODE_PATH=/node-deps/node_modules).

All four affected linters tested locally with TEST_KEYWORDS=<linter>_test: 6 passed / 1 skipped per linter (javascript_es, typescript_es, jsx_eslint, tsx_eslint). json_eslint_plugin_jsonc image smoke-builds clean (linter remains default-disabled).

Readiness Checklist

Author/Contributor

  • Add entry to the CHANGELOG listing the change and linking to the corresponding issue (if appropriate)
  • If documentation is needed for this change, has that been included in this pull request

Reviewing Maintainer

  • Label as breaking if this is a large fundamental change
  • Label as either automation, bug, documentation, enhancement, infrastructure, or performance

Bumps ESLint from 8.57.1 (EOL) to 9.39.4 (maintenance LTS).
Swaps unmaintained eslint-config-airbnb for eslint-config-airbnb-extended
3.1.0 and eslint-config-standard for neostandard 0.13.0 (both are the
community-blessed v9-compatible successors). Removes the --no-eslintrc
and --ignore-path flags that v9 deleted. Adds @eslint/eslintrc 3.3.5 to
bridge legacy .eslintrc.* configs via FlatCompat.

BREAKING CHANGE: end-users extending 'airbnb' must rename to
'airbnb-extended'; end-users extending 'standard' must rename to
'neostandard'.
Mirrors the javascript descriptor changes from the previous commit:
ESLint 8.57.1 -> 9.39.4, airbnb -> airbnb-extended 3.1.0,
standard -> neostandard 0.13.0, eslint-plugin-n -> 18.0.1,
eslint-plugin-promise -> 7.3.0. Keeps the TypeScript-specific
plugins (@typescript-eslint/*, prettier, prettyjson) intact.
Bumps ESLint 8.57.1 -> 9.39.4 and adds @eslint/eslintrc 3.3.5 for
FlatCompat. Removes leftover .eslintignore / --ignore-path knobs
that no longer exist in ESLint 9. JSX descriptor has no airbnb or
standard configs to swap, so the dependency list is otherwise
unchanged.
Mirrors the pattern from javascript, typescript, and jsx descriptors:
ESLint 8.57.1 -> 9.39.4, airbnb -> airbnb-extended 3.1.0, adds
@eslint/eslintrc 3.3.5 FlatCompat bridge. Removes --no-eslintrc,
--ignore-path, and ignore_file_name. Keeps TSX-specific packages
(typescript, @typescript-eslint/*, prettier, prettyjson) intact.
…bug)

Fixes a latent peer-dep mismatch: eslint-plugin-jsonc@3.1.2 declares
peer eslint>=9.38.0 but the image shipped eslint@8.57.1. Bumping
ESLint to 9.39.4 resolves the mismatch and adds @eslint/eslintrc 3.3.5
for FlatCompat. Removes --no-eslintrc and --ignore-path knobs deleted
by ESLint 9. The linter itself remains disabled by default per the
existing disabled_reason (upstream eslint-plugin-jsonc issue oxsecurity#328).
ESLint 9 removed --no-eslintrc and --ignore-path. Strip --no-eslintrc
defensively if it leaks in from upstream cli_config_extra_args or
end-user MEGALINTER variables that target the v8 CLI. Keeps the
existing --ignore-path branch harmless for forward compatibility.
ESLint 9 uses flat config by default. The js and ts fixtures keep
their existing .eslintrc.json files and add an eslint.config.js that
bridges to them via @eslint/eslintrc's FlatCompat shim, exercising
the same backward-compat path end-users will rely on. The tsx fixture
gains a minimal flat config from scratch (react + @typescript-eslint
recommended).
Replaces the from-scratch flat config for the tsx test fixture with a
FlatCompat bridge to its existing .eslintrc.json, matching the
javascript and typescript fixtures. Keeps the rule set identical
across the v8/v9 transition and exercises the same backward-compat
path end-users will rely on.
@eslint/eslintrc v3 FlatCompat does not bundle the eslint:recommended
config (to avoid a circular dependency on eslint). Pass it explicitly
via recommendedConfig/allConfig from @eslint/js, which is a transitive
dep of eslint@9 and available at NODE_PATH=/node-deps/node_modules.

Without this, all three fixtures (js/ts/tsx) crash with
'TypeError: Missing parameter recommendedConfig' when their
.eslintrc.json extends eslint:recommended.
@nvuillam

nvuillam commented May 14, 2026

Copy link
Copy Markdown
Member

@opravil-jan if it works (CI will tell ^^), that would be the best "first PR" ever on MegaLinter, thanks a lot :)

cc @bdovaz @echoix

ESLint 9 upgrade introduces neostandard@0.13.0 as the v9-compatible
successor to eslint-config-standard. cspell's repository scan flags
the word as unknown in 5 files (descriptors, Dockerfiles, root
Dockerfile).
@opravil-jan

Copy link
Copy Markdown
Contributor Author

Shoul I fix the problem with go version also?

@nvuillam

Copy link
Copy Markdown
Member

@opravil-jan i solved it in another PR, it won't be blocking now :)

@nvuillam nvuillam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The last test class should pass after i update so i force-merge :)

Thanks a lot for your PR :)

@nvuillam
nvuillam merged commit e5c62ca into oxsecurity:main May 15, 2026
lumarel pushed a commit to lumarel/oxsecurity-megalinter that referenced this pull request May 18, 2026
…oxsecurity#7780)

* feat(eslint)!: bump ESLint to 9.39.4 in javascript descriptor

Bumps ESLint from 8.57.1 (EOL) to 9.39.4 (maintenance LTS).
Swaps unmaintained eslint-config-airbnb for eslint-config-airbnb-extended
3.1.0 and eslint-config-standard for neostandard 0.13.0 (both are the
community-blessed v9-compatible successors). Removes the --no-eslintrc
and --ignore-path flags that v9 deleted. Adds @eslint/eslintrc 3.3.5 to
bridge legacy .eslintrc.* configs via FlatCompat.

BREAKING CHANGE: end-users extending 'airbnb' must rename to
'airbnb-extended'; end-users extending 'standard' must rename to
'neostandard'.

* feat(eslint)!: bump ESLint to 9.39.4 in typescript descriptor

Mirrors the javascript descriptor changes from the previous commit:
ESLint 8.57.1 -> 9.39.4, airbnb -> airbnb-extended 3.1.0,
standard -> neostandard 0.13.0, eslint-plugin-n -> 18.0.1,
eslint-plugin-promise -> 7.3.0. Keeps the TypeScript-specific
plugins (@typescript-eslint/*, prettier, prettyjson) intact.

* feat(eslint)!: bump ESLint to 9.39.4 in jsx descriptor

Bumps ESLint 8.57.1 -> 9.39.4 and adds @eslint/eslintrc 3.3.5 for
FlatCompat. Removes leftover .eslintignore / --ignore-path knobs
that no longer exist in ESLint 9. JSX descriptor has no airbnb or
standard configs to swap, so the dependency list is otherwise
unchanged.

* feat(eslint)!: bump ESLint to 9.39.4 in tsx descriptor

Mirrors the pattern from javascript, typescript, and jsx descriptors:
ESLint 8.57.1 -> 9.39.4, airbnb -> airbnb-extended 3.1.0, adds
@eslint/eslintrc 3.3.5 FlatCompat bridge. Removes --no-eslintrc,
--ignore-path, and ignore_file_name. Keeps TSX-specific packages
(typescript, @typescript-eslint/*, prettier, prettyjson) intact.

* fix(eslint)!: bump ESLint to 9.39.4 in json descriptor (jsonc latent bug)

Fixes a latent peer-dep mismatch: eslint-plugin-jsonc@3.1.2 declares
peer eslint>=9.38.0 but the image shipped eslint@8.57.1. Bumping
ESLint to 9.39.4 resolves the mismatch and adds @eslint/eslintrc 3.3.5
for FlatCompat. Removes --no-eslintrc and --ignore-path knobs deleted
by ESLint 9. The linter itself remains disabled by default per the
existing disabled_reason (upstream eslint-plugin-jsonc issue oxsecurity#328).

* feat(eslint): strip removed v8 CLI flags in EslintLinter

ESLint 9 removed --no-eslintrc and --ignore-path. Strip --no-eslintrc
defensively if it leaks in from upstream cli_config_extra_args or
end-user MEGALINTER variables that target the v8 CLI. Keeps the
existing --ignore-path branch harmless for forward compatibility.

* test(eslint): add flat eslint.config.js to js/ts/tsx fixtures

ESLint 9 uses flat config by default. The js and ts fixtures keep
their existing .eslintrc.json files and add an eslint.config.js that
bridges to them via @eslint/eslintrc's FlatCompat shim, exercising
the same backward-compat path end-users will rely on. The tsx fixture
gains a minimal flat config from scratch (react + @typescript-eslint
recommended).

* test(eslint): use FlatCompat bridge for tsx fixture too

Replaces the from-scratch flat config for the tsx test fixture with a
FlatCompat bridge to its existing .eslintrc.json, matching the
javascript and typescript fixtures. Keeps the rule set identical
across the v8/v9 transition and exercises the same backward-compat
path end-users will rely on.

* chore: regenerate Dockerfiles and test classes for ESLint 9

* docs(changelog): note ESLint 9 upgrade and jsonc latent bug fix

* fix(eslint): provide recommendedConfig to FlatCompat in test fixtures

@eslint/eslintrc v3 FlatCompat does not bundle the eslint:recommended
config (to avoid a circular dependency on eslint). Pass it explicitly
via recommendedConfig/allConfig from @eslint/js, which is a transitive
dep of eslint@9 and available at NODE_PATH=/node-deps/node_modules.

Without this, all three fixtures (js/ts/tsx) crash with
'TypeError: Missing parameter recommendedConfig' when their
.eslintrc.json extends eslint:recommended.

* chore: regenerate auto-tracked changelog entries and helps/versions JSON

* chore(cspell): add 'neostandard' to dictionary

ESLint 9 upgrade introduces neostandard@0.13.0 as the v9-compatible
successor to eslint-config-standard. cspell's repository scan flags
the word as unknown in 5 files (descriptors, Dockerfiles, root
Dockerfile).

* Fix test case

* Last fix :)

---------

Co-authored-by: Nicolas Vuillamy <nicolas.vuillamy@gmail.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.

2 participants