Skip to content

Commit 687c908

Browse files
committed
Merge remote-tracking branch 'upstream/trunk' into trunk
2 parents 6a9e7d0 + a41f67e commit 687c908

318 files changed

Lines changed: 29554 additions & 1535 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: PHPStan Static Analysis
2+
3+
on:
4+
# PHPStan testing was introduced in 7.0.0.
5+
push:
6+
branches:
7+
- trunk
8+
- '[7-9].[0-9]'
9+
tags:
10+
- '[7-9].[0-9]'
11+
- '[7-9]+.[0-9].[0-9]+'
12+
pull_request:
13+
branches:
14+
- trunk
15+
- '[7-9].[0-9]'
16+
paths:
17+
# This workflow only scans PHP files.
18+
- '**.php'
19+
# These files configure Composer. Changes could affect the outcome.
20+
- 'composer.*'
21+
# These files configure PHPStan. Changes could affect the outcome.
22+
- 'phpstan.neon.dist'
23+
- 'tests/phpstan/base.neon'
24+
- 'tests/phpstan/baseline.php'
25+
# Confirm any changes to relevant workflow files.
26+
- '.github/workflows/phpstan-static-analysis.yml'
27+
- '.github/workflows/reusable-phpstan-static-analysis.yml'
28+
workflow_dispatch:
29+
30+
# Cancels all previous workflow runs for pull requests that have not completed.
31+
concurrency:
32+
# The concurrency group contains the workflow name and the branch name for pull requests
33+
# or the commit hash for any other events.
34+
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
35+
cancel-in-progress: true
36+
37+
# Disable permissions for all available scopes by default.
38+
# Any needed permissions should be configured at the job level.
39+
permissions: {}
40+
41+
jobs:
42+
# Runs PHPStan Static Analysis.
43+
phpstan:
44+
name: PHP static analysis
45+
uses: ./.github/workflows/reusable-phpstan-static-analysis.yml
46+
permissions:
47+
contents: read
48+
if: ${{ github.repository == 'WordPress/wordpress-develop' || ( github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' ) }}
49+
50+
slack-notifications:
51+
name: Slack Notifications
52+
uses: ./.github/workflows/slack-notifications.yml
53+
permissions:
54+
actions: read
55+
contents: read
56+
needs: [ phpstan ]
57+
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name != 'pull_request' && always() }}
58+
with:
59+
calling_status: ${{ contains( needs.*.result, 'cancelled' ) && 'cancelled' || contains( needs.*.result, 'failure' ) && 'failure' || 'success' }}
60+
secrets:
61+
SLACK_GHA_SUCCESS_WEBHOOK: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }}
62+
SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }}
63+
SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }}
64+
SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }}
65+
66+
failed-workflow:
67+
name: Failed workflow tasks
68+
runs-on: ubuntu-24.04
69+
permissions:
70+
actions: write
71+
needs: [ slack-notifications ]
72+
if: |
73+
always() &&
74+
github.repository == 'WordPress/wordpress-develop' &&
75+
github.event_name != 'pull_request' &&
76+
github.run_attempt < 2 &&
77+
(
78+
contains( needs.*.result, 'cancelled' ) ||
79+
contains( needs.*.result, 'failure' )
80+
)
81+
82+
steps:
83+
- name: Dispatch workflow run
84+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
85+
with:
86+
retries: 2
87+
retry-exempt-status-codes: 418
88+
script: |
89+
github.rest.actions.createWorkflowDispatch({
90+
owner: context.repo.owner,
91+
repo: context.repo.repo,
92+
workflow_id: 'failed-workflow.yml',
93+
ref: 'trunk',
94+
inputs: {
95+
run_id: `${context.runId}`,
96+
}
97+
});

.github/workflows/reusable-end-to-end-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ jobs:
100100

101101
- name: Install Playwright browsers
102102
if: ${{ inputs.install-playwright }}
103-
run: npx playwright install --with-deps
103+
run: npx playwright install --with-deps chromium
104104

105105
- name: Build WordPress
106106
run: npm run build

.github/workflows/reusable-performance-test-v2.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,6 @@ jobs:
227227
- name: Deactivate WordPress Importer plugin
228228
run: npm run env:cli -- plugin deactivate wordpress-importer --path="/var/www/${LOCAL_DIR}"
229229

230-
- name: Update permalink structure
231-
run: npm run env:cli -- rewrite structure '/%year%/%monthnum%/%postname%/' --path="/var/www/${LOCAL_DIR}"
232-
233230
- name: Install additional languages
234231
run: |
235232
npm run env:cli -- language core install de_DE --path="/var/www/${LOCAL_DIR}"

.github/workflows/reusable-performance.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,6 @@ jobs:
203203
- name: Deactivate WordPress Importer plugin
204204
run: npm run env:cli -- plugin deactivate wordpress-importer --path="/var/www/${LOCAL_DIR}"
205205

206-
- name: Update permalink structure
207-
run: npm run env:cli -- rewrite structure '/%year%/%monthnum%/%postname%/' --path="/var/www/${LOCAL_DIR}"
208-
209206
- name: Install additional languages
210207
run: |
211208
npm run env:cli -- language core install de_DE --path="/var/www/${LOCAL_DIR}"
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
##
2+
# A reusable workflow that runs PHP Static Analysis tests.
3+
##
4+
name: PHP Static Analysis
5+
6+
on:
7+
workflow_call:
8+
inputs:
9+
php-version:
10+
description: 'The PHP version to use.'
11+
required: false
12+
type: 'string'
13+
default: 'latest'
14+
15+
# Disable permissions for all available scopes by default.
16+
# Any needed permissions should be configured at the job level.
17+
permissions: {}
18+
19+
jobs:
20+
# Runs PHP static analysis tests.
21+
#
22+
# Violations are reported inline with annotations.
23+
#
24+
# Performs the following steps:
25+
# - Checks out the repository.
26+
# - Sets up PHP.
27+
# - Logs debug information.
28+
# - Installs Composer dependencies.
29+
# - Configures caching for PHP static analysis scans.
30+
# - Make Composer packages available globally.
31+
# - Runs PHPStan static analysis (with Pull Request annotations).
32+
# - Saves the PHPStan result cache.
33+
# - Ensures version-controlled files are not modified or deleted.
34+
phpstan:
35+
name: Run PHP static analysis
36+
runs-on: ubuntu-24.04
37+
permissions:
38+
contents: read
39+
timeout-minutes: 20
40+
41+
steps:
42+
- name: Checkout repository
43+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
44+
with:
45+
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
46+
persist-credentials: false
47+
48+
- name: Set up Node.js
49+
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
50+
with:
51+
node-version-file: '.nvmrc'
52+
cache: npm
53+
54+
- name: Set up PHP
55+
uses: shivammathur/setup-php@20529878ed81ef8e78ddf08b480401e6101a850f # v2.35.3
56+
with:
57+
php-version: ${{ inputs.php-version }}
58+
coverage: none
59+
tools: cs2pr
60+
61+
# This date is used to ensure that the Composer cache is cleared at least once every week.
62+
# http://man7.org/linux/man-pages/man1/date.1.html
63+
- name: "Get last Monday's date"
64+
id: get-date
65+
run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT"
66+
67+
- name: General debug information
68+
run: |
69+
npm --version
70+
node --version
71+
composer --version
72+
73+
# Since Composer dependencies are installed using `composer update` and no lock file is in version control,
74+
# passing a custom cache suffix ensures that the cache is flushed at least once per week.
75+
- name: Install Composer dependencies
76+
uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1
77+
with:
78+
custom-cache-suffix: ${{ steps.get-date.outputs.date }}
79+
80+
- name: Make Composer packages available globally
81+
run: echo "${PWD}/vendor/bin" >> "$GITHUB_PATH"
82+
83+
- name: Install npm dependencies
84+
run: npm ci --ignore-scripts
85+
86+
- name: Build WordPress
87+
run: npm run build:dev
88+
89+
- name: Cache PHP Static Analysis scan cache
90+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
91+
with:
92+
path: .cache # This is defined in the base.neon file.
93+
key: "phpstan-result-cache-${{ github.run_id }}"
94+
restore-keys: |
95+
phpstan-result-cache-
96+
97+
- name: Run PHP static analysis tests
98+
id: phpstan
99+
run: composer run phpstan -- -vvv --error-format=checkstyle | cs2pr --errors-as-warnings --graceful-warnings
100+
101+
- name: "Save result cache"
102+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
103+
if: ${{ !cancelled() }}
104+
with:
105+
path: .cache
106+
key: "phpstan-result-cache-${{ github.run_id }}"
107+
108+
- name: Ensure version-controlled files are not modified or deleted
109+
run: git diff --exit-code

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ wp-tests-config.php
2323
/gutenberg
2424
/tests/phpunit/build
2525
/wp-cli.local.yml
26+
/phpstan.neon
2627
/jsdoc
2728
/composer.lock
2829
/vendor

Gruntfile.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,6 +1560,7 @@ module.exports = function(grunt) {
15601560
] );
15611561

15621562
grunt.registerTask( 'precommit:php', [
1563+
'phpstan',
15631564
'phpunit'
15641565
] );
15651566

@@ -2001,6 +2002,18 @@ module.exports = function(grunt) {
20012002

20022003
grunt.registerTask( 'test', 'Runs all QUnit and PHPUnit tasks.', ['qunit:compiled', 'phpunit'] );
20032004

2005+
grunt.registerTask( 'phpstan', 'Runs PHPStan on the entire codebase.', function() {
2006+
var done = this.async();
2007+
2008+
grunt.util.spawn( {
2009+
cmd: 'composer',
2010+
args: [ 'phpstan' ],
2011+
opts: { stdio: 'inherit' }
2012+
}, function( error ) {
2013+
done( ! error );
2014+
} );
2015+
} );
2016+
20042017
grunt.registerTask( 'format:php', 'Runs the code formatter on changed files.', function() {
20052018
var done = this.async();
20062019
var flags = this.flags;

composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"squizlabs/php_codesniffer": "3.13.5",
2424
"wp-coding-standards/wpcs": "~3.3.0",
2525
"phpcompatibility/phpcompatibility-wp": "~2.1.3",
26+
"phpstan/phpstan": "2.1.39",
2627
"yoast/phpunit-polyfills": "^1.1.0"
2728
},
2829
"config": {
@@ -32,6 +33,7 @@
3233
"lock": false
3334
},
3435
"scripts": {
36+
"phpstan": "@php ./vendor/bin/phpstan analyse --memory-limit=2G",
3537
"compat": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --standard=phpcompat.xml.dist --report=summary,source",
3638
"format": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf --report=summary,source",
3739
"lint": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --report=summary,source",

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://develop.svn.wordpress.org/trunk"
88
},
99
"gutenberg": {
10-
"ref": "7a11a53377a95cba4d3786d71cadd4c2f0c5ac52"
10+
"ref": "022d8dd3d461f91b15c1f0410649d3ebb027207f"
1111
},
1212
"engines": {
1313
"node": ">=20.10.0",
@@ -130,6 +130,7 @@
130130
"test:coverage": "npm run test:php -- --coverage-html ./coverage/html/ --coverage-php ./coverage/php/report.php --coverage-text=./coverage/text/report.txt",
131131
"test:e2e": "wp-scripts test-playwright --config tests/e2e/playwright.config.js",
132132
"test:visual": "wp-scripts test-playwright --config tests/visual-regression/playwright.config.js",
133+
"typecheck:php": "node ./tools/local-env/scripts/docker.js run --rm php composer phpstan",
133134
"gutenberg:checkout": "node tools/gutenberg/checkout-gutenberg.js",
134135
"gutenberg:build": "node tools/gutenberg/build-gutenberg.js",
135136
"gutenberg:copy": "node tools/gutenberg/copy-gutenberg-build.js",

phpcs.xml.dist

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
<!-- Exclude the build folder in the current directory. -->
4343
<exclude-pattern type="relative">^build/*</exclude-pattern>
4444

45+
<!-- Exclude the local copy of the Gutenberg repository. -->
46+
<exclude-pattern>/gutenberg/*</exclude-pattern>
47+
4548
<!-- Directories and third party library exclusions. -->
4649
<exclude-pattern>/node_modules/*</exclude-pattern>
4750
<exclude-pattern>/vendor/*</exclude-pattern>
@@ -73,6 +76,7 @@
7376
<exclude-pattern>/src/wp-includes/js/*</exclude-pattern>
7477
<exclude-pattern>/src/wp-includes/PHPMailer/*</exclude-pattern>
7578
<exclude-pattern>/src/wp-includes/Requests/*</exclude-pattern>
79+
<exclude-pattern>/src/wp-includes/php-ai-client/*</exclude-pattern>
7680
<exclude-pattern>/src/wp-includes/SimplePie/*</exclude-pattern>
7781
<exclude-pattern>/src/wp-includes/sodium_compat/*</exclude-pattern>
7882
<exclude-pattern>/src/wp-includes/Text/*</exclude-pattern>
@@ -81,6 +85,9 @@
8185
<exclude-pattern>/tests/phpunit/build*</exclude-pattern>
8286
<exclude-pattern>/tests/phpunit/data/*</exclude-pattern>
8387

88+
<!-- PHPStan bootstrap, stubs, and baseline. -->
89+
<exclude-pattern>/tests/phpstan/*</exclude-pattern>
90+
8491
<exclude-pattern>/tools/*</exclude-pattern>
8592

8693
<!-- Drop-in plugins. -->

0 commit comments

Comments
 (0)