diff --git a/.ci/Makefile b/.ci/Makefile index acec7e96d..68bfacdfc 100644 --- a/.ci/Makefile +++ b/.ci/Makefile @@ -33,6 +33,10 @@ ifneq ($(PHP_VERSION), 7.2) SEL_DISTRO := bullseye endif +ifeq ($(PHP_VERSION), 8.5) + SEL_DISTRO := bookworm +endif + CONAN_USER_HOME:=/tmp/conan_user_home MAP_CONAN_HOME_TO_DOCKER_HOST_CMD_LINE_ARG:= diff --git a/.ci/packer_cache.sh b/.ci/packer_cache.sh index 3b947b728..ec7c534fb 100755 --- a/.ci/packer_cache.sh +++ b/.ci/packer_cache.sh @@ -16,6 +16,7 @@ php:8.1-fpm php:8.2-fpm php:8.3-fpm php:8.4-fpm +php:8.5-fpm ruby:2.7.1-alpine3.12 ubuntu:20.04 " @@ -27,7 +28,7 @@ if [ -x "$(command -v docker)" ]; then # Make sure list of PHP versions supported by the Elastic APM PHP Agent is in sync. # See the comment in .ci/shared.sh - for version in 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 + for version in 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5 do PHP_VERSION=${version} make -f .ci/Makefile prepare || true DOCKERFILE=Dockerfile.alpine PHP_VERSION=${version} make -f .ci/Makefile prepare || true diff --git a/.ci/shared.sh b/.ci/shared.sh index 6d1641581..9d12a2d43 100644 --- a/.ci/shared.sh +++ b/.ci/shared.sh @@ -16,7 +16,7 @@ set -e # *) docker-compose.yml in packaging/test # -export ELASTIC_APM_PHP_TESTS_SUPPORTED_PHP_VERSIONS=(7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4) +export ELASTIC_APM_PHP_TESTS_SUPPORTED_PHP_VERSIONS=(7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5) export ELASTIC_APM_PHP_TESTS_SUPPORTED_LINUX_NATIVE_PACKAGE_TYPES=(apk deb rpm) export ELASTIC_APM_PHP_TESTS_SUPPORTED_LINUX_PACKAGE_TYPES=("${ELASTIC_APM_PHP_TESTS_SUPPORTED_LINUX_NATIVE_PACKAGE_TYPES[@]}" tar) diff --git a/.github/workflows/loop.yml b/.github/workflows/loop.yml index d1628ecd2..fbfc10446 100644 --- a/.github/workflows/loop.yml +++ b/.github/workflows/loop.yml @@ -24,6 +24,7 @@ jobs: - "8.2" - "8.3" - "8.4" + - "8.5" dockerfile: - "Dockerfile" - "Dockerfile.alpine" diff --git a/.github/workflows/phpt.yml b/.github/workflows/phpt.yml index 560668a96..e52d59a18 100644 --- a/.github/workflows/phpt.yml +++ b/.github/workflows/phpt.yml @@ -29,6 +29,7 @@ jobs: - "8.2" - "8.3" - "8.4" + - "8.5" steps: # - uses: actions/checkout@v6 # - name: Fetch and extract latest release of apm-agent-php diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9076a643b..a243fad33 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -59,6 +59,7 @@ jobs: - "8.2" - "8.3" - "8.4" + - "8.5" data: ${{ fromJson(needs.setup-build-matrix.outputs.matrix-combinations).include }} env: PHP_VERSION: ${{ matrix.php-version }} @@ -92,6 +93,7 @@ jobs: - "8.2" - "8.3" - "8.4" + - "8.5" dockerfile: - "Dockerfile" - "Dockerfile.alpine" diff --git a/Dockerfile b/Dockerfile index bfb2c2326..ecb903d1e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,11 +19,12 @@ RUN apt-get -qq update \ wget \ && rm -rf /var/lib/apt/lists/* -RUN docker-php-ext-install \ - mysqli \ - pcntl \ - pdo_mysql \ - opcache +RUN MODULES="mysqli pcntl pdo_mysql"; \ + case "${PHP_VERSION}" in \ + 8.5*) ;; \ + *) MODULES="$MODULES opcache" ;; \ + esac; \ + docker-php-ext-install $MODULES COPY --from=composer:latest /usr/bin/composer /usr/bin/composer diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 5235c2da8..bcbf4aed2 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -12,11 +12,12 @@ RUN apk update \ git \ unzip -RUN docker-php-ext-install \ - mysqli \ - pcntl \ - pdo_mysql \ - opcache +RUN MODULES="mysqli pcntl pdo_mysql"; \ + case "${PHP_VERSION}" in \ + 8.5*) ;; \ + *) MODULES="$MODULES opcache" ;; \ + esac; \ + docker-php-ext-install $MODULES COPY --from=composer:latest /usr/bin/composer /usr/bin/composer diff --git a/agent/native/CMakeLists.txt b/agent/native/CMakeLists.txt index 22252ec7b..3b6e129c1 100644 --- a/agent/native/CMakeLists.txt +++ b/agent/native/CMakeLists.txt @@ -43,7 +43,7 @@ include(elastic_conan_debugsymbols) # Install project dependencies -set(_supported_php_versions 72 73 74 80 81 82 83 84) +set(_supported_php_versions 72 73 74 80 81 82 83 84 85) function(get_php_api_from_release php_version ret_val) block(SCOPE_FOR VARIABLES) @@ -55,6 +55,7 @@ function(get_php_api_from_release php_version ret_val) set(_php_release_82 20220829) set(_php_release_83 20230831) set(_php_release_84 20240924) + set(_php_release_85 20250925) set(${ret_val} ${_php_release_${php_version}}) return(PROPAGATE ${ret_val}) diff --git a/agent/native/building/dependencies/php85/conandata.yml b/agent/native/building/dependencies/php85/conandata.yml new file mode 100644 index 000000000..2eca7a06f --- /dev/null +++ b/agent/native/building/dependencies/php85/conandata.yml @@ -0,0 +1,41 @@ +name: "php-headers-85" +version: "1.0" +php_source_version: 8.5.0 + +sources: + 7.2.34: + linux: + - url: "https://www.php.net/distributions/php-7.2.34.tar.gz" + contentsRoot: "php-7.2.34" + 7.3.33: + linux: + - url: "https://www.php.net/distributions/php-7.3.33.tar.gz" + contentsRoot: "php-7.3.33" + 7.4.33: + linux: + - url: "https://www.php.net/distributions/php-7.4.33.tar.gz" + contentsRoot: "php-7.4.33" + 8.0.28: + linux: + - url: "https://www.php.net/distributions/php-8.0.28.tar.gz" + contentsRoot: "php-8.0.28" + 8.1.18: + linux: + - url: "https://www.php.net/distributions/php-8.1.18.tar.gz" + contentsRoot: "php-8.1.18" + 8.2.5: + linux: + - url: "https://www.php.net/distributions/php-8.2.5.tar.gz" + contentsRoot: "php-8.2.5" + 8.3.2: + linux: + - url: "https://www.php.net/distributions/php-8.3.2.tar.gz" + contentsRoot: "php-8.3.2" + 8.4.1: + linux: + - url: "https://www.php.net/distributions/php-8.4.1.tar.gz" + contentsRoot: "php-8.4.1" + 8.5.0: + linux: + - url: "https://www.php.net/distributions/php-8.5.0.tar.gz" + contentsRoot: "php-8.5.0" diff --git a/agent/native/building/dependencies/php85/conanfile.py b/agent/native/building/dependencies/php85/conanfile.py new file mode 100644 index 000000000..2f1ec5fcc --- /dev/null +++ b/agent/native/building/dependencies/php85/conanfile.py @@ -0,0 +1,56 @@ +import os +import shutil + +from conans import tools, ConanFile, AutoToolsBuildEnvironment + +class PhpHeadersForPHP81Conan(ConanFile): + description = "PHP headers package required to build Elastic APM agent without additional PHP dependencies" + license = "The PHP License, version 3.01" + homepage = "https://php.net/" + url = "https://php.net/" + author = "pawel.filipczak@elastic.co" + + settings = "os", "compiler", "build_type", "arch" + platform = "linux" + + def init(self): + self.name = self.conan_data["name"] + self.version = self.conan_data["version"] # version of the package + self.php_version = self.conan_data["php_source_version"] # version of the PHP to build + self.source_temp_dir = "php-src" + + def requirements(self): + self.requires("libxml2/2.9.9") + self.requires("sqlite3/3.29.0") + + def source(self): + for source in self.conan_data["sources"][self.php_version][self.platform]: + + if "contentsRoot" in source: + # small hack - it can't contain custom fields, so we're removing it from source (got an unexpected keyword argument) + contentRoot = source["contentsRoot"] + del source["contentsRoot"] + tools.get(**source) + os.rename(contentRoot, self.source_temp_dir) + else: + self.output.error("Could not find 'contentsRoot' in conandata.yml") + raise Exception("Could not find 'contentsRoot' in conandata.yml") + + def build(self): + with tools.chdir(os.path.join(self.source_folder, self.source_temp_dir)): + buildEnv = AutoToolsBuildEnvironment(self) + envVariables = buildEnv.vars + envVariables['ac_cv_php_xml2_config_path'] = os.path.join(self.deps_cpp_info["libxml2"].rootpath, "bin/xml2-config") + envVariables['LIBXML_LIBS'] = os.path.join(self.deps_cpp_info["libxml2"].rootpath, self.deps_cpp_info["libxml2"].libdirs[0]) + envVariables['LIBXML_CFLAGS'] = "-I{}".format(os.path.join(self.deps_cpp_info["libxml2"].rootpath, self.deps_cpp_info["libxml2"].includedirs[0])) + envVariables['SQLITE_LIBS'] = os.path.join(self.deps_cpp_info["sqlite3"].rootpath, self.deps_cpp_info["sqlite3"].libdirs[0]) + envVariables['SQLITE_CFLAGS'] = "-I{}".format(os.path.join(self.deps_cpp_info["sqlite3"].rootpath, self.deps_cpp_info["sqlite3"].includedirs[0])) + self.run("./buildconf --force") + buildEnv.configure(args=[""], vars=envVariables, build=False, host=False) + + def package(self): + source = os.path.join(self.source_folder, self.source_temp_dir) + self.copy("*.h", src=source, dst='include', keep_path=True) + + def package_id(self): + del self.info.settings.compiler.version diff --git a/agent/native/ext/AST_debug.cpp b/agent/native/ext/AST_debug.cpp index cbe148df1..3b20eca31 100644 --- a/agent/native/ext/AST_debug.cpp +++ b/agent/native/ext/AST_debug.cpp @@ -75,7 +75,7 @@ String zendAstKindToString( zend_ast_kind kind ) return (#enumMember) \ /**/ - // Up to date with PHP v8.3.2 + // Up to date with PHP v8.5.0 switch ( kind ) { /** @@ -97,7 +97,9 @@ String zendAstKindToString( zend_ast_kind kind ) ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_CLASS ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_CLASS_CONST ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_CLASS_CONST_DECL ); + #if PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 5, 0 ) /* removed in PHP 8.5 */ ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_CLONE ); + #endif ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_CLOSURE ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_CLOSURE_USES ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_COALESCE ); @@ -112,7 +114,9 @@ String zendAstKindToString( zend_ast_kind kind ) ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_ECHO ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_EMPTY ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_ENCAPS_LIST ); + #if PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 5, 0 ) /* removed in PHP 8.5 */ ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_EXIT ); + #endif ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_EXPR_LIST ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_FOR ); ELASTIC_APM_GEN_ENUM_TO_STRING_SWITCH_CASE( ZEND_AST_FOREACH ); diff --git a/agent/native/ext/AST_instrumentation.cpp b/agent/native/ext/AST_instrumentation.cpp index 360f79aa2..8bab47ca9 100644 --- a/agent/native/ext/AST_instrumentation.cpp +++ b/agent/native/ext/AST_instrumentation.cpp @@ -195,7 +195,7 @@ bool isZendAstListKind( zend_ast_kind kind ) * - Increment minor part of PHP version in static_assert below */ static_assert( - PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 5, 0 ), + PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 6, 0 ), "Make sure g_astNodeMaxChildCount is correct. See max number of children in enum _zend_ast_kind in /Zend/zend_ast.h" ); static constexpr size_t g_astNodeMaxChildCount = diff --git a/agent/native/loader/code/phpdetection.cpp b/agent/native/loader/code/phpdetection.cpp index 42f58e653..64e724889 100644 --- a/agent/native/loader/code/phpdetection.cpp +++ b/agent/native/loader/code/phpdetection.cpp @@ -56,9 +56,10 @@ bool isThreadSafe() { std::tuple getZendModuleApiVersion(std::string_view zendVersion) { using namespace std::string_view_literals; - constexpr size_t knownVersionsCount = 17; + constexpr size_t knownVersionsCount = 18; constexpr std::array, knownVersionsCount> knownPhpVersions {{ + {"4.5"sv, 20250925, true}, // PHP 8.5 {"4.4"sv, 20240924, true}, // PHP 8.4 {"4.3"sv, 20230831, true}, // PHP 8.3 {"4.2"sv, 20220829, true}, // PHP 8.2 diff --git a/composer.json b/composer.json index 923abda65..7f6e6906c 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ { "name": "Sergey Kleyman" } ], "require": { - "php": "^7.2||8.0.*||8.1.*||8.2.*||8.3.*||8.4.*", + "php": "^7.2||8.0.*||8.1.*||8.2.*||8.3.*||8.4.*||8.5.*", "ext-json": "*", "ext-pcntl": "*", "psr/log": "^1.0" diff --git a/packaging/post-install.sh b/packaging/post-install.sh index 472af4852..5578a7a74 100755 --- a/packaging/post-install.sh +++ b/packaging/post-install.sh @@ -206,11 +206,12 @@ function is_php_supported() { [ "${PHP_MAJOR_MINOR}" == "8.1" ] || \ [ "${PHP_MAJOR_MINOR}" == "8.2" ] || \ [ "${PHP_MAJOR_MINOR}" == "8.3" ] || \ - [ "${PHP_MAJOR_MINOR}" == "8.4" ] + [ "${PHP_MAJOR_MINOR}" == "8.4" ] || \ + [ "${PHP_MAJOR_MINOR}" == "8.5" ] then return 0 else - echo 'Failed. The supported PHP versions are 7.2-8.4.' + echo 'Failed. The supported PHP versions are 7.2-8.5.' return 1 fi } diff --git a/packaging/test/docker-compose.yml b/packaging/test/docker-compose.yml index 85e9ff9ab..0d9ca1a03 100644 --- a/packaging/test/docker-compose.yml +++ b/packaging/test/docker-compose.yml @@ -1,5 +1,13 @@ version: "3" services: + deb-fpm-php85: + image: elasticobservability/apm-agent-php-dev:packages-test-deb-fpm-php-8.5-0.0.1 + build: + context: ubuntu + dockerfile: fpm/Dockerfile + args: + - PHP_VERSION=8.5 + - SEL_DISTRO=bookworm deb-fpm-php84: image: elasticobservability/apm-agent-php-dev:packages-test-deb-fpm-php-8.4-0.0.1 build: @@ -62,6 +70,14 @@ services: + deb-apache-php85: + image: elasticobservability/apm-agent-php-dev:packages-test-deb-apache-php-8.5-0.0.1 + build: + context: ubuntu + dockerfile: apache/Dockerfile + args: + - PHP_VERSION=8.5 + - SEL_DISTRO=bookworm deb-apache-php84: image: elasticobservability/apm-agent-php-dev:packages-test-deb-apache-php-8.4-0.0.1 build: @@ -122,6 +138,14 @@ services: - PHP_VERSION=7.2 + deb-php85: + image: elasticobservability/apm-agent-php-dev:packages-test-deb-php-8.5-0.0.1 + build: + context: ubuntu + dockerfile: Dockerfile + args: + - PHP_VERSION=8.5 + - SEL_DISTRO=bookworm deb-php84: image: elasticobservability/apm-agent-php-dev:packages-test-deb-php-8.4-0.0.1 build: @@ -181,6 +205,13 @@ services: args: - PHP_VERSION=7.2 + rpm-php85: + image: elasticobservability/apm-agent-php-dev:packages-test-rpm-php-8.5-0.1.1 + build: + context: fedora + dockerfile: Dockerfile + args: + - PHP_VERSION=8.5 rpm-php84: image: elasticobservability/apm-agent-php-dev:packages-test-rpm-php-8.4-0.1.1 build: @@ -238,6 +269,13 @@ services: args: - PHP_VERSION=7.2 + apk-php85: + image: elasticobservability/apm-agent-php-dev:packages-test-apk-php-8.5-0.0.1 + build: + context: alpine + dockerfile: Dockerfile + args: + - PHP_VERSION=8.5 apk-php84: image: elasticobservability/apm-agent-php-dev:packages-test-apk-php-8.4-0.0.1 build: diff --git a/tests/ElasticApmTests/ComponentTests/GenerateUnpackScriptsTest.php b/tests/ElasticApmTests/ComponentTests/GenerateUnpackScriptsTest.php index 60322db0d..3d9b39dd1 100644 --- a/tests/ElasticApmTests/ComponentTests/GenerateUnpackScriptsTest.php +++ b/tests/ElasticApmTests/ComponentTests/GenerateUnpackScriptsTest.php @@ -52,7 +52,7 @@ final class GenerateUnpackScriptsTest extends ComponentTestCaseBase implements L private const PHP_VERSION_7_4 = '7.4'; // Make sure list of PHP versions supported by the Elastic APM PHP Agent is in sync. // See the comment in .ci/shared.sh - private const SUPPORTED_PHP_VERSIONS = ['7.2', '7.3', self::PHP_VERSION_7_4, '8.0', '8.1', '8.2', '8.3', '8.4']; + private const SUPPORTED_PHP_VERSIONS = ['7.2', '7.3', self::PHP_VERSION_7_4, '8.0', '8.1', '8.2', '8.3', '8.4', '8.5']; private const LINUX_PACKAGE_TYPE_DEB = 'deb'; private const LINUX_PACKAGE_TYPE_RPM = 'rpm';