Skip to content

Conversation

@jrfnl
Copy link
Member

@jrfnl jrfnl commented Nov 24, 2025

⚠️ DO NOT MERGE (YET) ⚠️

Please do add approvals if you agree as otherwise we won't be able to release.

PR for tracking changes for the 3.3.0 release. Target release date: Tuesday November 25 2025.

Release checklist

General

  • Verify, and if necessary, update the allowed version ranges for various dependencies in the composer.json - various PRs
  • PHPCS: check if there have been releases since the last WordPressCS release and check through the changelog to see if there is anything WordPressCS could take advantage of - PR #xxx
  • PHPCSUtils: check if there have been releases since the last WordPressCS release and update WordPressCS code to take advantage of any new utilities - PR #xxx
  • PHPCSExtra: check if there have been releases since the last WordPressCS release and check through the changelog to see if there is anything WordPressCS could take advantage of - PR Composer: update to PHPCSExtra 1.5.0 + add two new sniffs to WordPress-Extra #2646
  • Check if the minimum WP version property needs updating in MinimumWPVersionTrait::$default_minimum_wp_version and if so, action it - PR Update the minimum_wp_version to WP 6.6 #2656
  • Check if any of the list based sniffs need updating and if so, action it.
    ✏️ Make sure the "last updated" annotation in the docblocks for these lists has also been updated!
    List based sniffs:
  • Check if any of the other lists containing information about WP Core need updating and if so, action it.
    • $allowed_core_constants in WordPress.NamingConventions.PrefixAllGlobals - N/A
    • $pluggable_functions in WordPress.NamingConventions.PrefixAllGlobals - PR Update list based sniffs for WP 6.9.0(-RC2) #2652
    • $pluggable_classes in WordPress.NamingConventions.PrefixAllGlobals - PR Update list based sniffs for WP 6.9.0(-RC2) #2652
    • $target_functions in WordPress.Security.PluginMenuSlug - N/A
    • $reserved_names in WordPress.NamingConventions.ValidPostTypeSlug - N/A
    • $wp_time_constants in WordPress.WP.CronInterval - N/A
    • $known_test_classes in IsUnitTestTrait - N/A
    • ...etc...
  • Verify there there has been no vandalism on the wiki (and if so, remove/fix it).

Release prep

  • Double-check that all PRs which were merged since the last release have a milestone attached to it.
  • Add changelog for the release - PR Changelog for the release of WordPressCS 3.3.0 #2657
    ✏️ Remember to add a release link at the bottom!
  • Update README (if applicable) - N/A
  • Update wiki (new customizable properties etc.) (if applicable) N/A

Release

  • Merge this PR.
  • Make sure all CI builds are green.
  • Tag and create a release against main (careful, GH defaults to develop!) & copy & paste the changelog to it.
    ✏️ Check if anything from the link collection at the bottom of the changelog needs to be copied in!
    • Remove square brackets from all ticket links or make them proper full links (as GH markdown parser doesn't parse these correctly).
    • Change all contributor links to full inline links (as GH markdown parser on the Releases page doesn't parse these correctly).
  • Make sure all CI builds are green.
  • Close the milestone.
  • Open a new milestone for the next release.
  • If any open PRs/issues which were milestoned for this release did not make it into the release, update their milestone.
  • Fast-forward develop to be equal to main.

After release

  • Open a Trac ticket for WordPress Core to update.

Publicize

  • [Major releases only] Publish post about the release on Make WordPress.
  • Tweet, toot, etc about the release from your personal account (there is no official WPCS account).
  • Post about it in #core channel on the WordPress.org Slack.
    ✏️ No need to post in the #core-coding-standard channel as that gets an automated release notification anyway.
    • Optionally post in #plugin-review if a sniff was added in a release which was requested by the plugin review team.
    • Optionally post in #core-docs if significant updates were made to the documentation ruleset.
  • Create a Marketing team "amplify request".
  • Submit for the "Monthy Dev Roundup".

rodrigoprimo and others added 30 commits July 18, 2025 15:55
This is necessary to be able to create more test case files with syntax errors in a future commit.
…us classes

This commit adds a few tests using readonly anonymous classes to the `WordPress.NamingConventions.ValidFunctionName` tests. This is just to ensure that the part of the sniff code that checks for `T_ANON_CLASS` tokens works correctly with readonly anonymous class added in PHP 8.3.

The sniff was already handling readonly anonymous classes correctly, and no change to the sniff code is needed.
…nymous classes

This commit modifies an existing test to use readonly anonymous classes to the `WordPress.NamingConventions.PrefixAllGlobals` tests. This is just to ensure that the part of the sniff code that checks for `T_ANON_CLASS` tokens works correctly with readonly anonymous class added in PHP 8.3.

The sniff was already handling readonly anonymous classes correctly, and no change to the sniff code is needed.
…lity properties

This commit adds a few tests using asymmetric visibility properties (including in constructor property promotion) to the `WordPress.NamingConventions.PrefixAllGlobals` tests. This is just to ensure that the part of the sniff code that ignores properties or method parameters (in the case of constructor property promotion) continues to handle PHP 8.4+ asymmetric visibility properties correctly. No change to the sniff code is needed.
…ility properties

This commit adds a few tests using asymmetric visibility properties (including in constructor property promotion) to the `WordPress.NamingConventions.ValidVariableName` tests. This is just to ensure that the sniff continues to apply its variable name rules when dealing with asymmetric visibility properties added in PHP 8.4.

The sniff was already handling asymmetric visibility properties correctly, and no change to the sniff code is needed.
…erties

This commit adds a test using asymmetric visibility properties to the `WordPress.Security.NonceVerification` tests. This is just to ensure that the sniff continues to ignore PHP 8.4+ asymmetric visibility properties.

The sniff was already handling asymmetric visibility properties correctly, and no change to the sniff code is needed.
Also update code comment related to the moved parse error test to include one more case where the code might bow out.
…perties

This commit adds a few tests using asymmetric visibility properties (including in constructor property promotion) to the `WordPress.WP.GlobalVariablesOverride` tests. This is just to ensure that the part of the sniff code that ignores properties or method parameters (in the case of constructor property promotion) continues to handle PHP 8.4+ asymmetric visibility properties correctly. No change to the sniff code is needed.
The `FilePath::getName()` method will strip quotes from the file name, as well as normalize the slashes to forward (*nix) slashes.

This allows for a minor simplication in the code and improves code readability.
The `FilePath::getName()` method will strip quotes from the file name, as well as normalize the slashes to forward (*nix) slashes.

This allows for a minor simplication in the code and improves code readability.
As of PHP 8.4, the internal of `T_EXIT` are changing in PHP itself and `exit`/`die` will internally be treated as a function call.

The net effect of this is that named parameters can now be used with `exit()`/`die()`.

For the `WordPress.Security.EscapeOutput` sniff this would lead to false positives as the parameter name would be seen as "not escaped".

As of PHPCSUtils 1.1.0, the methods within the `PassedParameters` class will allow for passing a `T_EXIT` token. This, in turn, allows for handling `exit`/`die` with named parameters correctly in the context of the `EscapeOutput` sniff.

This commit implements using the `PassedParameters` class for parsing calls to `exit`/`die`, which fixes the issue.

Includes tests.

Ref: https://wiki.php.net/rfc/exit-as-function
PHPCSUtils 1.1.0 introduces much more modular exceptions for a variety of errors the utility methods can throw.

This commit changes the exceptions being caught in various `catch` statements to more specific ones.

This means that exceptions which shouldn't be able to occur are no longer caught (passing incorrect data type and such) and only the potentially expected (and acceptable) exceptions will now be caught.
The `'type'` index in the token array should generally only be used for PHPCS cross-version compatibility, where the token constant we are looking for may not be defined in all supported PHPCS versions.

That's not the case for these.
… functions

The `wp_kses_allowed_html()` function is not an escaping function, but retrieves an array of allowed HTML tags and attributes for a given context.

Ref: https://developer.wordpress.org/reference/functions/wp_kses_allowed_html/
…ove-wp_kses_allowed_html

EscapingFunctionsTrait: remove `wp_kses_allowed_html()` from escaping functions
…an-up

NamingConventions/ValidPostTypeSlug: check token via code, not type
…asses (#2559)

* Security/EscapeOutput: fix false negatives when handling anonymous classes

This commit fixes false negatives when the sniff handles readonly anonymous classes and anonymous classes with attributes that are part of a throw statement.

When stepping over tokens after `T_THROW` to find the `T_OPEN_PARENTHESIS` of the exception creation function call/class instantiation, the sniff was not considering that it might need to step over `T_READONLY` tokens or attribute declarations when dealing with anonymous classes.

Fixes #2552

---------

Co-authored-by: jrfnl <[email protected]>
The `unit-tests` workflow runs code coverage for pushes to `main` and pull requests, but wasn't limited to this repo.

This resulted in failing builds for contributors who have actions enabled on their fork. The reason for the failure is that they don't have access to the `CODECOV_TOKEN`.

This commit changes the conditions on when to run the tests normally and when to run with code coverage to take the organisation where the repo lives into account. That should prevent the failing builds in forks.
GH Actions/unit-tests: don't run code coverage in forks
…n dynamic generated placeholders

The sniff was not accounting for fully qualified calls to `implode()` in the code that checks for quotes in dynamically generated placeholders.
The sniff was incorrectly flagging valid SQL escaping functions when they were
written with mixed or uppercase letters (e.g., 'Esc_Sql' instead of 'esc_sql').
This occurred because the function name comparison was case-sensitive when
checking against the predefined list of safe SQL escaping functions.

This fix ensures that function names are properly normalized to lowercase
before comparing them against the allowed escaping functions list, preventing
false positives regardless of the function name's capitalization.
…false-negative

DB/PreparedSQLPlaceholders: fix false negative when checking quotes in dynamic generated placeholders
…itive

DB/PreparedSQL: fix false positives with case-insensitive function names
…or non-standard casts

Four non-standard type casts are going to be deprecated in PHP 8.5.

When any of these type casts would be used in the parameter this sniff examines in the "code under scan" and the sniff would be run on PHP 8.5, the non-standard type cast would be executed via the `eval()`, leading to a deprecation notice, which would stop the scan of the file.

This commit works around this by always using the "standard" type cast syntax in the code which would be passed to `eval()`.

Includes tests.
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
…ions/checkout-5

GH Actions: Bump actions/checkout from 4 to 5
jrfnl and others added 19 commits November 18, 2025 19:09
…ion-runners-92fbf3c11c

GH Actions: Bump the action-runners group with 2 updates
Long anticipated, finally here: PHPCompatibility 10.0.0-alpha1 🎉

PHPCompatibility 10.0.0 brings huge improvements in both what is being detected (> 50 new sniffs), as well as the detection accuracy for pre-existing sniffs.

Even though still "unstable", it is stable enough for our purposes and the advantages of using it outweigh the disadvantage of it being an unstable version. By setting the `minimum-stability` and `prefer-stable` settings in the `composer.json`, we can ensure that we don't get the `dev-develop` branch, but rather get a `10.0.0` tag, unstable or not.

And what with the improved detection, a number of new PHP token constants previously not flagged, are now flagged, so let's ignore them as PHPCS polyfills these.

Ref:
* https://github.com/PHPCompatibility/PHPCompatibility/wiki/Upgrading-to-PHPCompatibility-10.0
* https://github.com/PHPCompatibility/PHPCompatibility/releases/tag/10.0.0-alpha1
…spaced-cache-functions

DB/DirectDatabaseQuery: add tests for namespaced names
…n WP 6.9.0-RC2

Based on a scan of WP Core at commit WordPress/wordpress-develop@87e656 using a preliminary sniff created for issue 1803.
Based on a scan of WP Core at commit WordPress/wordpress-develop@87e656 using a preliminary sniff created for issue 1803.
Based on a scan of WP Core at commit WordPress/wordpress-develop@87e656 using a preliminary sniff created for issue 1803.

Includes tests.
Based on a scan of WP Core at commit WordPress/wordpress-develop@87e656 using a preliminary sniff created for issue 1803.

Includes tests.
... to document when the lists were verified against WP Core last.
Remove the conditions containing a hard-coded repository name in favour of a more generic condition which should safeguard that select steps don't run on forks just the same.
While updating the pluggable function list for WP 6.9, I noticed there are now more cache functions in WP.

Based on the docs:
* [`wp_cache_get_multiple()`](https://developer.wordpress.org/reference/functions/wp_cache_get_multiple/) was added in WP 5.5.0.
* [`wp_cache_get_multiple_salted()`](https://developer.wordpress.org/reference/functions/wp_cache_get_multiple_salted/) was added in WP 6.9.0.
* [`wp_cache_get_salted()`](https://developer.wordpress.org/reference/functions/wp_cache_get_salted/) was added in WP 6.9.0.
* [`wp_cache_add_multiple()`](https://developer.wordpress.org/reference/functions/wp_cache_add_multiple/) was added in WP 6.0.0.
* [`wp_cache_set_multiple()`](https://developer.wordpress.org/reference/functions/wp_cache_set_multiple/) was added in WP 6.0.0.
* [`wp_cache_set_multiple_salted()`](https://developer.wordpress.org/reference/functions/wp_cache_set_multiple_salted/) was added in WP 6.9.0.
* [`wp_cache_set_salted()`](https://developer.wordpress.org/reference/functions/wp_cache_set_salted/) was added in WP 6.9.0.
* [`wp_cache_delete_multiple()`](https://developer.wordpress.org/reference/functions/wp_cache_delete_multiple/) was added in WP 6.0.0.
* [`wp_cache_flush_group()`](https://developer.wordpress.org/reference/functions/wp_cache_flush_group/) was added in WP 6.1.0.
* [`wp_cache_flush_runtime()`](https://developer.wordpress.org/reference/functions/wp_cache_flush_runtime/) was added in WP 6.0.0.

This commit adds these functions to the appropriate lists for the sniff to take into account.

Includes tests.
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.1 to 6.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@93cb6ef...1af3b93)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
…ions/checkout-6.0.0

GH Actions: Bump actions/checkout from 5.0.1 to 6.0.0
The minimum version should be three versions behind the latest WP release, so what with 6.9.0 slated for release on Dec 2nd, it should now become 6.6.

Includes updating the tests to match.

Previous: 2121, 2321. 2436, 2553
…pdate-function-lists

DB/DirectDatabaseQuery: allow for more caching functions
Release date tentatively set to this Tuesday November 25th.

Already includes entry for PR 2656 on the assumption that it will be merged in time for the release.

Includes removing a stray header.
Includes minor formatting consistency fixes for the file.
…sion

Update the minimum_wp_version to WP 6.6
Changelog for the release of WordPressCS 3.3.0
@jrfnl jrfnl merged commit 7795ec6 into main Nov 25, 2025
38 checks passed
@rodrigoprimo
Copy link
Collaborator

Documenting here that I addressed the remaining actions in the checklist:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants