Skip to content

Add repository-wide PHPCS specification and PR enforcement workflow#573

Closed
dd32 wants to merge 3 commits intoWordPress:trunkfrom
dd32:add/claude/571-phpcs-workflow
Closed

Add repository-wide PHPCS specification and PR enforcement workflow#573
dd32 wants to merge 3 commits intoWordPress:trunkfrom
dd32:add/claude/571-phpcs-workflow

Conversation

@dd32
Copy link
Copy Markdown
Member

@dd32 dd32 commented Mar 24, 2026

Summary

  • Adds phpcs.xml.dist with WordPress-Core, WordPress-Docs, and WordPress-Extra rules (modeled after WordCamp.org), including PHPCompatibility checks for PHP 8.4+
  • Adds GitHub Actions workflow that uses phpcs-changed to only flag new violations on changed lines, avoiding noise from pre-existing issues
  • Adds root composer.json with dev dependencies for local linting (composer lint, composer phpcs-changed)
  • Adds vendor/ to .gitignore

This replaces the approach in #572 with one consistent with how WordCamp.org handles PHPCS — using phpcs-changed to incrementally enforce standards without blocking PRs on pre-existing violations.

Fixes #571.

Test plan

  • Verify the workflow runs on PRs that modify PHP files
  • Verify only new/changed lines are flagged, not pre-existing violations
  • Verify composer install && composer lint works locally
  • Verify composer phpcs-changed works locally against trunk

🤖 Generated with Claude Code

Introduces PHP coding standards enforcement modeled after WordCamp.org:
- phpcs.xml.dist with WordPress-Core, WordPress-Docs, and WordPress-Extra rules
- PHPCompatibility checks for PHP 8.4+
- GitHub Actions workflow that only flags new violations via phpcs-changed
- Root composer.json with dev dependencies for local and CI linting

Fixes WordPress#571.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

- Bumps minimum_wp_version from 6.8 to 6.9
- Excludes plugin-directory/libs, theme-directory/lib, and wpf-stripe/stripe-php

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dd32
Copy link
Copy Markdown
Member Author

dd32 commented Mar 24, 2026

Existing PHPCS Violations Report

Baseline scan of the repository with third-party libraries excluded. 21,885 errors and 9,890 warnings across 1,133 files (19,974 auto-fixable by phpcbf).

Top 30 Violations by Count

# Sniff Count Auto-fix
1 Generic.Formatting.MultipleStatementAlignment.NotSameWarning 3,447
2 Generic.WhiteSpace.ScopeIndent.Incorrect 3,117
3 WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned 2,638
4 WordPress.Security.EscapeOutput.OutputNotEscaped 2,257
5 Squiz.Commenting.InlineComment.InvalidEndChar 1,858
6 Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed 1,595
7 Squiz.Commenting.FunctionComment.Missing 1,257
8 PEAR.Functions.FunctionCallSignature.MultipleArguments 1,091
9 WordPress.Security.EscapeOutput.UnsafePrintingFunction 867
10 Generic.WhiteSpace.ScopeIndent.IncorrectExact 782
11 Squiz.Scope.MethodScope.Missing 647
12 Universal.Operators.StrictComparisons.LooseEqual 524
13 Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction 420
14 Squiz.PHP.NonExecutableCode.Unreachable 377
15 NormalizedArrays.Arrays.CommaAfterLast.MissingMultiLine 361
16 WordPress.PHP.StrictInArray.MissingTrueStrict 357
17 Squiz.Strings.DoubleQuoteUsage.NotRequired 329
18 WordPress.WP.Capabilities.Unknown 266
19 WordPress.WhiteSpace.OperatorSpacing.NoSpaceAfter 265
20 Squiz.WhiteSpace.SuperfluousWhitespace.EndLine 250
21 WordPress.PHP.YodaConditions.NotYoda 249
22 WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound 244
23 Universal.Operators.StrictComparisons.LooseNotEqual 230
24 Universal.WhiteSpace.CommaSpacing.TooMuchSpaceAfter 227
25 Generic.ControlStructures.InlineControlStructure.NotAllowed 224
26 Squiz.PHP.CommentedOutCode.Found 224
27 NormalizedArrays.Arrays.ArrayBraceSpacing.SpaceBeforeArrayCloserSingleLine 218
28 Squiz.Commenting.FunctionComment.ParamCommentFullStop 217
29 Universal.WhiteSpace.PrecisionAlignment.Found 214
30 Universal.WhiteSpace.DisallowInlineTabs.NonIndentTabsUsed 185

Summary by Category

Category Errors Description
Whitespace/Formatting ~15,000 Indentation, alignment, spacing — mostly auto-fixable
Security ~3,200 Escaping, prepared SQL, safe redirects
Commenting/Docs ~4,200 Missing/malformed docblocks and inline comments
Naming Conventions ~450 Non-snake_case variables, method names
Strict Comparisons ~1,100 Loose ==/!= and missing strict param in in_array()
PHP Compatibility ~30 Deprecated extensions/functions for PHP 8.4+

344 distinct sniff sources total, 141 of which are auto-fixable.


Sniff Recommendations

Based on this baseline, here are suggested changes to the phpcs.xml.dist:

Sniffs to consider excluding (high noise, low signal for this codebase)

Sniff Count Rationale
Squiz.Commenting.InlineComment.InvalidEndChar 1,858 Requiring full stops on inline comments is pedantic and not enforced elsewhere in WP.org projects. WordCamp excludes similar comment sniffs.
Squiz.Commenting.FunctionComment.Missing 1,257 Already excluded MissingParamComment/MissingParamTag — the codebase intentionally omits many docblocks for simple/obvious functions.
Squiz.Commenting.FunctionComment.ParamCommentFullStop 217 Requiring full stops on param descriptions is stylistic noise.
WordPress.PHP.YodaConditions.NotYoda 249 Many files use non-Yoda style consistently. Could be left for gradual adoption.
WordPress.WP.Capabilities.Unknown 266 This sniff flags custom capabilities which are valid in the WP.org environment.
Squiz.PHP.CommentedOutCode.Found 224 Commented-out code is sometimes intentional (reference/documentation). WordCamp excludes this for specific files.

Sniffs to consider enabling explicitly (currently active, high value)

Sniff Count Rationale
WordPress.Security.EscapeOutput.OutputNotEscaped 2,257 Keep — critical security sniff. High count but every new violation should be caught.
WordPress.DB.PreparedSQL.* ~220 Keep — SQL injection prevention is essential.
Universal.Operators.StrictComparisons.* 754 Keep — strict comparisons prevent subtle bugs.
WordPress.PHP.StrictInArray.MissingTrueStrict 357 Keep — in_array() without true is a common source of bugs.
PHPCompatibility.* ~30 Keep — low noise, catches real incompatibilities before deployment.

Since this workflow only flags new violations on changed lines (via phpcs-changed), even high-count sniffs are manageable — contributors only need to fix what they touch.

- Squiz.Commenting.InlineComment.InvalidEndChar (1,858 violations)
- Squiz.Commenting.FunctionComment.Missing (1,257)
- Squiz.Commenting.FunctionComment.ParamCommentFullStop (217)
- WordPress.WP.Capabilities.Unknown (266)
- Squiz.PHP.CommentedOutCode.Found (224)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bazza bazza closed this in 6f7e23c Mar 26, 2026
bazza pushed a commit that referenced this pull request Mar 26, 2026
Take two, I missed composer.json in [14754].

Closes #573


git-svn-id: https://meta.svn.wordpress.org/sites/trunk@14755 74240141-8908-4e6f-9713-ba540dce6ec7
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.

Add a PHPCS action for PRs, and a PHPCS specification for the entire repository

1 participant