Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
236 commits
Select commit Hold shift + click to select a range
8ce8797
Docs: Use `@link` instead of `@see` for URL references.
westonruter Oct 17, 2026
6ea74c8
REST API: Correct the `action-unfiltered-html` link's target schema.
jorgefilipecosta Oct 17, 2026
5fad21a
Connectors: Preload the screen's REST API responses.
jorgefilipecosta Oct 17, 2026
69c05ff
Tests: Make formatting test data providers static.
lancewillett Oct 17, 2026
30a849a
Tests: Make function test data providers static.
lancewillett Oct 17, 2026
9cbfedb
Tests: Make admin test data providers static.
lancewillett Oct 17, 2026
1e7d5ea
Tests: Make bookmark test data providers static.
lancewillett Oct 17, 2026
05d314a
Tests: Make sitemap test data providers static.
lancewillett Oct 17, 2026
b65c057
Tests: Make comment test data providers static.
lancewillett Oct 17, 2026
6969ec3
Tests: Make term test data providers static.
lancewillett Oct 17, 2026
4aa62b3
Tests: Make compatibility test data providers static.
lancewillett Oct 17, 2026
4b28542
Tests: Make date test data providers static.
lancewillett Oct 17, 2026
716a329
Tests: Make font test data providers static.
lancewillett Oct 17, 2026
a2297e0
Tests: Make block support test data providers static.
lancewillett Oct 17, 2026
66e0f0b
Tests: Make canonical redirect test data providers static.
lancewillett Oct 17, 2026
3cf8712
Tests: Cover REST page response preparation.
lancewillett Oct 17, 2026
27f834b
Tests: Cover navigation fallback response preparation.
lancewillett Oct 17, 2026
1a95edb
Tests: Cover whitespace and character references in `class_list()`.
lancewillett Oct 17, 2026
c7c91ef
Tests: Add coverage for `WP_Importer` and `get_cli_args()`.
lancewillett Oct 17, 2026
b877d72
Tests: Cover serialized parent block helpers.
lancewillett Oct 17, 2026
d57569e
Tests: Add coverage for `get_category()`.
lancewillett Oct 17, 2026
696c1f4
Tests: Add coverage for `cat_is_ancestor_of()`.
lancewillett Oct 17, 2026
2695d61
Database: Avoid a fatal error in `wpdb::load_col_info()` if the resul…
SergeyBiryukov Oct 17, 2026
9f29727
Tests: Add coverage for `clean_category_cache()`.
lancewillett Oct 17, 2026
2fa1b23
Tests: Add coverage for `sanitize_category()`.
lancewillett Oct 17, 2026
119c23c
Tests: Add coverage for `sanitize_category_field()`.
lancewillett Oct 17, 2026
2930244
Tests: Add coverage for `get_the_category()`.
lancewillett Oct 17, 2026
883b5b5
Tests: Add coverage for `has_category()`.
lancewillett Oct 17, 2026
1341634
Tests: Add coverage for `user_can_access_admin_page()`.
lancewillett Oct 17, 2026
023740f
Tests: Add coverage for `the_category()`.
lancewillett Oct 17, 2026
795df58
Tests: Add coverage for `walk_category_tree()`.
lancewillett Oct 17, 2026
6c132f5
Tests: Add coverage for `get_tag()`.
lancewillett Oct 17, 2026
80188ad
Tests: Add coverage for `walk_category_dropdown_tree()`.
lancewillett Oct 17, 2026
6edd2f5
Tests: Add coverage for `wp_get_code_editor_settings()`.
lancewillett Oct 17, 2026
fda8803
Tests: Add coverage for `in_category()`.
lancewillett Oct 17, 2026
78a1867
Tests: Add coverage for `get_the_tags()`.
lancewillett Oct 17, 2026
f414f48
Tests: Add coverage for `image_edit_apply_changes()`.
lancewillett Oct 17, 2026
8c60f28
Tests: Add coverage for `get_the_term_list()`.
lancewillett Oct 17, 2026
94cbab2
Tests: Add coverage for `the_terms()`.
lancewillett Oct 17, 2026
b6100bd
Tests: Add coverage for `term_description()`.
lancewillett Oct 17, 2026
597a351
Tests: Add coverage for `get_the_tag_list()`.
lancewillett Oct 17, 2026
916b0ce
Tests: Add coverage for `the_tags()`.
lancewillett Oct 17, 2026
1ce5e8f
Tests: Add coverage for `the_author_meta()`.
lancewillett Oct 17, 2026
935dab6
Tests: Add coverage for `is_multi_author()`.
lancewillett Oct 17, 2026
7b8b2f4
Tests: Add coverage for `the_author()`.
lancewillett Oct 17, 2026
9c7eaad
Tests: Add coverage for `the_author_link()`.
lancewillett Oct 17, 2026
a1e45a0
Tests: Add coverage for `get_author_posts_url()`.
lancewillett Oct 17, 2026
e4d8bdd
Tests: Isolate the navigation menu ID filter per test.
lancewillett Oct 18, 2026
e1ed2ab
Tests: Reuse existing fixtures in REST user tests.
lancewillett Oct 18, 2026
acf82f5
Script Loader: Remove obsolete compression constants.
westonruter Oct 18, 2026
518cd65
Script Loader: Remove the unused compression test.
westonruter Oct 18, 2026
88912df
Database: Ignore default integer display widths in `dbDelta()` on Mar…
SergeyBiryukov Oct 18, 2026
8cffc95
Editor: Add emoji reactions ❤️ 🎉 😄 👀 🚀
adamsilverstein Oct 18, 2026
7ed4f03
Media: stop adding crossorigin attributes in the editor.
adamsilverstein Oct 18, 2026
8307885
Media: Generate animated image sub-sizes by default.
adamsilverstein Oct 18, 2026
4f9f74c
Editor: Remove theme.json preset items of unexpected types to prevent…
ramonjd Oct 18, 2026
d1cd73a
REST API: Send URL sideloads through the shared attachment insert path.
adamsilverstein Oct 18, 2026
883ff4a
Editor: ignore unsupported duotone attribute types.
tellthemachines Oct 19, 2026
a17507f
REST API: Enable filtering comments by multiple statuses.
adamsilverstein Oct 19, 2026
8e01500
HTML API: Simplify the `class_list()` loop.
sirreal Oct 19, 2026
8778884
Script Loader: Document `wp_inline_script_attributes` `$data` paramet…
sirreal Oct 19, 2026
a4cc58e
Docs: `get_block_wrapper_attributes()` expects unescaped values.
sirreal Oct 19, 2026
87e86a9
Administration: Avoid `$()` with non-literal selectors.
sirreal Oct 19, 2026
1f93570
Editor: Add author support to the `wp_block` post type.
fabiankaegy Oct 19, 2026
1881d63
Abilities API: Allow declaring required capabilities
gziolo Oct 19, 2026
f64aa5a
Interactivity API: Print `data-wp-html` tokens as the `wpServerHtml` …
luisherranz Oct 19, 2026
5fc0a06
Toolbar: Fix display name live preview and "Howdy" color
mcsf Oct 19, 2026
f29d3e1
View config endpoint: add align to author and extract utility.
oandregal Oct 19, 2026
254c36d
Toolbar: Undo partial changes to user menu
mcsf Oct 19, 2026
c23d0e5
Tests: Make AJAX data providers static.
lancewillett Oct 19, 2026
0d60d7e
Tests: Make HTTP data providers static.
lancewillett Oct 19, 2026
38b4b34
Tests: Make rewrite data providers static.
lancewillett Oct 19, 2026
6737fec
Tests: Simplify theme fixture setup in REST API tests.
lancewillett Oct 19, 2026
253dfb4
Tests: Cover `wp_is_serving_rest_request()`.
lancewillett Oct 19, 2026
3c6484f
Tests: Cover internal host and link helpers.
lancewillett Oct 19, 2026
38f5cdf
Tests: Cover `wp_removable_query_args()`.
lancewillett Oct 19, 2026
5fd32be
Tests: Cover `wp_get_server_protocol()`.
lancewillett Oct 19, 2026
9607bf4
Tests: Cover `wp_is_jsonp_request()`.
lancewillett Oct 19, 2026
a2b5979
Tests: Cover `wp_is_json_request()`.
lancewillett Oct 19, 2026
7e02b77
Tests: Cover `the_title_attribute()`.
lancewillett Oct 19, 2026
962c8d7
Tests: Cover `wp_is_xml_request()`.
lancewillett Oct 19, 2026
ecb7bfc
Editor: Add the entity actions API.
jorgefilipecosta Oct 19, 2026
1e91058
Tests: Pair the hidden admin-page access cases.
lancewillett Oct 19, 2026
2102b68
Toolbar: Fix display name live preview and "Howdy" color.
mcsf Oct 19, 2026
53b1105
Tests: Cover `tag_description()`.
lancewillett Oct 19, 2026
c30b2af
Tests: Strengthen code editor settings coverage.
lancewillett Oct 19, 2026
a3f014c
Tests: Verify edits target the filtered image editor.
lancewillett Oct 19, 2026
ffa4c0a
Tests: Cover `has_tag()`.
lancewillett Oct 19, 2026
880efab
Tests: Cover `the_author_posts_link()`.
lancewillett Oct 19, 2026
af4ae3b
Tests: Cover `the_privacy_policy_link()`.
lancewillett Oct 19, 2026
b9d0c53
Tests: Cover `the_author_posts()`.
lancewillett Oct 19, 2026
08b2dc2
Code Quality: Narrow types for REST requests and responses.
westonruter Oct 19, 2026
fef7474
Editor: Add the entity fields API.
oandregal Oct 19, 2026
983d4a0
Tests: Cover `get_year_link()`.
lancewillett Oct 19, 2026
1581a36
Tests: Cover `the_permalink()`.
lancewillett Oct 19, 2026
2ca11ef
Tests: Cover `get_month_link()`.
lancewillett Oct 19, 2026
402dc0e
Tests: Cover `wp_is_file_mod_allowed()`.
lancewillett Oct 19, 2026
e0fdb8a
Tests: Cover `get_day_link()`.
lancewillett Oct 19, 2026
344a454
Tests: Cover suggested privacy policy content updates.
lancewillett Oct 19, 2026
0831153
Tests: Cover `the_guid()`.
lancewillett Oct 19, 2026
ee70d19
Tests: Cover `wp_doing_ajax()`.
lancewillett Oct 19, 2026
b48f4a4
Tests: Cover `wp_doing_cron()`.
lancewillett Oct 19, 2026
5e2b02a
Tests: Cover `wp_using_themes()`.
lancewillett Oct 19, 2026
2fe2f15
Build/Test Tools: Report PHPStan errors in a pull request comment.
westonruter Oct 19, 2026
622e222
Tests: Cover `wp_get_environment_type()`.
lancewillett Oct 19, 2026
7e916f2
Tests: Cover `the_time()`.
lancewillett Oct 19, 2026
be7ad85
Tests: Cover `wp_installing()`.
lancewillett Oct 19, 2026
a6d66d9
Tests: Cover `the_modified_time()`.
lancewillett Oct 19, 2026
1758ea6
Tests: Cover `the_modified_date()`.
lancewillett Oct 19, 2026
520af33
Tests: Cover `wp_using_ext_object_cache()`.
lancewillett Oct 19, 2026
3508c2e
Tests: Cover `get_post_format_link()`.
lancewillett Oct 19, 2026
ea10c35
Tests: Cover `the_shortlink()`.
lancewillett Oct 19, 2026
4148046
Tests: Cover `the_modified_author()`.
lancewillett Oct 19, 2026
724c553
Tests: Cover `get_search_link()`.
lancewillett Oct 19, 2026
04e6a05
Tests: Cover `get_delete_post_link()`.
lancewillett Oct 19, 2026
a3248ad
Tests: Cover `is_protected_endpoint()`.
lancewillett Oct 19, 2026
8c0b2a9
Tests: Cover `is_protected_ajax_action()`.
lancewillett Oct 19, 2026
81ca319
Tests: Cover `wp_is_maintenance_mode()`.
lancewillett Oct 19, 2026
bb2e705
Tests: Cover `wp_skip_paused_plugins()`.
lancewillett Oct 19, 2026
861fef6
Tests: Cover `wp_skip_paused_themes()`.
lancewillett Oct 19, 2026
b70e572
Tests: Cover `wp_is_recovery_mode()`.
lancewillett Oct 19, 2026
dbc4560
Tests: Cover `wp_magic_quotes()`.
lancewillett Oct 19, 2026
3831bf5
Tests: Test edited-file error output.
lancewillett Oct 19, 2026
609b4cd
Tests: Test active plugin loading.
lancewillett Oct 19, 2026
5e67e01
Tests: Test internal character encoding.
lancewillett Oct 19, 2026
a2483a9
Tests: Test active theme loading.
lancewillett Oct 19, 2026
897fd88
Tests: Test edited-file error scraping setup.
lancewillett Oct 19, 2026
c4d8253
Tests: Test blog administration detection.
lancewillett Oct 19, 2026
5a52629
Tests: Test user edit links.
lancewillett Oct 19, 2026
de7ea88
Tests: Test comment edit link output.
lancewillett Oct 19, 2026
a9398d7
Editor: Register the core entity actions on the server.
jorgefilipecosta Oct 19, 2026
388a22f
Editor: Add the attachment entity view config for the media editor.
jorgefilipecosta Oct 19, 2026
afa224f
Tests: Cover tag retrieval.
lancewillett Oct 19, 2026
9765946
Tests: Cover media state labels.
lancewillett Oct 19, 2026
24af905
Tests: Cover JSONP callback edge cases.
lancewillett Oct 19, 2026
32518cf
Tests: Strengthen mobile detection fixtures.
lancewillett Oct 19, 2026
fc37f58
Tests: Cover tag edit links.
lancewillett Oct 19, 2026
caf396d
Tests: Cover feed link output.
lancewillett Oct 19, 2026
114231d
Tests: Use the error assertion in image resize tests.
lancewillett Oct 19, 2026
6264622
Tests: Cover registered entity action modules.
lancewillett Oct 19, 2026
47f473b
Tests: Use the error assertion in spam authentication tests.
lancewillett Oct 19, 2026
844fa77
Tests: Restore entity action module coverage annotations.
lancewillett Oct 19, 2026
aa7198f
Tests: Use the error assertion in term tests.
lancewillett Oct 19, 2026
fa3d847
Editor: Fix link color in the "Large title" query pattern.
mikachan Oct 19, 2026
e62a5de
Tests: Make media data providers static.
lancewillett Oct 19, 2026
e205f82
Editor: Register the core entity fields on the server.
jorgefilipecosta Oct 19, 2026
b3f6bc3
Upgrade/Install: Report fatal errors in auto-update emails.
westonruter Oct 19, 2026
5832f82
Administration: Replace Dashicons in admin bar and sidebar with wp-ic…
mcsf Oct 19, 2026
40979e0
Tests: Verify timezone persistence and restore original settings.
lancewillett Oct 19, 2026
cc60bcd
Script Loader: Retire script and style concatenation.
westonruter Oct 19, 2026
9038784
Upgrade/Install: Explain when automatic updates cannot run.
SergeyBiryukov Oct 19, 2026
7cede9a
General: Bump the pinned hash for Gutenberg to 7b95ee96b (24.2.0).
peterwilsoncc Oct 20, 2026
9fbaa2d
Media: Enable client-side uploads in the Media Library and modal.
adamsilverstein Oct 20, 2026
0a52ffb
Posts, Post Types: Add `pre_wp_count_attachments` filter.
westonruter Oct 20, 2026
1a03151
Editor: Add a background clip block support.
aaronrobertshaw Oct 20, 2026
065c362
Editor: Scope state rules to the block's own element.
aaronrobertshaw Oct 20, 2026
ba4c6de
Abilities API: Preserve empty objects in JSON results
gziolo Oct 20, 2026
051f9dc
Administration: Add a ”On This Day” section to the Activity widget
audrasjb Oct 20, 2026
a90a667
JSON Schema: Prepare default values according to their schemas
gziolo Oct 20, 2026
d1ce8fe
Editor: Preload the entity fields and actions the editors read.
jorgefilipecosta Oct 20, 2026
5caf6fe
Tests: Port Gutenberg tests for REST action links and view configs.
jorgefilipecosta Oct 20, 2026
147200e
Editor: Add pseudo-selector support for text inputs.
mikachan Oct 20, 2026
5890394
Editor: Add pseudo-selector support for select elements.
Mamaduka Oct 20, 2026
00dc70f
General: Bump the pinned hash for Gutenberg to be6a50be6.
Mamaduka Oct 20, 2026
43f60f4
Editor: Support the current state for Navigation Submenu in `theme.js…
audrasjb Oct 20, 2026
9ec9604
Editor: Remove the unsupported `single` action context.
jorgefilipecosta Oct 20, 2026
3673e3a
REST API: Use `wp_prepare_json_value_for_client()` for view configs a…
jorgefilipecosta Oct 20, 2026
168c48d
Administration: Add a reusable `.delete-link` CSS class.
audrasjb Oct 20, 2026
5f92be5
REST API: Cleanup empty test file.
dream-encode Oct 20, 2026
8573614
WordPress 7.2 Beta 1.
audrasjb Oct 20, 2026
f141543
Post WordPress 7.2 Beta 1 version bump.
audrasjb Oct 20, 2026
3892b84
Docs: Correct the `@param` tag in a `wp_is_internal_link()` test.
SergeyBiryukov Oct 20, 2026
0e8e5fa
Tests: Cover legacy widget settings conversion.
lancewillett Oct 20, 2026
9495270
Tests: Cover theme data preparation for JavaScript.
lancewillett Oct 20, 2026
2e9c2c7
Twenty Nineteen: Adjust `sass` usage.
SergeyBiryukov Oct 20, 2026
0d38a53
Tests: Cover automatic update eligibility decisions.
lancewillett Oct 20, 2026
f4a9abd
Tests: Expand category ancestry tests.
lancewillett Oct 20, 2026
ff0b79c
Tests: Cover permalink anchor output.
lancewillett Oct 20, 2026
69882e6
Tests: Cover navigation menu conditionals.
lancewillett Oct 20, 2026
4c8b298
Build/Test Tools: Cover user creation and bulk deletion.
lancewillett Oct 20, 2026
7c6970b
Tests: Cover media date filtering in attachment queries.
lancewillett Oct 20, 2026
3c8f6ae
Build/Test Tools: Cover page parent selection in Quick Edit.
lancewillett Oct 20, 2026
06c9868
Build/Test Tools: Cover restoring a trashed post with Undo.
lancewillett Oct 20, 2026
0e425ad
Build/Test Tools: Cover moving selected posts to Trash in bulk.
lancewillett Oct 20, 2026
70d7e25
Build/Test Tools: Cover changing selected posts to drafts in bulk.
lancewillett Oct 20, 2026
b853e9d
Tests: Cover elapsed request time from `timer_float()`.
lancewillett Oct 20, 2026
0c656c2
Build/Test Tools: Cover persisted dashboard preferences.
lancewillett Oct 20, 2026
a6fa21a
Build/Test Tools: Cover successful media uploads.
lancewillett Oct 20, 2026
1045d14
Build/Test Tools: Cover plugin upload and management.
lancewillett Oct 20, 2026
38b021e
Tests: Cover search feed links.
lancewillett Oct 20, 2026
7dccbf6
Tests: Cover plugin header markup and translation.
lancewillett Oct 20, 2026
b096f17
Tests: Cover plugin lifecycle hook registration.
lancewillett Oct 20, 2026
ab6830a
Tests: Cover dispatch to the all hook.
lancewillett Oct 20, 2026
2a29ae9
Tests: Cover plugin dependency notices.
lancewillett Oct 20, 2026
0146efd
Tests: Cover page permalink generation.
lancewillett Oct 20, 2026
4de3802
Tests: Cover post type archive feed links.
lancewillett Oct 20, 2026
c81dd32
Tests: Cover bookmark editing links.
lancewillett Oct 20, 2026
f63fea7
Tests: Cover post datetime and timestamp helpers.
lancewillett Oct 20, 2026
78c7f02
Tests: Cover privacy policy content registration.
lancewillett Oct 20, 2026
6278945
Tests: Cover archive link markup.
lancewillett Oct 20, 2026
bfc5008
HTML API: Use `@link` instead of `@see` for URL references.
westonruter Oct 20, 2026
627db7d
Tests: Cover language attributes.
lancewillett Oct 20, 2026
cffa4b4
Tests: Cover trackback URLs.
lancewillett Oct 20, 2026
8147891
Tests: Cover comment links.
lancewillett Oct 20, 2026
38afbd9
Tests: Use `assertWPError()` in user tests.
lancewillett Oct 20, 2026
d2720e7
Tests: Use `assertWPError()` in theme tests.
lancewillett Oct 20, 2026
e6ee56b
Tests: Use `assertWPError()` in taxonomy tests.
lancewillett Oct 20, 2026
de3ef30
Tests: Use `assertWPError()` in REST users controller tests.
lancewillett Oct 20, 2026
2b749d9
Tests: Use `assertWPError()` in REST server tests.
lancewillett Oct 20, 2026
36668cf
Tests: Use `assertWPError()` in REST API tests.
lancewillett Oct 20, 2026
eae8dcb
Tests: Use `assertWPError()` in GD image resize tests.
lancewillett Oct 20, 2026
d595ea6
Tests: Use `assertWPError()` in image function tests.
lancewillett Oct 20, 2026
0e1f633
Tests: Use `assertWPError()` in GD image editor tests.
lancewillett Oct 20, 2026
00f1c96
Tests: Use `assertWPError()` in Customizer setting tests.
lancewillett Oct 20, 2026
6b2c73e
Tests: Use `assertWPError()` in image editor tests.
lancewillett Oct 20, 2026
e35a93c
Tests: Cover plugin installation status.
lancewillett Oct 20, 2026
b2a3f52
Tests: Cover plugin list table bulk actions.
lancewillett Oct 20, 2026
3d3a7eb
Tests: Use error assertions in Customizer nav menu tests.
lancewillett Oct 20, 2026
7c5c57e
Tests: Use error assertions in nav menu item setting tests.
lancewillett Oct 20, 2026
bc94e32
Tests: Use error assertions in block template tests.
lancewillett Oct 20, 2026
fdfbe2a
Tests: Use error assertions in authentication tests.
lancewillett Oct 20, 2026
dcd687e
Tests: Use error assertions in Customizer manager tests.
lancewillett Oct 20, 2026
0ffcf14
Build/Test Tools: Recognize REST uploads in the media E2E test.
lancewillett Oct 20, 2026
efed318
Tests: Cover AJAX plugin dependency checks.
lancewillett Oct 20, 2026
f94cad9
Tests: Cover plugin overwrite confirmation.
lancewillett Oct 20, 2026
12d246c
Tests: Cover plugin package validation.
lancewillett Oct 20, 2026
3acd32a
Tests: Cover plugin update notices.
lancewillett Oct 20, 2026
b4de250
Tests: Cover update counts and titles.
lancewillett Oct 20, 2026
c0d4813
Tests: Cover Site Health auto-update checks.
lancewillett Oct 20, 2026
1dc0c7c
Tests: Cover plugin debug information.
lancewillett Oct 20, 2026
f73eda6
Tests: Cover circular plugin dependency detection.
lancewillett Oct 20, 2026
e02bb57
Tests: Cover Site Health plugin version checks.
lancewillett Oct 20, 2026
4966630
Tests: Cover empty plugin list messages.
lancewillett Oct 20, 2026
48d627a
Docs: Use triple digit convention for `since` mentions in class `WP_T…
audrasjb Oct 20, 2026
ff2a71f
Docs: Allow a callable `$args` in `register_setting()`.
westonruter Oct 20, 2026
6591179
Security: Update `composer/ca-bundle` to version `1.6.0`.
peterwilsoncc Oct 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
370 changes: 370 additions & 0 deletions .github/workflows/phpstan-pull-request-comments.yml

Large diffs are not rendered by default.

184 changes: 147 additions & 37 deletions .github/workflows/reusable-phpstan-static-analysis-v1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ permissions: {}
jobs:
# Runs PHP static analysis tests.
#
# Violations are reported inline with annotations.
# Violations are reported inline with annotations. For pull requests, the results are also uploaded
# as an artifact, which the PHPStan Pull Request Comments workflow summarizes in a comment.
#
# Performs the following steps:
# - Checks out the repository.
Expand All @@ -31,8 +32,10 @@ jobs:
# - Make Composer packages available globally.
# - Builds WordPress.
# - Configures caching for PHPStan static analysis scans.
# - Runs PHPStan static analysis (with Pull Request annotations).
# - Checks whether the baselines need regenerating.
# - Runs PHPStan static analysis.
# - Reports the results as annotations.
# - Uploads the results as an artifact (pull requests only).
# - Checks for errors that cannot be reported as warnings, such as out-of-date baselines.
# - Saves the PHPStan result cache.
# - Ensures version-controlled files are not modified or deleted.
phpstan:
Expand All @@ -43,18 +46,20 @@ jobs:
timeout-minutes: 20

steps:
# For a pull request, the parents of the merge commit are fetched too, to find the files that the base branch
# has changed since the pull request branched from it.
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false
fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 1 }}

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

- name: General debug information
run: |
Expand Down Expand Up @@ -98,35 +103,125 @@ jobs:
- name: Run PHP static analysis tests
id: phpstan
run: |
# The report is written to a file as well as piped to cs2pr, so that the step below
# can look at it.
# The report is written to a file for the steps below, which turn it into annotations,
# the pull request comment, and a check for errors that cannot be reported as warnings.
# Only the report goes to standard output; the debug output goes to standard error, so
# it stays in the log without corrupting the JSON.
#
# cs2pr exits successfully so that reported errors annotate the pull request without
# failing the run. A pipeline reports only the status of its last command, so that
# also discards the status of the analysis itself. Recover it from PIPESTATUS.
composer run phpstan -- -vvv --error-format=checkstyle | tee "${RUNNER_TEMP}/phpstan-report.xml" | cs2pr --errors-as-warnings --graceful-warnings
status="${PIPESTATUS[0]}"
# The step shell exits on the first failing command, which would also end the step on
# the status of 1 that PHPStan uses for reporting errors. Capture the status instead.
status=0
composer run phpstan -- -vvv --error-format=json > "${RUNNER_TEMP}/phpstan-report.json" || status=$?

# PHPStan exits 1 when it has errors to report, which is the expected case here and
# is what the annotations are for. Anything higher means it did not finish at all,
# which would otherwise pass silently, since the discarded status was the only sign.
# is what the annotations are for. Anything higher means it did not finish at all.
if [ "${status}" -gt 1 ]; then
echo "::error title=PHPStan did not complete::The analysis exited with status ${status}, so the code was not fully checked. This is a failure of the run itself rather than a problem found in the code."
exit "${status}"
fi

# An ignored error that no longer occurs, or occurs a different number of times, is
# reported under an `ignore.*` identifier. That is not something to fix in the code: the
# usual cause is that the error *was* fixed, leaving a baseline describing a state that
# no longer exists. PHPStan does not allow those reports to be ignored or baselined.
# Errors are annotated as warnings, so that they are visible on the pull request without
# failing the run. The exception is an error that PHPStan does not allow to be ignored,
# such as an out-of-date baseline entry, or one that is not specific to a file. These are
# annotated as errors instead, and the run fails on them in the check further below.
#
# The analysis above is reported as warnings, so this would otherwise surface as a
# passing run carrying an annotation that reads like a complaint about a fix. Call it
# out on its own, and say what to do about it.
# The results are also written out for the PHPStan Pull Request Comments workflow, which
# runs with the permissions needed to comment on the pull request. Only the facts are
# passed along: the comment is composed there, since a pull request can change anything
# that runs here.
- name: Report the analysis results
id: report
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const fs = require( 'fs' );

const report = JSON.parse( fs.readFileSync( `${ process.env.RUNNER_TEMP }/phpstan-report.json`, 'utf8' ) );
const workspace = `${ process.env.GITHUB_WORKSPACE }/`;

const errors = [];
for ( const [ absolutePath, file ] of Object.entries( report.files ) ) {
const relativePath = absolutePath.startsWith( workspace ) ? absolutePath.slice( workspace.length ) : absolutePath;
for ( const message of file.messages ) {
errors.push( {
file: relativePath,
line: message.line ?? null,
message: message.message,
identifier: message.identifier ?? null,
tip: message.tip ?? null,
ignorable: message.ignorable,
} );
}
}

// Errors that are not specific to a file, such as an `ignoreErrors` entry without a
// path that no longer matches. These cannot be ignored either.
for ( const message of report.errors ) {
errors.push( { file: null, line: null, message, identifier: null, tip: null, ignorable: false } );
}

for ( const error of errors ) {
const properties = { title: error.identifier ? `PHPStan: ${ error.identifier }` : 'PHPStan' };
if ( error.file ) {
properties.file = error.file;
}
if ( error.line ) {
properties.startLine = error.line;
}
const message = error.tip ? `${ error.message }\n${ error.tip }` : error.message;
if ( error.ignorable ) {
core.warning( message, properties );
} else {
core.error( message, properties );
}
}

// Tips are left out of the results, since they are only shown in the annotations, next to the code.
//
// The commit analyzed is the pull request merged into its base branch, whose second parent is the head
// commit. The files with errors that differ between the two are those the base branch has changed, in
// which the line numbers reported can be off in the head commit.
if ( context.eventName === 'pull_request' ) {
let changedInBase = [];
try {
const filesWithErrors = new Set( errors.map( ( error ) => error.file ) );
changedInBase = require( 'child_process' )
.execFileSync( 'git', [ 'diff', '--name-only', '--no-renames', 'HEAD^2', 'HEAD' ], { encoding: 'utf8' } )
.split( '\n' )
.filter( ( file ) => filesWithErrors.has( file ) );
} catch ( error ) {
core.warning( `The files changed in the base branch could not be found: ${ error.message }` );
}
fs.mkdirSync( `${ process.env.RUNNER_TEMP }/phpstan-results`, { recursive: true } );
fs.writeFileSync( `${ process.env.RUNNER_TEMP }/phpstan-results/results.json`, JSON.stringify( {
pull_request: context.payload.pull_request.number,
changed_in_base: changedInBase,
errors: errors.map( ( { tip, ...error } ) => error ),
} ) );
}

# Uploads the results for the PHPStan Pull Request Comments workflow, which keeps a comment on the
# pull request up to date with them.
- name: Upload the analysis results as an artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ github.event_name == 'pull_request' && steps.report.outcome == 'success' }}
with:
name: phpstan-results
path: ${{ runner.temp }}/phpstan-results/

# Some errors cannot be ignored, so they cannot be reported as warnings either. Most often
# this is an ignored error that no longer occurs, or occurs a different number of times,
# which is reported under an `ignore.*` identifier. That is not something to fix in the
# code: the usual cause is that the error *was* fixed, leaving a baseline describing a state
# that no longer exists.
#
# Such an error is reported without a line number, so its annotation is not shown alongside
# the changes in the pull request, and one that is not specific to a file has nowhere to be
# shown at all. A passing run would let it go unnoticed, so fail the run on it instead, and
# say what to do about it.
#
# Detection is on the identifier rather than the message, which is prose and may be
# reworded in any release. The checkstyle format carries it in the `source` attribute.
- name: Check whether the baselines need regenerating
# Detection is on PHPStan's own `ignorable` flag rather than on the identifier or message.
- name: Check for errors that cannot be reported as warnings
if: ${{ !cancelled() }}
env:
BASELINES_URL: ${{ github.server_url }}/${{ github.repository }}/tree/${{ github.sha }}/tests/phpstan/baselines
Expand All @@ -135,28 +230,36 @@ jobs:
# This step runs even when the analysis above it failed, in which case the report may
# never have been written. That failure is reported there, so there is nothing to add
# here beyond staying quiet about a file that was never going to exist.
if [ ! -f "${RUNNER_TEMP}/phpstan-report.xml" ]; then
report="${RUNNER_TEMP}/phpstan-report.json"
if [ ! -f "${report}" ]; then
exit 0
fi

# Leave the run alone unless PHPStan reported an ignore error, because everything
# below concerns an ignore configuration that no longer describes the code, and
# nothing else. Those errors are `ignore.unmatched`, where a pattern matched nothing
# at all, and `ignore.count`, where it matched a different number of times than the
# entry records. The `ignore.` prefix is matched rather than those two names so that
# any later addition to the group is caught as well.
if ! grep -q 'source="ignore\.' "${RUNNER_TEMP}/phpstan-report.xml"; then
# Errors that are not specific to a file are listed separately from the rest, and are
# never ignorable.
unignorable=$( jq '[ .files[].messages[] | select( .ignorable | not ) ] + .errors | length' "${report}" )
if [ "${unignorable}" -eq 0 ]; then
exit 0
fi

# Whether the errors include ignore errors decides what to say about them, but not whether to
# fail: every error that reaches this point fails the run. Ignore errors concern an ignore
# configuration that no longer describes the code. They are `ignore.unmatched`, where a
# pattern matched nothing at all, and `ignore.count`, where it matched a different number of
# times than the entry records. The `ignore.` prefix is matched rather than those two names
# so that any later addition to the group is caught as well. Any other error that cannot be
# ignored is something regenerating the baselines would not help with, so it is reported
# plainly instead.
ignore_errors=$( jq '[ .files[].messages[] | select( .identifier // "" | startswith( "ignore." ) ) ] | length' "${report}" )

# The summary is Markdown, and its code spans and fences are written literally, so the
# heredoc is quoted to keep the backticks out of the shell's hands. The links are
# written in reference style for the same reason: the URLs are the only part needing
# a variable, so defining them afterwards keeps the whole of the prose in here.
#
# A newline renders as a line break rather than a space, so each paragraph is one
# line however long that makes it, and the rendered summary wraps to its own width.
cat >> "${GITHUB_STEP_SUMMARY}" <<'SUMMARY'
baselines_summary=$( cat <<'SUMMARY'
## PHPStan baselines are out of date

An ignored error no longer occurs, or occurs a different number of times, so PHPStan reported it under an `ignore.unmatched` or `ignore.count` identifier.
Expand All @@ -182,13 +285,20 @@ jobs:
See [`tests/phpstan/README.md`][readme] for details.

SUMMARY
)

if [ "${ignore_errors}" -gt 0 ]; then
{
printf '%s\n\n' "${baselines_summary}"
echo "[baselines]: ${BASELINES_URL}"
echo "[readme]: ${README_URL}"
} >> "${GITHUB_STEP_SUMMARY}"

{
echo "[baselines]: ${BASELINES_URL}"
echo "[readme]: ${README_URL}"
} >> "${GITHUB_STEP_SUMMARY}"
echo "::error title=PHPStan baselines are out of date::An ignored error no longer occurs, or occurs a different number of times. If you fixed it, that is expected: run \`npm run typecheck:php:baselines\` or \`composer phpstan:baselines\` and commit the updated baselines. See ${README_URL}"
else
echo "::error title=PHPStan reported errors that cannot be ignored::PHPStan reported ${unignorable} error(s) that cannot be ignored or reported as warnings. See the error annotations for details, and ${README_URL} for how to run the analysis locally."
fi

echo "::error title=PHPStan baselines are out of date::An ignored error no longer occurs, or occurs a different number of times. If you fixed it, that is expected: run \`npm run typecheck:php:baselines\` or \`composer phpstan:baselines\` and commit the updated baselines. See ${README_URL}"
exit 1

- name: "Save result cache"
Expand Down
12 changes: 11 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,9 @@ module.exports = function(grunt) {
[ WORKING_DIR + 'wp-admin/js/language-chooser.js' ]: [ './src/js/_enqueues/lib/language-chooser.js' ],
[ WORKING_DIR + 'wp-admin/js/link.js' ]: [ './src/js/_enqueues/admin/link.js' ],
[ WORKING_DIR + 'wp-admin/js/media-gallery.js' ]: [ './src/js/_enqueues/deprecated/media-gallery.js' ],
[ WORKING_DIR + 'wp-admin/js/media-frame-upload.js' ]: [ './src/js/_enqueues/admin/media-frame-upload.js' ],
[ WORKING_DIR + 'wp-admin/js/media-new-upload.js' ]: [ './src/js/_enqueues/admin/media-new-upload.js' ],
[ WORKING_DIR + 'wp-admin/js/media-upload-pipeline.js' ]: [ './src/js/_enqueues/admin/media-upload-pipeline.js' ],
[ WORKING_DIR + 'wp-admin/js/media-upload.js' ]: [ './src/js/_enqueues/admin/media-upload.js' ],
[ WORKING_DIR + 'wp-admin/js/media.js' ]: [ './src/js/_enqueues/admin/media.js' ],
[ WORKING_DIR + 'wp-admin/js/nav-menu.js' ]: [ './src/js/_enqueues/lib/nav-menu.js' ],
Expand Down Expand Up @@ -697,7 +700,7 @@ module.exports = function(grunt) {
src: 'vendor/composer/ca-bundle/res/cacert.pem',
dest: SOURCE_DIR + 'wp-includes/certificates/ca-bundle.crt'
},
// Gutenberg PHP infrastructure files (routes.php, pages.php, constants.php, pages/).
// Gutenberg PHP infrastructure files (routes.php, pages.php, constants.php, pages/, core actions, core fields).
'gutenberg-php': {
options: {
process: function( content ) {
Expand All @@ -716,6 +719,10 @@ module.exports = function(grunt) {
'pages.php',
'constants.php',
'pages/**/*.php',
// The actions Core registers through the entity actions API.
'scripts/core-actions/**/*.php',
// The fields Core registers through the entity fields API.
'scripts/core-fields/**/*.php',
],
dest: SOURCE_DIR + 'wp-includes/build/',
} ],
Expand Down Expand Up @@ -1321,6 +1328,9 @@ module.exports = function(grunt) {
'src/wp-admin/js/language-chooser.js': 'src/js/_enqueues/lib/language-chooser.js',
'src/wp-admin/js/link.js': 'src/js/_enqueues/admin/link.js',
'src/wp-admin/js/media-gallery.js': 'src/js/_enqueues/deprecated/media-gallery.js',
'src/wp-admin/js/media-frame-upload.js': 'src/js/_enqueues/admin/media-frame-upload.js',
'src/wp-admin/js/media-new-upload.js': 'src/js/_enqueues/admin/media-new-upload.js',
'src/wp-admin/js/media-upload-pipeline.js': 'src/js/_enqueues/admin/media-upload-pipeline.js',
'src/wp-admin/js/media-upload.js': 'src/js/_enqueues/admin/media-upload.js',
'src/wp-admin/js/media.js': 'src/js/_enqueues/admin/media.js',
'src/wp-admin/js/nav-menu.js': 'src/js/_enqueues/lib/nav-menu.js',
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"ext-zlib": "*"
},
"require-dev": {
"composer/ca-bundle": "1.5.13",
"composer/ca-bundle": "1.6.0",
"squizlabs/php_codesniffer": "3.13.5",
"wp-coding-standards/wpcs": "~3.4.1",
"phpcompatibility/phpcompatibility-wp": "~2.1.3",
Expand Down
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://develop.svn.wordpress.org/trunk"
},
"gutenberg": {
"sha": "954fe7f9e04631c41aec4552acd627a7203a2aad",
"sha": "be6a50be6834e922b9db12c75c9a2cd817b2db59",
"ghcrRepo": "WordPress/gutenberg/gutenberg-wp-develop-build"
},
"engines": {
Expand Down Expand Up @@ -44,6 +44,7 @@
"@napi-rs/image": "1.14.0",
"@playwright/test": "1.61.1",
"@pmmmwh/react-refresh-webpack-plugin": "0.6.2",
"@types/backbone": "1.4.23",
"@types/codemirror": "5.60.17",
"@types/espree": "10.1.0",
"@types/htmlhint": "1.1.5",
Expand Down
2 changes: 1 addition & 1 deletion src/js/_enqueues/admin/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jQuery( function($) {
$(this).attr( 'aria-selected', 'true' ).removeAttr( 'tabindex' );
$(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
$('.tabs-panel').hide();
$(t).show();
$( document ).find( t ).show();
if ( '#categories-all' == t ) {
deleteUserSetting('cats');
} else {
Expand Down
Loading
Loading