Skip to content

Cache the apt archives, and verify the cache is used (#386) - #410

Open
ChronicallyJD wants to merge 1 commit into
commandprompt:mainfrom
ChronicallyJD:fix/386-apt-cache
Open

Cache the apt archives, and verify the cache is used (#386)#410
ChronicallyJD wants to merge 1 commit into
commandprompt:mainfrom
ChronicallyJD:fix/386-apt-cache

Conversation

@ChronicallyJD

Copy link
Copy Markdown
Collaborator

Closes #386, implementing the plan from the issue.

What this does

apt writes its archives to ~/apt-archives, which actions/cache keys on the PG major,
runner OS and arch, and ImageOS. Four install steps across ci.yml and nightly.yml.

ImageOS is in the key deliberately: a new runner image can bring a different LLVM major,
and a key that ignored it would serve debs for the wrong one.

The half I care about more

On a reported cache hit, the step fails if apt fetched anything over the network.

if [ "${{ steps.apt-build.outputs.cache-hit }}" = "true" ] \
   && grep -qE '^Get:[0-9]+ https?://' /tmp/apt-install.log; then
  echo "::error::apt cache reported a hit but packages were downloaded anyway"

A cache that populates and never hits looks identical in the log to one that works. The job
is simply still slow and nothing says so. That is the same shape as #396, where the suite
had the exemption and not the invocation, and it is the failure I would otherwise be
shipping here.

What I did not do

Raise the bound. At 30 kB/s the fetch needs about 50 minutes, so that trades a red check
for a runner held most of an hour.

Pin a mirror. The runner picks from its own mirrorlist. Betting on a different one is
the bet we are already losing.

Drop the toolchain. apt-cache depends postgresql-server-dev-18 shows
Depends: clang-21 and Depends: llvm-21-dev, hard, so no apt flag removes them. jd's view
and mine is that there is no reason to want to: it is a legitimate dependency of
postgresql-server-dev-N.

What I could not verify, and how it fails

I cannot run GitHub Actions locally, so the first CI run on this PR is the test. I have
validated what I can: both workflows still parse as YAML, all four install steps route
their archives and tee their output, and no package was dropped from any list.

That last one is not rhetorical. My first patch attempt inserted the tee mid-list:

liblz4-dev libzstd-dev zlib1g-dev 2>&1 | tee /tmp/apt-install.log python3-pip lcov

which would have silently stopped installing lcov and python3-pip in the coverage job.
Caught by reading the generated file rather than trusting the script. Fixed, and every
package list is asserted intact in the diff.

The failure modes are benign by construction. A miss degrades to exactly today's behaviour.
A stale entry is re-fetched by apt rather than used, because apt validates what is in the
archive directory. So the downside is a slow job, not a wrong one.

Worth watching the first few runs for the hit rate rather than assuming it.

…oads anyway

The measurement on commandprompt#386: across the last 80 runs, 352 successes of this step at
a median of 25s, and six failures all pinned at 606 to 608s. Nothing in between.
The step either finishes in half a minute or hits the 600s bound.

The stall is azure.archive.ubuntu.com serving the LLVM toolchain at around
30 kB/s. That toolchain is 91 MB of the 102 MB and is a hard dependency:

  $ apt-cache depends postgresql-server-dev-18
    Depends: clang-21
    Depends: llvm-21-dev

so --no-install-recommends cannot drop it, and there is no reason to want to.
It is a legitimate dependency. The problem is downloading it repeatedly across
a mirror that intermittently will not serve it.

apt now writes its archives to a cached directory, keyed on the PG major, the
runner OS and arch, and ImageOS. ImageOS is in the key because a new runner
image can bring a different LLVM major, and a key that ignored it would serve
debs for the wrong one.

The second half matters more than the first. A cache that populates and never
hits looks identical in the log to one that works: the job is simply still
slow, and nothing reports it. So on a reported hit, the step now fails if apt
fetched anything over the network. That is the same defect shape as commandprompt#396, where
a suite was exempt from the registration check and never invoked.

Two things deliberately not done, both from the issue:

Raising the bound. At 30 kB/s the fetch needs roughly 50 minutes, which trades
a red check for a runner held most of an hour.

Pinning a different mirror. The runner chooses from its own mirrorlist, and
betting on a different one is the same bet we are losing now.

A cache miss degrades to exactly today's behaviour, and a stale entry is
re-fetched by apt rather than used, so the failure mode is a slow job and not a
wrong one.
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.

CI: the PostgreSQL install step times out at exit 124, five times on 2026-08-04

1 participant