Skip to content

refactor: migrate to shared eslint config#3661

Draft
eablack wants to merge 12 commits intomainfrom
eb/move-to-shared-eslint
Draft

refactor: migrate to shared eslint config#3661
eablack wants to merge 12 commits intomainfrom
eb/move-to-shared-eslint

Conversation

@eablack
Copy link
Copy Markdown
Contributor

@eablack eablack commented Apr 14, 2026

Summary

Migrates the project from ESLint 8 with legacy .eslintrc.cjs to ESLint 9 with flat config (eslint.config.js), adopting the shared eslint configuration from @heroku-cli/test-utils. This reduces duplication across Heroku CLI projects and ensures consistent linting rules.

This PR primarily focuses on:

  • ESLint 9 migration and shared config adoption
  • Migrating test helpers to use utilities from @heroku-cli/test-utils (runCommand, expectOutput, etc.)
  • Applying linting fixes across unit tests (test/unit directory)
  • Adding semi: ['warn', 'never'] rule to enforce no-semicolon style
  • Fixing ESLint getter-return conflicts with proper TypeScript patterns

Note: Test helper, fixture, acceptance, and integration test linting changes are being handled in a separate PR (#3671).

Key changes:

  • Removed legacy .eslintrc.cjs and .eslintignore files
  • Created new eslint.config.js using ESLint 9 flat config format
  • Added @heroku-cli/test-utils dependency for shared linting rules and test utilities
  • Removed redundant eslint plugin dependencies (now handled by shared config)
  • Updated test helpers to import from @heroku-cli/test-utils instead of local implementations
  • Applied linting fixes to ~300 unit test files
  • Updated minor source file linting issues (dyno.ts, members/add.ts, etc.)
  • Updated dependencies (chai 4→5, nock 13→14, typescript-eslint 8.57→8.58)

Type of Change

Patch Updates (patch semver update)

  • refactor: Refactoring existing code without changing behavior

Testing

Notes:

  • All existing tests should pass with the new linting configuration
  • Linting rules are now consistent with other Heroku CLI projects
  • No functional changes - only formatting, linting, and test helper migration

Steps:

  1. Run npm run lint to verify all linting rules pass
  2. Run npm test to ensure all tests pass
  3. Verify CI checks pass (Passing CI suffices)

@eablack eablack requested a review from a team as a code owner April 14, 2026 16:09
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 16:09 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 16:09 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 16:09 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 16:09 — with GitHub Actions Inactive
@eablack eablack force-pushed the eb/move-to-shared-eslint branch from 8ee63aa to 303d032 Compare April 14, 2026 17:14
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:14 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:14 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:14 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:14 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:33 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:33 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:33 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 17:33 — with GitHub Actions Inactive
@eablack eablack marked this pull request as draft April 14, 2026 18:08
@eablack eablack force-pushed the eb/move-to-shared-eslint branch from bcac179 to 4904a1c Compare April 14, 2026 21:06
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:07 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:07 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:07 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:07 — with GitHub Actions Inactive
@eablack eablack force-pushed the eb/move-to-shared-eslint branch from 4904a1c to 3b6e983 Compare April 14, 2026 21:59
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:59 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:59 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:59 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 14, 2026 21:59 — with GitHub Actions Inactive
eablack added 10 commits April 15, 2026 16:20
- Migrate from local .eslintrc.cjs to @heroku-cli/test-utils/eslint-config
- Fix test failures caused by ESLint auto-formatting:
  - apps:favorites:add: update error test to use proper 404 response
  - spaces:ps: fix JSON date serialization in test expectation
  - HerokuExec: add basic auth to nock mocks for updateClientKey tests
- Update hook tests to modern style (remove old test chain syntax):
  - terms-of-service: use sinon stubs and standard Mocha tests
  - version: add comprehensive test coverage with proper mocking
- Rename files to kebab-case per linting rules
- Apply ESLint auto-fixes across codebase (object sorting, ternary operators, etc)
- Rename snake_case files to kebab-case per linting rules
- Fix test failures caused by linting changes:
  - autocomplete: Fix plugins iteration (Map vs Array)
  - pg:kill: Reorder args (required pid before optional database)
  - accounts: Fix YAML property order (username before password)
  - apps:favorites:add: Update test to use proper 404 response
  - spaces:ps: Fix JSON date serialization in test
- Add eslint-disable comments for intentional sort order exceptions

Note: HerokuExec updateClientKey tests still failing, needs investigation
- Add n/no-unpublished-bin: off to eslint config (false positives)
- Rename snake_case cert files to kebab-case:
  - certificate_details.ts → certificate-details.ts
  - format_date.ts → format-date.ts
  - get_cert_and_key.ts → get-cert-and-key.ts
- Fix various linting issues across codebase

Remaining: ~60 linting errors to be addressed
- 21 @stylistic/lines-between-class-members
- 9 perfectionist/sort-imports
- 8 unicorn/filename-case
- 6 no-undef (RequestInfo, BufferEncoding types)
- Others (no-fallthrough, array-callback-return, etc.)
- Rename test/helpers/runCommand.ts to legacy-run-command.ts for old-style tests
- Replace local run-command.ts with shared implementation from @heroku-cli/test-utils
- Update 226+ test files to import runCommand from @heroku-cli/test-utils
- Rename helper files to kebab-case: testInstances.ts -> test-instances.ts, uxStub.ts -> ux-stub.ts
- Consolidate test utilities to use shared @heroku-cli/test-utils package

This reduces code duplication and ensures all tests use the same command runner implementation.
- Replace local test/helpers/utils/expectOutput.ts with shared implementation
- Update 57 test files to import expectOutput from @heroku-cli/test-utils
- Use named import syntax for consistency with other test-utils exports

This continues the consolidation of test utilities into the shared package.
Remove eslint plugins that are now handled by shared config. Also fix URL construction in exec.ts to avoid duplicate slashes in the API path.
The shared eslint config requires eslint-import-resolver-typescript v4.x
for ESLint 9 flat config compatibility. Without it explicitly installed,
npm resolves to v3.x from eslint-config-oclif, which has an incompatible
interface and causes "invalid interface loaded as resolver" errors.
The bin/run.js file imports from the dist folder, which needs to exist
before linting can resolve those imports. Running build before lint
ensures the TypeScript compiler generates the dist folder first.
@eablack eablack force-pushed the eb/move-to-shared-eslint branch from cf0c261 to cb0d1bb Compare April 15, 2026 23:21
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:21 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:21 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:21 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:21 — with GitHub Actions Inactive
Use ternary expression with explicit return to satisfy getter-return rule
while avoiding no-useless-return. Added explicit return type annotation
for clarity.
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:36 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:36 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:36 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:36 — with GitHub Actions Inactive
- Add semi: ['warn', 'never'] to eslint config for no semicolons preference
- Fix unicorn/prefer-ternary warning in members/add.ts
- Remove unnecessary no-var from eslint-disable comment
- Use String.raw for better backslash escaping in tests
- Reorder imports and alphabetize mock properties
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:39 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:39 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:39 — with GitHub Actions Inactive
@eablack eablack temporarily deployed to AcceptanceTests April 15, 2026 23:39 — with GitHub Actions Inactive
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.

1 participant