Cache the packages php-builder installs, and restore PHP 8.5 #181

Merged
thatguygriff merged 4 commits from ci/cache-php-builder-deps into main 2026-08-20 19:18:46 +00:00
Owner

Now that thatguygriff/infra#1 has the runner cache server running, actions/cache has an endpoint for the first time and this can finally do something.

The cache

On self-hosted runners setup-php installs PHP 8.3+ through php-builder, whose install.sh apt-installs ~70 -dev packages before unpacking the build. The build tarball is only 19MB, so that apt work is essentially the whole cost of the step — the ~145s floor, the long tail, and the occasional hard timeout (#178).

Ubuntu's image drops the .debs after install, so every job re-fetches them. This keeps them and restores them through the cache server, which lives in the cluster, turning a WAN download into a local one.

Keyed per PHP version. Run 536 showed why: with one shared key, the jobs that saved it were 8.1 and 8.2. They take the ondrej PPA path — a handful of runtime packages — while 8.3+ takes php-builder and its ~70 -dev packages. A shared key lets whichever job finishes first decide what everyone else restores, and 8.1 is always first at ~30s against 8.3's several minutes. 8.3 would have restored a few useless .debs and then downloaded all 70 anyway.

Only the .debs are cached, never /var/lib/apt/lists — a stale index is how apt starts 404ing mid-install, and reducing flakiness is the point.

actions/cache moves to v4, since v4.2+ speaks the cache service v2 API the runner serves.

PHP 8.5

Back in the matrix. I removed it in f6481d4 on a misreading of "hold 8.5" and #179 merged without it; it was meant to stay. It takes the same php-builder path as 8.3, so the cache here is exactly what it needs. composer test passes on 8.5.9 locally: 915 tests, 2592 assertions.

Verified

The cache is confirmed working end to end — from run 536:

ACTIONS_CACHE_URL: http://10.42.0.41:34075/
Cache saved with key: apt-php-builder-deps-ARM64-v1

No GHES warning any more; the runner's bundle patching engages once there is a URL to patch toward.

Baseline to beat, run 526: 8.1 30s, 8.2 53s, 8.3 454s, quality 151s. 8.1 and 8.2 are the control — they take the ondrej path and should barely move.

No temporary steps remain. Keep downloaded .debs is not instrumentation: it disables Ubuntu's docker-clean, without which there are no .debs left to cache.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Uw545F1vveNJKjzLxdi2ks

Now that thatguygriff/infra#1 has the runner cache server running, `actions/cache` has an endpoint for the first time and this can finally do something. ## The cache On self-hosted runners setup-php installs PHP 8.3+ through php-builder, whose `install.sh` apt-installs **~70 `-dev` packages** before unpacking the build. The build tarball is only 19MB, so that apt work is essentially the whole cost of the step — the ~145s floor, the long tail, and the occasional hard timeout (#178). Ubuntu's image drops the `.debs` after install, so every job re-fetches them. This keeps them and restores them through the cache server, which lives in the cluster, turning a WAN download into a local one. **Keyed per PHP version.** Run 536 showed why: with one shared key, the jobs that saved it were 8.1 and 8.2. They take the ondrej PPA path — a handful of runtime packages — while 8.3+ takes php-builder and its ~70 `-dev` packages. A shared key lets whichever job finishes first decide what everyone else restores, and 8.1 is always first at ~30s against 8.3's several minutes. 8.3 would have restored a few useless `.debs` and then downloaded all 70 anyway. Only the `.debs` are cached, never `/var/lib/apt/lists` — a stale index is how apt starts 404ing mid-install, and reducing flakiness is the point. `actions/cache` moves to v4, since v4.2+ speaks the cache service v2 API the runner serves. ## PHP 8.5 Back in the matrix. I removed it in `f6481d4` on a misreading of "hold 8.5" and #179 merged without it; it was meant to stay. It takes the same php-builder path as 8.3, so the cache here is exactly what it needs. `composer test` passes on 8.5.9 locally: 915 tests, 2592 assertions. ## Verified The cache is confirmed working end to end — from run 536: ``` ACTIONS_CACHE_URL: http://10.42.0.41:34075/ Cache saved with key: apt-php-builder-deps-ARM64-v1 ``` No GHES warning any more; the runner's bundle patching engages once there is a URL to patch toward. Baseline to beat, run 526: 8.1 30s, 8.2 53s, 8.3 454s, quality 151s. 8.1 and 8.2 are the control — they take the ondrej path and should barely move. No temporary steps remain. `Keep downloaded .debs` is not instrumentation: it disables Ubuntu's `docker-clean`, without which there are no `.debs` left to cache. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Uw545F1vveNJKjzLxdi2ks
thatguygriff added 3 commits 2026-08-20 18:57:31 +00:00
Experiment for #178. On self-hosted runners setup-php installs PHP 8.3+
through php-builder, whose install.sh apt-installs ~70 -dev packages
before unpacking the build. The build tarball itself is only 19MB, so
that apt work is the whole cost, not the download.

Ubuntu's image drops the .debs after install, so every job fetches them
from the archive again. This keeps them and restores them through the
cache server, which lives in the cluster, so a WAN download becomes a
local one. The dependency list does not vary by PHP version, so a single
key serves 8.3 and 8.5 and the quality and build jobs alike.

Only the .debs are cached. /var/lib/apt/lists is deliberately left alone,
since a stale index is how apt starts 404ing mid-install, and reducing
flakiness is the entire point.

The Report restored .debs step is temporary instrumentation to show
whether the cache is actually being read. Baseline to beat, from run 526:
8.1 30s, 8.2 53s, 8.3 454s, quality 151s, 8.5 733s and a hard failure.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Uw545F1vveNJKjzLxdi2ks
thatguygriff/infra#1 turned the runner cache server on, so actions/cache
has an endpoint for the first time. v4 rather than v3 because v4.2+ can
speak the cache service v2 API, which is what the runner serves.

The instrumentation step now also prints ACTIONS_CACHE_URL, so a single
run shows the endpoint arriving and the cache being read in one log
rather than needing a separate probe.

Refs #178.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Uw545F1vveNJKjzLxdi2ks
Key the apt cache per PHP version and drop the instrumentation
CI / No Debug Code (pull_request) Successful in 26s
CI / Tests (PHP 8.1) (pull_request) Successful in 2m35s
CI / Tests (PHP 8.2) (pull_request) Successful in 2m35s
CI / Coding Standards & Static Analysis (pull_request) Successful in 4m1s
CI / Tests (PHP 8.3) (pull_request) Failing after 7m17s
CI / Build Plugin Zip (pull_request) Skipped
a90e06ae70
Run 536 proved the cache works -- ACTIONS_CACHE_URL is now populated, no
GHES warning, "Cache saved with key: apt-php-builder-deps-ARM64-v1" -- and
in doing so showed the key was wrong. The jobs that saved it were 8.1 and
8.2.

They take the ondrej PPA path, a handful of runtime packages, while 8.3
takes php-builder and its ~70 -dev packages. One shared key therefore lets
whichever job finishes first decide what every other job restores, and 8.1
is always first, at ~30s against 8.3's several minutes. 8.3 would have
restored a few runtime .debs it has no use for and then downloaded all 70
anyway. My "the dep list is the same for every PHP version" comment was
true only among the builder versions.

Keyed per version now, so each path caches what it actually installs. That
also picks up a small win on 8.1 and 8.2 rather than only avoiding harm.

Both temporary steps are gone. Report restored .debs was there to show the
cache URL arriving and the restore landing; both are established, so it
goes. Keep downloaded .debs stays -- it is not instrumentation, it disables
Ubuntu's docker-clean, without which there are no .debs left to cache.

Refs #178.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Uw545F1vveNJKjzLxdi2ks
thatguygriff force-pushed ci/cache-php-builder-deps from 3436b02ff5 to a90e06ae70 2026-08-20 18:57:31 +00:00 Compare
thatguygriff added 1 commit 2026-08-20 19:04:55 +00:00
Put PHP 8.5 back in the matrix
CI / No Debug Code (pull_request) Successful in 4s
CI / Tests (PHP 8.2) (pull_request) Successful in 55s
CI / Tests (PHP 8.1) (pull_request) Successful in 1m15s
CI / Tests (PHP 8.5) (pull_request) Successful in 6m41s
CI / Tests (PHP 8.3) (pull_request) Failing after 12m21s
CI / Coding Standards & Static Analysis (pull_request) Successful in 13m48s
CI / Build Plugin Zip (pull_request) Skipped
37c8d2b39e
I misread the instruction to hold 8.5 as "take it out until the cache
lands" and removed it in f6481d4, so #179 merged without it. It was meant
to stay where it was. Restoring it.

8.5 takes the same php-builder path as 8.3, so the apt cache in this
branch is exactly what it needs, and the per-version key means it caches
its own ~70 -dev packages rather than sharing with the ondrej-path jobs.

composer test passes on 8.5.9 locally: 915 tests, 2592 assertions.

Refs #178.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Uw545F1vveNJKjzLxdi2ks
thatguygriff changed title from Cache the packages php-builder installs to Cache the packages php-builder installs, and restore PHP 8.5 2026-08-20 19:05:13 +00:00
thatguygriff merged commit 8a34ec41e9 into main 2026-08-20 19:18:46 +00:00
thatguygriff deleted branch ci/cache-php-builder-deps 2026-08-20 19:18:47 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Unsupervised/unsupervised-scheduler#181