From 9adea280c4b3876777a6652b2d0f76ec013c5c2b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 12 Mar 2022 02:57:48 +0100 Subject: [PATCH] CI: switch to GitHub Actions - step 5: PHP unit tests This commit: * Adds a GH Actions workflow for the PHPUnit CI check. * Removes all references to that check from the `.travis.yml` configuration. * Adds a "Unit Tests" badge in the Readme using the results from the GH `Unit Test` Action runs. Notes: 1. Builds will run on: - Select pushes using branch filtering similar to before. - All pull requests. - When manually triggered. Note: manual triggering of builds has to be [explicitly allowed](https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/). This is not a feature which is enabled by default. 2. If a previous GH actions run for the same branch hadn't finished yet when the same branch is pushed again, the previous run will be cancelled. In Travis, this was an option on the "Settings" page - "Auto cancellation" -, which was turned on for most, if not all, Yoast repos. The `concurrency` configuration in the GHA script emulates the same behaviour. 3. The default ini settings used by the `setup-php` action are based on the `php.ini-production` configuration. This means that `error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT`, `display_errors` is set to `Off` and `zend.assertions` is set to `-1` (= do not compile). For the purposes of CI, especially for linting and testing code, I'd recommend running with `zend.assertions=-1`, `error_reporting=-1` and `display_errors=On` to ensure **all** PHP notices are shown. Note: the defaults will be changed in the next major of `setup-php` to be based on the `php.ini-develop` configuration, but that may still be a while off. Refs: * https://github.com/shivammathur/setup-php/issues/450 * https://github.com/shivammathur/setup-php/issues/469 4. While the `setup-php` action offers the ability to [install the PHAR file for PHPUnit](https://github.com/shivammathur/setup-php#wrench-tools-support), I've elected not to use that option as we need to do a `composer install` anyway to get the other dependencies, like WP Test Utils. 5. Composer dependency downloads will be cached for faster builds using a [predefined GH action](https://github.com/marketplace/actions/install-composer-dependencies) specifically created for this purpose. The alternative would be to handle the caching manually, which would add three extra steps to the script. Note: Caching works differently between Travis and GH Actions. On GH Actions, once a cache has been created, it can't be updated. It can only be replaced by a new cache with a different key. As the PHP version, the `composer.json` and a potential `composer.lock` hash are all part of the key used by the above mentioned action, this difference should not have a significant impact. Ref: https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows 6. As the prefixing of the dependencies needs a higher PHP version, the `setup-php` action is used twice within this workflow. The first time, it sets up PHP 7.2 to allow for creating the `vendor_prefixed` directory. The second time, it sets up the PHP version on which we want to do the actual linting. Note: last time I checked, I found that within a workflow you can only switch PHP versions once, but that is sufficient for our purposes. (may have changed in the mean time) 7. For these BrainMonkey based unit tests, we can (and should) use the most appropriate PHPUnit/BrainMonkey/Mockery/etc version for the PHP version the tests are being run on. Most notably, this is actually needed to get the tests running on PHP 8.0 and higher. As there is a committed `composer.lock` file and the PHPUnit version is locked at PHPUnit 5.x, this means we have to do an on-the-fly update of the PHPUnit version depending on the PHP version of the current build. As the `composer.lock` file for this plugin also contains dependencies which are locked at versions which are incompatible with the full range of PHP versions supported by the plugin, we need to do some juggling to allow the testing to work (on all supported PHP versions). Previously in Travis, an uncontrolled `composer update` would be run to get round this. Uncontrolled updates are generally not a good idea in CI as you may end up with passing tests based on updated dependencies, while in reality things would fail. So, for this workflow, I've chosen to approach this slightly differently (compared to Travis), but still tried to keep things as simple as possible. - First a full install is done on PHP 7.2. This will generate the `vendor_prefixed` directory and create the generated files for the dependency injection, as well as set up all dependencies. - Next, the dependencies which are only needed for the prefixing are removed. This will remove a couple of dependencies which would automatically be loaded by Composer on loading of the autoload file (due to the use of `autoload.files` in those dependencies) and would trigger a parse error on PHP < 7.2 as they contain non-cross-version compatible code. - Lastly, we remove the `vendor` directory. - Now those incompatible dependencies are removed, we switch to the actual PHP version we want to use for the tests. - Next, we remove the `phpunit/phpunit` root requirement as it is already a dependency of the WP Test Utils and we don't want to abide by the locked version of PHPUnit. - We then run a selective `composer update` to install the locked dependencies and update just and only the test dependencies to match the PHP version on which we will be running the tests. Altogether, this prevents the uncontrolled dependency update. Additionally, the `--no-scripts` addition to the Composer run commands when run on the _real_ PHP version, will prevent the prefixing/dependency injection tasks from being run again on incompatible PHP versions. Note: no need for adding `--no-interaction` to the plain `composer ...` commands as the `setup-php` action already sets an environment variable to ensure Composer will always run with `--no-interaction` in these workflows. Differences with the Travis implementation: * The most appropriate version of the test dependencies will now be used for _all_ builds, not just for builds against PHP 8.0/`nightly`. * In Travis, there was a reference to a `atanamo/php-codeshift` package, which was removed after the prefixing was finished. This package is not a (root) dependency of the WPSEO Free plugin, so removing it doesn't actually have any effect. Instead, the `league/oauth2-client` package is removed, as that package should not be used during the test run as it will be prefixed and the prefixed version should be used instead. * Except for the test dependencies, no other dependencies will be updated during the test run. * In addition to the PHP versions against which the tests were previously run on Travis, the tests will now also be run against PHP 8.1. As PHP 8.1 has been released, the (remaining) test failures on this build need to be fixed, though as these are only _deprecation notices_, the fact that these tests are currently failing is nothing to be too concerned about for the time being. To prevent new failures from being introduced in the mean time, I'm not allowing the build to fail, but will instead add expectations for the deprecations or skip requirements to the few tests which still have them for the time being. REMOVE ADD TO: unit test --- .github/workflows/unittest.yml | 78 ++++++++++++++++++++++++++++++++++ .travis.yml | 16 ------- README.md | 1 + 3 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/unittest.yml diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml new file mode 100644 index 00000000000..0cf6db1a4a3 --- /dev/null +++ b/.github/workflows/unittest.yml @@ -0,0 +1,78 @@ +name: Unit Test + +on: + # Run on pushes to select branches and on all pull requests. + push: + branches: + - master + - trunk + - 'release/**' + - 'hotfix/[0-9]+.[0-9]+*' + - 'feature/**' + pull_request: + # Allow manually triggering the workflow. + workflow_dispatch: + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + unit-test: + runs-on: ubuntu-latest + + strategy: + matrix: + php_version: ['5.6', '7.0', '7.2', '7.4', '8.0', '8.1'] + + name: "Unit Test: PHP ${{ matrix.php_version }}" + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + # The prefix-dependencies task makes use of reflection-based PHP code that only works on PHP > 7.2. + - name: Install PHP 7.x for generating the vendor_prefixed directory and dependency injection + uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + coverage: none + + - name: Install Composer dependencies, generate vendor_prefixed directory and run dependency injection + uses: ramsey/composer-install@v2 + + # Remove packages which are not PHP cross-version compatible and only used for the prefixing. + # - humbug/php-scoper is only needed to actually do the prefixing, so won't be shipped anyway. + # - league/oauth2-client and its dependencies *are* the packages being prefixed. + - name: Delete dependencies which are not cross-version compatible + run: composer remove --dev --no-scripts humbug/php-scoper league/oauth2-client + + - name: Remove vendor directory + run: rm -rf vendor/* + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php_version }} + ini-values: zend.assertions=1, error_reporting=-1, display_errors=On + coverage: none + + - name: "Composer: remove PHPUnit root requirement" + run: composer remove --dev phpunit/phpunit --no-update --no-scripts + + # Install dependencies and handle caching in one go. + # - Updates the test utilities (and only those!) to the most appropriate version + # for the PHP version on which the tests will be run. + # @link https://github.com/marketplace/actions/install-composer-dependencies + - name: Install Composer dependencies + uses: ramsey/composer-install@v2 + with: + # Force a `composer update` run. + dependency-versions: "highest" + # But make it selective. + composer-options: "yoast/wp-test-utils --with-dependencies --no-scripts" + + - name: Run unit tests + run: composer test diff --git a/.travis.yml b/.travis.yml index eae71a9fadd..104e997bdfa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -211,22 +211,6 @@ script: vendor/bin/phpunit -c phpunit-integration.xml.dist travis_time_finish && travis_fold end "PHP.integration-tests" fi - - | - if [[ "$PHPUNIT" == "1" && ${TRAVIS_PHP_VERSION:0:1} != "8" && $TRAVIS_PHP_VERSION != "nightly" ]]; then - # PHP < 8 - travis_fold start "PHP.tests" && travis_time_start - vendor/bin/phpunit - travis_time_finish && travis_fold end "PHP.tests" - fi - - | - if [[ "$PHPUNIT" == "1" ]] && [[ ${TRAVIS_PHP_VERSION:0:1} == "8" || $TRAVIS_PHP_VERSION == "nightly" ]]; then - # PHP >= 8 - travis_fold start "PHP.tests" && travis_time_start - travis_retry composer require --dev phpunit/phpunit:"^9.0" --update-with-dependencies --ignore-platform-reqs --no-interaction && - travis_retry composer update yoast/wp-test-utils --with-all-dependencies --ignore-platform-reqs --no-interaction && - vendor/bin/phpunit - travis_time_finish && travis_fold end "PHP.tests" - fi - | if [[ "$COVERAGE" == "1" ]]; then travis_fold start "PHP.coverage" && travis_time_start diff --git a/README.md b/README.md index 26353127f24..3dc048244c7 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![CS](https://github.com/Yoast/wordpress-seo/actions/workflows/cs.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/cs.yml) [![Lint](https://github.com/Yoast/wordpress-seo/actions/workflows/lint.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/lint.yml) [![JS](https://github.com/Yoast/wordpress-seo/actions/workflows/js.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/js.yml) +[![Unit Tests](https://github.com/Yoast/wordpress-seo/actions/workflows/unittest.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/unittest.yml) [![Build Status](https://api.travis-ci.com/Yoast/wordpress-seo.svg?branch=master)](https://travis-ci.com/Yoast/wordpress-seo) [![Stable Version](https://poser.pugx.org/yoast/wordpress-seo/v/stable.svg)](https://packagist.org/packages/yoast/wordpress-seo) [![License](https://poser.pugx.org/yoast/wordpress-seo/license.svg)](https://packagist.org/packages/yoast/wordpress-seo)