Skip to content

Fix cache restore: dpkg registration, tar permissions, base image hashing#192

Open
robtaylor wants to merge 4 commits intoawalsh128:masterfrom
robtaylor:fix/restore-and-caching
Open

Fix cache restore: dpkg registration, tar permissions, base image hashing#192
robtaylor wants to merge 4 commits intoawalsh128:masterfrom
robtaylor:fix/restore-and-caching

Conversation

@robtaylor
Copy link
Copy Markdown

Summary

Fixes several issues with cache restore reliability:

  • dpkg registration: Cache all /var/lib/dpkg/info/<package>.* files and save dpkg status entries so restored packages are recognized by dpkg -s, apt list --installed, etc. Handle multi-arch packages and version-differing upgrades correctly.
  • tar permissions: Include directories in tar archives to preserve ownership/permissions on restore (prevents 0077 umask issues on GPU runners where restored directories become inaccessible).
  • base image hashing: Hash pre-installed package names into the cache key so runners with different base images (e.g., GPU runners with CUDA pre-installed) get separate caches.
  • apt-fast progress: Use tee instead of redirect so install output is visible in workflow logs, with proper PIPESTATUS error checking.

Test plan

  • basic_install — fresh install + cache round-trip
  • dpkg_registration — verify dpkg -s reports packages after restore
  • basic_cache_hit — second run restores from cache
  • CI passes on all test jobs in action-tests.yml

After cache restore, dpkg had no record of the installed packages because:
1. Only preinst/postinst scripts were cached from /var/lib/dpkg/info/,
   missing .list, .md5sums, .conffiles, and other metadata files
2. The dpkg status database (/var/lib/dpkg/status) was never updated

This meant dpkg -s, apt list --installed, and anything checking package
state would not see the restored packages.

Fix:
- Cache all /var/lib/dpkg/info/<package>.* files (not just install scripts)
- Save each package's dpkg status entry to a .dpkg-status file
- On restore, append status entries to /var/lib/dpkg/status (skipping
  packages that are already registered)

Additionally:
- Include directories in tar archives so that tar preserves their ownership
  and permissions on restore (prevents 0077 umask issues on GPU runners)
- Include architecture qualifier (e.g., :i386) from apt's Unpacking log
  in get_installed_packages, so multi-arch variants get separate cache
  entries instead of being deduplicated
- When registering restored packages with dpkg, compare cached vs installed
  versions and handle upgrades by replacing the old status entry

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)
Hash the list of pre-installed package names (dpkg-query -W) into the
cache key. This prevents cache collisions when different runners (e.g.,
GPU runners with CUDA pre-installed vs plain Ubuntu) request the same
packages — a cache built where packages were already present won't be
restored on a runner where they're missing.

Also adds a ::notice annotation so users can see the fingerprint in
the workflow summary and understand why different runners produce
different cache keys.

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)
- Use tee instead of redirect so install output is visible in the
  workflow log while still being captured to the install log file
- Check PIPESTATUS[0] for the actual apt-fast exit code (since tee
  always succeeds) and exit with a clear error message on failure
- Remove the redundant installed package list logging — the full
  install output is now visible via tee, and the individual cache
  lines already show each package being processed

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)
Add comprehensive integration test workflow that exercises the action's
install, cache, and restore paths with real packages on GitHub Actions
runners. Tests cover:

- Basic install and cache round-trip (xdot, libxml2-dev)
- Cache hit and version pinning verification
- Custom apt repository support (ppa:savoury1/ffmpeg6)
- Multiple package installs with dependencies
- Support for apt-mark'd packages and version-pinned packages
- ARM64 architecture support
- Package with conflicts (default-jdk replacing default-jre-headless)
- Invalid inputs (bad version, empty packages, bad repo)
- dpkg registration verification after cache restore

Co-developed-by: Claude Code v2.1.58 (claude-opus-4-6)
@scottrobertson
Copy link
Copy Markdown

This would be good to get merged. It fixes the installation of imagemagick from what I can see.

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