diff --git a/.github/scripts/install-php86-windows.sh b/.github/scripts/install-php86-windows.sh new file mode 100644 index 00000000000..f7eebca091e --- /dev/null +++ b/.github/scripts/install-php86-windows.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +# setup-php supplies Composer, php.ini and CA certificates, but its 8.6 +# nightly has no matching development pack. Replace the runtime and bundled +# extensions with the official prerelease, preserving that configuration. +PHP_DIR="$(cygpath -u "$(php -r 'echo dirname(PHP_BINARY);')")" +case "$MATRIX_TS" in + zts) INFIX="" ;; + nts) INFIX="-nts" ;; + *) echo "Unknown thread-safety mode: $MATRIX_TS" >&2; exit 1 ;; +esac +PACK="php-$PHP86_WINDOWS_VERSION$INFIX-Win32-vs18-x64.zip" +ARCHIVE="$RUNNER_TEMP/$PACK" +curl -fsSLo "$ARCHIVE" "https://downloads.php.net/~windows/qa/$PACK" \ + || curl -fsSLo "$ARCHIVE" "https://downloads.php.net/~windows/qa/archives/$PACK" +unzip -qo "$ARCHIVE" -d "$PHP_DIR" +php -r ' + if (PHP_VERSION !== getenv("PHP86_WINDOWS_VERSION") || (bool) PHP_ZTS !== (getenv("MATRIX_TS") === "zts")) { + fwrite(STDERR, "PHP prerelease version or thread-safety mismatch\n"); + exit(1); + } + echo "Using PHP ", PHP_VERSION, PHP_ZTS ? " ZTS\n" : " NTS\n"; +' diff --git a/.github/workflows/phar.yml b/.github/workflows/phar.yml index 56396ef6804..e63efe2846d 100644 --- a/.github/workflows/phar.yml +++ b/.github/workflows/phar.yml @@ -29,6 +29,8 @@ env: # distro-default PHP. COMPOSER_VERSION: "2.9.2" COMPOSER_PHAR_SHA256: "471f2d857abf0ec18af7b055e61472214d91adb24f9bdbbb864c1c64faad7dd6" + # setup-php installs an 8.6 nightly, which has no matching Windows devel pack. + PHP86_WINDOWS_VERSION: "8.6.0beta3" jobs: compiler-tests: @@ -319,9 +321,9 @@ jobs: turbo-compile: name: "Compile Turbo Extension" - runs-on: ${{ matrix.target.runs-on }} + runs-on: ${{ matrix.php-version == '8.6' && matrix.target.family == 'gnu' && (matrix.target.name == 'linux-gnu-arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') || matrix.target.runs-on }} # Container legs pin the built binaries' userland floor independently of - # the runner image. The gnu legs run in a prebuilt ubuntu:22.04-based + # the runner image. The 8.3–8.5 gnu legs run in a prebuilt ubuntu:22.04-based # image (.github/turbo-build/Dockerfile, published to GHCR by # turbo-build-image.yml) with the PHP toolchain baked in: the glibc # symbol floor stays at 2.34 (RHEL 9, Ubuntu 22.04+, Debian 12+) and the @@ -339,7 +341,10 @@ jobs: # packages ZTS PHP (neither ppa:ondrej/php nor Alpine); setup-php # provides thread-safe builds. No musl ZTS for the same packaging # reason. - container: ${{ matrix.target.family == 'gnu' && format('ghcr.io/phpstan/turbo-build:gnu-php{0}', matrix.php-version) || matrix.target.container }} + # PHP 8.6 has no ondrej/php packages or prebuilt GNU image yet. Use + # setup-php on Jammy runners, preserving the shipped binary's glibc floor. + # Alpine's php86 packages are currently only in edge/testing. + container: ${{ matrix.target.family == 'gnu' && matrix.php-version != '8.6' && format('ghcr.io/phpstan/turbo-build:gnu-php{0}', matrix.php-version) || matrix.target.family == 'musl' && matrix.php-version == '8.6' && 'alpine:edge' || matrix.target.container }} timeout-minutes: 30 env: @@ -348,7 +353,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["8.3", "8.4", "8.5"] + php-version: ["8.3", "8.4", "8.5", "8.6"] target: - name: "linux-gnu-x86_64" runs-on: "ubuntu-latest" @@ -391,13 +396,15 @@ jobs: # The Alpine leg installs PHP and tooling before checkout: # actions/checkout needs git inside the container, and the build needs - # php/php-config symlinks pointing at the matrix PHP version. The gnu - # legs need no install step — their prebuilt turbo-build image bakes - # all of this in. + # php/php-config symlinks pointing at the matrix PHP version. The GNU + # container legs have the toolchain baked in; 8.6 uses setup-php below. - name: "Install PHP and build tools (Alpine container)" if: matrix.target.family == 'musl' run: | V="$(echo "$PHP_MINOR" | tr -d .)" + if [ "$PHP_MINOR" = "8.6" ]; then + echo 'https://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories + fi apk add --no-cache bash curl git make g++ musl-dev linux-headers patch tar zstd \ "php$V" "php$V-dev" "php$V-ctype" "php$V-curl" "php$V-mbstring" \ "php$V-tokenizer" "php$V-iconv" "php$V-openssl" "php$V-phar" \ @@ -429,11 +436,11 @@ jobs: coverage: "none" php-version: "${{ matrix.php-version }}" - - name: "Install PHP (ZTS runner)" - if: matrix.target.family == 'zts' + - name: "Install PHP (GNU runners)" + if: matrix.target.family == 'zts' || (matrix.target.family == 'gnu' && matrix.php-version == '8.6') uses: "shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240" # v2.37.2 env: - phpts: "ts" + phpts: "${{ matrix.target.family == 'zts' && 'ts' || 'nts' }}" with: coverage: "none" php-version: "${{ matrix.php-version }}" @@ -545,7 +552,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["8.3", "8.4", "8.5"] + php-version: ["8.3", "8.4", "8.5", "8.6"] steps: - name: Harden the runner (Audit all outbound calls) @@ -564,16 +571,21 @@ jobs: fetch-depth: 0 - name: "Start the Alpine build container" + env: + ALPINE_IMAGE: ${{ matrix.php-version == '8.6' && 'alpine:edge' || 'alpine:3.24' }} run: | docker run -d --name alpine-build \ -v "$PWD:/work" -w /work \ -e PHP_MINOR -e COMPOSER_VERSION -e COMPOSER_PHAR_SHA256 \ - alpine:3.24 sleep 7200 + "$ALPINE_IMAGE" sleep 7200 - name: "Install PHP and build tools" run: | docker exec -i alpine-build sh -e <<'EOF' V="$(echo "$PHP_MINOR" | tr -d .)" + if [ "$PHP_MINOR" = "8.6" ]; then + echo 'https://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories + fi apk add --no-cache bash curl git make g++ musl-dev linux-headers patch tar zstd \ "php$V" "php$V-dev" "php$V-ctype" "php$V-curl" "php$V-mbstring" \ "php$V-tokenizer" "php$V-iconv" "php$V-openssl" "php$V-phar" \ @@ -666,7 +678,7 @@ jobs: # token-numbering bug: 2462 of 21065 tests fail and self-analysis # crashes on the Bison 3.0.4 image, both green on the matched one). # The 8.3 images are pinned to one release of each known numbering; - # 8.4/8.5 float on the minor tag on purpose so that a future patch + # 8.4/8.5 float on the minor tag and 8.6 on the prerelease tag so a future # release with a surprising build is picked up on the next run without # a workflow change. Legs run on linux-gnu-x86_64 only: the token # numbering comes from the bison that generated the tarball's parser, @@ -677,6 +689,9 @@ jobs: runs-on: "ubuntu-latest" timeout-minutes: 60 + env: + IMAGE: ${{ matrix.php-version == '8.6' && 'phpstan-turbo-test:8.6' || matrix.image }} + permissions: contents: read @@ -688,6 +703,7 @@ jobs: - "php:8.3.22-cli-bookworm" - "php:8.4-cli-bookworm" - "php:8.5-cli-bookworm" + - "php:8.6-rc-cli-bookworm" check: ["tests", "phpstan"] include: - image: "php:8.3.21-cli-bookworm" @@ -698,6 +714,8 @@ jobs: php-version: "8.4" - image: "php:8.5-cli-bookworm" php-version: "8.5" + - image: "php:8.6-rc-cli-bookworm" + php-version: "8.6" # The tests legs invoke paratest directly instead of a literal # `make tests`: its install-paratest step needs a composer, which # the images do not carry — tests/vendor is installed on the @@ -741,12 +759,25 @@ jobs: name: "phpstan_turbo-linux-gnu-x86_64-php${{ matrix.php-version }}" path: "turbo-ext" + - name: "Add mbstring to the PHP 8.6 prerelease image" + if: matrix.php-version == '8.6' + env: + PHP_IMAGE: ${{ matrix.image }} + # Unlike the stable images, the 8.6 prerelease omits mbstring, + # which PHPUnit and PHPStan's test fixtures require. + run: | + docker build --build-arg "PHP_IMAGE=$PHP_IMAGE" -t "$IMAGE" - <<'DOCKERFILE' + ARG PHP_IMAGE + FROM ${PHP_IMAGE} + RUN apt-get update && apt-get install -y --no-install-recommends libonig-dev \ + && docker-php-ext-install mbstring \ + && rm -rf /var/lib/apt/lists/* + DOCKERFILE + # Fast fail with a one-line diagnosis: a token-numbering mismatch # would otherwise surface as thousands of unrelated-looking failures # in the suite run below. - name: "Token-id probe in ${{ matrix.image }}" - env: - IMAGE: ${{ matrix.image }} run: docker run --rm -v "$PWD:/work" -w /work "$IMAGE" php -d extension=/work/turbo-ext/phpstan_turbo.so turbo-ext/tests/token-id-probe.php # Bind-mounted into conf.d of every docker run below. The images @@ -756,8 +787,6 @@ jobs: run: printf 'extension=/work/turbo-ext/phpstan_turbo.so\nmemory_limit=-1\n' > "$RUNNER_TEMP/turbo-docker.ini" - name: "Verify the extension is active in ${{ matrix.image }}" - env: - IMAGE: ${{ matrix.image }} run: | docker run --rm -v "$PWD:/work" -v "$RUNNER_TEMP/turbo-docker.ini:/usr/local/etc/php/conf.d/zz-turbo.ini" -w /work "$IMAGE" php -r ' require "src/Turbo/TurboExtensionEnabler.php"; @@ -773,7 +802,6 @@ jobs: # --shm-size: the arena allocates cross-worker shared memory, and # docker's default 64M /dev/shm makes parallel analysis SIGBUS. env: - IMAGE: ${{ matrix.image }} SCRIPT: ${{ matrix.script }} run: docker run --rm --shm-size=1g -v "$PWD:/work" -v "$RUNNER_TEMP/turbo-docker.ini:/usr/local/etc/php/conf.d/zz-turbo.ini" -w /work "$IMAGE" bash -c "$SCRIPT" @@ -784,7 +812,8 @@ jobs: # toolset 14.4x) refuse to load — PHP's loader rejects modules linked # with a newer toolset generation than the core. The windows-2022 image # is the one that ships VS2022. - runs-on: "windows-2022" + # PHP 8.6's vs18 development packs need the VS2026 toolchain. + runs-on: ${{ matrix.php-version == '8.6' && 'windows-2025-vs2026' || 'windows-2022' }} timeout-minutes: 40 env: @@ -795,7 +824,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["8.3", "8.4", "8.5"] + php-version: ["8.3", "8.4", "8.5", "8.6"] ts: ["nts", "zts"] # The official 8.3 Windows binaries are built with VS16 (linker # 14.2x) and PHP's module loader is one-directional (module toolset @@ -810,6 +839,8 @@ jobs: vs: "vs17" - php-version: "8.5" vs: "vs17" + - php-version: "8.6" + vs: "vs18" steps: - name: "Checkout" @@ -828,6 +859,13 @@ jobs: coverage: "none" php-version: "${{ matrix.php-version }}" + - name: "Install the matching PHP 8.6 prerelease runtime" + if: matrix.php-version == '8.6' + shell: bash + env: + MATRIX_TS: ${{ matrix.ts }} + run: bash .github/scripts/install-php86-windows.sh + - name: "Compute the extension version and download the build tools" shell: bash env: @@ -844,7 +882,9 @@ jobs: PACK="php-devel-pack-$FULL$INFIX-Win32-$MATRIX_VS-x64.zip" echo "devel pack: $PACK" curl -fsSLo devel-pack.zip "https://windows.php.net/downloads/releases/$PACK" \ - || curl -fsSLo devel-pack.zip "https://windows.php.net/downloads/releases/archives/$PACK" + || curl -fsSLo devel-pack.zip "https://windows.php.net/downloads/releases/archives/$PACK" \ + || curl -fsSLo devel-pack.zip "https://downloads.php.net/~windows/qa/$PACK" \ + || curl -fsSLo devel-pack.zip "https://downloads.php.net/~windows/qa/archives/$PACK" unzip -q devel-pack.zip -d /c/php-devel git clone -q https://github.com/php/php-sdk-binary-tools.git /c/php-sdk @@ -854,7 +894,7 @@ jobs: uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 with: arch: x64 - # empty on the vs17 legs = the image's default (latest) toolset + # empty on the vs17/vs18 legs = the image's default toolset toolset: ${{ matrix.toolset }} - name: "Build the extension" @@ -989,7 +1029,7 @@ jobs: # vs17-built official PHP loads it fine. matrix: operating-system: ["ubuntu-latest", "windows-latest"] - php-version: ["8.3", "8.4", "8.5"] + php-version: ["8.3", "8.4", "8.5", "8.6"] ts: ["nts", "zts"] script: ["make tests", "make phpstan"] # macOS runs the shipped ad-hoc-signed arm64 binary; there is no @@ -1003,6 +1043,14 @@ jobs: php-version: "8.5" ts: "nts" script: "make phpstan" + - operating-system: "macos-latest" + php-version: "8.6" + ts: "nts" + script: "make tests" + - operating-system: "macos-latest" + php-version: "8.6" + ts: "nts" + script: "make phpstan" steps: - name: Harden the runner (Audit all outbound calls) @@ -1023,6 +1071,12 @@ jobs: coverage: "none" php-version: "${{ matrix.php-version }}" + - name: "Install the matching PHP 8.6 prerelease runtime" + if: matrix.operating-system == 'windows-latest' && matrix.php-version == '8.6' + env: + MATRIX_TS: ${{ matrix.ts }} + run: bash .github/scripts/install-php86-windows.sh + - name: "Download extension artifact" uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: