This file is the straight guide for the next PHP patch release cycle in this repo.
It covers:
- how to decide which version tag is valid
- how to test locally against Alpine packages
- how to trigger GitHub Actions
- how to verify Docker Hub publication
- what failed on March 11, 2026 and what must not regress
For versioned Docker tags, use this rule:
- The release number must exist as a stable
php/php-srctag. - The installed Alpine
phpXXpackage inside the image must report the same version. - Local tests must pass.
- GitHub Actions
workflow_dispatchrelease run must pass. - Docker Hub must show the exact published tags.
If any of those do not match, do not publish a versioned tag.
- PHP release workflows in this repo are manual by design. They use
workflow_dispatch. - The host-side test entrypoint is
tests/run-test.sh. - The inner scripts
tests/test-base.sh,tests/test-fpm.sh, andtests/test-unit.shrun inside a started container and must not be called directly from the host. make tagis not the release path for normal PHP patch releases. Use GitHub Actions after tests pass.
Use 84 or 85 below depending on the PHP series you are releasing.
git pull --ff-only
git status --shortIgnore only known local-only files such as .claude/settings.local.json.
Use the helper:
./release-php.sh latest 85
./release-php.sh check 85What this does:
- reads the latest stable version from
https://github.com/php/php-src/tags - reads the installed
PHP_VERSIONfrom the local image - reads the installed Alpine package version from
/lib/apk/db/installed - fails if the versions do not match exactly
Expected example output:
Series: 8.5
Image: skilldlabs/php:85
php-src tag: 8.5.4
Installed PHP: 8.5.4
Installed apk: 8.5.4-r0
8.5.4
make test-local TAGS="85 85-fpm 85-unit"Direct host-side smoke tests:
./tests/run-test.sh skilldlabs/php:85 8.5 base
./tests/run-test.sh skilldlabs/php:85-fpm 8.5 fpm
./tests/run-test.sh skilldlabs/php:85-unit 8.5 unitIf local tests fail, stop and fix the repo before dispatching GitHub Actions.
Use the helper:
./release-php.sh publish 85This dispatches the manual workflow:
gh workflow run "Build PHP 8.5" -f version=8.5.4Do the same for 84 when needed:
./release-php.sh publish 84./gh-debug.sh list
GH_TOKEN= gh run watch <RUN_ID> -R skilld-labs/docker-php --interval 10Success means all of these jobs pass:
build-basebuild-fpmbuild-unitbuild-unit-dev
Check exact version tags:
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/8.5.4'
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/8.4.19'Check versioned variant tags:
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/85-fpm-8.5.4'
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/85-unit-8.5.4'
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/84-fpm-8.4.19'
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/84-unit-8.4.19'Check floating tags:
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/85'
curl -L -s 'https://hub.docker.com/v2/repositories/skilldlabs/php/tags/84'What to confirm:
- tag exists
tag_statusisactivelast_updatedis currentamd64andarm64images are both present
Examples:
php-srclatest stable is8.5.5but local image still reports8.5.4- Alpine package reports
8.5.5-r0butphp-srcstable is still8.5.4
Then:
- Do not publish a versioned tag.
- Rebuild locally and check again if Alpine has updated.
- If Alpine is ahead of upstream stable, wait for stable upstream confirmation before versioned release tagging.
- If Alpine is behind upstream stable, wait for Alpine package availability or update the packaging source first.
Floating tags without a version input are a separate decision. Do not use them as a shortcut for versioned patch releases.
Validated and published on March 11, 2026:
8.5.485-fpm-8.5.485-unit-8.5.48.4.1984-fpm-8.4.1984-unit-8.4.19
Successful GitHub Actions runs:
Build PHP 8.5run22957765320Build PHP 8.4run22957781084
Commit containing the CI fix and release helper:
7531dc0
Local testing looked good, but GitHub Actions failed almost immediately in:
Build PHP 8.5- failed run
22954509499 - failed step
Test base image
The workflow and make test-local were calling:
tests/test-base.shtests/test-fpm.shtests/test-unit.sh
directly from the host.
Those scripts had been refactored to run inside a container that was already started. The correct host-side entrypoint was tests/run-test.sh.
So CI built the image successfully, then ran host-side commands like php, composer, and drush on the GitHub runner instead of inside the built container.
The fix was:
- route GitHub Actions through
tests/run-test.sh - route
make test-localthroughtests/run-test.sh - update docs so they no longer teach the wrong entrypoint
- add
release-php.shso version selection is explicit and reproducible
Before dispatching a release:
- run
./release-php.sh check <series> - if needed, run
make test-local TAGS="..."and./tests/run-test.sh ... - trigger release with
./release-php.sh publish <series> - verify Docker Hub explicitly
GitHub Actions prints Node.js 20 deprecation warnings for several actions.
This did not block the March 11, 2026 releases, but the action versions should be reviewed before GitHub forces Node.js 24 by default on June 2, 2026.