From 9c48c6daa5cfc9dffb96fb59945e842dec6d2664 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 11 Sep 2024 09:34:24 +0200 Subject: [PATCH] GH Actions: test with different sets of extensions PHP 8.4 removes the IMAP extension (moved to PECL). With this in mind, I've reviewed how the tests are being run versus the extension requirements and recommendations. As things are, the tests are currently run in the "ideal" environment, i.e. with all required and optional extensions available. However, the codebase also contains fall-backs for when certain extensions are **_not_** available and for at least some of those fallbacks, there are dedicated tests available, but in an ideal environment those tests will not run and the fall-backs are not tested, which is the case with the current CI setup. To improve this situation, I'm proposing to keep running the tests against all PHP versions with the "ideal" extension set, but to also have additional test runs with a far more limited set of PHP extensions. To determine which extensions should be in each set, I've looked at the following: * `@requires` tags found in the test suite and the conditions for calls to `markTestSkipped()`. This brought to light that the `openssl` extension was currently not listed in the "ideal" extension set. This has now been fixed. * The required extensions of PHPUnit - `dom, json, libxml, mbstring, tokenizer, xml, xmlwriter`. * The required extensions of PHPMailer itself - `ctype, filter, hash`. * Not strictly required, but more for convenience/workflow speed: `curl` for Composer. * And `xdebug` will still be enabled/disabled based on the `coverage` setting. Note: while some tests would benefit from being run _without_ the `mbstring` extension, that's unfortunately not an option as `mbstring` is a requirement of PHPUnit :shrug: Also note, the tests with the "minimal" extension setup needs to run `composer install` with an `--ignore-platform-req` flag to prevent running into the following issue: ``` Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems. ``` As this extension "requirement" is for a dependency which is not used in the test run, the extension requirement can be safely ignored. --- .github/workflows/tests.yml | 50 ++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cb32e6399..812c39965 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -88,23 +88,39 @@ jobs: strategy: matrix: php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + extensions: ['optimal', 'minimal'] coverage: [false] experimental: [false] include: # Run code coverage on high/low PHP. - php: '5.5' + extensions: 'optimal' + coverage: true + experimental: false + - php: '5.5' + extensions: 'minimal' + coverage: true + experimental: false + - php: '8.3' + extensions: 'optimal' coverage: true experimental: false - php: '8.3' + extensions: 'minimal' coverage: true experimental: false # Experimental builds. These are allowed to fail. - php: '8.4' + extensions: 'optimal' + coverage: false + experimental: true + - php: '8.4' + extensions: 'minimal' coverage: false experimental: true - name: "Test: PHP ${{ matrix.php }}" + name: "Test: PHP ${{ matrix.php }}, ${{ matrix.extensions }}" continue-on-error: ${{ matrix.experimental }} @@ -112,13 +128,40 @@ jobs: - name: Check out code uses: actions/checkout@v4 + # About the "extensions": + # + # In a "normal" test run, the "default" extension set for a PHP version is used + # and it is ensured that certain extensions will be available, no matter what. + # + # For the "minimal" test run, all extensions are disabled and then then only + # a limited set of minimally required extensions are re-enabled. + # The minimal set is based on the required extensions from PHPUnit + PHPMailer combined + # + Curl for Composer. + # Whether Xdebug will be enabled depends on the code coverage settings. + # + # Also see: + # https://github.com/shivammathur/setup-php/?tab=readme-ov-file#heavy_plus_sign-php-extension-support + # https://github.com/shivammathur/setup-php/wiki + - name: Determine extensions to use + id: set_extensions + run: | + if [[ "${{ matrix.extensions }}" == "optimal" ]]; then + # Optimal. + echo 'EXT=imap, mbstring, openssl, intl, ctype, filter, hash' >> $GITHUB_OUTPUT + echo 'COMPOSER_OPTIONS=' >> $GITHUB_OUTPUT + else + # Minimal. + echo 'EXT=none, curl, dom, json, libxml, mbstring, tokenizer, xml, xmlwriter, ctype, filter, hash' >> $GITHUB_OUTPUT + echo 'COMPOSER_OPTIONS=--ignore-platform-req=ext-simplexml' >> $GITHUB_OUTPUT + fi + - name: Set up PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} coverage: ${{ matrix.coverage && github.repository == 'PHPMailer/PHPMailer' && 'xdebug' || 'none' }} ini-values: sendmail_path=/usr/sbin/sendmail -t -i, error_reporting=E_ALL, display_errors=On - extensions: imap, mbstring, intl, ctype, filter, hash + extensions: ${{ steps.set_extensions.outputs.EXT }} # Install dependencies and handle caching in one go. # @link https://github.com/marketplace/actions/install-php-dependencies-with-composer @@ -126,6 +169,7 @@ jobs: if: ${{ matrix.php != '8.4' }} uses: "ramsey/composer-install@v3" with: + composer-options: ${{ steps.set_extensions.outputs.COMPOSER_OPTIONS }} # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") @@ -133,7 +177,7 @@ jobs: if: ${{ matrix.php == '8.4' }} uses: "ramsey/composer-install@v3" with: - composer-options: --ignore-platform-reqs + composer-options: --ignore-platform-reqs ${{ steps.set_extensions.outputs.COMPOSER_OPTIONS }} # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m")