Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions .github/files/generate-ci-matrix.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@
);
}

// todo: move to the main matrix once WP latest is compatible with PHP 8.5.
$matrix[] = array(
'name' => 'PHP tests: PHP 8.5 WP trunk',
'script' => 'test-php',
'php' => '8.5',
'wp' => 'trunk',
'timeout' => 20,
'force-package-tests' => true,
);

// Add WooCommerce tests.
$matrix[] = array(
'name' => 'PHP tests: PHP 7.4 WP latest with WooCommerce',
Expand Down
2 changes: 1 addition & 1 deletion .github/versions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ PNPM_VERSION=10.4.0

# Other useful version numbers.
MIN_PHP_VERSION=7.2
MAX_PHP_VERSION=8.4
MAX_PHP_VERSION=8.5
2 changes: 1 addition & 1 deletion .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php-versions: [ '7.2', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
php-versions: [ '7.2', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ]
experimental: [ false ]

steps:
Expand Down
6 changes: 3 additions & 3 deletions docs/monorepo.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ All GitHub Actions configuration for the monorepo, including CI, lives in `.gith

## Compatibility

All projects should be compatible with PHP versions WordPress supports. That's currently PHP 7.2 to 8.4.
All projects should be compatible with PHP versions WordPress supports. That's currently PHP 7.2 to 8.5.

## First Time

Expand Down Expand Up @@ -259,15 +259,15 @@ If a project contains PHP tests (typically PHPUnit), it must define `.scripts.te

A MySQL database is available if needed; credentials may be found in `~/.my.cnf`. Note that the host must be specified as `127.0.0.1`, as when passed `localhost` PHP will try to connect via a Unix domain socket which is not available in the Actions environment.

Tests are run with a variety of supported PHP versions from 7.2 to 8.4. If you have tests that only need to be run once, run them when `PHP_VERSION` matches that in `.github/versions.sh`.
Tests are run with a variety of supported PHP versions from 7.2 to 8.5. If you have tests that only need to be run once, run them when `PHP_VERSION` matches that in `.github/versions.sh`.

#### PHP tests for non-plugins

For all project types other than WordPress plugins, the necessary version of PHPUnit and/or any other tools should be pulled in via Composer.

We currently make use of the following packages in testing; it's encouraged to use these rather than introducing other tools that serve the same purpose.

* [yoast/phpunit-polyfills](https://packagist.org/packages/yoast/phpunit-polyfills) supplies polyfills for compatibility with PHPUnit 8.5 to 9.6, to support PHP 7.2 to 8.4.
* [yoast/phpunit-polyfills](https://packagist.org/packages/yoast/phpunit-polyfills) supplies polyfills for compatibility with PHPUnit 8.5 to 12.4, to support PHP 7.2 to 8.5.
* [automattic/phpunit-select-config](https://packagist.org/packages/automattic/phpunit-select-config) allows for selecting a configuration file based on the version of PHPUnit in use, since configs are often not compatible across major versions since PHPUnit 9.
* PHPUnit's built-in mocking is used for class mocks.
* [brain/monkey](https://packagist.org/packages/brain/monkey) is used for mocking functions, and can also provide some functions for minimal WordPress compatibility.
Expand Down
4 changes: 4 additions & 0 deletions projects/packages/assets/changelog/fix-php8.5-package_tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Tests: Improve compatibility with PHP 8.5.
14 changes: 14 additions & 0 deletions projects/packages/assets/tests/php/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,17 @@
* Load the composer packages.
*/
require_once __DIR__ . '/../../vendor/autoload.php';

// Suppress PHP 8.5 deprecation warnings from wikimedia/testing-access-wrapper.
// See here: https://phabricator.wikimedia.org/T406744
// @todo: Remove this when a new version is released with the fix.
if ( PHP_VERSION_ID >= 80500 ) {
set_error_handler(
function ( $errno, $errstr, $errfile = '' ) {
return E_DEPRECATED === $errno
&& str_contains( $errstr, 'setAccessible() is deprecated' )
&& str_ends_with( $errfile, 'vendor/wikimedia/testing-access-wrapper/src/TestingAccessWrapper.php' );
},
E_ALL
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Tests: Improve compatibility with PHP 8.5.
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,20 @@ private function execute_composer( $plugin_dir ) {
// the developer has installed is compatible. To address these differences we will download a
// composer package that is compatible based on ranges of autoloader versions.
$composer_versions = array(
// Version 2.8.12 is compatible with PHP 8.5.
'2.8.12' => array(
'min' => '2.6.0',
'url' => 'https://getcomposer.org/download/2.8.12/composer.phar',
'sha256' => 'f446ea719708bb85fcbf4ef18def5d0515f1f9b4d703f6d820c9c1656e10a2f2',
'min_php' => 70205,
),
// Version 2.4.0 renamed a class, we want to test with that.
'2.4.4' => array(
'min' => '2.6.0',
'url' => 'https://getcomposer.org/download/2.4.4/composer.phar',
'sha256' => 'c252c2a2219956f88089ffc242b42c8cb9300a368fd3890d63940e4fc9652345',
'min_php' => 70205,
'max_php' => 80499,
),
// Version 2.1.6 of Composer is the first to support PHP 8.1.
'2.1.6' => array(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Tests: Improve compatibility with PHP 8.5.
14 changes: 14 additions & 0 deletions projects/packages/changelogger/tests/php/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,17 @@

// Include the Composer autoloader.
require_once __DIR__ . '/../../vendor/autoload.php';

// Suppress PHP 8.5 deprecation warnings from wikimedia/testing-access-wrapper.
// See here: https://phabricator.wikimedia.org/T406744
// @todo: Remove this when a new version is released with the fix.
if ( PHP_VERSION_ID >= 80500 ) {
set_error_handler(
function ( $errno, $errstr, $errfile = '' ) {
return E_DEPRECATED === $errno
&& str_contains( $errstr, 'setAccessible() is deprecated' ) // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.str_containsFound -- this is a PHP 7.4+ function in a PHP 8.5+ block
&& str_ends_with( $errfile, 'vendor/wikimedia/testing-access-wrapper/src/TestingAccessWrapper.php' ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.str_ends_withFound -- this is a PHP 7.4+ function in a PHP 8.5+ block
},
E_ALL
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Tests: Improve compatibility with PHP 8.5.
2 changes: 1 addition & 1 deletion projects/packages/codesniffer/src/Utils/NamespaceInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public static function unqualifyClassName( $name, $nsname, array $aliases ) {
$unprefixed = null;
}
// Skip if the shortened version is an alias though.
if ( isset( $aliases[ $unprefixed ] ) ) {
if ( $unprefixed !== null && isset( $aliases[ $unprefixed ] ) ) {
$unprefixed = null;
}
$unprefixedCt = $unprefixed === null ? INF : substr_count( $unprefixed, '\\' );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Tests: Improve compatibility with PHP 8.5.
10 changes: 5 additions & 5 deletions projects/packages/connection/src/class-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -1747,16 +1747,16 @@ public function get_assumed_site_creation_date() {
* @return array $amended arguments.
*/
public static function apply_activation_source_to_args( $args ) {
list( $activation_source_name, $activation_source_keyword ) = get_option( 'jetpack_activation_source' );
$activation_source = get_option( 'jetpack_activation_source' );

if ( $activation_source_name ) {
if ( ! empty( $activation_source[0] ) ) {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.urlencode_urlencode
$args['_as'] = urlencode( $activation_source_name );
$args['_as'] = urlencode( $activation_source[0] );
}

if ( $activation_source_keyword ) {
if ( ! empty( $activation_source[1] ) ) {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.urlencode_urlencode
$args['_ak'] = urlencode( $activation_source_keyword );
$args['_ak'] = urlencode( $activation_source[1] );
}

return $args;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Improve PHP 8.5 compatibility.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
die( $arg );
} else {
// @phan-suppress-current-line UnusedPluginSuppression @phan-suppress-next-line PhanParamTooFewInternal -- Phan bug with PHP 8.4: https://github.com/phan/phan/issues/4888
die();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
exit( $arg );
} else {
// @phan-suppress-current-line UnusedPluginSuppression @phan-suppress-next-line PhanParamTooFewInternal -- Phan bug with PHP 8.4: https://github.com/phan/phan/issues/4888
exit();
}
2 changes: 0 additions & 2 deletions projects/packages/scheduled-updates/.phan/baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@
return [
// # Issue statistics:
// PhanTypeArraySuspiciousNullable : 2 occurrences
// PhanCompatibleAccessMethodOnTraitDefinition : 1 occurrence

// Currently, file_suppressions and directory_suppressions are the only supported suppressions
'file_suppressions' => [
'src/pluggable.php' => ['PhanTypeArraySuspiciousNullable'],
'tests/php/Scheduled_Updates_Test.php' => ['PhanCompatibleAccessMethodOnTraitDefinition'],
],
// 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed.
// (directory_suppressions will currently be ignored by subsequent calls to --save-baseline, but may be preserved in future Phan releases)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Tests: Improve compatibility with PHP 8.5.
1 change: 0 additions & 1 deletion projects/packages/scheduled-updates/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"yoast/phpunit-polyfills": "^4.0.0",
"automattic/jetpack-changelogger": "@dev",
"automattic/jetpack-test-environment": "@dev",
"php-mock/php-mock-phpunit": "^2.10",
"automattic/phpunit-select-config": "@dev"
},
"suggest": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@
#[CoversClass( WPCOM_REST_API_V2_Endpoint_Update_Schedules::class )]
class Scheduled_Updates_Health_Paths_Test extends \WorDBless\BaseTestCase {

/**
* Used to mock global functions inside a namespace.
*
* @see https://github.com/php-mock/php-mock-phpunit
*/
use \phpmock\phpunit\PHPMock;

/**
* Admin user ID.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,13 @@
#[CoversClass( Scheduled_Updates_Logs::class )]
class Scheduled_Updates_Logs_Test extends \WorDBless\BaseTestCase {

/**
* Used to mock global functions inside a namespace.
*
* @see https://github.com/php-mock/php-mock-phpunit
*/
use \phpmock\phpunit\PHPMock;

/**
* Admin user ID.
*
* @var int
*/
public $admin_id;

/**
* Set up before class.
*
* @see Restrictions here: https://github.com/php-mock/php-mock-phpunit?tab=readme-ov-file#restrictions
*/
public static function set_up_before_class() {
parent::set_up_before_class();

static::defineFunctionMock( 'Automattic\Jetpack', 'realpath' );
}

/**
* Set up.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
namespace Automattic\Jetpack;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;

/**
* Test class for Scheduled_Updates.
Expand All @@ -20,13 +19,6 @@
#[CoversClass( \WPCOM_REST_API_V2_Endpoint_Update_Schedules::class )]
class Scheduled_Updates_Test extends \WorDBless\BaseTestCase {

/**
* Used to mock global functions inside a namespace.
*
* @see https://github.com/php-mock/php-mock-phpunit
*/
use \phpmock\phpunit\PHPMock;

/**
* Admin user ID.
*
Expand All @@ -41,16 +33,6 @@ class Scheduled_Updates_Test extends \WorDBless\BaseTestCase {
*/
public $wp_filesystem;

/**
* Set up before class.
*
* @see Restrictions here: https://github.com/php-mock/php-mock-phpunit?tab=readme-ov-file#restrictions
*/
public static function set_up_before_class() {
parent::set_up_before_class();
\phpmock\phpunit\PHPMock::defineFunctionMock( 'Automattic\Jetpack', 'realpath' );
}

/**
* Set up.
*/
Expand Down Expand Up @@ -93,6 +75,8 @@ protected function tear_down() {
delete_option( 'jetpack_scheduled_update_statuses' );
delete_option( 'auto_update_plugins' );

unset( $GLOBALS['mock_realpath'] );

parent::tear_down_wordbless();
}

Expand Down Expand Up @@ -127,16 +111,12 @@ public function test_unmanaged_plugins_not_in_root_directory() {

/**
* Simulate managed plugins linked from a root /wordpress directory.
*
* @group failing
*/
#[Group( 'failing' )]
public function test_managed_plugins() {
symlink( WP_PLUGIN_DIR . '/wordpress/managed-plugin', WP_PLUGIN_DIR . '/managed-plugin' );

// Tweak realpath so that it returns `/wordpress/...`.
$realpath = $this->getFunctionMock( __NAMESPACE__, 'realpath' );
$realpath->expects( $this->once() )->willReturn( '/wordpress/plugins/managed-plugin' );
// Mock realpath to return a path starting with /wordpress/.
$GLOBALS['mock_realpath'][ WP_PLUGIN_DIR . '/managed-plugin' ] = '/wordpress/plugins/managed-plugin';

$request = new \WP_REST_Request( 'GET', '/wp/v2/plugins' );
$result = rest_do_request( $request );
Expand Down Expand Up @@ -690,13 +670,8 @@ public function test_verify_plugins_installed_mixed() {
$plugins = array( 'managed-plugin/managed-plugin.php', 'installed-plugin/installed-plugin.php' );
symlink( WP_PLUGIN_DIR . '/wordpress/managed-plugin', WP_PLUGIN_DIR . '/managed-plugin' );

// Tweak realpath so that it returns `/wordpress/...` for the managed plugin.
$realpath = $this->getFunctionMock( __NAMESPACE__, 'realpath' );
$realpath->expects( $this->once() )->willReturnCallback(
function ( $path ) {
return str_replace( WP_PLUGIN_DIR, '/wordpress/plugins', $path );
}
);
// Mock realpath to return a path starting with /wordpress/ for the managed plugin.
$GLOBALS['mock_realpath'][ WP_PLUGIN_DIR . '/managed-plugin' ] = '/wordpress/plugins/managed-plugin';

$request = new \WP_REST_Request( 'POST', '/wpcom/v2/update-schedules' );
$request->set_body_params(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@
#[CoversClass( WPCOM_REST_API_V2_Endpoint_Update_Schedules_Active::class )]
class WPCOM_REST_API_V2_Endpoint_Update_Schedules_Active_Test extends \WorDBless\BaseTestCase {

/**
* Used to mock global functions inside a namespace.
*
* @see https://github.com/php-mock/php-mock-phpunit
*/
use \phpmock\phpunit\PHPMock;

/**
* Admin user ID.
*
Expand Down
5 changes: 5 additions & 0 deletions projects/packages/scheduled-updates/tests/php/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
mkdir( WP_PLUGIN_DIR, 0777, true ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_mkdir
}

/**
* Include mock functions before autoloader so they're available when classes are loaded.
*/
require_once __DIR__ . '/mock-functions.php';

/**
* Include the composer autoloader and dependencies.
*/
Expand Down
24 changes: 24 additions & 0 deletions projects/packages/scheduled-updates/tests/php/mock-functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* Mock functions for testing
*
* @package automattic/scheduled-updates
*/

namespace Automattic\Jetpack;

/**
* Mock realpath in the current namespace
*
* If $GLOBALS['mock_realpath'][ $path ] is set, it will be used as the return value.
* Otherwise, it falls back to the native realpath function.
*
* @param string $path The path to resolve.
* @return string|false The resolved path or false on failure.
*/
function realpath( $path ) {
if ( isset( $GLOBALS['mock_realpath'][ $path ] ) ) {
return $GLOBALS['mock_realpath'][ $path ];
}
return \realpath( $path );
}
Loading
Loading