Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
48a9312
tests: configure PHPStan
justlevine Oct 22, 2024
8e9c0e0
chore: update config
justlevine Oct 27, 2024
cdd934c
tests: exclude `wp-include/blocks` from PHPStan analysis
justlevine Oct 30, 2024
8da1a4a
chore: remove `-v` flag from `analyse` composer command
justlevine Nov 4, 2024
9c8f096
tests: regenerate PHPStan baselines after rebase
justlevine Nov 4, 2024
7386db1
tests: exclude additional external libraries to match phpcs.xml.dist
justlevine Nov 4, 2024
0949e37
tmp: bump PHPStan to 2.x
justlevine Feb 1, 2025
4687567
chore: regenerate PHPStan Baselines after rebase
justlevine Feb 21, 2025
7b44654
tests: suppress errors when string is used as `callable`
justlevine Feb 21, 2025
370551f
chore: regenerate PHPStan Baselines after rebase
justlevine Apr 12, 2025
8bceab7
chore: regenerate PHPStan baselines after rebase
justlevine May 9, 2025
2ca6044
dev: revert PHPStan to v1.x
justlevine May 23, 2025
03e64f8
ci: add GH workflow for PHPStan
justlevine May 23, 2025
ac2ea4b
chore: regenerate PHPStan baselines after rebase
justlevine May 23, 2025
8f79e7e
ci: use verbose PHPStan debugging
justlevine May 23, 2025
46488de
chore: regenerate PHPStan baselines after rebase
justlevine May 31, 2025
88cc77b
tests: define PHPStan `dynamicConstantNames`
justlevine May 31, 2025
4c8fcf4
tests: Ignore `missingType.return` PHPStan error until `: void` types…
justlevine May 31, 2025
37a379d
chore: regenerate PHPStan baselines
justlevine May 31, 2025
0646dce
tests: set PHPStan `treatPhpDocTypesAsCertain` to false
justlevine May 31, 2025
64661b3
chore: regenerate PHPStan baselines
justlevine May 31, 2025
1375c99
chore: regenerate PHPStan baselines
justlevine Jun 1, 2025
788f5f1
tests: Don't stan deprecated `wp-tinymce.php`
justlevine Jun 10, 2025
c921307
chore: regenerate PHPStan baselines
justlevine Jun 10, 2025
bf2a9ae
PHPStan: define additional dynamic constants
justlevine Jun 11, 2025
f844811
PHPStan: additional dynamicConstantNames
justlevine Jun 18, 2025
7c6c2c0
chore: regenerate PHPStan baselines
justlevine Jun 18, 2025
f94f26b
chore: regenerate PHPStan baselines
justlevine Jun 23, 2025
6da7fe9
PHPStan: limit memory usage when running `composer analyse`
justlevine Jun 28, 2025
588a98c
chore: regenerate PHPStan baselines
justlevine Jun 28, 2025
3a13aed
tests: bump PHPStan to v2.x
justlevine Jul 8, 2025
6e191ca
chore: regenerate PHPStan baselines
justlevine Jul 8, 2025
ff32c3e
chore: regenerate baselines
justlevine Jul 11, 2025
8fe43f3
Remove some testing on < 7.4.
johnbillion Jul 12, 2025
b099803
chore: use tabs for `.neon` and update annotation tenses
justlevine Jul 14, 2025
0f1ee0b
PHPStan: restore and baseline inner function smells.
justlevine Jul 14, 2025
49dcda3
ci: rename job + fix version targeting
justlevine Jul 14, 2025
89b4c20
PHPStan: clarify `dynamicConstantNames`
justlevine Jul 14, 2025
fe6ece2
chore: regenerate baselines
justlevine Jul 19, 2025
c12ed00
chore: fix mixed tabs/spaces
justlevine Jul 19, 2025
92941c5
chore: fix typo in phpstan.neon
justlevine Jul 25, 2025
2df0536
chore: regenerate baselines
justlevine Jul 25, 2025
92bdb86
chore: bump phpstan to minimum 2.1.19 (bugfix)
justlevine Jul 26, 2025
ebae3fa
phpstan: regenerate baselines
justlevine Jul 26, 2025
12675ea
phpstan: regenerate baselines after rebase
justlevine Aug 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab

[*.yml]
[{*.yml}]
indent_style = space
indent_size = 2

Expand Down
100 changes: 100 additions & 0 deletions .github/workflows/php-static-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: PHPStan Static Analysis

on:
# PHPStan testing was introduced in @todo.
push:
branches:
- trunk
- '6.9'
- '[7-9].[0-9]'
tags:
- '6.9'
- '6.9.[0-9]+'
- '[7-9].[0-9]'
- '[7-9]+.[0-9].[0-9]+'
pull_request:
branches:
- trunk
- '6.9'
- '[7-9].[0-9]'
paths:
# This workflow only scans PHP files.
- '**.php'
# These files configure Composer. Changes could affect the outcome.
- 'composer.*'
# These files configure PHPStan. Changes could affect the outcome.
- 'phpstan.neon.dist'
- 'tests/phpstan/base.neon'
# Confirm any changes to relevant workflow files.
- '.github/workflows/php-static-analysis.yml'
- '.github/workflows/reusable-php-static-analysis.yml'
workflow_dispatch:

# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
# The concurrency group contains the workflow name and the branch name for pull requests
# or the commit hash for any other events.
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true

# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}

jobs:
# Runs PHPStan Static Analysis.
phpstan:
name: PHP coding standards
uses: ./.github/workflows/reusable-php-static-analysis.yml
permissions:
contents: read
if: ${{ github.repository == 'WordPress/wordpress-develop' || ( github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' ) }}

slack-notifications:
name: Slack Notifications
uses: ./.github/workflows/slack-notifications.yml
permissions:
actions: read
contents: read
needs: [ phpstan ]
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name != 'pull_request' && always() }}
with:
calling_status: ${{ contains( needs.*.result, 'cancelled' ) && 'cancelled' || contains( needs.*.result, 'failure' ) && 'failure' || 'success' }}
secrets:
SLACK_GHA_SUCCESS_WEBHOOK: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }}
SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }}
SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }}
SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }}

failed-workflow:
name: Failed workflow tasks
runs-on: ubuntu-24.04
permissions:
actions: write
needs: [ slack-notifications ]
if: |
always() &&
github.repository == 'WordPress/wordpress-develop' &&
github.event_name != 'pull_request' &&
github.run_attempt < 2 &&
(
contains( needs.*.result, 'cancelled' ) ||
contains( needs.*.result, 'failure' )
)

steps:
- name: Dispatch workflow run
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
retries: 2
retry-exempt-status-codes: 418
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: `${context.runId}`,
}
});
8 changes: 4 additions & 4 deletions .github/workflows/phpunit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-24.04 ]
php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be dropping 7.2 and 7.3 testing which should be separate from phpstan

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @johnbillion (I believe this was just to suppress the failing CI notifications until #9181 is merged)

db-type: [ 'mysql' ]
db-version: [ '5.7', '8.0', '8.4' ]
tests-domain: [ 'example.org' ]
Expand Down Expand Up @@ -147,7 +147,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-24.04 ]
php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
db-type: [ 'mariadb' ]
db-version: [ '5.5', '10.3', '10.4', '10.5', '10.6', '10.11', '11.4', '11.8' ]
multisite: [ false, true ]
Expand Down Expand Up @@ -199,7 +199,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-24.04 ]
php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
db-type: [ 'mysql' ]
db-version: [ '9.4' ]
multisite: [ false, true ]
Expand Down Expand Up @@ -241,7 +241,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: [ '7.2', '7.4', '8.0', '8.4' ]
php: [ '7.4', '8.0', '8.4' ]
db-type: [ 'mysql' ]
db-version: [ '8.4' ]
phpunit-test-groups: [ 'html-api-html5lib-tests' ]
Expand Down
95 changes: 95 additions & 0 deletions .github/workflows/reusable-php-static-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
##
# A reusable workflow that runs PHP Static Analysis tests.
##
name: PHP Static Analysis

on:
workflow_call:
inputs:
php-version:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The php tests just uses php as this variable name while phpcompatability and this new one use php-version. I think we should make all of these consistent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something to be addressed in this PR, and if so in which direction?

(regular PHPCS also uses php-version https://github.com/justlevine/wordpress-develop/blob/7391ed6aadf101ca4e6e3c82fe841cbade4358ee/.github/workflows/reusable-coding-standards-php.yml#L9 )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's something that should be addressed before this PR and then this PR may need to be updated. I'll raise a slack discussion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

description: 'The PHP version to use.'
required: false
type: 'string'
default: 'latest'
Copy link
Author

@justlevine justlevine Jul 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking this is why CI fails despite passing locally - I've baselined on v8.3.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to leave out a default since this could cause issues in the future. For example, once 9.0 is the latest PHP, versions of WP that don't support it shouldn't have that as the default. Better to be explicit about the version.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but what version do we use:

  • latest official PHP release,
  • latest non-beta-compatibility PHP version,
  • the lowest compatible version,
  • something else?


# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}

jobs:
# Runs PHP static analysis tests.
#
# Violations are reported inline with annotations.
#
# Performs the following steps:
# - Checks out the repository.
# - Sets up PHP.
# - Logs debug information.
# - Installs Composer dependencies.
# - Configures caching for PHP static analysis scans.
# - Make Composer packages available globally.
# - Runs PHPStan static analysis (with Pull Request annotations).
# - Saves the PHPStan result cache.
# - Ensures version-controlled files are not modified or deleted.
phpstan:
name: Run PHP static analysis
runs-on: ubuntu-24.04
permissions:
contents: read
timeout-minutes: 20

steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Set up PHP
uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
with:
php-version: ${{ inputs.php-version }}
coverage: none
tools: cs2pr

- name: Log debug information
run: |
composer --version
# This date is used to ensure that the Composer cache is cleared at least once every week.
# http://man7.org/linux/man-pages/man1/date.1.html
- name: "Get last Monday's date"
id: get-date
run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT"

# Since Composer dependencies are installed using `composer update` and no lock file is in version control,
# passing a custom cache suffix ensures that the cache is flushed at least once per week.
- name: Install Composer dependencies
uses: ramsey/composer-install@a2636af0004d1c0499ffca16ac0b4cc94df70565 # v3.1.0
with:
custom-cache-suffix: ${{ steps.get-date.outputs.date }}

- name: Make Composer packages available globally
run: echo "${PWD}/vendor/bin" >> "$GITHUB_PATH"

- name: Cache PHP Static Analysis scan cache
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: .cache # This is defined in the base.neon file.
key: "phpstan-result-cache-${{ github.run_id }}"
restore-keys: |
phpstan-result-cache-
- name: Run PHP static analysis tests
id: phpstan
run: phpstan analyse -vvv --error-format=checkstyle | cs2pr

- name: "Save result cache"
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
if: ${{ !cancelled() }}
with:
path: .cache
key: "phpstan-result-cache-${{ github.run_id }}"

- name: Ensure version-controlled files are not modified or deleted
run: git diff --exit-code
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ wp-tests-config.php
/build
/tests/phpunit/build
/wp-cli.local.yml
/phpstan.neon
/jsdoc
/composer.lock
/vendor
Expand Down
2 changes: 0 additions & 2 deletions .version-support-php.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"6-9": [
"7.2",
"7.3",
"7.4",
"8.0",
"8.1",
Expand Down
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"squizlabs/php_codesniffer": "3.13.2",
"wp-coding-standards/wpcs": "~3.2.0",
"phpcompatibility/phpcompatibility-wp": "~2.1.3",
"phpstan/phpstan": "~2.1.19",
"yoast/phpunit-polyfills": "^1.1.0"
},
"config": {
Expand All @@ -32,6 +33,7 @@
"lock": false
},
"scripts": {
"analyse": "@php ./vendor/bin/phpstan analyse --memory-limit=2G",
"compat": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --standard=phpcompat.xml.dist --report=summary,source",
"format": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf --report=summary,source",
"lint": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --report=summary,source",
Expand Down
3 changes: 3 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
<exclude-pattern>/tests/phpunit/build*</exclude-pattern>
<exclude-pattern>/tests/phpunit/data/*</exclude-pattern>

<!-- PHPStan bootstrap, stubs, and baseline. -->
<exclude-pattern>/tests/phpstan/*</exclude-pattern>

<exclude-pattern>/tools/*</exclude-pattern>

<!-- Drop-in plugins. -->
Expand Down
42 changes: 42 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# PHPStan configuration for WordPress Core.
#
# To overload this configuration, copy this file to phpstan.neon and adjust as needed.
#
# https://phpstan.org/config-reference

includes:
# The WordPress Core configuration file includes the base configuration for the WordPress codebase.
- tests/phpstan/base.neon
# The baseline file includes preexisting errors in the codebase that should be ignored.
# https://phpstan.org/user-guide/baseline
- tests/phpstan/baseline/level-0.php
- tests/phpstan/baseline/level-1.php
- tests/phpstan/baseline/level-2.php
- tests/phpstan/baseline/level-3.php
- tests/phpstan/baseline/level-4.php
- tests/phpstan/baseline/level-5.php
- tests/phpstan/baseline/level-6.php

parameters:
level: 6
reportUnmatchedIgnoredErrors: true

ignoreErrors:
# Level 0:
- # Inner functions arent supported by PHPstan.
message: '#Function wxr_[a-z_]+ not found#'
path: src/wp-admin/includes/export.php

# Level 1:
- # These are too noisy at the moment.
message: '#Variable \$[a-zA-Z0-9_]+ might not be defined\.#'

# Level 2:
- # Callable-strings are used as callables in WordPress.
message: '#Default value of the parameter .* is incompatible with type callable.*#'

# Level 6:
- # WPCS syntax for iterable types is not supported.
identifier: missingType.iterableValue
- # Too noisy until `void` return types are allowed.
identifier: missingType.return
Loading
Loading