Problem/Motivation

The 3.0.x branch runs the Drupal Association GitLab CI template's five lint jobs, and four of them are dirty. They are filed together in one issue rather than five because they share a single decision - when to start gating - rather than a common cause.

Numbers below are from pipeline 923686 against the current 3.0.x tip (checked 2026-08-14, after several unrelated fixes landed). phpcs, stylelint, eslint and cspell are unchanged from when this issue was filed; phpstan's Drupal 10 count grew from 18 to 22 errors in that time.

  • phpcs - 124 ERRORS AND 60 WARNINGS ... IN 31 FILES. phpcbf reports it can auto-fix 142 of the 184 violations.
  • phpstan - Found 20 errors on Drupal 11 and 22 on Drupal 10 (was 18 when this issue was filed). The job already auto-generates a phpstan-baseline.neon artifact.
  • stylelint - 80 problems (80 errors, 0 warnings), 68 of them auto-fixable with --fix.
  • eslint - 2 problems (2 errors), both no-jquery/no-val.
  • cspell - green.

All five jobs are allow_failure: true via the DA template, so none of them blocks a merge today. That is why the debt has been able to accumulate quietly - and why phpstan's Drupal 10 count was able to grow by 4 errors without anyone noticing.

Proposed resolution

Clean each tool first, and only then flip its _*_ALLOW_FAILURE variable to 0 so it starts gating. The order matters: flipping any of these to blocking while the branch is still dirty just makes the pipeline permanently red, which trains everyone to ignore it and is strictly worse than the current advisory state.

Suggested order, cheapest signal-per-effort first:

  1. eslint - 2 errors, both the same rule. Effectively free. Fix and gate.
  2. stylelint - 68 of 80 problems are auto-fixable with --fix; the remaining 12 are a small manual pass. Fix and gate.
  3. phpstan - best handled by committing the phpstan-baseline.neon the job already produces. That makes the job green immediately and, more importantly, makes it gate new errors from that point on. Burning down the baseline is separate follow-up work.
  4. phpcs - the largest at 124 errors. It deserves its own dedicated, purely mechanical phpcbf commit, kept strictly separate from any behavioural change so the diff stays reviewable. Bundling a 142-violation auto-fix with a logic change makes both unreviewable.

cspell

To be explicit, because a green job is easy to misread: cspell is currently green and it is not masking typos. Running bare cspell on 3.0.x with no project configuration surfaces 18 unique unknown words, and every one of them is legitimate technical vocabulary - no real misspellings:

Drupalci, LANGCODE, Simpletest, csslint, drupalci, eslinting, jquery, nightwatch, nightwatchjs, phpcs, phplint, phpunit, simpletest, simpletests, testbot, testgroups, webp, youtu.

Most of them came from drupalci.yml and drupalci.yml_.txt, which have since been removed from 3.0.x - those two specific sources are gone, but the same dead words are still sitting in .cspell.json's allowlist below, uncurated.

Two things should still be tidied, on general principle that an allowlist you do not curate is an allowlist that stops being a signal:

  • 3.0.x's .cspell.json was ported wholesale from 4.0.x, and 8 of its 13 words are dead on 3.0.x: DDEV, dripyard, Drush, icontext, LBKD, onecol, performantlabs, tabledrag. Carrying another branch's allowlist is exactly how a spell checker quietly stops catching anything. This is still true as of 2026-08-14.
  • Both branches set minWordLength: 4, which silently suppresses every 1-3 character word. Worth a deliberate decision rather than an inherited default.

Remaining tasks

  • eslint: fix the 2 no-jquery/no-val errors, set its allow-failure variable to 0.
  • stylelint: run --fix, resolve the ~12 remaining manually, set its allow-failure variable to 0.
  • phpstan: commit the generated phpstan-baseline.neon, set its allow-failure variable to 0, open a follow-up to burn the baseline down. Re-check the Drupal 10 count before baselining, since it has already grown once.
  • phpcs: one standalone mechanical phpcbf commit, then a manual pass on the ~42 remaining, then set its allow-failure variable to 0.
  • cspell: trim .cspell.json to words that actually occur on 3.0.x, and make a deliberate call on minWordLength.
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

aangel created an issue.

  • aangel committed 01cbcb92 on 3.0.x
    Issue #3616878: Fix eslint and gate it