From 9ee17a79210e9010fb774c841de559c2cf26d2fe Mon Sep 17 00:00:00 2001
From: Anton Vlasenko <43744263+anton-vlasenko@users.noreply.github.com>
Date: Mon, 16 Jan 2023 13:49:44 +0100
Subject: [PATCH] Run PHPUnit jobs across multiple PHP versions (#46510)
1. Run PHPUnit tests on all PHP versions (5.6 through 8.2) using the CI jobs.
2. Shows code style errors on the "Files changed" tab (same as Core);
3. Fix an issue with wp-env as it used non-optimal PHPUnit versions on PHP 7.3 and 7.4;
Props @jrfnl , @dmsnell , @anton-vlasenko
---
.cache/.gitkeep | 0
.github/workflows/unit-test.yml | 162 ++++++++++++++++--
.gitignore | 7 +
packages/env/CHANGELOG.md | 6 +
.../env/lib/build-docker-compose-config.js | 6 +-
phpcs.xml.dist | 3 +
phpunit/block-supports/layout-test.php | 15 ++
...ock-pattern-categories-controller-test.php | 27 ++-
phpunit/class-wp-theme-json-resolver-test.php | 15 ++
phpunit/wp-theme-json-test.php | 14 ++
10 files changed, 235 insertions(+), 20 deletions(-)
create mode 100644 .cache/.gitkeep
diff --git a/.cache/.gitkeep b/.cache/.gitkeep
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml
index c1fd9850191da..4a5d1f89bb33e 100644
--- a/.github/workflows/unit-test.yml
+++ b/.github/workflows/unit-test.yml
@@ -9,6 +9,8 @@ on:
- trunk
- 'release/**'
- 'wp/**'
+ # Allow manually triggering the workflow.
+ workflow_dispatch:
# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
@@ -51,39 +53,179 @@ jobs:
- name: Running the date tests
run: npm run test:unit:date -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache"
- unit-php:
- name: PHP
+ test-php:
+ name: PHP ${{ matrix.php }}${{ matrix.multisite && ' multisite' || '' }} on ubuntu-latest
runs-on: ubuntu-latest
+ timeout-minutes: 20
if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }}
+ strategy:
+ fail-fast: true
+ matrix:
+ php:
+ - '5.6'
+ - '7.0'
+ - '7.1'
+ - '7.2'
+ - '7.3'
+ - '7.4'
+ - '8.0'
+ - '8.1'
+ - '8.2'
+ multisite: [false, true]
+
+ env:
+ WP_ENV_PHP_VERSION: ${{ matrix.php }}
steps:
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
- - name: Use desired version of NodeJS
+ - name: Set up Node.js
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3.5.1
with:
node-version-file: '.nvmrc'
cache: npm
- - name: Npm install and build
+ ##
+ # This allows Composer dependencies to be installed using a single step.
+ #
+ # Since the tests are currently run within the Docker containers where the PHP version varies,
+ # the same PHP version needs to be configured for the action runner machine so that the correct
+ # dependency versions are installed and cached.
+ ##
+ - name: Set up PHP
+ uses: shivammathur/setup-php@1a18b2267f80291a81ca1d33e7c851fe09e7dfc4 # v2.22.0
+ with:
+ php-version: '${{ matrix.php }}'
+ ini-file: development
+ coverage: none
+
+ # Ensure that Composer installs the correct versions of packages.
+ - name: Override PHP version in composer.json
+ run: composer config platform.php ${{ matrix.php }}
+
+ # The spatie/phpunit-watcher package is not compatible with PHP < 7.2.
+ # It must be removed before running the tests.
+ - name: Remove incompatible Composer packages
+ if: ${{ matrix.php < '7.2' }}
+ run: composer remove spatie/phpunit-watcher --dev --no-update
+
+ # 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@83af392bf5f031813d25e6fe4cd626cdba9a2df6 # v2.2.0
+ with:
+ custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F")
+
+ - name: Install npm dependencies
run: |
npm ci
npm run build
- - name: Install WordPress
+ - name: Docker debug information
run: |
- npm run wp-env start
+ docker -v
+ docker-compose -v
- - name: Running lint check
- run: npm run lint:php
+ - name: General debug information
+ run: |
+ npm --version
+ node --version
+ curl --version
+ git --version
+ svn --version
+ locale -a
+
+ - name: Start Docker environment
+ run: npm run wp-env start
+
+ - name: Log running Docker containers
+ run: docker ps -a
+
+ - name: Docker container debug information
+ run: |
+ npm run wp-env run tests-mysql "mysql --version"
+ npm run wp-env run tests-wordpress "php --version"
+ npm run wp-env run tests-wordpress "php -m"
+ npm run wp-env run tests-wordpress "php -i"
+ npm run wp-env run tests-wordpress "/var/www/html/wp-content/plugins/gutenberg/vendor/bin/phpunit --version"
+ npm run wp-env run tests-wordpress "locale -a"
- name: Running single site unit tests
+ if: ${{ ! matrix.multisite }}
run: npm run test:unit:php
- if: ${{ success() || failure() }}
- name: Running multisite unit tests
+ if: ${{ matrix.multisite }}
run: npm run test:unit:php:multisite
- if: ${{ success() || failure() }}
+
+ phpcs:
+ name: PHP coding standards
+ runs-on: ubuntu-latest
+ timeout-minutes: 20
+ if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }}
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+
+ - name: Set up PHP
+ uses: shivammathur/setup-php@1a18b2267f80291a81ca1d33e7c851fe09e7dfc4 # v2.22.0
+ with:
+ php-version: '7.4'
+ coverage: none
+ tools: cs2pr
+
+ # This date is used to ensure that the PHPCS 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
+
+ - name: Cache PHPCS scan cache
+ uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ with:
+ path: .cache/phpcs.json
+ key: ${{ runner.os }}-date-${{ steps.get-date.outputs.date }}-phpcs-cache-${{ hashFiles('**/composer.json', 'phpcs.xml.dist') }}
+
+ # 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@83af392bf5f031813d25e6fe4cd626cdba9a2df6 # v2.2.0
+ with:
+ custom-cache-suffix: ${{ steps.get-date.outputs.date }}
+
+ - name: Make Composer packages available globally
+ run: echo "${PWD}/vendor/bin" >> $GITHUB_PATH
+
+ - name: Run PHPCS on all Gutenberg files
+ id: phpcs-gutenberg
+ run: phpcs --report-full --report-checkstyle=./.cache/phpcs-report.xml
+
+ - name: Show PHPCS results in PR
+ if: ${{ always() && steps.phpcs-gutenberg.outcome == 'failure' }}
+ run: cs2pr ./.cache/phpcs-report.xml
+
+ - name: Ensure version-controlled files are not modified during the tests
+ run: git diff --exit-code
+
+ # This job is deprecated but be present for compatibility reasons.
+ unit-php:
+ name: PHP
+ runs-on: ubuntu-latest
+ needs: [test-php, phpcs]
+ if: ${{ always() }}
+ steps:
+ - name: Fail the job if the PHPUnit tests fail
+ if: ${{ needs.test-php.result != 'success' }}
+ run: exit 1
+
+ - name: "Fail the job if the code doesn't conform to the coding standards"
+ if: ${{ needs.phpcs.result != 'success' }}
+ run: exit 1
+
+ - name: Mark the job as passed if all the checks pass
+ if: ${{ needs.test-php.result == 'success' && needs.phpcs.result == 'success' }}
+ run: exit 0
mobile-unit-js:
name: Mobile
diff --git a/.gitignore b/.gitignore
index aebfcd623ad2f..71ffc1c5bbb25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,7 +16,14 @@ yarn.lock
/perf-envs
/composer.lock
+# The /.cache folder is needed for phpcs to cache results between runs, while other .cache folders must be ignored
+# It is not possible to re-include a file if a parent directory of that file is excluded
+# So, both /.cache and /.cache./.gitkeep must be re-included
.cache
+!/.cache/
+/.cache/**
+!/.cache/.gitkeep
+
.eslintcache
*.tsbuildinfo
diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md
index 8bf26e02df19f..e8e0c0e1b5407 100644
--- a/packages/env/CHANGELOG.md
+++ b/packages/env/CHANGELOG.md
@@ -2,6 +2,12 @@
## Unreleased
+### Bug fix
+- PHP 7.3 and 7.4 must use PHPUnit 9.
+
+### Enhancement
+- It's now possible to run PHPUnit tests on PHP 8.1 and 8.2.
+
## 5.9.0 (2023-01-02)
## 5.8.0 (2022-12-14)
diff --git a/packages/env/lib/build-docker-compose-config.js b/packages/env/lib/build-docker-compose-config.js
index ff85ba807f00a..7b27f85a7f6cf 100644
--- a/packages/env/lib/build-docker-compose-config.js
+++ b/packages/env/lib/build-docker-compose-config.js
@@ -181,9 +181,11 @@ module.exports = function buildDockerComposeConfig( config ) {
phpunitTag = '6' + phpunitPhpVersion;
} else if ( testsPhpVersion === '7.1' ) {
phpunitTag = '7' + phpunitPhpVersion;
- } else if ( [ '7.2', '7.3', '7.4' ].indexOf( testsPhpVersion ) >= 0 ) {
+ } else if ( testsPhpVersion === '7.2' ) {
phpunitTag = '8' + phpunitPhpVersion;
- } else if ( testsPhpVersion === '8.0' ) {
+ } else if (
+ [ '7.3', '7.4', '8.0', '8.1', '8.2' ].indexOf( testsPhpVersion ) >= 0
+ ) {
phpunitTag = '9' + phpunitPhpVersion;
}
const phpunitImage = `wordpressdevelop/phpunit:${ phpunitTag }`;
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 7473a44d819bc..e48167d470ee8 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -32,6 +32,9 @@
+
+
+
./bin
./gutenberg.php
./lib
diff --git a/phpunit/block-supports/layout-test.php b/phpunit/block-supports/layout-test.php
index a22d77cf35408..9a01a371f72de 100644
--- a/phpunit/block-supports/layout-test.php
+++ b/phpunit/block-supports/layout-test.php
@@ -7,6 +7,21 @@
*/
class WP_Block_Supports_Layout_Test extends WP_UnitTestCase {
+ /**
+ * @var string|null
+ */
+ private $theme_root;
+
+ /**
+ * @var array|null
+ */
+ private $orig_theme_dir;
+
+ /**
+ * @var array|null
+ */
+ private $queries;
+
public function set_up() {
parent::set_up();
$this->theme_root = realpath( __DIR__ . '/../data/themedir1' );
diff --git a/phpunit/class-wp-rest-block-pattern-categories-controller-test.php b/phpunit/class-wp-rest-block-pattern-categories-controller-test.php
index beadbfc75d073..bdbaa819ba3f8 100644
--- a/phpunit/class-wp-rest-block-pattern-categories-controller-test.php
+++ b/phpunit/class-wp-rest-block-pattern-categories-controller-test.php
@@ -14,7 +14,7 @@
*/
class WP_REST_Block_Pattern_Categories_Controller_Test extends WP_Test_REST_Controller_Testcase {
protected static $admin_id;
- protected static $orig_registry;
+ protected static $original_instance_value;
public function set_up() {
parent::set_up();
@@ -26,11 +26,13 @@ public static function wpSetupBeforeClass( $factory ) {
self::$admin_id = $factory->user->create( array( 'role' => 'administrator' ) );
// Setup an empty testing instance of `WP_Block_Pattern_Categories_Registry` and save the original.
- $reflection = new ReflectionClass( 'WP_Block_Pattern_Categories_Registry' );
- $reflection->getProperty( 'instance' )->setAccessible( true );
- self::$orig_registry = $reflection->getStaticPropertyValue( 'instance' );
- $test_registry = new WP_Block_Pattern_Categories_Registry();
- $reflection->setStaticPropertyValue( 'instance', $test_registry );
+ $reflection = new ReflectionClass( 'WP_Block_Pattern_Categories_Registry' );
+ $instance_property = $reflection->getProperty( 'instance' );
+ $instance_property->setAccessible( true );
+ self::$original_instance_value = $instance_property->getValue( null );
+
+ $test_registry = new WP_Block_Pattern_Categories_Registry();
+ $instance_property->setValue( $test_registry );
// Register some categories in the test registry.
$test_registry->register( 'test', array( 'label' => 'Test' ) );
@@ -42,8 +44,11 @@ public static function wpTearDownAfterClass() {
self::delete_user( self::$admin_id );
// Restore the original registry instance.
- $reflection = new ReflectionClass( 'WP_Block_Pattern_Categories_Registry' );
- $reflection->setStaticPropertyValue( 'instance', self::$orig_registry );
+ $reflection = new ReflectionClass( 'WP_Block_Pattern_Categories_Registry' );
+ $instance_property = $reflection->getProperty( 'instance' );
+ $instance_property->setAccessible( true );
+ $instance_property->setValue( self::$original_instance_value );
+ $instance_property->setAccessible( false );
}
public function test_register_routes() {
@@ -79,21 +84,27 @@ public function test_get_items() {
public function test_context_param() {
$this->markTestIncomplete();
}
+
public function test_get_item() {
$this->markTestIncomplete();
}
+
public function test_create_item() {
$this->markTestIncomplete();
}
+
public function test_update_item() {
$this->markTestIncomplete();
}
+
public function test_delete_item() {
$this->markTestIncomplete();
}
+
public function test_prepare_item() {
$this->markTestIncomplete();
}
+
public function test_get_item_schema() {
$this->markTestIncomplete();
}
diff --git a/phpunit/class-wp-theme-json-resolver-test.php b/phpunit/class-wp-theme-json-resolver-test.php
index f872b251a7784..7b46dc3cd0d4a 100644
--- a/phpunit/class-wp-theme-json-resolver-test.php
+++ b/phpunit/class-wp-theme-json-resolver-test.php
@@ -43,6 +43,21 @@ class WP_Theme_JSON_Resolver_Gutenberg_Test extends WP_UnitTestCase {
*/
private static $property_core_orig_value;
+ /**
+ * @var string|null
+ */
+ private $theme_root;
+
+ /**
+ * @var array|null
+ */
+ private $orig_theme_dir;
+
+ /**
+ * @var array|null
+ */
+ private $queries;
+
public static function set_up_before_class() {
parent::set_up_before_class();
diff --git a/phpunit/wp-theme-json-test.php b/phpunit/wp-theme-json-test.php
index 0d92d33faf88d..96fd1ec82c5f1 100644
--- a/phpunit/wp-theme-json-test.php
+++ b/phpunit/wp-theme-json-test.php
@@ -6,6 +6,20 @@
*/
class WP_Theme_Json_Test extends WP_UnitTestCase {
+ /**
+ * @var string|null
+ */
+ private $theme_root;
+
+ /**
+ * @var array|null
+ */
+ private $orig_theme_dir;
+
+ /**
+ * @var array|null
+ */
+ private $queries;
public function set_up() {
parent::set_up();