पाठ 13 / 25
Dependency Caching
Keys, restore keys and lockfiles.
Exact keys and fallbacks
Caching restores dependency directories between runs. A cache key usually combines the OS and a hash of the lockfile (hashFiles('**/package-lock.json')), so the key changes exactly when dependencies change. On a miss, restore-keys prefixes allow a partial hit from an older cache, after which the package manager installs only the difference. Many setup actions (setup-node, setup-python, setup-java) have a built-in cache: option. Caches are scoped by branch, with access to the default branch's caches, and old entries are evicted when the repository's cache limit is reached.
Less waiting, fewer minutes
Caching, concurrency control and timeouts cut cost and feedback time.
Exact hits, partial hits and misses, run
I ran this with Python 3. It is a simplified model of GitHub Actions behaviour for learning, not GitHub's implementation. The same lockfile restores the cache exactly; a changed lockfile misses the exact key but restores the older Linux cache through the restore-key prefix; a macOS job has no matching cache and installs everything.
import hashlib
def hash_files(*contents):
h = hashlib.sha256()
for c in contents: h.update(c.encode())
return h.hexdigest()[:12]
lock_v1 = '{"lodash": "4.17.21"}'
lock_v2 = '{"lodash": "4.17.21", "zod": "3.23.8"}'
saved = {f"npm-Linux-{hash_files(lock_v1)}": "node_modules@v1"} # caches already stored
def restore(key, restore_keys):
if key in saved: return f"exact hit: {key}"
for prefix in restore_keys: # newest matching prefix wins
hits = [k for k in saved if k.startswith(prefix)]
if hits: return f"partial hit via '{prefix}': {hits[-1]} (then npm installs the difference)"
return "miss: full install"
print(restore(f"npm-Linux-{hash_files(lock_v1)}", ["npm-Linux-"]))
print(restore(f"npm-Linux-{hash_files(lock_v2)}", ["npm-Linux-"]))
print(restore(f"npm-macOS-{hash_files(lock_v2)}", ["npm-macOS-"]))
Output:
exact hit: npm-Linux-bb5d4b6bb85e partial hit via 'npm-Linux-': npm-Linux-bb5d4b6bb85e (then npm installs the difference) miss: full install
Cache dependencies, not build outputs of untrusted code
Cache poisoning is possible if untrusted workflows can write caches used by trusted ones; keep sensitive release builds cache-free or isolated.
त्वरित जाँच: What should a dependency cache key usually include?
- The current time
- The OS and a hash of the lockfile
- A random number
- The workflow file name only
Answer
The OS and a hash of the lockfile — Change the key exactly when dependencies change.