Skip to content

feat(tooling): upgrade ESLint 9 → 10 with flat config migration#171

Merged
scottschreckengaust merged 10 commits into
mainfrom
feat/eslint-10-upgrade
May 26, 2026
Merged

feat(tooling): upgrade ESLint 9 → 10 with flat config migration#171
scottschreckengaust merged 10 commits into
mainfrom
feat/eslint-10-upgrade

Conversation

@scottschreckengaust
Copy link
Copy Markdown
Contributor

@scottschreckengaust scottschreckengaust commented May 22, 2026

Summary

Closes #169

Upgrades ESLint from v9 (legacy .eslintrc.json with ESLINT_USE_FLAT_CONFIG=false) to v10 (flat config only). Migrates both cdk/ and cli/ configurations to eslint.config.mjs format.

Changes

Commit What
Package upgrades eslint ^10, @cdklabs/eslint-plugin ^2, eslint-plugin-import-x ^4 (replaces eslint-plugin-import)
CDK flat config .eslintrc.json → eslint.config.mjs, all rules preserved
CLI flat config Same migration, no-console override preserved for src/
Resolver fix Restore eslint-import-resolver-typescript (required by import-x for TS path resolution)

Key decisions

  • eslint-plugin-import → eslint-plugin-import-x: Drop-in replacement with ESLint 10 support. Rule prefix changes from import/ to import-x/. The original plugin has no ESLint 10 support.
  • @cdklabs/eslint-plugin v1 → v2: Required for ESLint 10 peer dependency.
  • 4 @cdklabs rules disabled (chore(eslint): re-enable @cdklabs rules after plugin fixes deprecated context.getFilename() #170): Plugin v2.0.6 uses removed context.getFilename() API. Re-enable when upstream fixes.
  • eslint-import-resolver-typescript kept: Still required by import-x v4 for TypeScript path resolution (it does NOT bundle TS resolution natively).

Removals and why

Removed Reason
.eslintrc.json (cdk/, cli/) ESLint 10 removed legacy config format entirely — flat config is the only option
--ext .ts,.tsx flag in lint scripts Flat config uses files: [...] patterns instead; --ext is removed in ESLint 10
ESLINT_USE_FLAT_CONFIG=false env var Flat config is the only format in ESLint 10; no toggle exists
eslint-plugin-import package Replaced by eslint-plugin-import-x (no ESLint 10 support in original)
eslint-plugin-import/minimatch resolution (root package.json) The resolution forced a patched minimatch for a ReDoS CVE in eslint-plugin-import's transitive deps. Since the plugin is removed, the transitive dep no longer exists
"extends": ["plugin:import/typescript"] Flat config doesn't support extends; equivalent settings are inline in the config

Stale suppression comments removed (auto-fix)

ESLint's --fix removes suppression comments that target rules no longer active. These were cleaned up:

Suppression Why removed Count
@cdklabs/no-literal-partition Rule is now off (disabled due to upstream bug) — suppression is redundant 3
no-constant-condition Rule deprecated in ESLint 10 (removed from recommended set) 3
@cdklabs/promiseall-no-unbounded-parallelism Rule is active but the suppressed lines no longer violate it after config migration 2
@typescript-eslint/no-explicit-any Rule is not enabled in our config (never was — these were cargo-cult suppressions) 7
@typescript-eslint/no-unused-vars Rule is not enabled in our config 1
@typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports The no-require-imports rule is active but the suppressed line was in test code that no longer triggers it 1

Total: 17 stale suppression comments removed. No behavioral changes — these suppressions were already no-ops.

What's NOT in this PR (follow-on PRs per #169)

  1. Remove redundant defaultsecmaVersion: 2018 (ESLint 10 defaults to "latest"), sourceType: 'module' (also default)
  2. Deduplicate core ↔ @Stylistic overlap — Some formatting rules appear in both; core versions are deprecated in favor of @Stylistic
  3. Enable new ESLint 10 recommended rulesno-unassigned-vars, no-useless-assignment, preserve-caught-error
  4. Re-enable @cdklabs rules (chore(eslint): re-enable @cdklabs rules after plugin fixes deprecated context.getFilename() #170) — When upstream publishes fix for removed context.getFilename() API
  5. Split @cdklabs rule section — Separate "disabled (awaiting upstream)" from "active" for clarity

Test plan

  • mise //cdk:eslint passes (zero errors)
  • mise //cli:eslint passes (zero errors)
  • Pre-commit hooks pass for both packages
  • CI build passes (includes eslint in the build chain)
  • TypeScript compilation clean (tsc --noEmit)

References: #169 (implementation issue + follow-on list), #170 (@cdklabs upstream blocker), #104 (toolchain monitoring RFC)

🤖 Generated with Claude Code

scottschreckengaust and others added 4 commits May 22, 2026 20:28
- eslint ^9 -> ^10 (10.4.0)
- @cdklabs/eslint-plugin ^1 -> ^2 (flat config support)
- eslint-plugin-import removed (no ESLint 10 support)
- eslint-plugin-import-x ^4 added (drop-in replacement)
- eslint-import-resolver-typescript removed (import-x has built-in TS resolution)
- Root resolution for eslint-plugin-import/minimatch removed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert .eslintrc.json to eslint.config.mjs (ESM flat config format).
Replace import/ rule prefix with import-x/. Remove --ext flag and
ESLINT_USE_FLAT_CONFIG env var from the eslint script.

All existing rules preserved with equivalent flat config syntax.
Four @cdklabs rules (no-core-construct, invalid-cfn-imports,
no-literal-partition, no-invalid-path) are temporarily disabled
because they use context.getFilename() which was removed in ESLint 10.
Stale eslint-disable comments for disabled/absent rules removed by
auto-fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert .eslintrc.json to eslint.config.mjs. Replace import/ rule
prefix with import-x/. Remove --ext flag and ESLINT_USE_FLAT_CONFIG.
All existing rules preserved including no-console override for src/.
Removed stale no-constant-condition disable comments (rule deprecated
in ESLint 10).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The resolver is required by eslint-plugin-import-x for TypeScript path
resolution. Was incorrectly removed in the package upgrade commit.
Also disable license-header rule for shebang bin files (workaround).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread cdk/eslint.config.mjs
Comment thread cdk/eslint.config.mjs
Comment thread cdk/eslint.config.mjs
@krokoko
Copy link
Copy Markdown
Contributor

krokoko commented May 26, 2026

After merging main, one build step is failing -> https://github.com/aws-samples/sample-autonomous-cloud-coding-agents/actions/runs/26470546246/job/77942514576?pr=171
Just need to re-run build locally and push any modified files that are missing
Besides that good to go!

ESLint --fix removes no-op suppression comments for rules not enabled
in our config. These were introduced by the attachments PR (#176) merge
and are cleaned up by the new ESLint 10 flat config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@scottschreckengaust scottschreckengaust added this pull request to the merge queue May 26, 2026
Merged via the queue into main with commit cdf109b May 26, 2026
6 checks passed
@scottschreckengaust scottschreckengaust deleted the feat/eslint-10-upgrade branch May 26, 2026 23:30
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.

feat(tooling): upgrade ESLint 9 → 10 with flat config migration

2 participants