feat(catalog): bump redis PECL 6.2.0 → 6.3.0 (restores PHP 8.5)#76
Conversation
The runtime 'phpup install' path used a hardcoded inline catalog in cmd/phpup/main.go that duplicated catalog/extensions/*.yaml version pins. Bumping redis to 6.3.0 in the YAML without updating the inline copy caused resolve failures on PHP 8.5 with 'extension redis 6.2.0 ... not found in lockfile'. Extract the inline extension specs into runtimeExtensionSpecs() and add TestRuntimeExtensionSpecsMatchYAML to catch version/kind drift between the two sources of truth, mirroring the existing TestCatalogBundledMatchesCompat pattern for catalog/php.yaml <-> internal/compat.
CI status noteAll 20 `pipeline` cells (4 OS × arch × 5 PHP) pass — redis 6.3.0 builds cleanly across the matrix and the harness fixtures are green, including the newly redis-bearing 8.5 fixtures (`multi-ext-85`, `none-reset-85`, `single-ext-85`). The 4 `smoke-action` cells fail with: ``` This is structural, not a regression in this PR: `smoke-action` resolves bundles through the committed `bundles.lock` + GHCR, and the `publish` job (which writes `ext:redis:6.3.0:*` entries to `bundles.lock` and pushes the bundles to GHCR) is gated on `if: github.ref == 'refs/heads/main'`. Any PR that bumps a bundle version hits this; merging the PR triggers `publish` on main, which auto-commits `chore(lock): update bundles.lock from pipeline ` and unblocks GHCR — matches the recent main-history pattern (`2135981`, `5ef5c4f`, `de13af7`). Filed as #83 — proposes making `smoke-action` consume the `pipeline`-built oci-layout artifacts via `PHPUP_REGISTRY`/`PHPUP_LOCKFILE` env so future bump PRs can validate end-to-end without GHCR roundtrip (matches the design intent in `docs/superpowers/specs/2026-04-23-local-ci-unification-design.md`). |
…ns (#87) phpup push wrote each promoted manifest to a digest-prefix tag like 'sha256-<first12hex>' instead of the canonical '<version>-<phpver>-<ts>-<os>-<arch>' shape. Bundles landed on GHCR but were unreachable to lockfile-update, which queries the canonical tag and got 404, silently dropping the entry from bundles.lock. Switch PushAll to ListKeyed (which exposes the source manifest's io.buildrush.bundle.key annotation), derive the canonical (image-name, tag) pair from the key via canonicalRefFromBundleKey, and propagate BundleKey + SpecHash annotations to the destination so LookupBySpec also resolves on the promoted remote. Reproduces the failure that left main with redis 6.3.0 in the catalog but no 6.3.0 entries in bundles.lock or canonical GHCR tags after PR #76 merged: phpup push pushed redis 6.3.0 blobs+manifests under sha256-* tags, lockfile-update HEAD'd 'redis:6.3.0-8.5-nts-linux-x86_64' and got 404, and the canonical-tag listing on GHCR remained 6.2.0-only. Comment on the previous deriveTagForPromotion explicitly flagged this as a 'PR 6 will fix' stub that never landed. Updates push_test.go to assert canonical tags + propagated annotations, adds TestCanonicalRefFromBundleKey covering core/ext/error shapes, and fixes a stale ext-key example in registry/annotations.go that used the defunct '8.4-nts' joined PHPAbi format.
…89) Manually-regenerated bundles.lock from `phpup lockfile-update` against ghcr.io/buildrush. Replaces the 8 existing `ext:redis:6.2.0:{8.1..8.4}:*` entries with the corresponding 6.3.0 entries, and adds 2 new `ext:redis:6.3.0:8.5:*` entries (8.5 was previously excluded for redis pre-#76). Brings main back to a fully consistent state — catalog, lockfile, and GHCR all agree on redis 6.3.0 — completing the work started in #76. The non-redis line-level churn in this diff is in-entry digest/spec_hash refresh from the multiple publish runs that fired during the chain of fixes (#85, #86, #87, #88). Bundle keys themselves are unchanged outside of redis. Per internal/testsuite/runner.go:345-346, manifest digests are non-reproducible across pushes because meta.json carries a build-time timestamp; this is expected behavior, not a regression. Why this is committed by hand rather than auto-committed by the publish job: the publish job's git push is rejected by the main-branch ruleset ("Changes must be made through a pull request"). A follow-up will either switch the auto-commit to a bot-PR flow or grant the publish identity a ruleset bypass; until then, version-bump PRs require this manual lockfile-update PR step.
Summary
catalog/extensions/redis.yamlfrom redis6.2.0→6.3.0and drops theexclude: [{ php: "8.5" }]block.multi-ext-85,none-reset-85,single-ext-85), which were temporarily swapped to apcu in feat: enable PHP 8.5 core + PECL rebuild (phase 2) #37. Also restores redis inmulti-ext-top14-arm64-85.cmd/phpup/main.go(extracted to a newruntimeExtensionSpecs()function) with the YAML source of truth.TestRuntimeExtensionSpecsMatchYAMLto guard against future drift between the inline runtime catalog andcatalog/extensions/*.yaml(mirrors the pattern ofTestCatalogBundledMatchesCompat).Closes #38.
Why 6.3.0
redis 6.2.0's
common.hincludesext/standard/php_smart_string.h, an internal PHP header removed in the 8.5 source tree — compilation fails withfatal error: ext/standard/php_smart_string.h: No such file or directory. Upstream redis 6.3.0 drops the include.Implementation discovery: duplicate catalog source of truth
Local CI reproduction (
make ci-cell OS=jammy ARCH=x86_64 PHP=8.5) after the YAML-only change failed with:Root cause:
cmd/phpup/main.gocarried a hardcoded inlinecatalog.Catalog{...}literal used by the runtimeinstallpath, duplicating the version pins incatalog/extensions/*.yaml. The YAML change alone was insufficient.Fix: extract the inline spec into
runtimeExtensionSpecs()in a newcmd/phpup/runtime_catalog.go, bump redis to6.3.0there, and addTestRuntimeExtensionSpecsMatchYAMLto enforce inline↔YAML version/kind parity going forward. Further unification (making the runtime load from YAML directly) is a bigger refactor outside this slice's scope; the drift test makes the current duplication safe.Upstream 6.2.0 → 6.3.0 behavior review
Feature-additive release; no user-facing BC breaks.
DELIFEQ, Redis vector-set commands,GEOSEARCH[STORE] BYPOLYGON,HGETEX/HSETEX/HGETDEL,Redis::serverName/Redis::serverVersion, constructordatabaseoption, connectionmaxRetries, INI knob to restore 5.x legacy session-lock-failure behavior.Redis::execHellovisibility changed toprotected(affects only subclasses that called it directly — rare).ext/standard/php_smart_string.hinclude (the reason for this bump).Upstream notes: https://github.com/phpredis/phpredis/releases/tag/6.3.0
PR self-publish flow
Per the bundle-rollout design, PR CI will rebuild all 10 redis bundles (5 PHP ABIs × 2 arches), push them to GHCR, commit the refreshed
bundles.lockback to this PR head, then run the compat harness against the freshly published bundles. The PR merges atomically with code + bundle content + lockfile.Local pre-push verification
make check— green.make ci-cell OS=jammy ARCH=x86_64 PHP=8.5— green (11/11 8.5 fixtures pass including the newly redis-bearingmulti-ext-85/none-reset-85/single-ext-85).Test plan
build-extension.ymlbuilds redis 6.3.0 for all 10 cells and pushes to GHCR.lockfile-updatecommits refreshedbundles.lockback to this PR head; lockfile containsext:redis:6.3.0:{8.1..8.5}:linux:{x86_64,aarch64}:ntsand noext:redis:6.2.0:*entries.multi-ext-top14-arm64-85, jumbo fixtures).make checkpasses;TestRuntimeExtensionSpecsMatchYAMLis green.Spec:
docs/superpowers/specs/2026-04-24-redis-6.3.0-bump-design.md