dotnet restore not cached, re-downloading every run in CI
When the NuGet global packages folder is not cached between runs, every CI job re-downloads all dependencies. That is slow and re-exposes the job to any transient feed error on each run.
What this error means
restore takes minutes on every run and occasionally fails on a transient feed timeout, because nothing is cached and each job fetches every package from scratch.
Determining projects to restore...
Restored /home/runner/work/app/app.csproj (in 3 min 42 sec).Common causes
No cache of the global packages folder
Without caching ~/.nuget/packages, restore downloads every dependency again on each run.
Cache key does not track the lockfile
A cache keyed on something other than the lockfile either never hits or serves a stale set, so restore falls back to downloading.
How to fix it
Cache the NuGet packages folder
- Cache
~/.nuget/packageskeyed on the lockfiles. - Restore against the cache so unchanged dependencies are not re-fetched.
- Invalidate only when a lockfile changes.
- uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${{ hashFiles('**/packages.lock.json') }}Enable the built-in cache with lockfiles
setup-dotnet can cache automatically when a lockfile is present, keeping restore fast and deterministic.
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
cache: trueHow to prevent it
- Cache
~/.nuget/packageskeyed on the lockfiles. - Commit lockfiles so cache keys are stable and deterministic.
- Invalidate the cache only when dependencies actually change.