Skip to content

Add PHP 8.3-8.5 and migrate CI to GitHub Actions#44

Merged
rick-lam merged 15 commits into
masterfrom
add-php-8.3-8.5-and-gha
May 28, 2026
Merged

Add PHP 8.3-8.5 and migrate CI to GitHub Actions#44
rick-lam merged 15 commits into
masterfrom
add-php-8.3-8.5-and-gha

Conversation

@rick-lam
Copy link
Copy Markdown
Contributor

@rick-lam rick-lam commented May 28, 2026

Summary

New PHP versions

  • 8.3, 8.4, 8.5 added. All three inherit from the upstream docker-library/php images (php:8.3-cli-alpine3.19, php:8.4-cli-alpine3.21, php:8.5-cli-alpine3.23) so PHP is compiled against gnu-libiconv directly via --with-iconv=/usr. The historical LD_PRELOAD=/usr/lib/preloadable_libiconv.so workaround and the alpine 3.13/community --allow-untrusted pull are gone for these versions; iconv("UTF-8", "ASCII//TRANSLIT", …) still works.
  • Per-version extension install: bcmath, intl, mysqli, pcntl, pdo_mysql, pdo_pgsql, pgsql, soap, sockets, zip via docker-php-ext-install; apcu, event, memcached, yaml via pecl. event is forced to load after sockets via a zz- prefixed ini. opcache enabled on 8.3 (upstream ships it as an un-enabled shared module there).
  • ENTRYPOINT [] resets upstream's docker-php-entrypoint to preserve the historical "run anything" UX of this image.
  • latest_8 and latest bumped to 8.5; new versions wired into every aggregate Makefile target (build, prod-build, tag, test, push, clean, deploy).

CI migrated from Travis to GitHub Actions

  • .travis.yml deleted, .github/workflows/build.yml added with a fail-fast=false matrix across all 12 PHP versions.
  • Test phase builds single-arch amd64 with the default docker builder so the bats container can load it from the daemon.
  • Master pushes additionally run a multi-arch buildx --push step with per-version platforms matching what the underlying alpine base supports:
    • 5.6, 7.0, 7.1, 7.2 — linux/amd64 only
    • 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5 — linux/amd64, linux/arm/v7, linux/arm64
  • Floating alias tags (5, 7, 8, latest, and -test variants) are computed inline so the manifest list pushes correctly.
  • Auth uses DOCKERHUB_USERNAME / DOCKERHUB_TOKEN secrets.

Single source of truth for supported versions

  • New versions.json at the repo root with one {version, platforms} entry per PHP version. Adding a future version is a one-line edit.
  • Makefile derives VERSIONS via jq and uses $(addprefix …,$(VERSIONS)) for every aggregate target — no more hand-maintained "build-5.6 build-7.0 …" lines.
  • GitHub Actions workflow has a tiny matrix prep job that runs jq -c . versions.json and emits the include for the build job to consume via fromJson.

Bats test improvements

  • common/php.bats: dropped the LD_PRELOAD env-var assertion (no longer applies to 8.3+); the iconv functional test now uses non-ASCII input (café) so it actually exercises //TRANSLIT, with assertions tolerant of different gnu-libiconv version outputs (caf'e from 1.15-r3 vs cafe from 1.18+).
  • common/php.bats: grep memory_limitgrep -w memory_limit to avoid matching PHP 8.5's new max_memory_limit directive.
  • Makefile: bats container now receives GIT_CONFIG_* env vars marking /app as a safe.directory (fixes "dubious ownership" failures inside the container).
  • 8.5/tags.bats: extended to assert the aggregate 8 / latest aliases (and -test variants) point at the 8.5 image after make tag-8.5.
  • 8.1/tags.bats, 8.2/tags.bats: corrected pre-existing image-id references that were pointing at 8.0 (only surfaced now that the GH Actions matrix isolates per-version jobs).

README

  • Travis badge → GitHub Actions badge.
  • Image lists updated to include 8.3, 8.4, 8.5 and to reflect 8.5 holding the 8 and latest aliases.
  • Corrected long-standing evevent labelling typo in the modules list (the image has always installed pecl-event).
  • phpdbg7 example replaced with phpdbg to match the binary name on the current :test tag (now 8.5, docker-library based).

Test plan

  • Add DOCKERHUB_USERNAME and DOCKERHUB_TOKEN repo secrets before merging
  • All 12 matrix jobs + the Load matrix prep job green (build → tag → test)
  • After merge: confirm graze/php-alpine:{8.3,8.4,8.5,8,latest} (and -test variants) appear on Docker Hub
  • Verify multi-arch manifests: docker buildx imagetools inspect graze/php-alpine:8.5 should list amd64, arm/v7, arm64

🤖 Generated with Claude Code

Add 8.3 (alpine:3.19), 8.4 (alpine:3.21), and 8.5 (alpine:3.22) images
mirroring the 8.2 layout, switching libssl1.1 to libssl3 on the newer
Alpine bases. Replace .travis.yml with .github/workflows/build.yml
running a matrix build/test across all supported PHP versions and
deploying to Docker Hub on master pushes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 28, 2026 12:37
The Makefile defaults build-% to multi-platform, which is incompatible
with --output=type=docker (manifest lists can't be exported into the
local Docker daemon). The bats tests need the image in the daemon, so
pin platform=linux/amd64 for the CI build step.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds new Alpine-based PHP 8.3/8.4/8.5 image definitions, updates the repo’s “latest” tagging to point at PHP 8.5, and migrates CI from Travis to a GitHub Actions matrix workflow.

Changes:

  • Add new image directories for PHP 8.3 (Alpine 3.19), 8.4 (Alpine 3.21), and 8.5 (Alpine 3.22), including debug images and bats tests.
  • Update Makefile aggregate targets and bump latest_8/latest to 8.5.
  • Remove .travis.yml and introduce .github/workflows/build.yml; update README badge and image lists.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
README.md Update CI badge and document new 8.3–8.5 tags (including latest).
Makefile Add 8.3–8.5 to aggregate targets; switch latest_8/latest to 8.5.
8.3/Dockerfile New PHP 8.3 image (Alpine 3.19) and package set.
8.3/debug.Dockerfile New PHP 8.3 debug image with phpdbg.
8.3/php.bats New PHP 8.3 functional/module test.
8.3/php_debug.bats New PHP 8.3 phpdbg availability test.
8.3/tags.bats New PHP 8.3 tag creation test.
8.3/php/conf.d/00_memlimit.ini New memory limit config for 8.3.
8.3/php/conf.d/00_short_open_tag.ini New short open tag config for 8.3.
8.3/.dockerignore Exclude bats files from the Docker build context (8.3).
8.4/Dockerfile New PHP 8.4 image (Alpine 3.21) and package set.
8.4/debug.Dockerfile New PHP 8.4 debug image with phpdbg.
8.4/php.bats New PHP 8.4 functional/module test.
8.4/php_debug.bats New PHP 8.4 phpdbg availability test.
8.4/tags.bats New PHP 8.4 tag creation test.
8.4/php/conf.d/00_memlimit.ini New memory limit config for 8.4.
8.4/php/conf.d/00_short_open_tag.ini New short open tag config for 8.4.
8.4/.dockerignore Exclude bats files from the Docker build context (8.4).
8.5/Dockerfile New PHP 8.5 image (Alpine 3.22) and package set.
8.5/debug.Dockerfile New PHP 8.5 debug image with phpdbg.
8.5/php.bats New PHP 8.5 functional/module test.
8.5/php_debug.bats New PHP 8.5 phpdbg availability test.
8.5/tags.bats New PHP 8.5 tag creation test.
8.5/php/conf.d/00_memlimit.ini New memory limit config for 8.5.
8.5/php/conf.d/00_short_open_tag.ini New short open tag config for 8.5.
8.5/.dockerignore Exclude bats files from the Docker build context (8.5).
.travis.yml Remove Travis CI configuration.
.github/workflows/build.yml Add GitHub Actions matrix CI for build/tag/test and master deploy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/build.yml Outdated
Comment thread 8.3/Dockerfile Outdated
Comment thread 8.4/Dockerfile Outdated
Comment thread 8.5/Dockerfile Outdated
Comment thread Makefile
rick-lam and others added 9 commits May 28, 2026 13:43
Build single-arch (amd64) for the test step so the bats suite can load
the image into the local Docker daemon, then run a second multi-arch
buildx build with --push directly to Docker Hub on master.

Platform set per PHP version matches what the underlying alpine base
image supports:
  5.6, 7.0          alpine:3.5      amd64
  7.1, 7.2          alpine:3.7/3.8  amd64
  7.3 ... 8.5       alpine:3.12+    amd64, arm/v7, arm64

The deploy step also computes the floating aliases (5/7/8/latest and
their -test variants) inline rather than via make tag-/push-, since
those targets work on the local daemon and can't manage multi-arch
manifest lists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 8.5: bump alpine 3.22 -> 3.23; php85 is only in 3.23/community
- Move setup-buildx-action to the deploy step only. The default docker
  driver is single-platform but shares images with the daemon, so the
  debug image (FROM graze/php-alpine:VER) can resolve the just-built
  base. setup-buildx-action creates a docker-container builder that
  can't see daemon images, which broke the debug build for any version
  whose tag wasn't already on Docker Hub (8.3, 8.4).
- Pass GIT_CONFIG_COUNT/KEY/VALUE to the bats container so git inside
  the container treats the host-owned mount as a safe.directory; fixes
  the "dubious ownership in repository at '/app'" failure in every test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- alpine:3.23/community does not package php85-opcache or php85-zlib;
  remove them from 8.5/Dockerfile and drop the corresponding asserts
  from 8.5/php.bats.
- 8.1/tags.bats and 8.2/tags.bats reference graze/php-alpine:8.0 when
  looking up image IDs. Travis built every PHP version in the same
  workspace so 8.0 happened to be present, but per-job isolation in
  GitHub Actions means the test runs without an 8.0 image and grep
  receives an empty pattern. Point each test at its own version.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PHP 8.5 introduced a new max_memory_limit INI directive, so the
existing `grep memory_limit` returns two lines instead of one and the
equality assertion fails. Switch to `grep -w` so only the exact
memory_limit row is matched across every PHP version.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
php85-zlib doesn't exist as a real apk package in alpine 3.23, but
php85-common's `provides:` list includes php85-zlib (zlib was merged
into php-common upstream). Installing it via the virtual still works,
so list it explicitly to keep the package set consistent with the
other PHP versions, and restore the zlib assertion in 8.5/php.bats.

php85-opcache stays removed because it's neither a real package nor
provided by anything in alpine 3.23.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
make tag-8.5 reassigns the aggregate tags (8, 8-test, latest, test) to
the 8.5 image but nothing was verifying that. Extend the tags bats
file so the same docker-images lookup also asserts the alias tags are
present alongside the versioned 8.5 / 8.5-test tags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…biconv

gnu-libiconv 1.15-r3 is the last release that ships the LD_PRELOAD-
compatible preloadable_libiconv.so, and that file is what makes PHP's
iconv extension pick up GNU iconv's //TRANSLIT support at runtime
without rebuilding PHP from source. We still have to pull the .apk
from alpine 3.13/community, but rather than passing --allow-untrusted
and HTTP we now:

- fetch the alpine-devel 4a6a0840 signing key over HTTPS from aports
  and verify it against a pinned sha256
- drop the key into /etc/apk/keys/
- use the HTTPS mirror for the 3.13 community repository

apk can now verify the package signature normally, --allow-untrusted
is gone, and the transport is TLS-protected. Verified locally that
iconv("UTF-8", "ASCII//TRANSLIT", "café") still transliterates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the apk phpXX-based 8.3/8.4/8.5 Dockerfiles with builds that
inherit from php:X.Y-cli-alpine. The upstream PHP images compile PHP
from source linked against the current alpine gnu-libiconv package
(--with-iconv=/usr after rm /usr/include/iconv.h), so the LD_PRELOAD
preloadable_libiconv.so workaround and the alpine-3.13/community
package pull go away entirely. iconv //TRANSLIT keeps working.

What changed per Dockerfile:
- FROM php:X.Y-cli-alpine3.NN (3.19 / 3.21 / 3.23).
- docker-php-ext-install bcmath intl mysqli pcntl pdo_mysql pdo_pgsql
  pgsql soap sockets zip; pecl install apcu event memcached yaml.
- event's .ini is forced to load after sockets via the zz- prefix
  (event references sockets symbols at runtime).
- ENTRYPOINT [] resets the upstream docker-php-entrypoint so the
  "empty entrypoint" bats assertion keeps passing.

debug.Dockerfile becomes a passthrough since php-cli-alpine already
ships phpdbg, and php_debug.bats now greps for the unversioned binary.
common/php.bats drops the LD_PRELOAD env-var assertion (no longer
present on 8.3+) and the "iconv works" test now uses non-ASCII input
so it actually exercises //TRANSLIT for every PHP version.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Unlike upstream's php:8.4-cli-alpine (which auto-enables opcache via a
docker-php-ext-opcache.ini in conf.d) and php:8.5-cli-alpine (which
compiles opcache directly into PHP core), the 8.3 base ships opcache
only as an installable shared module. Add it to the docker-php-ext-
enable list so the "Zend OPcache" module assertion in php.bats passes.

Also expect the 8.5 retry to resolve a transient docker.io manifest
fetch error that hit graze/bats on the previous run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated 3 comments.

Comment thread Makefile Outdated
Comment thread common/php.bats
Comment thread 8.5/Dockerfile
rick-lam and others added 4 commits May 28, 2026 15:58
- The bats container mounts the host workspace at /app, so the
  safe.directory entry only needs to cover /app rather than the
  catch-all '*'. Same outcome, scoped to the actual mount.
- The TRANSLIT functional test was asserting an exact "caf'e" match,
  which is what gnu-libiconv 1.15-r3 produces. Newer gnu-libiconv
  (1.18+ used by the docker-library based 8.3-8.5 images) returns
  "cafe" with no apostrophe. Both prove TRANSLIT worked; assert on
  the absence of warnings, a "caf" prefix, and inequality with the
  original input instead of pinning a specific output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace seven hand-edited "build-5.6 build-7.0 ... build-8.5"-style
lines with $(addprefix …,$(VERSIONS)). Adding a future PHP version
now means one edit (the VERSIONS line) instead of touching every
aggregate target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a versions.json at the repo root with one entry per supported
PHP version, including the multi-arch platforms it ships to Docker
Hub. The Makefile derives its VERSIONS list via jq, and the GitHub
Actions workflow now has a tiny prep job that reads the file and
emits the matrix include for the build job to consume.

Adding a new version is now a one-line addition to versions.json;
the Makefile and CI matrix update themselves.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- The image installs the `event` PECL extension, not `ev`; correct the
  name and the linked PHP manual URL.
- The `phpdbg7` example only worked when the :test tag pointed at a
  7.x image. Since :test now resolves to 8.5 (built on docker-library
  php-cli-alpine), the binary is just `phpdbg`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rick-lam rick-lam merged commit 6ccd4e6 into master May 28, 2026
13 checks passed
@rick-lam rick-lam deleted the add-php-8.3-8.5-and-gha branch May 28, 2026 15:27
@biggianteye biggianteye mentioned this pull request May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants