fix: repair pnpm run lint and gate it in CI - #107
Conversation
`pnpm run lint` has been broken on the default branch. Dependabot bumped
`typescript` to ^7.0.2 (the native port), which no longer exposes the legacy
compiler API. `ts-api-utils` reads `ts.TypeFlags.Intrinsic` at module load,
`ts.TypeFlags` is now undefined, and eslint dies before linting anything:
TypeError: Failed to load plugin '@typescript-eslint' declared in
'.eslintrc.cjs » eslint-config-etherpad/plugin ...':
Cannot read properties of undefined (reading 'Intrinsic')
No released `@typescript-eslint` supports TypeScript 7 — 8.70.0 and its
alphas all declare `typescript: ">=4.8.4 <6.1.0"` — so the fix is to hold
`typescript` inside that supported range. `~6.0.3` is the newest line that
works and matches the upstream ceiling exactly.
Removing `typescript` from devDependencies does NOT work: `@typescript-eslint/
typescript-estree` declares `typescript` as an unversioned *optional peer*, so
pnpm just auto-installs the latest (7.0.2) and the same crash returns. The
version has to be pinned explicitly.
Also drops eslint from ^10.10.0 back to ^8.57.1. eslint-config-etherpad
4.0.5 ships only eslintrc-format configs (index.js / node.js / browser.js /
plugin.js); it has no flat-config entry point, so eslint 10 aborts with
"ESLint couldn't find an eslint.config.* file" before it lints anything.
Lint ran in no CI job in this repo, which is why this rotted unnoticed. Adds a
reusable `lint.yml` and wires it into `test-and-release.yml` as a third job
that `release` depends on, so a future dependency bump that breaks lint turns
the "Node.js Package" run red and is not auto-merged.
`pnpm run lint` now exits 0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Toh2QEdVZd7WsTdua9qYL2
PR Summary by QodoRestore ESLint compatibility and enforce linting in CI
AI Description
Diagram
High-Level Assessment
Files changed (4)
|
Code Review by Qodo
1. Compromised lint tools can alter code
|
| lint: | ||
| uses: ./.github/workflows/lint.yml | ||
| secrets: inherit |
There was a problem hiding this comment.
1. Compromised lint tools can alter code 🐞 Bug ⛨ Security
The lint reusable job runs checkout, dependency installation, and ESLint while inheriting the caller's workflow-wide contents: write and id-token: write permissions. A compromised action, ESLint configuration, or loaded lint dependency therefore executes with publishing-oriented privileges even though this job only needs repository read access.
Agent Prompt
## Issue description
The reusable lint job inherits the publishing workflow's write and identity-token permissions despite only requiring repository read access, unnecessarily increasing the impact of a compromised lint action or dependency.
## Fix Focus Areas
- .github/workflows/test-and-release.yml[17-19]
## Recommended Fix
Add a job-level `permissions` block with only `contents: read` to the `lint` caller job, which implicitly disables `id-token: write`, and remove `secrets: inherit` because the lint workflow does not consume repository secrets.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
The bug
pnpm run lintfails on the default branch of this repo (and of ~80 otherether/ep_*plugins). Before this PR:Root cause
Dependabot bumped
typescriptto^7.0.2. TypeScript 7 is the native (Go) port and no longer exposes the legacy compiler API surface, sots.TypeFlagsisundefined.ts-api-utilsevaluates this at module load:…which throws, taking
@typescript-eslint— and therefore all ofeslint-config-etherpad— down with it. ESLint exits 2 without linting a single file.No released
@typescript-eslintsupports TypeScript 7.8.70.0and every8.70.1-alpha.*declaretypescript: ">=4.8.4 <6.1.0". So this cannot be fixed by upgrading the lint toolchain today;typescripthas to be held inside the supported range.The fix
Pin
typescriptto~6.0.3— the newest line@typescript-eslintsupports, and an exact match for its<6.1.0ceiling.Two alternatives were tried and do not work:
typescriptfromdevDependencies(this is a JS plugin)@typescript-eslint/typescript-estreedeclarestypescriptas an unversioned optional peer, so pnpm auto-installs the latest (7.0.2) anyway. pnpmoverrides/packageExtensionsdon't redirect peers either.pnpm.overrides→ts-api-utils: ^2.5.0ts.TypeFlags.Intrinsic(just at line 787).The lockfile shrinks because TypeScript 7 ships ~20 per-platform native binary packages (
@typescript/typescript-linux-x64,-darwin-arm64, …) that TypeScript 6 doesn't have. No unrelated packages change.Why it rotted: lint ran in no CI job
That's the real defect — the breakage sat on
mainunnoticed. This PR adds a reusable.github/workflows/lint.ymland wires it intotest-and-release.ymlas a third job thatreleasedepends on:Because
automerge.ymlonly auto-merges Dependabot PRs when the Node.js Package run succeeds, a future dependency bump that breaks lint now turns that run red and is held back instead of landing silently. No Dependabot ignore rule is added — CI is the gate.Second failure shape in this repo: eslint 10
This repo had also been bumped to
eslint: ^10.10.0, which fails differently:eslint-config-etherpad@4.0.5ships only eslintrc-format configs (index.js,node.js,browser.js,plugin.js) and has no flat-config entry point, so eslint 9/10 cannot consume it at all. This PR moveseslintback to^8.57.1, matching the ~78 sibling plugins. Migrating the org to flat config needs a neweslint-config-etherpadmajor first — tracked separately, not in this PR.Verification
Lint now runs and exits 0. The 7 remaining items are warnings only (
camelcase,no-use-before-define), whicheslint-config-etherpaddeliberately sets towarnrather thanerror. They are pre-existing and are left alone here so this PR stays a build fix rather than a code rewrite.🤖 Generated with Claude Code
https://claude.ai/code/session_01Toh2QEdVZd7WsTdua9qYL2