Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ body:
id: php-version
attributes:
label: PHP version (full `php -v` first line)
placeholder: 'PHP 8.5.3 (cli) (built: ...) (NTS)'
placeholder: 'PHP 8.6.0 (cli) (built: ...) (NTS)'
validations:
required: true
- type: dropdown
Expand All @@ -34,7 +34,7 @@ body:
id: z-engine-version
attributes:
label: z-engine version / branch
placeholder: 'dev-master (PHP 8.5), or the 8.4 branch'
placeholder: 'dev-master (PHP 8.6), or the 8.5 branch'
validations:
required: true
- type: textarea
Expand Down
3 changes: 2 additions & 1 deletion .github/branch-flow.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"$comment": "Cascade-merge flow: fixes land on the minimum affected version branch and are merged upward. Key = source branch, value = successor branch (null = frozen, no cascade). See AGENTS.md.",
"8.0": null,
"8.4": "master"
"8.4": "8.5",
"8.5": "master"
}
32 changes: 25 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

# This branch targets PHP 8.5 only - engine structures are version-specific.
# This branch targets PHP 8.6 only - engine structures are version-specific.
env:
PHP_MINOR: '8.5'
PHP_MINOR: '8.6'

jobs:
tests:
Expand Down Expand Up @@ -436,8 +436,19 @@ jobs:
done
return 1
}
if digest="$(resolve "php:${PHP_MINOR}-cli" | sha256sum | cut -d' ' -f1)" && [ "${#digest}" -eq 64 ]; then
echo "php:${PHP_MINOR}-cli is sha256:${digest}"
# While the minor is pre-release Docker publishes only the -rc family
# (which also covers betas): fall back to it and hand the winning tag
# to the build step below, self-healing to the stable tag at GA
tag="${PHP_MINOR}"
manifest=""
if manifest="$(resolve "php:${PHP_MINOR}-cli")"; then
:
elif manifest="$(resolve "php:${PHP_MINOR}-rc-cli")"; then
tag="${PHP_MINOR}-rc"
echo "php:${PHP_MINOR}-cli is not published yet - building from php:${tag}-cli"
fi
if [ -n "$manifest" ] && digest="$(printf '%s' "$manifest" | sha256sum | cut -d' ' -f1)" && [ "${#digest}" -eq 64 ]; then
echo "php:${tag}-cli is sha256:${digest}"
else
# A registry hiccup must not fail this job over a cache key. A
# run-unique value guarantees a miss, so the restore-keys still give a
Expand All @@ -446,6 +457,7 @@ jobs:
digest="unresolved-${{ github.run_id }}"
echo "::warning::Could not resolve the php:${PHP_MINOR}-cli digest - building without an exact cache key"
fi
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
# Thread safety and minor come first so the loosest restore-key below
# still matches entries written before OS/arch joined the key.
prefix="docker-debug-${{ matrix.ts }}-${PHP_MINOR}-${{ runner.os }}-${{ runner.arch }}-"
Expand Down Expand Up @@ -483,7 +495,7 @@ jobs:
fi
docker buildx build \
-f tools/docker/php-debug.Dockerfile \
--build-arg "PHP_VERSION=${PHP_MINOR}" \
--build-arg "PHP_VERSION=${{ steps.image-cache-key.outputs.tag }}" \
--build-arg "PHP_TS=${{ matrix.ts }}" \
--cache-from "type=local,src=/tmp/.buildx-cache" \
$cache_to \
Expand Down Expand Up @@ -556,9 +568,15 @@ jobs:
done
return 1
}
if cli="$(resolve "php:${PHP_MINOR}-cli")" && zts="$(resolve "php:${PHP_MINOR}-zts")"; then
# While the minor is pre-release Docker publishes only the -rc family
# (which also covers betas); generate.php falls back the same way, so
# the key hashes whichever manifests the build will actually use
resolve_variant() {
resolve "php:${PHP_MINOR}-$1" || resolve "php:${PHP_MINOR}-rc-$1"
}
if cli="$(resolve_variant cli)" && zts="$(resolve_variant zts)"; then
digest="$(printf '%s%s' "$cli" "$zts" | sha256sum | cut -d' ' -f1)"
echo "php:${PHP_MINOR}-cli + php:${PHP_MINOR}-zts hash to ${digest}"
echo "php:${PHP_MINOR}[-rc]-cli + php:${PHP_MINOR}[-rc]-zts hash to ${digest}"
else
# As above: a registry hiccup costs an exact key, never the job.
digest="unresolved-${{ github.run_id }}"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/generate-darwin-headers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }}
cancel-in-progress: false

# This branch targets PHP 8.5 only - engine structures are version-specific.
# This branch targets PHP 8.6 only - engine structures are version-specific.
env:
PHP_MINOR: '8.5'
PHP_MINOR: '8.6'

jobs:
generate:
Expand Down
24 changes: 19 additions & 5 deletions .github/workflows/generate-windows-headers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || github.ref }}
cancel-in-progress: false

# This branch targets PHP 8.5 only - engine structures are version-specific.
# This branch targets PHP 8.6 only - engine structures are version-specific.
env:
PHP_MINOR: '8.5'
PHP_MINOR: '8.6'

jobs:
generate:
Expand Down Expand Up @@ -115,9 +115,23 @@ jobs:
php -d ffi.enable=1 -r 'FFI::cdef("extern unsigned long long __vectorcall zend_string_hash_func(void *str);", "${{ matrix.dll }}");' \
|| { echo "::error::FFI cannot bind a __vectorcall symbol from ${{ matrix.dll }} - this build lacks vectorcall support"; exit 1; }

# The generator itself can also skip cleanly (exit 0 with a SKIPPED
# notice) when windows.php.net has no build or devel pack for the
# running version - snapshot builds of a pre-release minor. Track that in
# an output so the artifact checks below do not demand files no run
# could have produced; the leg self-heals on the first tagged build.
- name: Generate windows artifacts
if: steps.build.outputs.available == 'true'
run: php tools/generator/generate.php --native --php=${{ env.PHP_MINOR }} --ts=${{ matrix.ts }}
id: gen
run: |
php tools/generator/generate.php --native --php=${{ env.PHP_MINOR }} --ts=${{ matrix.ts }} | tee gen-output.log
if grep -q '^==> SKIPPED:' gen-output.log; then
echo "generated=false" >> "$GITHUB_OUTPUT"
echo "::warning::windows-x64-${{ matrix.ts }} generation skipped for this pre-release PHP build - see the generator notice above"
else
echo "generated=true" >> "$GITHUB_OUTPUT"
fi
rm -f gen-output.log

# On failure, surface the intermediate build dir (emitted engine.h,
# preprocessed source, probe) so the broken declaration can be diagnosed
Expand All @@ -135,7 +149,7 @@ jobs:
if-no-files-found: ignore

- name: Smoke-check the artifacts
if: steps.build.outputs.available == 'true'
if: steps.build.outputs.available == 'true' && steps.gen.outputs.generated == 'true'
run: |
dir="include/${PHP_MINOR}/windows-x64-${{ matrix.ts }}"
for file in engine.h constants.php layouts.json probe.c; do
Expand All @@ -147,7 +161,7 @@ jobs:
|| { echo "::error::${dir}/engine.h does not name ${{ matrix.dll }} as FFI_LIB - symbols would not resolve on Windows"; exit 1; }

- uses: actions/upload-artifact@v7
if: steps.build.outputs.available == 'true'
if: steps.build.outputs.available == 'true' && steps.gen.outputs.generated == 'true'
with:
name: windows-x64-${{ matrix.ts }}
path: include/${{ env.PHP_MINOR }}/windows-x64-${{ matrix.ts }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

# This branch targets PHP 8.5 only - engine structures are version-specific.
# This branch targets PHP 8.6 only - engine structures are version-specific.
env:
PHP_MINOR: '8.5'
PHP_MINOR: '8.6'

jobs:
benchmark:
Expand Down
4 changes: 4 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@

return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
// This branch targets PHP 8.6, which php-cs-fixer does not list as
// supported while it is pre-release; the codebase uses no 8.6-only syntax,
// so the fixer output stays stable. Drop once the fixer supports 8.6.
->setUnsupportedPhpVersionAllowed(true)
->setRules([
'@PER-CS2.0' => true,
'declare_strict_types' => true,
Expand Down
6 changes: 5 additions & 1 deletion .phpstorm.meta.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/*
* Generated by tools/generator for PHP 8.5 - DO NOT EDIT.
* Generated by tools/generator for PHP 8.6 - DO NOT EDIT.
* Regenerate with `composer gen-headers`.
*
* PhpStorm-only type maps for the ZEngine\Core typed entry points: a stub
Expand Down Expand Up @@ -44,6 +44,7 @@
'zend_constant' => \ZEngine\Generated\zend_constant::class,
'zend_declarables' => \ZEngine\Generated\zend_declarables::class,
'zend_early_binding' => \ZEngine\Generated\zend_early_binding::class,
'zend_err_buf' => \ZEngine\Generated\zend_err_buf::class,
'zend_error_info' => \ZEngine\Generated\zend_error_info::class,
'zend_execute_data' => \ZEngine\Generated\zend_execute_data::class,
'zend_executor_globals' => \ZEngine\Generated\zend_executor_globals::class,
Expand Down Expand Up @@ -128,6 +129,7 @@
'zend_constant' => \ZEngine\Generated\zend_constant::class,
'zend_declarables' => \ZEngine\Generated\zend_declarables::class,
'zend_early_binding' => \ZEngine\Generated\zend_early_binding::class,
'zend_err_buf' => \ZEngine\Generated\zend_err_buf::class,
'zend_error_info' => \ZEngine\Generated\zend_error_info::class,
'zend_execute_data' => \ZEngine\Generated\zend_execute_data::class,
'zend_executor_globals' => \ZEngine\Generated\zend_executor_globals::class,
Expand Down Expand Up @@ -241,6 +243,8 @@
'zend_declarables *' => \ZEngine\Generated\zend_declarables::class,
'zend_early_binding' => \ZEngine\Generated\zend_early_binding::class,
'zend_early_binding *' => \ZEngine\Generated\zend_early_binding::class,
'zend_err_buf' => \ZEngine\Generated\zend_err_buf::class,
'zend_err_buf *' => \ZEngine\Generated\zend_err_buf::class,
'zend_error_info' => \ZEngine\Generated\zend_error_info::class,
'zend_error_info *' => \ZEngine\Generated\zend_error_info::class,
'zend_execute_data' => \ZEngine\Generated\zend_execute_data::class,
Expand Down
25 changes: 13 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ every minor version (`zend_class_entry` alone changed size in 8.1, 8.3 and
version and you are reading and writing the wrong memory — the result is a
crash, or worse, silent corruption.

- `master` targets the newest supported PHP minor (currently **8.5**).
- `master` targets the newest supported PHP minor (currently **8.6**).
- Branch `8.5` targets **PHP 8.5**.
- Branch `8.4` targets **PHP 8.4**.
- Branch `8.0` is the frozen legacy line for PHP 8.0.

Expand All @@ -30,12 +31,12 @@ never cherry-picked downward. The succession is declared in
which opens a merge-up PR when a version branch is pushed.

```
8.0 (frozen) 8.4 ──► master (8.5)
8.0 (frozen) 8.4 ──► 8.5 ──► master (8.6)
```

So a bug that exists in both 8.4 and 8.5 is fixed on `8.4`, and the cascade
carries it into `master`. A bug that only exists on 8.5 is fixed on `master`
directly. When resolving a merge-up conflict inside `include/`, do **not**
So a bug that exists in 8.4, 8.5 and 8.6 is fixed on `8.4`, and the cascade
carries it through `8.5` into `master`. A bug that only exists on 8.6 is fixed
on `master` directly. When resolving a merge-up conflict inside `include/`, do **not**
merge the generated headers textually — regenerate them on the target branch
(`composer gen-headers`) instead.

Expand Down Expand Up @@ -132,12 +133,12 @@ Darwin covers **NTS and ZTS**: the workflow's matrix crosses both
architectures with both thread-safety modes (setup-php builds the ZTS PHP via
`phpts: ts`). As on Linux, the ZTS artifacts reach EG/CG through the TSRM
offsets; the opcache file-cache relocator runs on ZTS since issue #118.
The 8.4 artifacts are maintained on the `8.4` branch;
`include/8.5/darwin-*` is maintained here - after changing the generator,
The 8.4 and 8.5 artifacts are maintained on the `8.4` and `8.5` branches;
`include/8.6/darwin-*` is maintained here - after changing the generator,
refresh it with one `workflow_dispatch` run of the workflow on `master`.
A leg whose thread-safety mode setup-php cannot provide (currently ZTS
PHP 8.5 on Intel) skips cleanly and self-heals on a later run; the CI
presence guards keep the gap visible as warnings.
A leg whose PHP build setup-php cannot provide (a pre-release 8.6, or a
thread-safety mode with no build) skips cleanly and self-heals on a later
run; the CI presence guards keep the gap visible as warnings.

### Windows artifacts

Expand Down Expand Up @@ -173,8 +174,8 @@ Windows differs from the POSIX platforms in four load-bearing ways:

Not supported on Windows: the opcache file-cache relocator (issue #119, its
tests self-skip and the CI legs carry no opcache non-skip gate) and
`opcache.preload` (does not exist on Windows). As with darwin, the 8.4
artifacts are maintained on the `8.4` branch; `include/8.5/windows-*` is
`opcache.preload` (does not exist on Windows). As with darwin, the 8.4 and
8.5 artifacts are maintained on their branches; `include/8.6/windows-*` is
maintained here - after changing the generator, refresh it with one
`workflow_dispatch` run of the workflow on `master`.

Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[![CI](https://img.shields.io/github/actions/workflow/status/lisachenko/z-engine/ci.yml?branch=master&label=CI)](https://github.com/lisachenko/z-engine/actions/workflows/ci.yml)
[![GitHub release](https://img.shields.io/github/release/lisachenko/z-engine.svg)](https://github.com/lisachenko/z-engine/releases/latest)
[![PHP Version](https://img.shields.io/badge/php-8.4%20%7C%208.5-8892BF.svg)](https://php.net/)
[![PHP Version](https://img.shields.io/badge/php-8.4%20%7C%208.5%20%7C%208.6-8892BF.svg)](https://php.net/)
[![License](https://img.shields.io/packagist/l/lisachenko/z-engine.svg)](https://packagist.org/packages/lisachenko/z-engine)
[![PHPStan](https://img.shields.io/badge/PHPStan-level%20max-brightgreen.svg)](https://phpstan.org/)

Expand Down Expand Up @@ -43,11 +43,14 @@ Engine memory layouts change between every PHP minor version, so each PHP minor

| PHP | OS / Arch / TS | Branch | Status |
|-----|----------------|--------|--------|
| 8.5 | linux-x64 (nts, zts), darwin-x64 (nts), darwin-arm64 (nts, zts), windows-x64 (nts, zts) | `master` | ✅ supported¹ |
| 8.6 | linux-x64 (nts, zts) | `master` | 🚧 in progress¹ |
| 8.5 | linux-x64 (nts, zts), darwin-x64 (nts), darwin-arm64 (nts, zts), windows-x64 (nts, zts) | `8.5` | ✅ supported² |
| 8.4 | linux-x64 (nts, zts), darwin-x64 (nts, zts), darwin-arm64 (nts, zts), windows-x64 (nts, zts) | `8.4` | ✅ supported |
| 8.0 | linux-x64-nts | `8.0` | 🧊 frozen (legacy) |

¹ `darwin-x64-zts` on 8.5 lands as soon as a ZTS PHP 8.5 build exists for Intel macOS runners — the generation workflow picks it up automatically.
¹ PHP 8.6 is pre-release; definitions track the latest beta. darwin-* and windows-* artifacts land through the generation workflows as 8.6 builds become available on those runners.

² `darwin-x64-zts` on 8.5 lands as soon as a ZTS PHP 8.5 build exists for Intel macOS runners — the generation workflow picks it up automatically.

> **Version matching is not optional.** Running Z-Engine against a PHP minor it was not built for corrupts memory. `Core::init()` enforces the match and aborts with a clear message rather than letting you crash.

Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
}
],
"require": {
"php": "~8.5.0",
"php": "~8.6.0",
"ext-ffi": "*"
},
"require-dev": {
Expand Down Expand Up @@ -66,7 +66,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "8.5.x-dev"
"dev-master": "8.6.x-dev"
}
}
}
Loading
Loading