Fix Forgejo Actions cache backend (actions/cache@v4 always misses) #16

Open
opened 2026-06-10 19:58:16 +02:00 by myrmidex · 0 comments
Owner

Problem

A recent CI run breakdown:

Set up job              19s
checkout@v4              1s
Cache PHP installation   1s
Set up PHP            7m46s
Cache Composer deps      1s
Install dependencies    17s
Build Tailwind CSS       16s
Lint                      3s
Static analysis          17s
Architecture (Deptrac)    2s
Create/migrate test DB    3s
Tests                     1s
Parse coverage            0s
Comment coverage on PR    0s
Complete job              0s

Total ~9 minutes, of which "Set up PHP" is 7m46s — everything else combined is under 1 minute.

Investigation summary (2026-06-10)

Extensive debugging session, findings:

  1. actions/cache@v4 never saves on this runner. Confirmed via ACTIONS_STEP_DEBUG=true:

    • ACTIONS_CACHE_URL is correctly injected into job containers (e.g. http://192.168.178.172:41843/<scope>/)
    • The cache proxy is reachable from inside the job container (curl gets a real HTTP 301 response)
    • Restore makes a real round-trip and gets a genuine "not found" (not a silent skip)
    • No "Post Cache ..." step ever appears in the job's step list — the save/upload phase never runs, for either the /usr/local/php or ~/.composer/cache cache entries, even after composer install populated ~/.composer/cache
    • This affects every repo on this runner using actions/cache@v4 (rater, ffr, trove, buckets-budget) — none have ever produced a cache entry on disk (~/.cache/actcache/cache/ only contains entries from docker/setup-buildx-action and actions/setup-node's built-in caching, not plain actions/cache@v4)
  2. Separately: the /usr/local/php cache path was also wrong regardless — setup-php@v2 installs PHP to /usr/bin/php, not /usr/local/php, so that cache path would never have anything to save even if caching worked.

  3. Runner version: forgejo-runner v12.6.4 (current at time of investigation).

Conclusion

This looks like either a runner-level limitation/bug (post-step for actions/cache@v4 not executing in container jobs on this runner version) or a deeper Forgejo Actions cache-server quirk not yet root-caused. Diagnosis was inconclusive after ~2h of investigation; further digging would likely require filing an issue upstream against forgejo/runner with this reproduction.

Decision

Deprioritized in favor of #17 (custom CI image with PHP 8.4 + Tailwind binary baked in), which sidesteps this caching mystery entirely and addresses the actual time cost more directly. The dead/non-functional cache steps and /usr/local/php cache were removed from ci.yml as part of that pivot.

Revisit if: (a) actions/cache@v4 becomes valuable for a future use case (e.g. Playwright browser binary caching) where #17-style baking-in isn't practical, or (b) a runner upgrade changes this behavior.

## Problem A recent CI run breakdown: ``` Set up job 19s checkout@v4 1s Cache PHP installation 1s Set up PHP 7m46s Cache Composer deps 1s Install dependencies 17s Build Tailwind CSS 16s Lint 3s Static analysis 17s Architecture (Deptrac) 2s Create/migrate test DB 3s Tests 1s Parse coverage 0s Comment coverage on PR 0s Complete job 0s ``` Total ~9 minutes, of which **"Set up PHP" is 7m46s** — everything else combined is under 1 minute. ## Investigation summary (2026-06-10) Extensive debugging session, findings: 1. **`actions/cache@v4` never saves on this runner.** Confirmed via `ACTIONS_STEP_DEBUG=true`: - `ACTIONS_CACHE_URL` is correctly injected into job containers (e.g. `http://192.168.178.172:41843/<scope>/`) - The cache proxy is reachable from inside the job container (`curl` gets a real HTTP 301 response) - Restore makes a real round-trip and gets a genuine "not found" (not a silent skip) - **No "Post Cache ..." step ever appears in the job's step list** — the save/upload phase never runs, for either the `/usr/local/php` or `~/.composer/cache` cache entries, even after `composer install` populated `~/.composer/cache` - This affects **every repo on this runner** using `actions/cache@v4` (`rater`, `ffr`, `trove`, `buckets-budget`) — none have ever produced a cache entry on disk (`~/.cache/actcache/cache/` only contains entries from `docker/setup-buildx-action` and `actions/setup-node`'s built-in caching, not plain `actions/cache@v4`) 2. **Separately**: the `/usr/local/php` cache path was also wrong regardless — `setup-php@v2` installs PHP to `/usr/bin/php`, not `/usr/local/php`, so that cache path would never have anything to save even if caching worked. 3. Runner version: `forgejo-runner v12.6.4` (current at time of investigation). ## Conclusion This looks like either a runner-level limitation/bug (post-step for `actions/cache@v4` not executing in container jobs on this runner version) or a deeper Forgejo Actions cache-server quirk not yet root-caused. Diagnosis was inconclusive after ~2h of investigation; further digging would likely require filing an issue upstream against `forgejo/runner` with this reproduction. ## Decision Deprioritized in favor of **#17** (custom CI image with PHP 8.4 + Tailwind binary baked in), which sidesteps this caching mystery entirely and addresses the actual time cost more directly. The dead/non-functional cache steps and `/usr/local/php` cache were removed from `ci.yml` as part of that pivot. Revisit if: (a) `actions/cache@v4` becomes valuable for a future use case (e.g. Playwright browser binary caching) where #17-style baking-in isn't practical, or (b) a runner upgrade changes this behavior.
myrmidex added this to the v0.1.0 MVP milestone 2026-06-10 19:58:16 +02:00
myrmidex added the
ci-cd
label 2026-06-10 19:58:16 +02:00
myrmidex self-assigned this 2026-06-10 19:59:03 +02:00
myrmidex changed title from CI "Set up PHP" step takes 7m46s of a ~9min pipeline to Fix Forgejo Actions cache backend (actions/cache@v4 always misses) 2026-06-10 20:05:40 +02:00
myrmidex added the
bug
label 2026-06-11 00:47:40 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lvl0/rater#16
No description provided.