Which cache key strategy ensures the npm cache is invalidated when package-lock.json changes?
Select an answer to reveal the explanation.
Short Explanation and Infographic
Hash the lock file, prefix with OS — you get an exact fingerprint that changes only when dependencies actually change.
Full explanation below image
Full Explanation
The recommended cache key pattern is '${{ runner.os }}-npm-${{ hashFiles("**/package-lock.json") }}'. Breaking it down: 'runner.os' ensures separate caches per OS (node_modules can differ between Linux/Windows/macOS); 'npm-' provides a namespace; 'hashFiles()' generates a SHA-256 of the lock file contents, changing whenever dependencies change. Using 'github.run_id' creates a new cache every run (defeating the purpose). Using 'github.ref' creates per-branch caches that miss across branches. 'npm-latest' is static and never invalidates.