diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml index 1313bd9e..9ad14740 100644 --- a/.github/workflows/plugin-ci-workflow.yml +++ b/.github/workflows/plugin-ci-workflow.yml @@ -45,12 +45,23 @@ jobs: integration-test: timeout-minutes: 45 runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.experimental }} strategy: fail-fast: false matrix: - php: ['8.2', '8.3', '8.4'] + php: ['8.2', '8.3', '8.4', '8.5'] os: [ubuntu-latest] + experimental: [false] + include: + # PHP 8.6 runs as a non-blocking (experimental) leg because + # its packages can lag on the runners and in Ondřej Surý's PPA. + # Pinned to Ubuntu 24.04 (Noble): ubuntu-latest is now Ubuntu 26.04 + # (Resolute), which Ondrej Sury's PPA does not yet serve, so the 8.6 + # PPA toolchain install 404s. Noble carries the latest packaged 8.6 RC. + - php: '8.6' + os: ubuntu-24.04 + experimental: true services: mariadb: @@ -88,6 +99,7 @@ jobs: fetch-depth: 0 - name: Install PHP ${{ matrix.php }} + if: matrix.php != '8.6' uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # 2.40.0 with: php-version: ${{ matrix.php }} @@ -96,6 +108,41 @@ jobs: coverage: xdebug ini-values: "post_max_size=256M, max_execution_time=60, date.timezone=America/New_York" + # PHP 8.6 is still pre-release. shivammathur/setup-php ships a nightly + # 8.6.0-dev build whose bundled extensions are ABI-skewed against their own + # core (undefined symbol: smart_str_ferealloc / _safe_femalloc), so every + # extension fails to load and the CLI install dies. Ondřej Surý's PPA + # provides a coherent 8.6 RC build, so this experimental leg provisions the + # CLI from there instead. + - name: Install PHP 8.6 toolchain from Ondřej Surý's PPA + if: matrix.php == '8.6' + run: | + set -euo pipefail + sudo add-apt-repository -y ppa:ondrej/php + sudo apt-get update + sudo apt-get install -y \ + php8.6-cli php8.6-common \ + php8.6-intl php8.6-mysql php8.6-gd php8.6-ldap \ + php8.6-gmp php8.6-xml php8.6-curl php8.6-mbstring \ + php8.6-snmp php8.6-sqlite3 + # Make the Ondřej 8.6 CLI the default `php` so composer and the tests + # run under the same ABI-coherent build. + sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.6 86 + sudo update-alternatives --set php /usr/bin/php8.6 + # Mirror the ini values the other legs receive via setup-php. + printf '%s\n' \ + 'post_max_size=256M' \ + 'max_execution_time=60' \ + 'date.timezone=America/New_York' \ + | sudo tee /etc/php/8.6/cli/conf.d/99-cacti-ci.ini >/dev/null + # setup-php normally provides Composer; it is skipped for this leg, so + # make sure a Composer binary is available for the dependency steps. + if ! command -v composer >/dev/null 2>&1; then + sudo apt-get install -y composer + fi + php -v + composer --version + - name: Check PHP version run: php -v @@ -235,7 +282,9 @@ jobs: # inside a live Cacti. What is enforceable is that a change covers the # lines it adds. - name: Enforce coverage of changed lines - if: github.event_name == 'pull_request' + # PHP 8.6 installs from the Ondřej PPA, which has no matching xdebug + # build yet, so there is no coverage driver on that experimental leg. + if: github.event_name == 'pull_request' && matrix.php != '8.6' env: BASE_REF: ${{ github.event.pull_request.base.sha }} run: | @@ -295,7 +344,7 @@ jobs: - name: Run Cacti Poller run: | cd ${{ github.workspace }}/cacti - sudo -u www-data php poller.php --poller=1 --force --debug + sudo runuser -u www-data -g runner -- php poller.php --poller=1 --force --debug if ! grep -q "SYSTEM STATS" log/cacti.log; then echo "Cacti poller did not finish successfully" cat log/cacti.log diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ac11755..5e392cd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ --- develop --- +* dev: Run the CI poller with the shared runner group so RRD files and structured directories pass permission verification * security: Add the Cacti request nonce to plugin script tags so pages comply with the Content-Security-Policy nonce migration * test: Extend the browser E2E run with import, reprocess, dashboard and long owner name paths, and make its login work on Cacti 1.2.x and develop diff --git a/tests/Unit/QueryBuilderGuardTest.php b/tests/Unit/QueryBuilderGuardTest.php index ce4b5222..6a27f6ab 100644 --- a/tests/Unit/QueryBuilderGuardTest.php +++ b/tests/Unit/QueryBuilderGuardTest.php @@ -117,8 +117,19 @@ ->and($report['alert_full_error'])->toBe('The structured query builder is unavailable.') ->and($report['removal'])->toBe([]) ->and($report['removal_error'])->toBe('The structured query builder is unavailable.') - ->and($report['normalize'])->toBe($document, 'The normalize guard must pass the raw document through.') - ->and(is_file(dirname(__DIR__, 2) . '/coverage/clover-guard.xml'))->toBeTrue('The guard fragment must be written for the patch-coverage gate.'); + ->and($report['normalize'])->toBe($document, 'The normalize guard must pass the raw document through.'); + + /* + * The subprocess writes the clover-guard fragment only when an + * xdebug code-coverage driver is available (see run.php above and + * tests/bin/coverage-prepend.php). PHP 8.6 currently ships no + * coverage driver (no xdebug/pcov build yet), so the fragment is + * never produced there. Assert it only when a driver is present, + * so 8.2-8.5 still enforce the patch-coverage gate unchanged. + */ + if (function_exists('xdebug_start_code_coverage')) { + expect(is_file(dirname(__DIR__, 2) . '/coverage/clover-guard.xml'))->toBeTrue('The guard fragment must be written for the patch-coverage gate.'); + } } finally { foreach (['includes/functions.php', 'includes/alarmmanager.php', 'run.php'] as $relative) { $file = $shim . '/' . $relative;