Skip to content

Commit 771aa0c

Browse files
committed
Merge branch 'add/build-script-results-check' into trunk
2 parents 39de88a + 68df55e commit 771aa0c

16 files changed

Lines changed: 630 additions & 47 deletions

.github/workflows/check-built-files.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ on:
2323
- '.nvmrc'
2424
- 'Gruntfile.js'
2525
- 'webpack.config.js'
26-
- 'tools/webpack/**'
26+
- 'tools/**'
2727
# These files configure Composer. Changes could affect the outcome.
2828
- 'composer.*'
2929
# Confirm any changes to relevant workflow files.
3030
- '.github/workflows/check-built-files.yml'
31+
- '.github/workflows/reusable-check-built-files.yml'
32+
- '.github/workflows/reusable-compare-built-files-*.yml'
3133
# Changes to the default themes should be handled by the themes workflows.
3234
- '!src/wp-content/themes/twenty**'
3335

@@ -42,10 +44,19 @@ concurrency:
4244
# Any needed permissions should be configured at the job level.
4345
permissions: {}
4446

47+
4548
jobs:
4649
check-for-built-file-changes:
47-
name: Check built files
50+
name: Check built files for uncommitted changes
4851
if: ${{ github.repository == 'wordpress/wordpress-develop' }}
4952
uses: ./.github/workflows/reusable-check-built-files.yml
5053
permissions:
5154
contents: read
55+
56+
# Compares the results of the build script with WordPress/WordPress.
57+
compare-build-script-results:
58+
name: Compare built files to WordPress/WordPress
59+
uses: ./.github/workflows/reusable-compare-built-files-v1.yml
60+
permissions:
61+
contents: read
62+
#if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }}

.github/workflows/reusable-check-built-files.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
##
22
# A reusable workflow that checks for uncommitted changes to built files in pull requests.
33
##
4-
name: Check Built Files (PRs)
4+
name: Check for Uncommitted Changes (PRs)
55

66
on:
77
workflow_call:
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
##
2+
# A reusable workflow that compares the results of the build script with the most recent build server commit.
3+
##
4+
name: Reusable Compare Built Files
5+
6+
on:
7+
workflow_call:
8+
9+
# Disable permissions for all available scopes by default.
10+
# Any needed permissions should be configured at the job level.
11+
permissions: {}
12+
13+
jobs:
14+
# Runs the PHP coding standards checks.
15+
#
16+
# Violations are reported inline with annotations.
17+
#
18+
# Performs the following steps:
19+
# - Checks out the repository.
20+
# - Sets up Node.js.
21+
# - Logs debug information about the GitHub Action runner.
22+
# - Installs npm dependencies.
23+
# - Builds WordPress to run from the build directory.
24+
# - Ensures version-controlled files are not modified or deleted.
25+
# - Checks out the WordPress/WordPress repository.
26+
# - Creates a directory for text files to be uploaded as an artifact.
27+
# - Storse a list of files that differ in the build directory from WordPress/WordPress.
28+
# - Storse a diff file comparing the build directory to WordPress/WordPress.
29+
# - Saves the pull request number to a text file.
30+
# - Uploads the generated files as an artifact.
31+
compare-built-files:
32+
name: Compare built files to WordPress/WordPress
33+
runs-on: ubuntu-24.04
34+
permissions:
35+
contents: read
36+
timeout-minutes: 10
37+
38+
steps:
39+
- name: Checkout repository
40+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
41+
with:
42+
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
43+
persist-credentials: false
44+
45+
- name: Set up Node.js
46+
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
47+
with:
48+
node-version-file: '.nvmrc'
49+
cache: npm
50+
51+
- name: Set up PHP
52+
uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0
53+
with:
54+
php-version: '8.4'
55+
coverage: none
56+
57+
# Since Composer dependencies are installed using `composer update` and no lock file is in version control,
58+
# passing a custom cache suffix ensures that the cache is flushed at least once per week.
59+
- name: Install Composer dependencies
60+
uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # v4.0.0
61+
with:
62+
custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F")
63+
64+
- name: Log debug information
65+
run: |
66+
npm --version
67+
node --version
68+
git --version
69+
70+
- name: Install npm Dependencies
71+
run: npm ci
72+
73+
- name: Build WordPress to run from build directory
74+
run: npm run build
75+
76+
- name: Ensure version-controlled files are not modified or deleted
77+
run: git diff --exit-code
78+
79+
- name: Checkout WordPress/WordPress
80+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
81+
with:
82+
repository: 'WordPress/WordPress'
83+
path: ${{ github.workspace }}/built-wordpress
84+
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
85+
persist-credentials: false
86+
87+
- name: Create directory for artifacts
88+
run: mkdir artifacts
89+
90+
- name: Create a list of files that have changed
91+
run: diff -rq ${{ github.workspace }}/build ${{ github.workspace }}/built-wordpress | sed "s|${{ github.workspace }}/||g" > artifacts/file-changes.txt
92+
93+
- name: Create a list of files that have changed
94+
run: diff -r ${{ github.workspace }}/build ${{ github.workspace }}/built-wordpress | sed "s|${{ github.workspace }}/||g" > artifacts/changes.diff
95+
96+
- name: Save PR number
97+
run: echo "${EVENT_NUMBER}" > ./artifacts/NR
98+
env:
99+
EVENT_NUMBER: ${{ github.event.number }}
100+
101+
# Uploads the associated text files as an artifact.
102+
- name: Upload comparison results as an artifact
103+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
104+
#if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name == 'pull_request' }}
105+
with:
106+
name: build-script-comparison
107+
path: artifacts/

.github/workflows/test-old-branches.yml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,6 @@ jobs:
117117
workflow: 'performance.yml'
118118
- branch: '6.8'
119119
workflow: 'performance.yml'
120-
- branch: '6.7'
121-
workflow: 'performance.yml'
122-
- branch: '6.6'
123-
workflow: 'performance.yml'
124-
- branch: '6.5'
125-
workflow: 'performance.yml'
126-
- branch: '6.4'
127-
workflow: 'performance.yml'
128120

129121
# Run all branches monthly, but only the currently supported one twice per month.
130122
steps:

src/wp-admin/css/login.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ p {
105105
border: 1px solid transparent;
106106
box-shadow: none;
107107
font-size: 14px;
108-
line-height: 2;
108+
line-height: normal;
109109
width: 2.5rem;
110110
height: 2.5rem;
111111
min-width: 40px;

src/wp-admin/includes/post.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2564,7 +2564,7 @@ function the_block_editor_meta_box_post_form_hidden_fields( $post ) {
25642564
$classic_output = ob_get_clean();
25652565

25662566
$classic_elements = wp_html_split( $classic_output );
2567-
$hidden_inputs = '';
2567+
25682568
foreach ( $classic_elements as $element ) {
25692569
if ( ! str_starts_with( $element, '<input ' ) ) {
25702570
continue;

src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@
88
*/
99

1010
use WordPress\AiClient\Builders\PromptBuilder;
11+
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
12+
use WordPress\AiClient\Common\Exception\TokenLimitReachedException;
1113
use WordPress\AiClient\Files\DTO\File;
1214
use WordPress\AiClient\Files\Enums\FileTypeEnum;
1315
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;
1416
use WordPress\AiClient\Messages\DTO\Message;
1517
use WordPress\AiClient\Messages\DTO\MessagePart;
1618
use WordPress\AiClient\Messages\Enums\ModalityEnum;
1719
use WordPress\AiClient\Providers\Http\DTO\RequestOptions;
20+
use WordPress\AiClient\Providers\Http\Exception\ClientException;
21+
use WordPress\AiClient\Providers\Http\Exception\NetworkException;
22+
use WordPress\AiClient\Providers\Http\Exception\ServerException;
1823
use WordPress\AiClient\Providers\Models\Contracts\ModelInterface;
1924
use WordPress\AiClient\Providers\Models\DTO\ModelConfig;
2025
use WordPress\AiClient\Providers\Models\Enums\CapabilityEnum;
@@ -179,13 +184,7 @@ public function __construct( ProviderRegistry $registry, $prompt = null ) {
179184
$this->builder = new PromptBuilder( $registry, $prompt );
180185
} catch ( Exception $e ) {
181186
$this->builder = new PromptBuilder( $registry );
182-
$this->error = new WP_Error(
183-
'prompt_builder_error',
184-
$e->getMessage(),
185-
array(
186-
'exception_class' => get_class( $e ),
187-
)
188-
);
187+
$this->error = $this->exception_to_wp_error( $e );
189188
}
190189

191190
/**
@@ -311,7 +310,7 @@ public function __call( string $name, array $arguments ) {
311310
'prompt_prevented',
312311
__( 'Prompt execution was prevented by a filter.' ),
313312
array(
314-
'exception_class' => 'WP_AI_Client_Prompt_Prevented',
313+
'status' => 503,
315314
)
316315
);
317316

@@ -333,13 +332,7 @@ public function __call( string $name, array $arguments ) {
333332

334333
return $result;
335334
} catch ( Exception $e ) {
336-
$this->error = new WP_Error(
337-
'prompt_builder_error',
338-
$e->getMessage(),
339-
array(
340-
'exception_class' => get_class( $e ),
341-
)
342-
);
335+
$this->error = $this->exception_to_wp_error( $e );
343336

344337
if ( self::is_generating_method( $name ) ) {
345338
return $this->error;
@@ -348,6 +341,51 @@ public function __call( string $name, array $arguments ) {
348341
}
349342
}
350343

344+
/**
345+
* Converts an exception into a WP_Error with a structured error code and message.
346+
*
347+
* This method maps different exception types to specific WP_Error codes and HTTP status codes.
348+
* The presence of the status codes means these WP_Error objects can be easily used in REST API responses
349+
* or other contexts where HTTP semantics are relevant.
350+
*
351+
* @since 7.0.0
352+
*
353+
* @param Exception $e The exception to convert.
354+
* @return WP_Error The resulting WP_Error object.
355+
*/
356+
private function exception_to_wp_error( Exception $e ): WP_Error {
357+
if ( $e instanceof NetworkException ) {
358+
$error_code = 'prompt_network_error';
359+
$status_code = 503;
360+
} elseif ( $e instanceof ClientException ) {
361+
// `ClientException` uses HTTP status codes as exception codes, so we can rely on them.
362+
$error_code = 'prompt_client_error';
363+
$status_code = $e->getCode() ? $e->getCode() : 400;
364+
} elseif ( $e instanceof ServerException ) {
365+
// `ServerException` uses HTTP status codes as exception codes, so we can rely on them.
366+
$error_code = 'prompt_upstream_server_error';
367+
$status_code = $e->getCode() ? $e->getCode() : 500;
368+
} elseif ( $e instanceof TokenLimitReachedException ) {
369+
$error_code = 'prompt_token_limit_reached';
370+
$status_code = 400;
371+
} elseif ( $e instanceof InvalidArgumentException ) {
372+
$error_code = 'prompt_invalid_argument';
373+
$status_code = 400;
374+
} else {
375+
$error_code = 'prompt_builder_error';
376+
$status_code = 500;
377+
}
378+
379+
return new WP_Error(
380+
$error_code,
381+
$e->getMessage(),
382+
array(
383+
'status' => $status_code,
384+
'exception_class' => get_class( $e ),
385+
)
386+
);
387+
}
388+
351389
/**
352390
* Checks if a method name is a support check method (is_supported*).
353391
*

src/wp-includes/blocks.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,7 @@ function insert_hooked_blocks( &$parsed_anchor_block, $relative_position, $hooke
971971
'blockName' => $hooked_block_type,
972972
'attrs' => array(),
973973
'innerBlocks' => array(),
974+
'innerHTML' => '',
974975
'innerContent' => array(),
975976
);
976977

src/wp-includes/general-template.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4669,12 +4669,26 @@ function paginate_links( $args = '' ) {
46694669
$total = $wp_query->max_num_pages ?? 1;
46704670
$current = get_query_var( 'paged' ) ? (int) get_query_var( 'paged' ) : 1;
46714671

4672-
// Append the format placeholder to the base URL.
4673-
$pagenum_link = trailingslashit( $url_parts[0] ) . '%_%';
4672+
/*
4673+
* Ensures sites not using trailing slashes get links in the form
4674+
* `/page/2` rather than `/page/2/`. On these sites, linking to the
4675+
* URL with a trailing slash will result in a 301 redirect from the
4676+
* incorrect URL to the correctly formatted one. This presents an
4677+
* unnecessary performance hit.
4678+
*/
4679+
if ( $wp_rewrite->using_permalinks() && ! $wp_rewrite->use_trailing_slashes ) {
4680+
$pagenum_link = untrailingslashit( $url_parts[0] );
4681+
} else {
4682+
$pagenum_link = trailingslashit( $url_parts[0] );
4683+
}
4684+
$pagenum_link .= '%_%';
46744685

46754686
// URL base depends on permalink settings.
46764687
$format = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
46774688
$format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';
4689+
if ( $wp_rewrite->using_permalinks() && ! $wp_rewrite->use_trailing_slashes ) {
4690+
$format = '/' . ltrim( $format, '/' );
4691+
}
46784692

46794693
$defaults = array(
46804694
'base' => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below).

src/wp-includes/link-template.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2649,7 +2649,8 @@ function get_previous_posts_page_link() {
26492649
* @return string|null The previous posts page link if `$display = false`.
26502650
*/
26512651
function previous_posts( $display = true ) {
2652-
$output = esc_url( get_previous_posts_page_link() );
2652+
$link = get_previous_posts_page_link();
2653+
$output = $link ? esc_url( $link ) : '';
26532654

26542655
if ( $display ) {
26552656
echo $output;

0 commit comments

Comments
 (0)