name: Nightly on: schedule: - cron: "0 1 * * *" workflow_dispatch: ~ jobs: GENERATE_MATRIX: name: Generate Matrix if: github.repository_owner == 'php' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest outputs: branches: ${{ steps.set-matrix.outputs.branches }} matrix-include: ${{ steps.set-matrix.outputs.matrix-include }} steps: - uses: actions/checkout@v3 with: # Set fetch-depth to 0 to clone the full repository # including all branches. This is required to find # the correct commit hashes. fetch-depth: 0 - name: Grab the commit mapping uses: actions/cache@v3 with: path: branch-commit-cache.json # The cache key needs to change every time for the # cache to be updated after this job finishes. key: nightly-${{ github.run_id }}-${{ github.run_attempt }} restore-keys: | nightly- - name: Generate Matrix id: set-matrix run: php .github/nightly_matrix.php "${{ github.event_name }}" "${{ github.run_attempt }}" LINUX_X64: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} strategy: fail-fast: false matrix: branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} configuration_parameters: [''] debug: [true, false] name: [''] run_tests_parameters: [''] test_function_jit: [true] zts: [true, false] include: ${{ fromJson(needs.GENERATE_MATRIX.outputs.matrix-include) }} name: "${{ matrix.branch.name }}_LINUX_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: ubuntu-20.04 steps: - name: git checkout uses: actions/checkout@v3 with: ref: ${{ matrix.branch.ref }} - name: Create MSSQL container uses: ./.github/actions/setup-mssql - name: Create Oracle container uses: ./.github/actions/setup-oracle - name: apt uses: ./.github/actions/apt-x64 - name: ./configure uses: ./.github/actions/configure-x64 with: configurationParameters: >- ${{ matrix.configuration_parameters }} --${{ matrix.debug && 'enable' || 'disable' }}-debug --${{ matrix.zts && 'enable' || 'disable' }}-zts - name: make run: make -j$(/usr/bin/nproc) >/dev/null - name: make install uses: ./.github/actions/install-linux - name: Setup uses: ./.github/actions/setup-x64 - name: Test uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} - name: Test Tracing JIT uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.jit_buffer_size=16M - name: Test OpCache uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test Function JIT # ASAN frequently timeouts. Each test run takes ~90 minutes, we can # avoid running into the 6 hour timeout by skipping the function JIT. if: matrix.test_function_jit uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.jit_buffer_size=16M -d opcache.jit=1205 - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files LINUX_X32: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} strategy: fail-fast: false matrix: branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} debug: [true, false] zts: [true, false] name: "${{ matrix.branch.name }}_LINUX_X32_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: ubuntu-latest container: image: ubuntu:20.04 env: MYSQL_TEST_HOST: mysql PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test PDO_MYSQL_TEST_HOST: mysql services: mysql: image: mysql:8 ports: - 3306:3306 env: MYSQL_DATABASE: test MYSQL_ROOT_PASSWORD: root steps: - name: git checkout uses: actions/checkout@v3 with: ref: ${{ matrix.branch.ref }} - name: apt uses: ./.github/actions/apt-x32 - name: ./configure uses: ./.github/actions/configure-x32 with: configurationParameters: >- --${{ matrix.debug && 'enable' || 'disable' }}-debug --${{ matrix.zts && 'enable' || 'disable' }}-zts - name: make run: make -j$(/usr/bin/nproc) >/dev/null - name: make install uses: ./.github/actions/install-linux-x32 - name: Test uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} - name: Test Tracing JIT uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.jit_buffer_size=16M - name: Test OpCache uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Test Function JIT uses: ./.github/actions/test-linux with: runTestsParameters: >- ${{ matrix.run_tests_parameters }} -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.jit_buffer_size=16M -d opcache.jit=1205 MACOS: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} strategy: fail-fast: false matrix: branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} debug: [true, false] zts: [true, false] name: "${{ matrix.branch.name }}_MACOS_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" runs-on: macos-11 steps: - name: git checkout uses: actions/checkout@v3 with: ref: ${{ matrix.branch.ref }} - name: brew uses: ./.github/actions/brew - name: ./configure uses: ./.github/actions/configure-macos with: configurationParameters: >- --${{ matrix.debug && 'enable' || 'disable' }}-debug --${{ matrix.zts && 'enable' || 'disable' }}-zts - name: make run: |- export PATH="/usr/local/opt/bison/bin:$PATH" make -j$(sysctl -n hw.logicalcpu) >/dev/null - name: make install run: sudo make install - name: Test uses: ./.github/actions/test-macos - name: Test Tracing JIT uses: ./.github/actions/test-macos with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=16M - name: Test OpCache uses: ./.github/actions/test-macos with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.protect_memory=1 - name: Test Function JIT uses: ./.github/actions/test-macos with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=16M -d opcache.jit=1205 - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files COVERAGE_DEBUG_NTS: if: github.repository_owner == 'php' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-20.04 steps: - name: git checkout uses: actions/checkout@v3 - name: Create MSSQL container uses: ./.github/actions/setup-mssql - name: Create Oracle container uses: ./.github/actions/setup-oracle - name: apt uses: ./.github/actions/apt-x64 - name: Install gcovr run: sudo -H pip install gcovr - name: ./configure uses: ./.github/actions/configure-x64 with: configurationParameters: --enable-debug --disable-zts --enable-gcov - name: make run: make -j$(/usr/bin/nproc) >/dev/null - name: make install uses: ./.github/actions/install-linux - name: Setup uses: ./.github/actions/setup-x64 # We only test with OpCache, the difference in coverage is negligible - name: Test OpCache uses: ./.github/actions/test-linux with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Upload Test Coverage to Codecov.io if: always() run: bash <(curl -s https://codecov.io/bash) COMMUNITY: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} strategy: fail-fast: false matrix: branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} name: "${{ matrix.branch.name }}_COMMUNITY" runs-on: ubuntu-20.04 env: UBSAN_OPTIONS: print_stacktrace=1 USE_ZEND_ALLOC: 0 USE_TRACKED_ALLOC: 1 steps: - name: git checkout uses: actions/checkout@v3 with: ref: ${{ matrix.branch.ref }} - name: apt uses: ./.github/actions/apt-x64 - name: ./configure uses: ./.github/actions/configure-x64 with: configurationParameters: >- --enable-debug --enable-zts CFLAGS='-fsanitize=undefined,address -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC' LDFLAGS='-fsanitize=undefined,address' - name: make run: make -j$(/usr/bin/nproc) >/dev/null - name: make install uses: ./.github/actions/install-linux - name: Setup run: | sudo service mysql start mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" mysql -uroot -proot -e "SET GLOBAL local_infile = true" - name: Enable Opcache and JIT run: | echo zend_extension=opcache.so > /etc/php.d/opcache.ini echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini echo opcache.jit_buffer_size=1G >> /etc/php.d/opcache.ini - name: Test Laravel if: matrix.branch.ref != 'PHP-8.0' run: | git clone https://github.com/laravel/framework.git --branch=master --depth=1 cd framework git rev-parse HEAD php /usr/bin/composer install --no-progress --ignore-platform-reqs # Hack to disable a test that hangs php -r '$c = file_get_contents("tests/Filesystem/FilesystemTest.php"); $c = str_replace("*/\n public function testSharedGet()", "* @group skip\n */\n public function testSharedGet()", $c); file_put_contents("tests/Filesystem/FilesystemTest.php", $c);' export ASAN_OPTIONS=exitcode=139 php vendor/bin/phpunit --exclude-group skip || EXIT_CODE=$? if [ $EXIT_CODE -gt 128 ]; then exit 1 fi - name: Test Symfony if: matrix.branch.ref != 'PHP-8.0' run: | git clone https://github.com/symfony/symfony.git --depth=1 cd symfony git rev-parse HEAD php /usr/bin/composer install --no-progress --ignore-platform-reqs php ./phpunit install # Test causes a heap-buffer-overflow but I cannot reproduce it locally... php -r '$c = file_get_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php"); $c = str_replace("public function testSanitizeDeepNestedString()", "/** @group skip */\n public function testSanitizeDeepNestedString()", $c); file_put_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php", $c);' # Buggy FFI test in Symfony, see https://github.com/symfony/symfony/issues/47668 php -r '$c = file_get_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php"); $c = str_replace("*/\n public function testCastNonTrailingCharPointer()", "* @group skip\n */\n public function testCastNonTrailingCharPointer()", $c); file_put_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php", $c);' export ASAN_OPTIONS=exitcode=139 export SYMFONY_DEPRECATIONS_HELPER=max[total]=999 X=0 for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do php ./phpunit $component --exclude-group tty,benchmark,intl-data,transient --exclude-group skip || EXIT_CODE=$? if [ $EXIT_CODE -gt 128 ]; then X=1; fi done exit $X - name: Test PHPUnit if: always() run: | git clone https://github.com/sebastianbergmann/phpunit.git --branch=main --depth=1 cd phpunit git rev-parse HEAD export ASAN_OPTIONS=exitcode=139 php /usr/bin/composer install --no-progress --ignore-platform-reqs php ./phpunit || EXIT_CODE=$? if [ $EXIT_CODE -gt 128 ]; then exit 1 fi - name: 'Symfony Preloading' if: matrix.branch.ref != 'PHP-8.0' run: | php /usr/bin/composer create-project symfony/symfony-demo symfony_demo --no-progress --ignore-platform-reqs cd symfony_demo git rev-parse HEAD sed -i 's/PHP_SAPI/"cli-server"/g' var/cache/dev/App_KernelDevDebugContainer.preload.php php -d opcache.preload=var/cache/dev/App_KernelDevDebugContainer.preload.php public/index.php - name: Test Wordpress if: always() run: | git clone https://github.com/WordPress/wordpress-develop.git wordpress --depth=1 cd wordpress git rev-parse HEAD export ASAN_OPTIONS=exitcode=139 php /usr/bin/composer install --no-progress --ignore-platform-reqs cp wp-tests-config-sample.php wp-tests-config.php sed -i 's/youremptytestdbnamehere/test/g' wp-tests-config.php sed -i 's/yourusernamehere/root/g' wp-tests-config.php sed -i 's/yourpasswordhere/root/g' wp-tests-config.php php vendor/bin/phpunit || EXIT_CODE=$? if [ $EXIT_CODE -gt 128 ]; then exit 1 fi OPCACHE_VARIATION: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} strategy: fail-fast: false matrix: branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} name: "${{ matrix.branch.name }}_OPCACHE_VARIATION" runs-on: ubuntu-20.04 steps: - name: git checkout uses: actions/checkout@v3 with: ref: ${{ matrix.branch.ref }} - name: Create MSSQL container uses: ./.github/actions/setup-mssql - name: Create Oracle container uses: ./.github/actions/setup-oracle - name: apt uses: ./.github/actions/apt-x64 - name: ./configure uses: ./.github/actions/configure-x64 with: configurationParameters: >- --enable-debug --disable-zts - name: make run: make -j$(/usr/bin/nproc) >/dev/null - name: make install uses: ./.github/actions/install-linux - name: Setup uses: ./.github/actions/setup-x64 - name: Test File Cache (prime shm) uses: ./.github/actions/test-linux with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-prime - name: Test File Cache (prime shm, use shm) uses: ./.github/actions/test-linux with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-use - name: Test File Cache (prime shm, use file) uses: ./.github/actions/test-linux with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-use -d opcache.file_cache_only=1 - name: Test File Cache Only (prime) uses: ./.github/actions/test-linux with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-prime -d opcache.file_cache_only=1 - name: Test File Cache Only (use) uses: ./.github/actions/test-linux with: runTestsParameters: >- -d zend_extension=opcache.so -d opcache.enable_cli=1 --file-cache-use -d opcache.file_cache_only=1 - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files MSAN: needs: GENERATE_MATRIX if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} strategy: fail-fast: false matrix: branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} name: "${{ matrix.branch.name }}_MSAN" runs-on: ubuntu-22.04 steps: - name: git checkout uses: actions/checkout@v3 with: ref: ${{ matrix.branch.ref }} - name: apt uses: ./.github/actions/apt-x64 - name: ./configure run: | export CC=clang export CXX=clang++ export CFLAGS="-DZEND_TRACK_ARENA_ALLOC" ./buildconf --force # msan requires all used libraries to be instrumented, # so we should avoiding linking against anything but libc here ./configure \ --enable-debug \ --enable-zts \ --enable-option-checking=fatal \ --prefix=/usr \ --without-sqlite3 \ --without-pdo-sqlite \ --without-libxml \ --disable-dom \ --disable-simplexml \ --disable-xml \ --disable-xmlreader \ --disable-xmlwriter \ --without-pcre-jit \ --disable-opcache-jit \ --enable-phpdbg \ --enable-fpm \ --with-pdo-mysql=mysqlnd \ --with-mysqli=mysqlnd \ --disable-mysqlnd-compression-support \ --without-pear \ --enable-exif \ --enable-sysvsem \ --enable-sysvshm \ --enable-shmop \ --enable-pcntl \ --enable-mbstring \ --disable-mbregex \ --enable-sockets \ --enable-bcmath \ --enable-calendar \ --enable-ftp \ --enable-zend-test \ --enable-werror \ --enable-memory-sanitizer \ --with-config-file-path=/etc \ --with-config-file-scan-dir=/etc/php.d - name: make run: make -j$(/usr/bin/nproc) >/dev/null - name: make install run: | sudo make install sudo mkdir /etc/php.d sudo chmod 777 /etc/php.d echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini echo pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini - name: Setup run: | set -x sudo service mysql start mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" # Ensure local_infile tests can run. mysql -uroot -proot -e "SET GLOBAL local_infile = true" sudo locale-gen de_DE - name: Test uses: ./.github/actions/test-linux with: runTestsParameters: >- --msan - name: Test Opcache uses: ./.github/actions/test-linux with: runTestsParameters: >- --msan -d zend_extension=opcache.so -d opcache.enable_cli=1 - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files