diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9cb7895679..ae6a1c1855 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: - name: Install PHP and Composer uses: shivammathur/setup-php@v2 with: - php-version: "8.2" + php-version: "8.3" tools: "composer:2.8" - name: Install packages from requirements.txt, plus s5cmd (for some tests) run: | diff --git a/.github/workflows/platform-sync.yml b/.github/workflows/platform-sync.yml index b681e19d77..040531f66a 100644 --- a/.github/workflows/platform-sync.yml +++ b/.github/workflows/platform-sync.yml @@ -317,6 +317,7 @@ jobs: echo >> "$GITHUB_STEP_SUMMARY" echo '``````markdown' >> "$GITHUB_STEP_SUMMARY" # six instead of three backticks because our output is likely to also contain series of backticks cat php-support.md >> "$GITHUB_STEP_SUMMARY" + [[ -n "$(tail -c1 php-support.md)" ]] && echo >> "$GITHUB_STEP_SUMMARY" # add trailing newline if necessary echo '``````' >> "$GITHUB_STEP_SUMMARY" # six instead of three backticks because our output is likely to also contain series of backticks - name: Update Dev Center article if: inputs.dry-run == false && inputs.update-devcenter == true diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3d3065c1..a8ec53d286 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## [Unreleased] +### ADD + +- ext-blackfire/1.92.29 [David Zuelke] +- ext-pcov/1.0.12 [David Zuelke] +- PHP/8.4.1 [David Zuelke] + +### CHG + +- Composer/2.2.25 [David Zuelke] ## [v259] - 2024-11-21 diff --git a/bin/compile b/bin/compile index c712e18dce..18e7e41fb9 100755 --- a/bin/compile +++ b/bin/compile @@ -368,9 +368,9 @@ composer validate --no-plugins --no-check-publish --no-check-all --quiet "$COMPO status "Preparing platform package installation..." if [[ $STACK == "heroku-20" ]]; then - HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^7.3.0 | ^8.0.0 <8.4" + HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^7.3.0 | ^8.0.0 <8.5" else - HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^8.0.0 <8.4" + HEROKU_PHP_DEFAULT_RUNTIME_VERSION="^8.0.0 <8.5" fi export HEROKU_PHP_DEFAULT_RUNTIME_VERSION # extract requirements from composer.lock diff --git a/bin/util/eol.php b/bin/util/eol.php index 7567e6e9c7..d3198807cf 100644 --- a/bin/util/eol.php +++ b/bin/util/eol.php @@ -14,6 +14,7 @@ "8.1" => array("2023-11-25", "2025-12-31"), "8.2" => array("2024-12-31", "2026-12-31"), "8.3" => array("2025-12-31", "2027-12-31"), + "8.4" => array("2026-12-31", "2028-12-31"), ); if(basename(__FILE__) != basename($_SERVER["PHP_SELF"])) return $eol; // we're being included, just return the data diff --git a/conf/README.md b/conf/README.md new file mode 100644 index 0000000000..89abb83901 --- /dev/null +++ b/conf/README.md @@ -0,0 +1,7 @@ +These folders contain run-time configs for HTTPD, Nginx and PHP. + +The logic that finds these looks in the base directory first, and then traverses into sub-folders that represent specific version string parts. + +This allows sharing configs between version series, but also overriding (or adding) files for more specific versions, as they take precedence. + +For example, a general `php/php-fpm.conf` can be overridden for PHP 8.* by having a `php/8/php-fpm.conf`; a file that should only apply to PHP 7.3.* without overriding a "parent" could be put into `php/7/3/php-fpm.somepool.conf`. diff --git a/support/build/_conf/README.md b/support/build/_conf/README.md new file mode 100644 index 0000000000..89d8ea573c --- /dev/null +++ b/support/build/_conf/README.md @@ -0,0 +1,7 @@ +These folders contain build-time configs for HTTPD and PHP. + +The logic that finds these looks in the base directory first, and then traverses into sub-folders that represent specific version string parts. + +This allows sharing configs between version series, but also overriding (or adding) files for more specific versions, as they take precedence. + +For example, a general `php/conf.d/000-heroku.ini` can be overridden for PHP 7.* by having a `php/7/conf.d/000-heroku.ini`; a file that should only apply to PHP 8.0.* without overriding a "parent" could be put into `php/8/0/conf.d/001-foobar.ini`. diff --git a/support/build/_conf/php/5/conf.d/010-ext-zend_opcache.ini b/support/build/_conf/php/5/conf.d/010-ext-zend_opcache.ini deleted file mode 100644 index 34b47fcb35..0000000000 --- a/support/build/_conf/php/5/conf.d/010-ext-zend_opcache.ini +++ /dev/null @@ -1,6 +0,0 @@ -zend_extension=opcache.so -opcache.enable_cli=1 -opcache.validate_timestamps=0 -opcache.memory_consumption=128 -opcache.interned_strings_buffer=8 -opcache.max_accelerated_files=4000 diff --git a/support/build/_conf/php/7/0/conf.d/000-heroku.ini b/support/build/_conf/php/7/0/conf.d/000-heroku.ini deleted file mode 100644 index 5e2f79f811..0000000000 --- a/support/build/_conf/php/7/0/conf.d/000-heroku.ini +++ /dev/null @@ -1,17 +0,0 @@ -; in line with Heroku dynos' TZ -date.timezone = UTC - -; we want users to see E_DEPRECATED warnings, as it's not uncommon to accidentally run PHP series newer than on local dev -error_reporting = E_ALL & ~E_STRICT - -; do not expose PHP via headers (just like we don't with web servers) -expose_php = Off - -; legacy -short_open_tag = On - -; dyno filesystems are ephemeral, so there is no point in checking for .user.ini changes -user_ini.cache_ttl = 86400 - -; we need environment variables included in superglobals, as they're used for configuration -variables_order = EGPCS diff --git a/support/build/_conf/php/5/conf.d/000-heroku.ini b/support/build/_conf/php/8/4/conf.d/000-heroku.ini similarity index 90% rename from support/build/_conf/php/5/conf.d/000-heroku.ini rename to support/build/_conf/php/8/4/conf.d/000-heroku.ini index 5e2f79f811..155d5888dd 100644 --- a/support/build/_conf/php/5/conf.d/000-heroku.ini +++ b/support/build/_conf/php/8/4/conf.d/000-heroku.ini @@ -2,7 +2,8 @@ date.timezone = UTC ; we want users to see E_DEPRECATED warnings, as it's not uncommon to accidentally run PHP series newer than on local dev -error_reporting = E_ALL & ~E_STRICT +; PHP 8.4+ no longer has E_STRICT +error_reporting = E_ALL ; do not expose PHP via headers (just like we don't with web servers) expose_php = Off diff --git a/support/build/_conf/php/README.md b/support/build/_conf/php/README.md new file mode 100644 index 0000000000..5d2c849be1 --- /dev/null +++ b/support/build/_conf/php/README.md @@ -0,0 +1,5 @@ +Our builds of PHP use the recommended `php.ini-production` file from the respective release. + +These values are often different from the built-in default, and for a subset of settings, we want to override them. Examples include the default timezone (which is unset by default and in the recommended configs), errir reporting level (we want users to see deprecation warnings), or session ID length (which for legacy reasons defaults to 26 in the recommended development and production INI files, even though PHP's built-in default is 32). + +Doing this using a `conf.d` file allows our settings to apply even if users bring their own "full" `php.ini` (and we can just copy these in without having to track possible upstream INI changes). diff --git a/support/build/_conf/php/conf.d/000-heroku.ini b/support/build/_conf/php/conf.d/000-heroku.ini index 957c9ea538..9a266db600 100644 --- a/support/build/_conf/php/conf.d/000-heroku.ini +++ b/support/build/_conf/php/conf.d/000-heroku.ini @@ -7,7 +7,9 @@ error_reporting = E_ALL & ~E_STRICT ; do not expose PHP via headers (just like we don't with web servers) expose_php = Off -; 32 or more is recommended and always has been the default for PHP 7 on Heroku +; 32 or more is recommended and always has been the default for PHP 7+ on Heroku +; the production config we use as the baseline sets this to 26 +; this setting is gone in PHP 8.4, so the more specific file for that version does not have this session.sid_length = 32 ; legacy diff --git a/support/build/composer-2.2.24 b/support/build/composer-2.2.25 similarity index 100% rename from support/build/composer-2.2.24 rename to support/build/composer-2.2.25 diff --git a/support/build/extensions/no-debug-non-zts-20180731/blackfire b/support/build/extensions/no-debug-non-zts-20180731/blackfire index 2aa292248f..b448f6b900 100755 --- a/support/build/extensions/no-debug-non-zts-20180731/blackfire +++ b/support/build/extensions/no-debug-non-zts-20180731/blackfire @@ -32,6 +32,9 @@ case ${ZEND_MODULE_API_VERSION} in 20230831) series=8.3 ;; + 20240924) + series=8.4 + ;; *) echo "Unsupported PHP/Zend Module API version: ${ZEND_MODULE_API_VERSION}" exit 1 diff --git a/support/build/extensions/no-debug-non-zts-20180731/blackfire-1.92.28 b/support/build/extensions/no-debug-non-zts-20180731/blackfire-1.92.29 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20180731/blackfire-1.92.28 rename to support/build/extensions/no-debug-non-zts-20180731/blackfire-1.92.29 diff --git a/support/build/extensions/no-debug-non-zts-20180731/pcov-1.0.11 b/support/build/extensions/no-debug-non-zts-20180731/pcov-1.0.12 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20180731/pcov-1.0.11 rename to support/build/extensions/no-debug-non-zts-20180731/pcov-1.0.12 diff --git a/support/build/extensions/no-debug-non-zts-20190902/blackfire-1.92.28 b/support/build/extensions/no-debug-non-zts-20190902/blackfire-1.92.29 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20190902/blackfire-1.92.28 rename to support/build/extensions/no-debug-non-zts-20190902/blackfire-1.92.29 diff --git a/support/build/extensions/no-debug-non-zts-20190902/pcov-1.0.11 b/support/build/extensions/no-debug-non-zts-20190902/pcov-1.0.12 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20190902/pcov-1.0.11 rename to support/build/extensions/no-debug-non-zts-20190902/pcov-1.0.12 diff --git a/support/build/extensions/no-debug-non-zts-20200930/blackfire-1.92.28 b/support/build/extensions/no-debug-non-zts-20200930/blackfire-1.92.29 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20200930/blackfire-1.92.28 rename to support/build/extensions/no-debug-non-zts-20200930/blackfire-1.92.29 diff --git a/support/build/extensions/no-debug-non-zts-20200930/pcov-1.0.11 b/support/build/extensions/no-debug-non-zts-20200930/pcov-1.0.12 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20200930/pcov-1.0.11 rename to support/build/extensions/no-debug-non-zts-20200930/pcov-1.0.12 diff --git a/support/build/extensions/no-debug-non-zts-20210902/blackfire-1.92.28 b/support/build/extensions/no-debug-non-zts-20210902/blackfire-1.92.29 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20210902/blackfire-1.92.28 rename to support/build/extensions/no-debug-non-zts-20210902/blackfire-1.92.29 diff --git a/support/build/extensions/no-debug-non-zts-20210902/pcov-1.0.11 b/support/build/extensions/no-debug-non-zts-20210902/pcov-1.0.12 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20210902/pcov-1.0.11 rename to support/build/extensions/no-debug-non-zts-20210902/pcov-1.0.12 diff --git a/support/build/extensions/no-debug-non-zts-20220829/blackfire-1.92.28 b/support/build/extensions/no-debug-non-zts-20220829/blackfire-1.92.29 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20220829/blackfire-1.92.28 rename to support/build/extensions/no-debug-non-zts-20220829/blackfire-1.92.29 diff --git a/support/build/extensions/no-debug-non-zts-20220829/pcov-1.0.11 b/support/build/extensions/no-debug-non-zts-20220829/pcov-1.0.12 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20220829/pcov-1.0.11 rename to support/build/extensions/no-debug-non-zts-20220829/pcov-1.0.12 diff --git a/support/build/extensions/no-debug-non-zts-20230831/blackfire-1.92.28 b/support/build/extensions/no-debug-non-zts-20230831/blackfire-1.92.29 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20230831/blackfire-1.92.28 rename to support/build/extensions/no-debug-non-zts-20230831/blackfire-1.92.29 diff --git a/support/build/extensions/no-debug-non-zts-20230831/pcov-1.0.11 b/support/build/extensions/no-debug-non-zts-20230831/pcov-1.0.12 similarity index 100% rename from support/build/extensions/no-debug-non-zts-20230831/pcov-1.0.11 rename to support/build/extensions/no-debug-non-zts-20230831/pcov-1.0.12 diff --git a/support/build/extensions/no-debug-non-zts-20240924/amqp-2.1.2 b/support/build/extensions/no-debug-non-zts-20240924/amqp-2.1.2 new file mode 100755 index 0000000000..9ccefee35b --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/amqp-2.1.2 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/amqp diff --git a/support/build/extensions/no-debug-non-zts-20240924/apcu-5.1.24 b/support/build/extensions/no-debug-non-zts-20240924/apcu-5.1.24 new file mode 100755 index 0000000000..0c89dcae5e --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/apcu-5.1.24 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/apcu diff --git a/support/build/extensions/no-debug-non-zts-20240924/blackfire-1.92.29 b/support/build/extensions/no-debug-non-zts-20240924/blackfire-1.92.29 new file mode 100755 index 0000000000..e65058fa32 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/blackfire-1.92.29 @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php + +source $(dirname $0)/../no-debug-non-zts-20180731/blackfire diff --git a/support/build/extensions/no-debug-non-zts-20240924/ev-1.2.0 b/support/build/extensions/no-debug-non-zts-20240924/ev-1.2.0 new file mode 100755 index 0000000000..7bb1bf9a45 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/ev-1.2.0 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/ev diff --git a/support/build/extensions/no-debug-non-zts-20240924/event-3.1.4 b/support/build/extensions/no-debug-non-zts-20240924/event-3.1.4 new file mode 100755 index 0000000000..05cc666587 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/event-3.1.4 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/event diff --git a/support/build/extensions/no-debug-non-zts-20240924/imagick-3.7.0 b/support/build/extensions/no-debug-non-zts-20240924/imagick-3.7.0 new file mode 100755 index 0000000000..989bee2839 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/imagick-3.7.0 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/imagick diff --git a/support/build/extensions/no-debug-non-zts-20240924/imap b/support/build/extensions/no-debug-non-zts-20240924/imap new file mode 100755 index 0000000000..4ab7a86663 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/imap @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +dep_name=$(basename $BASH_SOURCE) + +# we need these libs already installed +needed=( libc-client2007e libkrb5-3 libpam0g ) +missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort)) +if [[ "$missing" ]]; then + echo "Error! Missing libraries: $missing" + exit 1 +fi + +# we need the headers for compilation +needed=( libc-client2007e-dev libkrb5-dev libpam0g-dev ) +missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort)) +if [[ "$missing" ]]; then + apt-get update -qq || { echo "Failed to 'apt-get update'. You must build this formula using Docker."; exit 1; } + apt-get install -q -y $missing +fi + +CONFIGURE_EXTRA="--with-imap-ssl --with-kerberos" + +source $(dirname $BASH_SOURCE)/../pecl diff --git a/support/build/extensions/no-debug-non-zts-20240924/imap-1.0.3 b/support/build/extensions/no-debug-non-zts-20240924/imap-1.0.3 new file mode 100755 index 0000000000..b6c5536545 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/imap-1.0.3 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20240924/imap diff --git a/support/build/extensions/no-debug-non-zts-20240924/memcached-3.3.0 b/support/build/extensions/no-debug-non-zts-20240924/memcached-3.3.0 new file mode 100755 index 0000000000..1a25407556 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/memcached-3.3.0 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/memcached diff --git a/support/build/extensions/no-debug-non-zts-20240924/mongodb-1.20.0 b/support/build/extensions/no-debug-non-zts-20240924/mongodb-1.20.0 new file mode 100755 index 0000000000..b19a1527a1 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/mongodb-1.20.0 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/mongodb diff --git a/support/build/extensions/no-debug-non-zts-20240924/oauth-2.0.9 b/support/build/extensions/no-debug-non-zts-20240924/oauth-2.0.9 new file mode 100755 index 0000000000..1d73a62f3b --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/oauth-2.0.9 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/oauth diff --git a/support/build/extensions/no-debug-non-zts-20240924/pcov-1.0.12 b/support/build/extensions/no-debug-non-zts-20240924/pcov-1.0.12 new file mode 100755 index 0000000000..4eded3dc4e --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/pcov-1.0.12 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/pcov diff --git a/support/build/extensions/no-debug-non-zts-20240924/pq-2.2.3 b/support/build/extensions/no-debug-non-zts-20240924/pq-2.2.3 new file mode 100755 index 0000000000..d2cfb9c3b2 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/pq-2.2.3 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.*, extensions/no-debug-non-zts-20240924/raphf-2.* + +source $(dirname $0)/../no-debug-non-zts-20180731/pq diff --git a/support/build/extensions/no-debug-non-zts-20240924/psr-1.2.0 b/support/build/extensions/no-debug-non-zts-20240924/psr-1.2.0 new file mode 100755 index 0000000000..08db563ac0 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/psr-1.2.0 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/psr diff --git a/support/build/extensions/no-debug-non-zts-20240924/raphf-2.0.1 b/support/build/extensions/no-debug-non-zts-20240924/raphf-2.0.1 new file mode 100755 index 0000000000..4740698cc1 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/raphf-2.0.1 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/raphf diff --git a/support/build/extensions/no-debug-non-zts-20240924/rdkafka-6.0.5 b/support/build/extensions/no-debug-non-zts-20240924/rdkafka-6.0.5 new file mode 100755 index 0000000000..813e4d5740 --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/rdkafka-6.0.5 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.*, libraries/librdkafka-* + +source $(dirname $0)/../no-debug-non-zts-20180731/rdkafka diff --git a/support/build/extensions/no-debug-non-zts-20240924/redis-6.1.0 b/support/build/extensions/no-debug-non-zts-20240924/redis-6.1.0 new file mode 100755 index 0000000000..f4393f228b --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/redis-6.1.0 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/redis diff --git a/support/build/extensions/no-debug-non-zts-20240924/uuid-1.2.1 b/support/build/extensions/no-debug-non-zts-20240924/uuid-1.2.1 new file mode 100755 index 0000000000..2fb9738b4d --- /dev/null +++ b/support/build/extensions/no-debug-non-zts-20240924/uuid-1.2.1 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Build Path: /app/.heroku/php +# Build Deps: php-8.4.* + +source $(dirname $0)/../no-debug-non-zts-20180731/uuid diff --git a/support/build/php b/support/build/php index 1901505254..f80fc1ab47 100755 --- a/support/build/php +++ b/support/build/php @@ -28,6 +28,8 @@ if [[ $dep_version == *alpha* ]] || [[ $dep_version == *beta* ]] || [[ $dep_vers dep_url=https://downloads.php.net/~pierrick/${dep_archive_name} elif [[ $dep_version == 8.3.* ]]; then dep_url=https://downloads.php.net/~eric/${dep_archive_name} + elif [[ $dep_version == 8.4.* ]]; then + dep_url=https://downloads.php.net/~calvinb/${dep_archive_name} fi else dep_url=https://www.php.net/distributions/${dep_archive_name} @@ -40,8 +42,8 @@ curl -L ${dep_url} | tar xz pushd ${dep_dirname} -# we need libgmp for GMP, libpam0g/libc-client for IMAP, libicu for intl, libsasl2/krb/ldap for LDAP, libreadline for PHP -needed=( libgmp10 libpam0g libc-client2007e libsasl2-2 libkrb5-3 ) +# we need libgmp for GMP, libicu for intl, libsasl2/ldap for LDAP, libreadline for PHP +needed=( libgmp10 libsasl2-2 ) needed+=( libonig5 ) needed+=( libsodium23 ) if [[ $STACK == "heroku-20" ]]; then @@ -60,14 +62,20 @@ else needed+=( libreadline8t64 ) needed+=( libzip4t64 ) fi +if [[ $dep_version == 7.* || $dep_version == 8.[0-3].* ]]; then + needed+=( libc-client2007e libkrb5-3 libpam0g ) # the IMAP extension was bundled before PHP 8.4 +fi missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort)) if [[ "$missing" ]]; then echo "Error! Missing libraries: $missing" exit 1 fi -# we need libgmp-dev for GMP, libpam0g-dev/libc-client-dev for IMAP, libicu-dev for intl, libsasl2/krb5/ldap2-dev for LDAP, libreadline-dev for PHP -needed=( libgmp-dev libpam0g-dev libc-client2007e-dev libicu-dev libsasl2-dev libkrb5-dev libldap2-dev libonig-dev libreadline-dev libsodium-dev libsqlite3-dev libzip-dev libwebp-dev ) +# we need libgmp-dev for GMP, libicu-dev for intl, libsasl2/ldap2-dev for LDAP, libreadline-dev for PHP +needed=( libgmp-dev libicu-dev libsasl2-dev libldap2-dev libonig-dev libreadline-dev libsodium-dev libsqlite3-dev libzip-dev libwebp-dev ) +if [[ $dep_version == 7.* || $dep_version == 8.[0-3].* ]]; then + needed+=( libc-client2007e-dev libkrb5-dev libpam0g-dev ) # the IMAP extension was bundled before PHP 8.4 +fi missing=$(comm -1 -3 <(dpkg-query -W -f '${package}\n' | sort) <(IFS=$'\n'; echo "${needed[*]}" | sort)) if [[ "$missing" ]]; then apt-get update -qq || { echo "Failed to 'apt-get update'. You must build this formula using Docker."; exit 1; } @@ -84,10 +92,12 @@ fi # we want to build FPM with tracing using pread, which uses /proc/$pid/mem # depending on host/container capabilities, it will likely detect ptrace as present, but that's blocked on the platform -# the only easy way to force it to use pread is by patching configure so it assumes the ptrace check has failed +# the only easy way to force it to use pread is by patching configure to write out pread to the appropriate variable even if the ptrace check was successful # see the AC_DEFUN([AC_FPM_TRACE] bits in sapi/fpm/config.m4 -sed -i 's/have_ptrace=yes/have_ptrace=no/' configure +echo "Patching configure to force pread for PHP-FPM tracing..." +grep "fpm_trace_type=ptrace" configure && sed -i 's/fpm_trace_type=ptrace/fpm_trace_type=pread/' configure || exit 99 +echo "Patching SIGTERM handling in PHP-FPM..." if [[ $dep_version == 7.4.* ]]; then patch -p1 < "$(dirname $BASH_SOURCE)/patches/php/7/4/ignoresigterm.patch" elif [[ $dep_version == 7.* ]]; then @@ -112,6 +122,10 @@ fi if [[ $dep_version == 7.3.* ]]; then configureopts+=("--with-libzip=/usr" "--with-onig=/usr") # PHP before 7.4 bundles these, so give explicit locations fi +if [[ $dep_version == 7.* || $dep_version == 8.[0-3].* ]]; then + configureopts+=("--with-imap=shared" "--with-imap-ssl") # the IMAP extension was bundled before PHP 8.4 + configureopts+=("--with-kerberos") # for IMAP and OpenSSL before PHP 8.4 +fi export PATH=${OUT_PREFIX}/bin:$PATH # cannot be built shared: date, ereg, opcache (always), pcre, reflection, sockets (?), spl, standard, @@ -127,7 +141,6 @@ export PATH=${OUT_PREFIX}/bin:$PATH --with-pdo-mysql \ --with-mysqli \ --with-openssl \ - --with-kerberos \ --with-password-argon2 \ --with-pgsql \ --with-pdo-pgsql \ @@ -140,8 +153,6 @@ export PATH=${OUT_PREFIX}/bin:$PATH --enable-ftp=shared \ --with-gettext=shared \ --with-gmp=shared \ - --with-imap=shared \ - --with-imap-ssl \ --enable-intl=shared \ --with-ldap=shared \ --with-ldap-sasl \ @@ -218,7 +229,7 @@ if ! curl -sL https://composer.github.io/installer.sha384sum | sha384sum --quiet exit 1 fi -php composer-setup.php --2.2 # https://github.com/composer/composer/issues/11046 +php composer-setup.php # first, read all platform packages (just "ext-" and "php-") that are already there; could be statically built, or enabled through one of the INIs loaded platform_default=$(php composer.phar show --platform | grep -E '^(ext-\S+|php-\S+)' | sed s@^@heroku-sys/@ | tr -s " " | cut -d " " -f1,2 | sort) diff --git a/support/build/php-7.0.33 b/support/build/php-7.0.33 deleted file mode 100755 index 6fe432accd..0000000000 --- a/support/build/php-7.0.33 +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/php - -source $(dirname $0)/php diff --git a/support/build/php-7.1.33 b/support/build/php-7.1.33 deleted file mode 100755 index 6fe432accd..0000000000 --- a/support/build/php-7.1.33 +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/php - -source $(dirname $0)/php diff --git a/support/build/php-7.2.34 b/support/build/php-7.2.34 deleted file mode 100755 index 6fe432accd..0000000000 --- a/support/build/php-7.2.34 +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash -# Build Path: /app/.heroku/php - -source $(dirname $0)/php diff --git a/support/build/php-5.6.40 b/support/build/php-8.4.1 similarity index 100% rename from support/build/php-5.6.40 rename to support/build/php-8.4.1 diff --git a/support/devcenter/generate.php b/support/devcenter/generate.php index 68bfd01b2f..11bb02a381 100755 --- a/support/devcenter/generate.php +++ b/support/devcenter/generate.php @@ -43,6 +43,7 @@ '8.1', '8.2', '8.3', + '8.4', ]; } diff --git a/support/installer/composer.json b/support/installer/composer.json index 9497d61aae..6e8186ec2c 100644 --- a/support/installer/composer.json +++ b/support/installer/composer.json @@ -1,7 +1,7 @@ { "type": "composer-plugin", "name": "heroku/installer-plugin", - "version": "1.7.1", + "version": "1.7.2", "autoload": { "psr-4": { "Heroku\\Buildpack\\PHP\\": "src/" @@ -13,6 +13,7 @@ "plugin-modifies-install-path": true }, "require": { - "composer-plugin-api": "^2.3.0" + "composer-plugin-api": "^2.3.0", + "php": ">=7.1" } } diff --git a/support/installer/src/NoopDownloader.php b/support/installer/src/NoopDownloader.php index 104212b70c..5f521e4931 100644 --- a/support/installer/src/NoopDownloader.php +++ b/support/installer/src/NoopDownloader.php @@ -24,12 +24,12 @@ public function getInstallationSource(): string return "dist"; } - public function download(PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface + public function download(PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface { return \React\Promise\resolve(null); } - public function prepare(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface + public function prepare(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface { return \React\Promise\resolve(null); } @@ -50,7 +50,7 @@ public function remove(PackageInterface $package, string $path): PromiseInterfac return \React\Promise\resolve(null); } - public function cleanup(string $type, PackageInterface $package, string $path, PackageInterface $prevPackage = null): PromiseInterface + public function cleanup(string $type, PackageInterface $package, string $path, ?PackageInterface $prevPackage = null): PromiseInterface { return \React\Promise\resolve(null); } diff --git a/test/fixtures/ci/atoum/composer.json b/test/fixtures/ci/atoum/composer.json index 12b3dca518..9208072434 100644 --- a/test/fixtures/ci/atoum/composer.json +++ b/test/fixtures/ci/atoum/composer.json @@ -1,6 +1,6 @@ { "require": { - "php": "*" + "php": "8.3.*" }, "require-dev": { "atoum/atoum": "^4.0" diff --git a/test/fixtures/ci/atoum/composer.lock b/test/fixtures/ci/atoum/composer.lock index 28c4e397b6..505c929997 100644 --- a/test/fixtures/ci/atoum/composer.lock +++ b/test/fixtures/ci/atoum/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "472c0fe020d93c0e281898de7626dfaf", + "content-hash": "c064c0d023d65161ad688c153f59ba08", "packages": [], "packages-dev": [ { @@ -101,7 +101,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "*" + "php": "8.3.*" }, "platform-dev": [], "plugin-api-version": "2.6.0" diff --git a/test/spec/newrelic_spec.rb b/test/spec/newrelic_spec.rb index aced649873..e40eee80db 100644 --- a/test/spec/newrelic_spec.rb +++ b/test/spec/newrelic_spec.rb @@ -9,25 +9,25 @@ # ext-newrelic is listed as a dependency in composer.json, and a NEW_RELIC_LICENSE_KEY is provided @app = new_app_with_stack_and_platrepo('test/fixtures/bootopts', config: { "NEW_RELIC_LOG_LEVEL" => "info", "NEW_RELIC_LICENSE_KEY" => "somethingfake" }, - before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" } + before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" } ) elsif mode == "without NEW_RELIC_LICENSE_KEY" # ext-newrelic is listed as a dependency in composer.json, but a NEW_RELIC_LICENSE_KEY is missing @app = new_app_with_stack_and_platrepo('test/fixtures/bootopts', config: { "NEW_RELIC_LOG_LEVEL" => "info" }, - before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" } + before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" } ) elsif mode == "with default NEW_RELIC_LOG_LEVEL" # ext-newrelic is listed as a dependency in composer.json, and NEW_RELIC_LOG_LEVEL is the default (warning) @app = new_app_with_stack_and_platrepo('test/fixtures/bootopts', config: { "NEW_RELIC_LICENSE_KEY" => "somethingfake" }, - before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" } + before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*' 'ext-newrelic:*'") or raise "Failed to require PHP/ext-newrelic" } ) else # a NEW_RELIC_LICENSE_KEY triggers the automatic installation of ext-newrelic at the end of the build @app = new_app_with_stack_and_platrepo('test/fixtures/bootopts', config: { "NEW_RELIC_LOG_LEVEL" => "info", "NEW_RELIC_LICENSE_KEY" => "thiswilltriggernewrelic" }, - before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:*'") or raise "Failed to require PHP version" } + before_deploy: -> { system("composer require --quiet --ignore-platform-reqs 'php:8.3.*'") or raise "Failed to require PHP version" } ) end @app.deploy diff --git a/test/spec/php-8.4_base_spec.rb b/test/spec/php-8.4_base_spec.rb new file mode 100644 index 0000000000..39c51bc68d --- /dev/null +++ b/test/spec/php-8.4_base_spec.rb @@ -0,0 +1,5 @@ +require_relative "php_base_shared" + +describe "A basic PHP 8.4 application", :requires_php_on_stack => "8.4" do + include_examples "A basic PHP application", "8.4" +end diff --git a/test/spec/php-8.4_boot-apache2_spec.rb b/test/spec/php-8.4_boot-apache2_spec.rb new file mode 100644 index 0000000000..460eaa69c7 --- /dev/null +++ b/test/spec/php-8.4_boot-apache2_spec.rb @@ -0,0 +1,5 @@ +require_relative "php_boot_shared" + +describe "A PHP 8.4/Apache application for testing boot options", :requires_php_on_stack => "8.4" do + include_examples "A PHP application for testing boot options", "8.4", "apache2" +end diff --git a/test/spec/php-8.4_boot-nginx_spec.rb b/test/spec/php-8.4_boot-nginx_spec.rb new file mode 100644 index 0000000000..618c6af054 --- /dev/null +++ b/test/spec/php-8.4_boot-nginx_spec.rb @@ -0,0 +1,5 @@ +require_relative "php_boot_shared" + +describe "A PHP 8.4/Nginx application for testing boot options", :requires_php_on_stack => "8.4" do + include_examples "A PHP application for testing boot options", "8.4", "nginx" +end diff --git a/test/spec/php-8.4_concurrency-apache2_spec.rb b/test/spec/php-8.4_concurrency-apache2_spec.rb new file mode 100644 index 0000000000..fc39ceca1f --- /dev/null +++ b/test/spec/php-8.4_concurrency-apache2_spec.rb @@ -0,0 +1,5 @@ +require_relative "php_concurrency_shared" + +describe "A PHP 8.4/Apache application for testing WEB_CONCURRENCY behavior", :requires_php_on_stack => "8.4" do + include_examples "A PHP application for testing WEB_CONCURRENCY behavior", "8.4", "apache2" +end diff --git a/test/spec/php-8.4_concurrency-nginx_spec.rb b/test/spec/php-8.4_concurrency-nginx_spec.rb new file mode 100644 index 0000000000..e186e66912 --- /dev/null +++ b/test/spec/php-8.4_concurrency-nginx_spec.rb @@ -0,0 +1,5 @@ +require_relative "php_concurrency_shared" + +describe "A PHP 8.4/Nginx application for testing WEB_CONCURRENCY behavior", :requires_php_on_stack => "8.4" do + include_examples "A PHP application for testing WEB_CONCURRENCY behavior", "8.4", "nginx" +end diff --git a/test/spec/php-8.4_sigterm-apache2_spec.rb b/test/spec/php-8.4_sigterm-apache2_spec.rb new file mode 100644 index 0000000000..1481486660 --- /dev/null +++ b/test/spec/php-8.4_sigterm-apache2_spec.rb @@ -0,0 +1,5 @@ +require_relative "php_sigterm_shared" + +describe "A PHP 8.4 application with long-running requests", :requires_php_on_stack => "8.4" do + include_examples "A PHP application with long-running requests", "8.4", "apache2" +end diff --git a/test/spec/php-8.4_sigterm-nginx_spec.rb b/test/spec/php-8.4_sigterm-nginx_spec.rb new file mode 100644 index 0000000000..abcb0387bb --- /dev/null +++ b/test/spec/php-8.4_sigterm-nginx_spec.rb @@ -0,0 +1,5 @@ +require_relative "php_sigterm_shared" + +describe "A PHP 8.4 application with long-running requests", :requires_php_on_stack => "8.4" do + include_examples "A PHP application with long-running requests", "8.4", "nginx" +end diff --git a/test/spec/php_base_shared.rb b/test/spec/php_base_shared.rb index f462953ab6..8f1dd0c6ac 100644 --- a/test/spec/php_base_shared.rb +++ b/test/spec/php_base_shared.rb @@ -3,6 +3,8 @@ shared_examples "A basic PHP application" do |series| context "with a composer.json requiring PHP #{series}" do + have_bundled_imap = series.match?(/^(7\.|8\.[0-3]$)/) + before(:all) do @app = new_app_with_stack_and_platrepo('test/fixtures/default', before_deploy: -> { system("composer require --quiet --ignore-platform-reqs php '#{series}.*'") or raise "Failed to require PHP version" } @@ -10,11 +12,16 @@ @app.deploy delimiter = SecureRandom.uuid + exts_and_libs = { + "mbstring.so": "-e 'libonig.so'", + "pdo_sqlite.so,sqlite3.so": "-e 'libsqlite3.so'" + } + exts_and_libs["imap.so"] = "-e 'libc-client.so'" if have_bundled_imap run_cmds = [ "php -v", "php -i", "php -i | grep memory_limit", - "ldd .heroku/php/bin/php .heroku/php/lib/php/extensions/no-debug-non-zts-*/{imap,mbstring,pdo_sqlite,sqlite3}.so | grep -E ' => (/usr)?/lib/' | grep -e 'libc-client.so' -e 'libonig.so' -e 'libsqlite3.so' -e 'libzip.so' | wc -l", + "ldd .heroku/php/bin/php .heroku/php/lib/php/extensions/no-debug-non-zts-*/{#{exts_and_libs.keys.join(",")}} | grep -E ' => (/usr)?/lib/' | grep #{exts_and_libs.values.join(" ")} -e 'libzip.so' | wc -l", ] # there are very rare cases of stderr and stdout getting read (by the dyno runner) slightly out of order # if that happens, the last stderr line(s) from the program might get picked up after the next thing we echo @@ -51,17 +58,16 @@ end it "is running a PHP build that links against libc-client, libonig, libsqlite3 and libzip from the stack" do - # 1x libc-client.so for extensions/…/imap.so + # 1x libc-client.so for extensions/…/imap.so on PHP < 8.4 # 1x libonig for extensions/…/mbstring.so # 1x libsqlite3.so for extensions/…/pdo_sqlite.so # 1x libsqlite3.so for extensions/…/sqlite3.so # 1x libsqlite3.so for bin/php (before heroku-22) # 1x libzip.so for bin/php - if "heroku-20" == ENV['STACK'] - expect(@run[3]).to match(/^6$/) - else - expect(@run[3]).to match(/^5$/) - end + expected_count = 4 + expected_count += 1 if have_bundled_imap # libc-client.so in extensions/…/imap.so + expected_count += 1 if "heroku-20" == ENV['STACK'] # libsqlite3.so in bin/php + expect(@run[3]).to match(/^#{expected_count}$/) end end end diff --git a/test/spec/platform_spec.rb b/test/spec/platform_spec.rb index bfc8e5eb86..f9f74791b8 100644 --- a/test/spec/platform_spec.rb +++ b/test/spec/platform_spec.rb @@ -214,7 +214,7 @@ end end - describe "Repository Sync Operations Program", :focused => true do + describe "Repository Sync Operations Program" do it "produces the expected list of operations when syncing between two repositories" do bp_root = [".."].cycle("#{sync_fixtures_subdir}".count("/")+1).to_a.join("/") # right "../.." sequence to get us back to the root of the buildpack Dir.chdir("#{sync_fixtures_subdir}") do |cwd| diff --git a/test/spec/spec_helper.rb b/test/spec/spec_helper.rb index 5ff8b1fb5d..633638eb79 100644 --- a/test/spec/spec_helper.rb +++ b/test/spec/spec_helper.rb @@ -57,7 +57,12 @@ def expect_exit(expect: :to, operator: :eq, code: 0) end def expected_default_php(stack) - "8.3" + case stack + when "heroku-20" + "8.3" + else + "8.4" + end end def php_on_stack?(series) @@ -65,9 +70,9 @@ def php_on_stack?(series) when "heroku-20" available = ["7.3", "7.4", "8.0", "8.1", "8.2", "8.3"] when "heroku-22" - available = ["8.1", "8.2", "8.3"] + available = ["8.1", "8.2", "8.3", "8.4"] else - available = ["8.2", "8.3"] + available = ["8.2", "8.3", "8.4"] end available.include?(series) end diff --git a/test/var/log/parallel_runtime_rspec.heroku-22.log b/test/var/log/parallel_runtime_rspec.heroku-22.log index c002370866..9f69091818 100644 --- a/test/var/log/parallel_runtime_rspec.heroku-22.log +++ b/test/var/log/parallel_runtime_rspec.heroku-22.log @@ -30,5 +30,12 @@ test/spec/php-8.3_concurrency-apache2_spec.rb:70 test/spec/php-8.3_concurrency-nginx_spec.rb:65 test/spec/php-8.3_sigterm-apache2_spec.rb:70 test/spec/php-8.3_sigterm-nginx_spec.rb:70 +test/spec/php-8.4_base_spec.rb:30 +test/spec/php-8.4_boot-apache2_spec.rb:65 +test/spec/php-8.4_boot-nginx_spec.rb:55 +test/spec/php-8.4_concurrency-apache2_spec.rb:70 +test/spec/php-8.4_concurrency-nginx_spec.rb:65 +test/spec/php-8.4_sigterm-apache2_spec.rb:70 +test/spec/php-8.4_sigterm-nginx_spec.rb:70 test/spec/php_default_spec.rb:60 test/spec/platform_spec.rb:60 diff --git a/test/var/log/parallel_runtime_rspec.heroku-24.log b/test/var/log/parallel_runtime_rspec.heroku-24.log index 58b5a82420..39b94d77e5 100644 --- a/test/var/log/parallel_runtime_rspec.heroku-24.log +++ b/test/var/log/parallel_runtime_rspec.heroku-24.log @@ -23,5 +23,12 @@ test/spec/php-8.3_concurrency-apache2_spec.rb:70 test/spec/php-8.3_concurrency-nginx_spec.rb:65 test/spec/php-8.3_sigterm-apache2_spec.rb:70 test/spec/php-8.3_sigterm-nginx_spec.rb:70 +test/spec/php-8.4_base_spec.rb:30 +test/spec/php-8.4_boot-apache2_spec.rb:65 +test/spec/php-8.4_boot-nginx_spec.rb:55 +test/spec/php-8.4_concurrency-apache2_spec.rb:70 +test/spec/php-8.4_concurrency-nginx_spec.rb:65 +test/spec/php-8.4_sigterm-apache2_spec.rb:70 +test/spec/php-8.4_sigterm-nginx_spec.rb:70 test/spec/php_default_spec.rb:60 test/spec/platform_spec.rb:60