Repository navigation
Bring the Node and file baselines in line with WordPress's tools - #63
Merged
Merged
Conversation
The locks trailed the latest releases within range. Both Composer locks and the block.json tools' npm lock need nothing; the root npm lock moves electron-to-chromium to 1.5.469, and no version moves down. zizmor 1.32.0 is out, but the pinned zizmor-action v0.8.0 carries no lock for it; v0.8.1 does, and Dependabot's cooldown holds that bump until it is seven days old, so Workflow Checks stays on 1.31.1. Assisted-by: Claude Code:claude-opus-5-5
The tracked JSON files used two or four spaces, and the NEON files and phpunit.dist.xml four, while WordPress core's .editorconfig gives every file but YAML a tab and WordPress's Prettier config writes JSON with tabs, so an editor following either mixed the indentation of the file it touched. Every such file now indents with one tab per level; the PHPUnit root's attributes keep their column with two tabs and a space, as the framework's do. npm writes a lock with its manifest's indentation, so both npm locks follow their package.json files here rather than in the next update. Composer writes its locks with four spaces whatever the manifest uses, so they stay as they are. The change is whitespace only: git diff -w is empty, and every file parses to the same value as before. Assisted-by: Claude Code:claude-opus-5-5
The smoke never checked a plain .jsx file, which the ESLint base leaves unconfigured, or the .spec and __tests__ names wp-scripts treats as unit tests; it checked the end-to-end folder as tests/e2e beside the PascalCase test tiers, and no Node baseline was checked against the vendor-prefixed/ tree the scoping pipeline writes. The SCSS baseline's formatting rules, which wp-scripts' own default enforces, had no row, and the release's forbidden-entry rows lacked CONTRIBUTING.md, SECURITY.md and a PostCSS config. The smoke now asserts that a .jsx file is linted, that .spec, __tests__ and test/ paths get the unit-test rules while a spec under tests/EndToEnd gets only the Playwright rules, that both lint baselines ignore vendor-prefixed/, that the Stylelint base carries the stylistic preset and that Playwright's testDir is tests/EndToEnd. The release rows add the three files. All of these fail until the next commits. Assisted-by: Claude Code:claude-opus-5-5
ESLint discovers only .js, .mjs and .cjs files unless a config names another extension, and the recommended config names only the TypeScript ones, so `wp-scripts lint-js` passed a project's .jsx files without linting them, accessibility rules included. The unit-test rules matched test/ folders and *.test.* names only, so a *.spec.* file or a __tests__/ folder lost its vitest checks. The base names **/*.jsx before the recommended config, as wp-scripts' own default does, and scopes the unit-test rules to wp-scripts' globs, which also keep a snapshot or JSON file in a test/ folder unlinted. The end-to-end folder stays outside them, since its Playwright specs share the .spec suffix. Assisted-by: Claude Code:claude-opus-5-5
The Playwright factory's testDir and the ESLint base's Playwright scope named tests/e2e, the one lowercase folder beside the PascalCase Unit, Integration, Fixtures and Support tiers, and a name the sibling a8csp baselines spell tests/EndToEnd. Both now read tests/EndToEnd, and the README says so. Consumers rename their folder when they move their pin. Assisted-by: Claude Code:claude-opus-5-5
The ESLint and Stylelint baselines ignored vendor/ and node_modules/ but not vendor-prefixed/, where the scoping pipeline copies each scoped package whole, its scripts and styles included, while both PHPCS profiles already skip it. A project-wide lint run, such as an editor's, then reported findings in third-party code. Both lists now skip it. Assisted-by: Claude Code:claude-opus-5-5
The base extended @wordpress/stylelint-config/scss, which leaves out the formatting rules, such as tab indentation and trailing semicolons, that the scss-stylistic preset adds and that wp-scripts' own default config extends. wp-scripts format does not touch SCSS, so nothing checked how a consumer's styles were formatted. The base now extends scss-stylistic, keeping its ignores, disable-comment reports and the selector-class-pattern override, and the README names the preset. Assisted-by: Claude Code:claude-opus-5-5
The PostCSS base rebuilt the chain @wordpress/scripts already uses when a project has no PostCSS config, while overriding a project's own cssnano config, and no consumer imported it; it cost an export, a peer dependency, README rows and a smoke probe. The base, its export, the @wordpress/postcss-plugins-preset peer, its README rows and its probe go, and wp-scripts' fallback serves. @wordpress/e2e-test-utils-playwright was a direct devDependency that nothing in the package imports and @wordpress/scripts already brings at the same range, so it goes, and the lock keeps every version. format:scripts formatted only node/ while lint:scripts also linted the smoke harness, and neither reached eslint.config.mjs, so a Prettier finding in the harness had no fixer and the root config was never linted. Both scripts now take one path list. Assisted-by: Claude Code:claude-opus-5-5
The baseline .distignore left CONTRIBUTING.md and SECURITY.md in a plugin's archive, which every consumer then excluded by hand, and it named a config for every Node tool but PostCSS, whose project config wp-scripts reads. The release's forbidden-entry check missed the same three, so a consumer that copied the baseline shipped them unnoticed. The baseline excludes CONTRIBUTING.md, SECURITY.md and postcss.config.*, the release's forbidden arms mirror them, and the README lists the documents. A wp dist-archive build of a probe plugin from the baseline, holding every forbidden entry, passes the check, which fails the same build from the previous baseline on these files. Assisted-by: Claude Code:claude-opus-5-5
The file differed from WordPress core's in two places: it indented JSON
with two spaces, which WordPress's Prettier config rewrites with tabs,
and it applied CRLF to *.txt without core's wp-config-sample.php. It
also inherited what core's file leaves out: no tab width, so editors
drew tabs at their own width rather than the four columns PHPCS and
Prettier align to, and a two-space rule for .yml alone, which handed a
.yaml file the tab default YAML forbids.
The file is now core's with indent_size = 4, [*.{yml,yaml}] in place of
[*.yml], and no CRLF section, as Gutenberg, WooCommerce, PHPStan and
Playground also drop it: core keeps it for the Windows users of its
download zip, and an editor following it rewrote an LF readme.txt as
CRLF. JSON, NEON and XML take the tab default, which the files already
use. The README describes the file.
Assisted-by: Claude Code:claude-opus-5-5
.github/actionlint.yaml was the one YAML file in the repository with the .yaml extension, beside dependabot.yml, zizmor.yml and every workflow. actionlint finds .github/actionlint.yml the same way, and under that name its ignore for the job context's workflow_repository and workflow_sha holds, while a run without the config reports both. Assisted-by: Claude Code:claude-opus-5-5
The framework's, the template's and the monorepo's quality-check open with composer validate --strict, which CI's PHP lint workflow runs as its own job, but configs' quality-check and quality-check:all did not, so an invalid or out-of-date manifest passed locally and failed in CI. Both now open with it, and the command lists in AGENTS.md, CONTRIBUTING.md, the README and tests/README.md say so; CONTRIBUTING's separate validate step goes. Assisted-by: Claude Code:claude-opus-5-5
Composer stops a script after 300 seconds, and Infection over the unit suite runs longer, so composer test:unit:mutation, test:all and quality-check:all failed locally with a timeout once Infection had processed about a sixth of its mutants. The mutation script now opens with Composer\Config::disableProcessTimeout, as the framework's long scripts do. Assisted-by: Claude Code:claude-opus-5-5
npm's quality-check:all passed straight to composer quality-check:all, which runs only the Composer side, so the cross-tool maximum skipped the Node baselines' lint and smoke that lint:all runs. audit ran plain composer audit and npm audit, which fail on development advisories and abandoned packages the CI gate only reports, so it failed where CI passed. format:all stopped whenever PHPCBF fixed a file, since PHPCBF exits 1 then, and never reached the script formatter. quality-check:all now runs composer quality-check:all, which keeps the manifest validation, the PHP lint and the tests in Composer's quality group, and then lint:scripts and lint:config. audit runs the gate's composer audit --locked --abandoned=report and npm audit --omit=dev --audit-level=high, and format:all continues on PHPCBF's exit 1 while still stopping on its exit 2, a fix that failed. Assisted-by: Claude Code:claude-opus-5-5
The typescript peer admitted any version from 6.0.0, TypeScript 7 included, which typescript-eslint, loaded by the ESLint base whenever TypeScript is installed, refuses; Dependabot offered that major and its pull request failed. The peer now reads ^6.0.0, the README says why, and both npm entries in dependabot.yml ignore TypeScript's major updates. Assisted-by: Claude Code:claude-opus-5-5
configs was the one repository whose PHPStan run covered its tests, while the framework, the template and the plugins analyse none of theirs; its PHPUnit config ran in a fixed order and let a deprecation pass, where the framework and the template randomize and fail on one; and Infection wrote its reports to build/infection/, outside the tests/.cache/ directory every other test tool writes to. PHPStan's self-lint now analyses php/ alone, PHPUnit runs in random order and fails on a deprecation, and Infection reports to tests/.cache/infection/. Three runs of the unit suite under different seeds pass. Assisted-by: Claude Code:claude-opus-5-5
The .gitignore carried only the toptal block's exact dotenv names, so .env.production, auth.json, .npmrc, a private key or an id_rsa file could be staged by an accidental git add, while the sibling a8csp repositories ignore all of them. The rules a8csp uses now sit above the toptal block; no tracked file matches them, so no fixture needs an exception, and git check-ignore confirms each pattern at the root and in a nested folder. Assisted-by: Claude Code:claude-opus-5-5
The fixtures folder was lowercase beside configs' own tests/Unit and tests/Support, and against the tests/Fixtures folder of the framework and the template, which name the same tier. It is now tests/Fixtures, renamed in two steps because macOS's filesystem folds case, and every reference follows: Quality's paths, the classmap exclusion, the smoke and lint scripts, the tests ruleset's case-sensitive exclusion, the tests' fixture paths, the smoke's probes and the layout in AGENTS.md and tests/README.md. Its subfolders keep their kebab-case names, as fixture projects. The change is a rename only. Assisted-by: Claude Code:claude-opus-5-5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Node lint baselines missed
.jsxfiles, common unit-test names, the scopedvendor-prefixed/tree and WordPress's SCSS formatting rules; the.editorconfig,.distignore, ignore rules and script lanes drifted from WordPress core, the release check and CI. This aligns each one, moves the end-to-end tier totests/EndToEnd, removes the unused PostCSS base, and indents JSON and NEON with tabs.Type of change
.github/workflows/reusable-*.yml)php/quality-assurance/)Checklist
tests/Unit/)composer testpasses locallydocs/workflows.mdis updated to reflect the new contractdev-trunkconsumers immediately)Breaking changes for downstream consumers
testDirand the ESLint base's Playwright scope aretests/EndToEnd; renametests/e2ewhen moving the npm pin..jsxfiles are linted, and*.spec.*files and__tests__/folders outsidetests/EndToEndget the unit-test rules.@wordpress/stylelint-config/scss-stylistic, so existing SCSS may report formatting errors to fix.node/postcss.config.base.jsand the@wordpress/postcss-plugins-presetpeer are gone; wp-scripts' fallback serves a project without a PostCSS config.typescriptpeer is^6.0.0.CONTRIBUTING.md,SECURITY.mdandpostcss.config.*must not ship; the baseline.distignoreexcludes them, so copy it again..editorconfigis WordPress core's withindent_size = 4, every YAML extension at two spaces and no CRLF rule, so JSON and NEON indent with tabs; copy it and re-indent.Additive: both lint baselines ignore
vendor-prefixed/.